00001 #include <eh_utils.h>
00002 #include <stdarg.h>
00003 #include <string.h>
00004
00005 CLASS( Eh_symbol_table )
00006 {
00007 GHashTable* t;
00008 };
00009
00010 typedef struct
00011 {
00012 FILE *fp;
00013 int max_key_len;
00014 }
00015 aligned_st G_GNUC_INTERNAL;
00016
00017 GQuark
00018 eh_symbol_table_error_quark( void )
00019 {
00020 return g_quark_from_static_string( "eh-symbol-table-error-quark" );
00021 }
00022
00023
00024
00025
00026
00027 guint eh_str_case_hash(gconstpointer key);
00028 gboolean eh_str_case_equal(gconstpointer a, gconstpointer b);
00029
00030 void eh_symbol_table_free_label( gpointer label )
00031 {
00032 eh_free( label );
00033 }
00034
00035 guint eh_str_case_hash(gconstpointer key)
00036 {
00037 gchar* new_key = g_ascii_strup( key , -1 );
00038 guint ans;
00039
00040 ans = g_str_hash(new_key);
00041 eh_free(new_key);
00042
00043 return ans;
00044 }
00045
00046 gboolean eh_str_case_equal(gconstpointer a, gconstpointer b)
00047 {
00048 return (g_ascii_strcasecmp((char*)a,(char*)b)==0)?TRUE:FALSE;
00049 }
00050
00051 void eh_destroy_key( gpointer key , gpointer value , gpointer user_data)
00052 {
00053 eh_free(key);
00054 }
00055
00056 void __eh_symbol_table_insert( char *key, char *value, Eh_symbol_table t )
00057 {
00058 eh_symbol_table_insert( t , g_strdup(key) , g_strdup(value) );
00059 }
00060
00061 void eh_print_symbol(char *key, char *value, FILE *fp)
00062 {
00063 fprintf(fp,"%s : %s\n",key,value);
00064 }
00065
00066 void eh_print_symbol_aligned( char *key, char *value, aligned_st *st )
00067 {
00068 int len = st->max_key_len-strlen(key)+1;
00069 char *fill = g_strnfill( len , ' ' );
00070 fprintf(st->fp,"%s%s: %s\n",key,fill,value);
00071 eh_free(fill);
00072 }
00073
00074 void eh_get_max_key_len( char *key , char *value , int *max_len )
00075 {
00076 int len = strlen(key);
00077 if ( len > *max_len )
00078 *max_len = len;
00079 }
00080
00081
00082
00083
00084
00085 Eh_symbol_table eh_symbol_table_new( void )
00086 {
00087 Eh_symbol_table s;
00088 NEW_OBJECT( Eh_symbol_table , s );
00089 s->t = g_hash_table_new_full( &eh_str_case_hash ,
00090 &eh_str_case_equal ,
00091 &eh_symbol_table_free_label ,
00092 &eh_symbol_table_free_label );
00093 return s;
00094 }
00095
00096 Eh_symbol_table eh_symbol_table_dup( Eh_symbol_table t )
00097 {
00098 return eh_symbol_table_copy( NULL , t );
00099 }
00100
00101 Eh_symbol_table eh_symbol_table_copy( Eh_symbol_table dest , Eh_symbol_table src )
00102 {
00103 if ( !dest )
00104 dest = eh_symbol_table_new();
00105
00106 g_hash_table_foreach( src->t , (GHFunc)&__eh_symbol_table_insert , dest );
00107
00108 return dest;
00109 }
00110
00111 void eh_symbol_table_foreach( Eh_symbol_table s , GHFunc f , gpointer user_data )
00112 {
00113 g_hash_table_foreach( s->t , f , user_data );
00114 }
00115
00116 Eh_symbol_table eh_symbol_table_merge( Eh_symbol_table table1 , ... )
00117 {
00118 va_list args;
00119 Eh_symbol_table rtn, table;
00120
00121 rtn = eh_symbol_table_new();
00122 g_hash_table_foreach( table1->t , (GHFunc)&__eh_symbol_table_insert , rtn );
00123
00124 va_start( args , table1 );
00125 table = va_arg( args , Eh_symbol_table );
00126 while ( table )
00127 {
00128 g_hash_table_foreach( table->t , (GHFunc)&__eh_symbol_table_insert , rtn );
00129 table = va_arg( args , Eh_symbol_table );
00130 }
00131 va_end( args );
00132 return rtn;
00133 }
00134
00135 void eh_symbol_table_insert(Eh_symbol_table s, char *key, char *value)
00136 {
00137 g_hash_table_insert(s->t,g_strdup(key),g_strdup(value));
00138 }
00139
00140 void eh_symbol_table_replace( Eh_symbol_table s , char* key , char* value )
00141 {
00142 g_hash_table_replace(s->t,g_strdup(key),g_strdup(value));
00143 }
00144
00145 char*
00146 eh_symbol_table_lookup(Eh_symbol_table s, const char *key)
00147 {
00148 char *value = (char*)g_hash_table_lookup(s->t,key);
00149 if ( value )
00150 return value;
00151
00152
00153
00154
00155
00156
00157
00158
00159 return NULL;
00160 }
00161
00162 void eh_symbol_table_print( Eh_symbol_table s , FILE *fp )
00163 {
00164 g_hash_table_foreach( s->t , (GHFunc)&eh_print_symbol , fp );
00165 }
00166
00167 void eh_symbol_table_print_aligned( Eh_symbol_table s , FILE *fp )
00168 {
00169 int max_len=0;
00170 aligned_st st;
00171 g_hash_table_foreach( s->t , (GHFunc)&eh_get_max_key_len , &max_len );
00172 st.fp = fp;
00173 st.max_key_len = max_len;
00174 g_hash_table_foreach( s->t , (GHFunc)&eh_print_symbol_aligned , &st );
00175 }
00176
00177 gssize eh_symbol_table_size( Eh_symbol_table s )
00178 {
00179 return g_hash_table_size( s->t );
00180 }
00181
00182 Eh_symbol_table eh_symbol_table_destroy( Eh_symbol_table s )
00183 {
00184 if ( s )
00185 {
00186 g_hash_table_destroy( s->t );
00187 eh_free( s );
00188 }
00189 return NULL;
00190 }
00191
00192 gboolean eh_symbol_table_has_label( Eh_symbol_table s , gchar* label )
00193 {
00194 if ( s && label )
00195 {
00196 if ( g_hash_table_lookup( s->t , label ) )
00197 return TRUE;
00198 else
00199 return FALSE;
00200 }
00201 return FALSE;
00202 }
00203
00204 gboolean
00205 eh_symbol_table_has_labels( Eh_symbol_table s , gchar** labels )
00206 {
00207 gboolean has_all_labels = TRUE;
00208
00209 if ( labels )
00210 {
00211 gchar** this_label;
00212
00213 for ( this_label=labels ; *this_label && has_all_labels ; this_label++ )
00214 has_all_labels = has_all_labels && eh_symbol_table_has_label( s , *this_label );
00215 }
00216
00217 return has_all_labels;
00218 }
00219
00220 gboolean
00221 eh_symbol_table_require_labels( Eh_symbol_table s , gchar** labels , GError** error )
00222 {
00223 gboolean has_all_labels = TRUE;
00224
00225 eh_return_val_if_fail( error==NULL || *error==NULL , FALSE );
00226
00227 if ( labels )
00228 {
00229 GError* tmp_err = NULL;
00230 gchar** err_s = NULL;
00231 gchar** this_label;
00232
00233 for ( this_label=labels ; *this_label ; this_label++ )
00234 {
00235 if ( !eh_symbol_table_has_label( s , *this_label ) )
00236 eh_strv_append( &err_s , g_strdup_printf( "Label not found: %s" , *this_label ) );
00237 }
00238
00239 if ( err_s )
00240 {
00241 eh_set_error_strv( &tmp_err , EH_SYM_TABLE_ERROR , EH_SYM_TABLE_ERROR_MISSING_LABEL , err_s );
00242
00243 g_propagate_error( error , tmp_err );
00244 g_strfreev ( err_s );
00245
00246 has_all_labels = FALSE;
00247 }
00248 }
00249
00250 return has_all_labels;
00251 }
00252
00253 gchar*
00254 eh_symbol_table_value( Eh_symbol_table s , const gchar* label )
00255 {
00256 gchar* ans = NULL;
00257 if ( s && label )
00258 ans = g_strdup( g_hash_table_lookup( s->t , label ) );
00259 return ans;
00260 }
00261
00262 gchar**
00263 eh_symbol_table_values( Eh_symbol_table s , const gchar* label , const gchar* delimiters )
00264 {
00265 gchar** str_list = NULL;
00266
00267 if ( s )
00268 {
00269 gchar* value_str = eh_symbol_table_value( s , label );
00270
00271 if ( value_str )
00272 {
00273 if ( !delimiters )
00274 delimiters = ",:;";
00275
00276 str_list = g_strsplit_set( value_str , delimiters , -1 );
00277 }
00278
00279 eh_free( value_str );
00280 }
00281
00282 return str_list;
00283 }
00284
00285 double
00286 eh_symbol_table_dbl_value( Eh_symbol_table s , gchar* label )
00287 {
00288 gchar* str = eh_symbol_table_value( s , label );
00289 double ans;
00290
00291 if ( str )
00292 ans = g_ascii_strtod( str , NULL );
00293 else
00294 ans = eh_nan();
00295
00296 eh_free( str );
00297
00298 return ans;
00299 }
00300
00301 double*
00302 eh_symbol_table_dbl_range( Eh_symbol_table s , gchar* label )
00303 {
00304 gchar* str = eh_symbol_table_value( s , label );
00305 double* ans;
00306
00307 if ( str )
00308 ans = eh_str_to_dbl_range( str , NULL );
00309 else
00310 ans = NULL;
00311
00312 eh_free( str );
00313
00314 return ans;
00315 }
00316
00317 double* eh_symbol_table_dbl_array_value( Eh_symbol_table s , gchar* label , gint* len , const gchar* delims )
00318 {
00319 double* dbl_array = NULL;
00320
00321 eh_require( s );
00322 eh_require( label );
00323
00324 if ( s && label )
00325 {
00326 gchar** str_array = eh_symbol_table_values( s , label , delims );
00327
00328 if ( str_array )
00329 {
00330 gint i;
00331 gchar** str;
00332
00333 dbl_array = eh_new( double , g_strv_length( str_array ) );
00334
00335 for ( str=str_array,i=0 ; *str ; str++,i++ )
00336 dbl_array[i] = g_ascii_strtod( *str , NULL );
00337
00338 *len = i;
00339 }
00340
00341 eh_free( str_array );
00342 }
00343
00344 return dbl_array;
00345 }
00346
00347 double
00348 eh_symbol_table_time_value( Eh_symbol_table s , gchar* label )
00349 {
00350 gchar* str = eh_symbol_table_value( s , label );
00351 double ans;
00352
00353 if ( str )
00354 ans = eh_str_to_time_in_years( str , NULL );
00355 else
00356 ans = eh_nan();
00357
00358 eh_free( str );
00359
00360 return ans;
00361 }
00362
00363 double*
00364 eh_symbol_table_time_array_value( Eh_symbol_table s , gchar* label , gint* len , const gchar* delims )
00365 {
00366 double* dbl_array = NULL;
00367
00368 eh_require( s );
00369 eh_require( label );
00370
00371 if ( s && label )
00372 {
00373 gchar** str_array = eh_symbol_table_values( s , label , delims );
00374
00375 if ( str_array )
00376 {
00377 gint i;
00378 gchar** str;
00379
00380 dbl_array = eh_new( double , g_strv_length( str_array ) );
00381
00382 for ( str=str_array,i=0 ; *str ; str++,i++ )
00383 dbl_array[i] = eh_str_to_time_in_years( *str , NULL );
00384
00385 *len = i;
00386 }
00387
00388 eh_free( str_array );
00389 }
00390
00391 return dbl_array;
00392 }
00393
00394 double*
00395 eh_symbol_table_time_range( Eh_symbol_table s , gchar* label )
00396 {
00397 gchar* str = eh_symbol_table_value( s , label );
00398 double* ans;
00399
00400 if ( str )
00401 ans = eh_str_to_time_range( str , NULL );
00402 else
00403 ans = NULL;
00404
00405 eh_free( str );
00406
00407 return ans;
00408 }
00409
00410 gboolean eh_symbol_table_bool_value( Eh_symbol_table s , gchar* label )
00411 {
00412 gchar* str = eh_symbol_table_value( s , label );
00413 gboolean ans;
00414
00415 if ( str )
00416 ans = eh_str_to_boolean( str , NULL );
00417
00418 eh_free( str );
00419
00420 return ans;
00421 }
00422
00423 gint eh_symbol_table_int_value( Eh_symbol_table s , gchar* label )
00424 {
00425 gchar* str = eh_symbol_table_value( s , label );
00426 gint ans = G_MAXINT;
00427
00428 if ( str )
00429 sscanf( str , "%d" , &ans );
00430
00431 eh_free( str );
00432
00433 return ans;
00434 }
00435
00436 Eh_input_val eh_symbol_table_input_value( Eh_symbol_table s , gchar* label , GError** err )
00437 {
00438 return eh_input_val_set( eh_symbol_table_lookup( s , label ) , err );
00439 }
00440