00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include <eh_utils.h>
00022
00023 CLASS( Eh_opt_context )
00024 {
00025 GOptionContext* context;
00026 Eh_symbol_table values;
00027 gchar* name;
00028 gchar* description;
00029 gchar* help_description;
00030 };
00031
00032
00033
00034
00035
00036 gboolean add_new_value( const gchar* option_name ,
00037 const gchar* value ,
00038 gpointer data ,
00039 GError **error )
00040 {
00041 gchar* new_str=NULL;
00042
00043 if ( g_str_has_prefix(option_name , "--" ) )
00044 new_str = g_strdup( option_name+2 );
00045 else if ( g_str_has_prefix(option_name , "-" ) )
00046 new_str = g_strdup( option_name+1 );
00047 else
00048 eh_require_not_reached();
00049
00050 eh_symbol_table_replace( data , new_str , g_strdup(value) );
00051
00052 return TRUE;
00053 }
00054
00055 gssize get_n_entries( Eh_opt_entry* entries )
00056 {
00057 gssize n_entries;
00058
00059 for ( n_entries=0 ; entries[n_entries].long_name != NULL ; n_entries++ );
00060
00061 return n_entries;
00062 }
00063
00064 GOptionEntry convert_eh_option_entry_to_g_option_entry( Eh_opt_entry entry )
00065 {
00066 GOptionEntry new_entry;
00067
00068 new_entry.long_name = entry.long_name;
00069 new_entry.short_name = entry.short_name;
00070 new_entry.flags = 0;
00071
00072 new_entry.arg = G_OPTION_ARG_CALLBACK;
00073 new_entry.arg_data = &add_new_value;
00074
00075 new_entry.description = entry.description;
00076 new_entry.arg_description = entry.arg_description;
00077
00078 return new_entry;
00079 }
00080
00081 Eh_symbol_table set_default_values( const char *name ,
00082 Eh_opt_entry* entries ,
00083 Eh_symbol_table tab )
00084 {
00085 char *ehrc = g_strdup( ".ehrc" );
00086 char *cur_dir = g_get_current_dir();
00087 const char *home_dir = g_get_home_dir();
00088 char *rc_file;
00089 gssize n_entries = get_n_entries( entries );
00090 Eh_symbol_table default_tab = NULL;
00091 gssize i;
00092
00093
00094
00095
00096 if ( tab )
00097 default_tab = tab;
00098 else
00099 default_tab = eh_symbol_table_new();
00100
00101
00102
00103
00104 for ( i=0 ; i<n_entries ; i++ )
00105 eh_symbol_table_insert( default_tab ,
00106 (gchar*)entries[i].long_name ,
00107 (gchar*)entries[i].default_val );
00108
00109
00110
00111
00112 rc_file = g_build_filename( home_dir , ehrc , NULL );
00113 if ( eh_is_readable_file( rc_file ) )
00114 default_tab = eh_key_file_scan_for( rc_file , name , default_tab , NULL );
00115 eh_free( rc_file );
00116
00117
00118
00119
00120 rc_file = g_build_filename( cur_dir , ehrc , NULL );
00121 if ( eh_is_readable_file( rc_file ) )
00122 default_tab = eh_key_file_scan_for( rc_file , name , default_tab , NULL );
00123
00124 eh_free( rc_file );
00125
00126 eh_free( ehrc );
00127 eh_free( cur_dir );
00128
00129 return default_tab;
00130 }
00131
00132
00133
00134
00135
00136 Eh_opt_context eh_opt_create_context( const gchar* name ,
00137 const gchar* description ,
00138 const gchar* help_description )
00139 {
00140 Eh_opt_context new_context;
00141
00142 NEW_OBJECT( Eh_opt_context , new_context );
00143
00144 new_context->context = g_option_context_new( description );
00145 new_context->name = g_strdup( name );
00146 new_context->description = g_strdup( description );
00147 new_context->help_description = g_strdup( help_description );
00148 new_context->values = eh_symbol_table_new();
00149
00150 return new_context;
00151 }
00152
00153 Eh_opt_context eh_destroy_context( Eh_opt_context context )
00154 {
00155 if ( context )
00156 {
00157 eh_free( context->name );
00158 eh_free( context->description );
00159 eh_free( context->help_description );
00160
00161 g_option_context_free( context->context );
00162 eh_symbol_table_destroy( context->values );
00163
00164 eh_free( context );
00165
00166 context = NULL;
00167 }
00168
00169 return context;
00170 }
00171
00172 Eh_opt_context eh_opt_set_context( Eh_opt_context context ,
00173 Eh_opt_entry* entries )
00174 {
00175 gssize n_entries = get_n_entries( entries );
00176 GOptionEntry* g_entry = g_new( GOptionEntry , n_entries+1 );
00177 GOptionGroup* grp;
00178 gssize i;
00179
00180
00181
00182
00183
00184 set_default_values( context->name , entries , context->values );
00185
00186
00187
00188
00189 for ( i=0 ; i<n_entries ; i++ )
00190 {
00191 g_entry[i] = convert_eh_option_entry_to_g_option_entry( entries[i] );
00192 }
00193 g_entry[n_entries].long_name = NULL;
00194
00195
00196
00197
00198 grp = g_option_group_new( context->name ,
00199 context->description ,
00200 context->help_description ,
00201 context->values ,
00202 NULL );
00203 g_option_group_add_entries( grp , g_entry );
00204
00205
00206
00207
00208 g_option_context_add_group( context->context , grp );
00209
00210 return context;
00211 }
00212
00213 gboolean eh_opt_parse_context( Eh_opt_context context ,
00214 gint* argc ,
00215 gchar*** argv ,
00216 GError** error )
00217 {
00218 return g_option_context_parse( context->context , argc , argv , error );
00219 }
00220
00221 void eh_opt_print_label_value( Eh_opt_context context , char *label )
00222 {
00223 fprintf( stderr , "%s=%s" , label , eh_opt_value( context , label ) );
00224 }
00225
00226 char *eh_opt_value( Eh_opt_context context , char* label )
00227 {
00228 char *value = eh_symbol_table_lookup( context->values , label );
00229 char *rtn = NULL;
00230 if ( value )
00231 rtn = value;
00232 return rtn;
00233 }
00234
00235 char* eh_opt_str_value( Eh_opt_context c , char* label )
00236 {
00237 char *value = eh_opt_value( c , label );
00238 char *rtn = NULL;
00239
00240 if ( value )
00241 rtn = g_strdup(value);
00242
00243 return rtn;
00244 }
00245
00246 gboolean
00247 eh_opt_bool_value( Eh_opt_context c , char *label )
00248 {
00249 char *value = eh_opt_value( c , label );
00250 gboolean rtn = FALSE;
00251
00252 if ( value )
00253 rtn = eh_str_to_boolean( value , NULL );
00254
00255 return rtn;
00256 }
00257
00258 int eh_opt_key_value( Eh_opt_context c , char *label , char *keys[] )
00259 {
00260 char *value = eh_opt_value( c , label );
00261 int rtn = -1;
00262
00263 if ( value )
00264 {
00265 gssize i;
00266
00267 for ( i=0 ; keys[i] ; i++ )
00268 if ( g_ascii_strcasecmp( value , keys[i] )==0 )
00269 {
00270 rtn = i;
00271 break;
00272 }
00273
00274 if ( !keys[i] )
00275 {
00276 fprintf( stderr ,
00277 "error : unknown key (%s) for opt %s.\n" ,
00278 value ,
00279 label );
00280
00281 fprintf( stderr , "error : possible keys are: ");
00282 for ( i=0 ; keys[i+1] ; i++ )
00283 fprintf( stderr , "%s, " , keys[i] );
00284 fprintf( stderr , "or %s\n" , keys[i] );
00285
00286 eh_exit(-1);
00287 }
00288 }
00289
00290 return rtn;
00291 }
00292
00293 gint eh_opt_int_value( Eh_opt_context c , char *label )
00294 {
00295 char *value = eh_opt_value( c , label );
00296 int rtn = G_MININT;
00297
00298 if ( value )
00299 sscanf(value, "%d" , &rtn );
00300
00301 return rtn;
00302 }
00303
00304 double eh_opt_dbl_value( Eh_opt_context c , char *label )
00305 {
00306 char *value = eh_opt_value( c , label );
00307 double rtn = G_MINDOUBLE;
00308
00309 if ( value )
00310 sscanf(value, "%lf" , &rtn );
00311
00312 return rtn;
00313 }
00314
00315 void eh_opt_print_label_value_helper( gchar* label , gchar* value , gpointer fp )
00316 {
00317 fprintf( fp , "%s=%s\n" , label , value );
00318 }
00319
00320 void eh_opt_print_key_file( Eh_opt_context c , FILE *fp )
00321 {
00322 fprintf( fp , "[ %s ]\n" , c->name );
00323 eh_symbol_table_foreach( c->values ,
00324 (GHFunc)&eh_opt_print_label_value_helper ,
00325 fp );
00326 return;
00327 }
00328
00329 typedef struct
00330 {
00331 int max_key_len;
00332 int max_value_len;
00333 Eh_opt_context context;
00334 }
00335 Print_opt_padded_st;
00336
00337 void eh_opt_print_opt_padded( char *key ,
00338 char *unused ,
00339 Print_opt_padded_st *user_data ) ;
00340 void eh_opt_get_max_label_length( char *key ,
00341 char *value ,
00342 Print_opt_padded_st *user_data );
00343
00344 void eh_opt_print_all_opts( Eh_opt_context c , FILE *fp )
00345 {
00346 Print_opt_padded_st data;
00347
00348 data.max_key_len = 0;
00349 data.max_value_len = 0;
00350 data.context = c;
00351
00352 fprintf( fp , "--- %s ---\n" , c->name );
00353
00354 eh_symbol_table_foreach( c->values ,
00355 (GHFunc)&eh_opt_get_max_label_length ,
00356 &data );
00357
00358 eh_symbol_table_foreach( c->values ,
00359 (GHFunc)&eh_opt_print_opt_padded ,
00360 &data );
00361
00362 return;
00363 }
00364
00365 void eh_opt_print_opt_padded( char *key ,
00366 char *unused ,
00367 Print_opt_padded_st *user_data )
00368 {
00369 char *str;
00370 char *value;
00371
00372 str = g_strdup_printf( "%%-%ds : %%-%ds\n" ,
00373 user_data->max_key_len ,
00374 user_data->max_value_len );
00375 value = eh_opt_value( user_data->context , key );
00376 if ( strlen( value )>0 && g_strtod(value,NULL)!=E_NOVAL )
00377 fprintf( stderr , str , key , value );
00378 else
00379 fprintf( stderr , str , key , "<no value>" );
00380 eh_free( str );
00381
00382 return;
00383 }
00384
00385 void eh_opt_get_max_label_length( char *key ,
00386 char *value ,
00387 Print_opt_padded_st *user_data )
00388 {
00389 int key_len = strlen( key );
00390 int value_len = strlen( value );
00391
00392 if ( key_len > user_data->max_key_len )
00393 user_data->max_key_len = key_len;
00394 if ( value_len > user_data->max_value_len )
00395 user_data->max_value_len = value_len;
00396
00397 return;
00398 }
00399