/Users/huttone/Devel/sedflux-new/sedflux/trunk/ew/utils/eh_opt_context.c

Go to the documentation of this file.
00001 //---
00002 //
00003 // This file is part of sedflux.
00004 //
00005 // sedflux is free software; you can redistribute it and/or modify
00006 // it under the terms of the GNU General Public License as published by
00007 // the Free Software Foundation; either version 2 of the License, or
00008 // (at your option) any later version.
00009 //
00010 // sedflux is distributed in the hope that it will be useful,
00011 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013 // GNU General Public License for more details.
00014 //
00015 // You should have received a copy of the GNU General Public License
00016 // along with sedflux; if not, write to the Free Software
00017 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
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 // Local functions.
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    // If the supplied symbol table is NULL, create a new one.
00095    //---
00096    if ( tab )
00097       default_tab = tab;
00098    else
00099       default_tab = eh_symbol_table_new();
00100 
00101    //---
00102    // Create a symbol table with default values.
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    // Load values from .ehrc in home directoy.
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    // Load values from .ehrc in current directoy.
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 //      default_tab = eh_key_file_scan_for( rc_file , name , NULL );
00124    eh_free( rc_file );
00125 
00126    eh_free( ehrc );
00127    eh_free( cur_dir );
00128 
00129    return default_tab;
00130 }
00131 
00132 //---
00133 // Global functions.
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    // Create a symbol table that holds the default values for each
00182    // key-value pair.
00183    //---
00184    set_default_values( context->name , entries , context->values );
00185 
00186    //---
00187    // Convert Eh_opt_entry to GOptionEntry.
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    // Add the entries to a goup.
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    // Add the group to the context.
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 

Generated on Fri Jan 4 18:04:16 2008 for sedflux by  doxygen 1.5.2