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 Eh_args *eh_create_args( void )
00024 {
00025 Eh_args *new_args = eh_new( Eh_args , 1 );
00026 new_args->args = eh_symbol_table_new();
00027 new_args->defaults = eh_symbol_table_new();
00028 return new_args;
00029 }
00030
00031 void eh_destroy_args( Eh_args *args )
00032 {
00033 if ( args )
00034 {
00035 if ( args->args )
00036 eh_symbol_table_destroy( args->args );
00037 if ( args->defaults )
00038 eh_symbol_table_destroy( args->defaults );
00039 eh_free( args );
00040 }
00041 }
00042
00043 Eh_args *eh_opts_init( int argc, char *argv[] )
00044 {
00045 Eh_args* args = eh_new( Eh_args , 1 );
00046 char *base_name = g_path_get_basename( argv[0]);
00047 int i, len, arg_no;
00048 char **opt;
00049 char *label, *value;
00050
00051 args->args = eh_symbol_table_new();
00052
00053 for ( i=1,arg_no=0 ; i<argc ; i++ )
00054 {
00055 opt = g_strsplit( argv[i] , "=" , -1 );
00056 for ( len=0 ; opt[len] ; len++ );
00057 if ( len==1 )
00058 {
00059 label = g_strdup_printf( "arg%d" , arg_no );
00060 value = opt[0];
00061 arg_no++;
00062 }
00063 else
00064 {
00065 label = g_strstrip(opt[0]);
00066 value = g_strstrip(opt[1]);
00067 }
00068 eh_free( opt );
00069 eh_symbol_table_insert( args->args , label , value );
00070 }
00071
00072 args->defaults = eh_get_opt_defaults( base_name );
00073
00074 eh_free( base_name );
00075
00076 return args;
00077 }
00078
00079 Eh_symbol_table eh_get_opt_defaults( const char *prog_name )
00080 {
00081 char *ehrc = g_strdup( ".ehrc" );
00082 char *cur_dir = g_get_current_dir();
00083 const char *home_dir = g_get_home_dir();
00084 char *rc_file;
00085 Eh_symbol_table defaults;
00086 Eh_symbol_table home_defaults=NULL;
00087 Eh_symbol_table dir_defaults=NULL;
00088
00089
00090 rc_file = g_strconcat( home_dir , "/" , ehrc , NULL );
00091 if ( eh_is_readable_file( rc_file ) )
00092 home_defaults = eh_key_file_scan_for( rc_file , prog_name , NULL , NULL );
00093 if ( !home_defaults )
00094 home_defaults = eh_symbol_table_new();
00095 eh_free(rc_file);
00096
00097
00098
00099 rc_file = g_strconcat( cur_dir , "/" , ehrc , NULL );
00100 if ( eh_is_readable_file( rc_file ) )
00101 dir_defaults = eh_key_file_scan_for( rc_file , prog_name , NULL , NULL );
00102 if ( !dir_defaults )
00103 dir_defaults = eh_symbol_table_new();
00104 eh_free(rc_file);
00105 eh_free( cur_dir );
00106
00107
00108
00109 defaults = eh_symbol_table_merge( home_defaults , dir_defaults , NULL );
00110
00111
00112 eh_symbol_table_destroy( home_defaults );
00113 eh_symbol_table_destroy( dir_defaults );
00114
00115 eh_free( ehrc );
00116
00117 return defaults;
00118 }
00119
00120 char *eh_args_lookup(Eh_args *t, char *key)
00121 {
00122 return eh_symbol_table_lookup(t->args,key);
00123 }
00124
00125 void eh_args_insert(Eh_args *t, char *key, char *value)
00126 {
00127 eh_symbol_table_insert(t->args,key,value);
00128 }
00129
00130 void eh_args_insert_default(Eh_args *t, char *key, char *value)
00131 {
00132 eh_symbol_table_insert(t->defaults,key,value);
00133 }
00134
00135 typedef struct
00136 {
00137 char **possible;
00138 gboolean err_flag;
00139 }
00140 Label_is_valid_st;
00141
00142 void check_label_is_possible( char *key , char *value , Label_is_valid_st *user_data );
00143 void check_label_is_valid( char *key , char *value , int *err_flag );
00144
00145 gboolean eh_check_opts( Eh_args* args , char **required , char **possible , char *help[] )
00146 {
00147 gboolean print_help=FALSE;
00148 int i, err_flag=0;
00149 Label_is_valid_st possible_st;
00150
00151 possible_st.possible = possible;
00152 possible_st.err_flag = err_flag;
00153
00154 if ( required )
00155 for ( i=0 ; required[i] ; i++ )
00156 {
00157 if ( !eh_symbol_table_lookup( args->args , required[i] ) )
00158 fprintf(stderr,"error : required arg %s not given\n",required[i]), err_flag++;
00159 }
00160
00161 if ( possible )
00162 {
00163 possible_st.err_flag = err_flag;
00164 eh_symbol_table_foreach( args->args , (GHFunc)&check_label_is_possible, &possible_st );
00165 err_flag = possible_st.err_flag;
00166 }
00167
00168 eh_symbol_table_foreach( args->args , (GHFunc)&check_label_is_valid , &err_flag);
00169
00170 print_help = eh_get_opt_bool( args , g_strdup("help") , FALSE );
00171 if ( (err_flag || print_help) && help )
00172 eh_print_message( stderr , help );
00173
00174 return err_flag||print_help;
00175 }
00176
00177 void check_label_is_possible( char *key , char *value , Label_is_valid_st *user_data )
00178 {
00179 char **possible = user_data->possible;
00180 int i;
00181 gboolean found=FALSE;
00182 gboolean is_valid=FALSE;
00183
00184 if ( g_strncasecmp( key , "arg" , 3 )==0 )
00185 is_valid=TRUE;
00186 else
00187 {
00188 for ( i=0 ; possible[i] && !found ; i++ )
00189 if ( g_strcasecmp ( key , possible[i] )==0 )
00190 found = TRUE;
00191 if ( !found )
00192 fprintf(stderr,"error : arg %s is not a valid argument\n",key);
00193 else
00194 is_valid=TRUE;
00195 }
00196 user_data->err_flag = is_valid;
00197 }
00198
00199 void check_label_is_valid( char *key , char *value , int *err_flag )
00200 {
00201 gboolean is_valid=FALSE;
00202
00203 if ( g_strncasecmp( key , "arg" , 3 )==0 )
00204 is_valid=TRUE;
00205 else if ( g_strcasecmp( value , "" )==0 )
00206 fprintf(stderr,"error : no value given for arg %s\n",key);
00207 else
00208 is_valid=TRUE;
00209 if ( !is_valid )
00210 (*err_flag)++;
00211 }
00212
00213 void eh_print_opt( Eh_args *args , char *label )
00214 {
00215 fprintf( stderr , "%s = %s" , label , eh_get_opt( args , label ) );
00216 fprintf( stderr , " [%s]\n" , eh_get_opt_default( args , label ) );
00217 }
00218
00219 char *eh_get_opt( Eh_args *args , char *label )
00220 {
00221 char *value = eh_args_lookup( args , label );
00222 char *rtn;
00223 if ( value )
00224 rtn = value;
00225 else
00226 rtn = eh_get_opt_default( args , label );
00227 return rtn;
00228 }
00229
00230 char *eh_get_opt_default( Eh_args *args , char *label )
00231 {
00232 return eh_symbol_table_lookup( args->defaults , label );
00233 }
00234
00235 char *eh_get_arg_n( Eh_args *args , int n )
00236 {
00237 char *arg_label = g_strdup_printf( "arg%d" , n );
00238 char *rtn = eh_get_opt( args , arg_label );
00239 eh_free( arg_label );
00240 return rtn;
00241 }
00242
00243 char *eh_get_opt_str( Eh_args *args , char *label , char *default_val )
00244 {
00245 char *value = eh_get_opt( args , label );
00246 char *default_str = g_strdup( default_val );
00247 char *rtn;
00248
00249 if ( !eh_get_opt_default( args , label ) )
00250 eh_args_insert_default( args , label , default_str );
00251
00252 if ( value )
00253 rtn = g_strdup(value);
00254 else
00255 rtn = g_strdup(default_val);
00256
00257 return rtn;
00258 }
00259
00260 gboolean
00261 eh_get_opt_bool( Eh_args *args , char *label , gboolean default_val )
00262 {
00263 char *value = eh_get_opt( args , label );
00264 char *default_str = g_strdup_printf( "%d" , default_val );
00265 gboolean rtn;
00266
00267 if ( !eh_get_opt_default( args , label ) )
00268 eh_args_insert_default( args , label , default_str );
00269
00270 if ( value )
00271 rtn = eh_str_to_boolean(value,NULL);
00272 else
00273 rtn = default_val;
00274 return rtn;
00275 }
00276
00277 int eh_get_opt_key( Eh_args *args , char *label , int default_val , char *keys[] )
00278 {
00279 char *value = eh_get_opt( args , label );
00280 char *default_str = g_strdup_printf( "%d" , default_val );
00281 int i, rtn;
00282
00283 if ( !eh_get_opt_default( args , label ) )
00284 eh_args_insert_default( args , label , default_str );
00285
00286 if ( value )
00287 {
00288 for ( i=0 ; keys[i] ; i++ )
00289 if ( g_ascii_strcasecmp( value , keys[i] )==0 )
00290 {
00291 rtn = i;
00292 break;
00293 }
00294 if ( !keys[i] )
00295 {
00296 fprintf( stderr , "error : unknown key (%s) for opt %s.\n" , value , label );
00297 fprintf( stderr , "error : possible keys are: ");
00298 for ( i=0 ; keys[i+1] ; i++ )
00299 fprintf( stderr , "%s, " , keys[i] );
00300 fprintf( stderr , "or %s\n" , keys[i] );
00301 eh_exit(-1);
00302 }
00303 }
00304 else
00305 rtn = default_val;
00306
00307 return rtn;
00308 }
00309
00310 int eh_get_opt_int( Eh_args *args , char *label , int default_val )
00311 {
00312 char *value = eh_get_opt( args , label );
00313 char *default_str = g_strdup_printf( "%d" , default_val );
00314 int rtn;
00315
00316 if ( !eh_get_opt_default( args , label ) )
00317 eh_args_insert_default( args , label , default_str );
00318
00319 if ( value )
00320 sscanf(value, "%d" , &rtn );
00321 else
00322 rtn = default_val;
00323
00324 return rtn;
00325 }
00326
00327 double eh_get_opt_dbl( Eh_args *args , char *label , double default_val )
00328 {
00329 char *value = eh_get_opt( args , label );
00330 char *default_str = g_strdup_printf( "%g" , default_val );
00331 double rtn;
00332
00333 if ( !eh_get_opt_default( args , label ) )
00334 eh_args_insert_default( args , label , default_str );
00335
00336 if ( value )
00337 sscanf(value, "%lf" , &rtn );
00338 else
00339 rtn = default_val;
00340 return rtn;
00341 }
00342
00343 gint
00344 eh_print_message( FILE *fp , char *msg[] )
00345 {
00346 gint n = 0;
00347 if ( fp )
00348 {
00349 gchar **p;
00350 for ( p=msg ; *p ; p++ )
00351 n += fprintf(fp,"%s\n",*p);
00352 }
00353 return n;
00354 }
00355
00356 typedef struct
00357 {
00358 int max_key_len;
00359 int max_value_len;
00360 Eh_args *args;
00361 }
00362 Print_opt_pad_st;
00363
00364 void print_opt_pad( char *key , char *value , Print_opt_pad_st *user_data );
00365 void get_max_label_length( char *key , char *value , Print_opt_pad_st *user_data );
00366
00367 void eh_print_all_opts( Eh_args *args , char *prog_name , FILE *fp )
00368 {
00369 Print_opt_pad_st data;
00370
00371 data.max_key_len = 0;
00372 data.max_value_len = 0;
00373 data.args = args;
00374
00375 fprintf( fp , "--- %s ---\n" , prog_name );
00376
00377 eh_symbol_table_foreach( args->defaults , (GHFunc)&get_max_label_length , &data );
00378 eh_symbol_table_foreach( args->defaults , (GHFunc)&print_opt_pad , &data );
00379
00380 return;
00381 }
00382
00383 void print_opt_pad( char *key , char *unused , Print_opt_pad_st *user_data )
00384 {
00385 char *str;
00386 char *value;
00387
00388 str = g_strdup_printf( "%%-%ds : %%-%ds\n" ,
00389 user_data->max_key_len ,
00390 user_data->max_value_len );
00391 value = eh_get_opt( user_data->args , key );
00392 if ( strlen( value )>0 && g_strtod(value,NULL)!=E_NOVAL )
00393 fprintf( stderr , str , key , value );
00394 else
00395 fprintf( stderr , str , key , "<no value>" );
00396 eh_free( str );
00397
00398 return;
00399 }
00400
00401 void get_max_label_length( char *key , char *value , Print_opt_pad_st *user_data )
00402 {
00403 int key_len = strlen( key );
00404 int value_len = strlen( value );
00405
00406 if ( key_len > user_data->max_key_len )
00407 user_data->max_key_len = key_len;
00408 if ( value_len > user_data->max_value_len )
00409 user_data->max_value_len = value_len;
00410
00411 return;
00412 }
00413
00414