00001 #include <eh_utils.h>
00002
00003
00004 gchar* eh_dlm_prepare ( const gchar* file ,
00005 GError** err );
00006 double** eh_dlm_read_data ( gchar* str ,
00007 gchar* delims ,
00008 gint* n_rows ,
00009 gint* n_cols ,
00010 GError** err );
00011
00012 gint eh_dlm_find_n_cols ( gchar* content , gchar* delims );
00013 gint eh_dlm_find_n_rows ( gchar* content , gint delim );
00014
00015 gchar** eh_dlm_split_records ( gchar* str ,
00016 const gchar* start_str ,
00017 const gchar* end_str ,
00018 gchar*** rec_data );
00019
00020 gchar*
00021 eh_dlm_prepare( const gchar* file , GError** err )
00022 {
00023 gchar* str = NULL;
00024
00025 eh_return_val_if_fail( err==NULL || *err==NULL , NULL );
00026
00027 if ( file )
00028 {
00029 GError* tmp_error = NULL;
00030
00031 g_file_get_contents( file , &str , NULL , &tmp_error );
00032
00033 if ( !tmp_error )
00034 {
00035
00036 eh_str_remove_c_style_comments( str );
00037 eh_str_remove_to_eol_comments ( str , "#" );
00038 eh_str_remove_to_eol_comments ( str , "//" );
00039 eh_str_replace ( str , '\r' , '\n' );
00040 eh_dlm_remove_empty_lines ( str );
00041 }
00042 else
00043 g_propagate_error( err , tmp_error );
00044 }
00045
00046 return str;
00047 }
00048
00066 double**
00067 eh_dlm_read( const gchar* file ,
00068 gchar* delims ,
00069 gint* n_rows ,
00070 gint* n_cols ,
00071 GError** err )
00072 {
00073 double** data = NULL;
00074
00075 eh_return_val_if_fail( err==NULL || *err==NULL , NULL );
00076
00077 if ( file )
00078 {
00079 double*** data_3;
00080 gint* n_x = NULL;
00081 gint* n_y = NULL;
00082 GError* tmp_err = NULL;
00083
00084 data_3 = eh_dlm_read_full( file , delims , &n_x , &n_y , NULL , 1 , &tmp_err );
00085
00086 if ( data_3 )
00087 {
00088 data = data_3[0];
00089 *n_rows = n_x[0];
00090 *n_cols = n_y[0];
00091
00092 eh_free( data_3 );
00093 eh_free( n_x );
00094 eh_free( n_y );
00095 }
00096 else
00097 g_propagate_error( err , tmp_err );
00098 }
00099
00100 return data;
00101 }
00102
00119 double** eh_dlm_read_swap( const gchar* file ,
00120 gchar* delims ,
00121 gint* n_rows ,
00122 gint* n_cols ,
00123 GError** err )
00124 {
00125 double** data = NULL;
00126
00127 eh_return_val_if_fail( err==NULL || *err==NULL , NULL );
00128
00129 if ( file )
00130 {
00131 gint tmp_rows, tmp_cols;
00132 double** tmp;
00133 GError* tmp_err = NULL;
00134
00135 tmp = eh_dlm_read( file , delims , &tmp_rows , &tmp_cols , &tmp_err );
00136
00137 if ( tmp )
00138 {
00139 gint i, j;
00140
00141 data = eh_new_2( double , tmp_cols , tmp_rows );
00142
00143 for ( i=0 ; i<tmp_rows ; i++ )
00144 for ( j=0 ; j<tmp_cols ; j++ )
00145 data[j][i] = tmp[i][j];
00146
00147 *n_rows = tmp_cols;
00148 *n_cols = tmp_rows;
00149
00150 }
00151 else
00152 g_propagate_error( err , tmp_err );
00153
00154 eh_free_2( tmp );
00155 }
00156
00157 return data;
00158 }
00159
00180 double***
00181 eh_dlm_read_full( const gchar* file ,
00182 gchar* delims ,
00183 gint** n_rows ,
00184 gint** n_cols ,
00185 gchar*** rec_data ,
00186 gint max_records ,
00187 GError** err )
00188 {
00189 double*** data = NULL;
00190
00191 eh_return_val_if_fail( err==NULL || *err==NULL , NULL );
00192
00193 if ( file )
00194 {
00195 gchar* str;
00196 GError* tmp_error = NULL;
00197
00198 str = eh_dlm_prepare( file , &tmp_error );
00199
00200 if ( !tmp_error )
00201 {
00202 gchar** rec;
00203 gint i, n_recs;
00204 rec = eh_dlm_split_records( str , "[" , "]" , rec_data );
00205
00206 n_recs = g_strv_length( rec );
00207
00208 if ( max_records>0 )
00209 n_recs = MAX( max_records , n_recs );
00210
00211 data = eh_new( double** , n_recs+1 );
00212 *n_rows = eh_new( gint , n_recs );
00213 *n_cols = eh_new( gint , n_recs );
00214
00215 for ( i=0 ; i<n_recs ; i++ )
00216 {
00217 data[i] = eh_dlm_read_data( rec[i] ,
00218 delims ,
00219 *n_rows+i ,
00220 *n_cols+i ,
00221 NULL );
00222 }
00223 data[i] = NULL;
00224
00225 g_strfreev( rec );
00226 }
00227 else
00228 g_propagate_error( err , tmp_error );
00229
00230 eh_free( str );
00231 }
00232
00233 return data;
00234 }
00235
00254 double***
00255 eh_dlm_read_full_swap( const gchar* file ,
00256 gchar* delims ,
00257 gint** n_rows ,
00258 gint** n_cols ,
00259 gchar*** rec_data ,
00260 gint max_records ,
00261 GError** err )
00262 {
00263 double*** data = NULL;
00264
00265 eh_return_val_if_fail( err==NULL || *err==NULL , NULL );
00266
00267 if ( file )
00268 {
00269 gint i, j;
00270 gint n, n_recs;
00271 double*** tmp;
00272 GError* tmp_err = NULL;
00273
00274 tmp = eh_dlm_read_full( file , delims , n_rows , n_cols , rec_data , max_records , &tmp_err );
00275
00276 n_recs = g_strv_length( (gchar**)tmp );
00277
00278 data = eh_new( double** , n_recs+1 );
00279
00280 for ( n=0 ; n<n_recs ; n++ )
00281 {
00282 data[n] = eh_new_2( double , (*n_cols)[n] , (*n_rows)[n] );
00283
00284 for ( i=0 ; i<(*n_rows)[n] ; i++ )
00285 for ( j=0 ; j<(*n_cols)[n] ; j++ )
00286 data[n][j][i] = tmp[n][i][j];
00287
00288 eh_free_2( tmp[n] );
00289 }
00290 data[n_recs] = 0;
00291
00292 EH_SWAP_PTR( *n_rows , *n_cols );
00293
00294 eh_free( tmp );
00295 }
00296
00297 return data;
00298 }
00299
00300 double**
00301 eh_dlm_read_data( gchar* str ,
00302 gchar* delims ,
00303 gint* n_rows ,
00304 gint* n_cols ,
00305 GError** err )
00306 {
00307 double** data;
00308
00309 eh_return_val_if_fail( err==NULL || *err==NULL , NULL );
00310
00311 if ( !delims )
00312 delims = ";,";
00313
00314 if ( str )
00315 {
00316 *n_rows = eh_dlm_find_n_rows( str , '\n' );
00317 *n_cols = eh_dlm_find_n_cols( str , delims );
00318
00319
00320 {
00321 gint i, j;
00322 gchar* pos_0;
00323 gchar* pos_1;
00324 gchar** values;
00325 gint n_vals;
00326 gchar* str_end = str+strlen(str);
00327
00328 data = eh_new_2( double , *n_rows , *n_cols );
00329
00330 pos_0 = str;
00331 for ( i=0 ; pos_0<str_end ; i++ )
00332 {
00333 pos_1 = strchr( pos_0 , '\n' );
00334 if ( !pos_1 )
00335 pos_1 = str_end;
00336 pos_1[0] = '\0';
00337
00338 values = g_strsplit_set( pos_0 , delims , -1 );
00339
00340 n_vals = g_strv_length( values );
00341
00342 for ( j=0 ; j<n_vals ; j++ )
00343 data[i][j] = g_ascii_strtod( values[j] , NULL );
00344 for ( ; j<*n_cols ; j++ )
00345 data[i][j] = 0.;
00346
00347 pos_0 = pos_1+1;
00348
00349 g_strfreev( values );
00350 }
00351 }
00352 }
00353
00354 return data;
00355 }
00356
00357 gint
00358 eh_dlm_find_n_rows( gchar* str , gint delim )
00359 {
00360 gint n = 0;
00361
00362 if ( str )
00363 {
00364 n = eh_str_count_chr( str , str+strlen(str) , delim )+1;
00365 }
00366
00367 return n;
00368 }
00369
00370 gint
00371 eh_dlm_find_n_cols( gchar* str , gchar* delims )
00372 {
00373 gint n_cols = 0;
00374
00375 if ( str )
00376 {
00377 gint i, n;
00378 gint n_delims = strlen(delims);
00379 gchar* str_end = str + strlen(str);
00380 gchar* pos_0;
00381 gchar* pos_1;
00382
00383 pos_0 = str;
00384 while ( pos_0<str_end )
00385 {
00386 pos_1 = strchr( pos_0 , '\n' );
00387 if ( !pos_1 )
00388 pos_1 = str_end;
00389
00390 for ( i=0,n=0 ; i<n_delims ; i++ )
00391 n += eh_str_count_chr( pos_0 , pos_1 , delims[i] );
00392
00393 if ( n>n_cols )
00394 n_cols = n;
00395
00396 pos_0 = pos_1+1;
00397 }
00398 }
00399
00400 return n_cols+1;
00401 }
00402
00413 gchar*
00414 eh_dlm_remove_empty_lines( gchar* str )
00415 {
00416 if ( str && str[0]!='\0' )
00417 {
00418 gchar* pos;
00419 gchar* pos_0;
00420 gchar* last_line;
00421 gint len = strlen(str);
00422 gchar* str_end = str+len;
00423 gchar** block = eh_new0( gchar* , len );
00424 gchar** block_end = eh_new0( gchar* , len );
00425 gint i=0;
00426
00427 pos_0 = str;
00428 while ( pos_0>=str && pos_0<str_end )
00429 {
00430 last_line = NULL;
00431
00432 for ( pos=pos_0 ; pos<str_end && g_ascii_isspace(*pos) ; pos++ )
00433 {
00434 if ( *pos == '\n' )
00435 last_line = pos;
00436 }
00437
00438 if ( last_line )
00439 {
00440 block[i] = pos_0;
00441 block_end[i] = last_line+1;
00442 i += 1;
00443 }
00444
00445 pos_0 = strchr( pos , '\n' )+1;
00446 }
00447 eh_str_remove_blocks( str , block , block_end );
00448
00449 eh_free( block_end );
00450 eh_free( block );
00451
00452 if ( str[strlen(str)-1]=='\n' )
00453 str[strlen(str)-1]='\0';
00454 }
00455 return str;
00456 }
00457
00458 gchar**
00459 eh_dlm_split_records( gchar* str ,
00460 const gchar* start_str ,
00461 const gchar* end_str ,
00462 gchar*** rec_data )
00463 {
00464 gchar** split_str = NULL;
00465
00466 eh_require( start_str );
00467 eh_require( end_str );
00468
00469 if ( rec_data )
00470 *rec_data = NULL;
00471
00472 if ( str )
00473 {
00474 for ( ; g_ascii_isspace(*str) ; str++ );
00475
00476 if ( strstr( str , start_str ) != str )
00477 {
00478 eh_strv_append( &split_str , g_strdup(str) );
00479 }
00480 else
00481 {
00482 gchar* pos_0;
00483 gchar* pos_1;
00484 gchar* str_end = str+strlen(str);
00485 gint start_len = strlen(start_str);
00486 gint end_len = strlen(end_str );
00487 gint len;
00488 gchar* new_line;
00489
00490 pos_0 = str+start_len;
00491 for ( len=2 ; pos_0<str_end ; len++ )
00492 {
00493
00494 pos_1 = strstr( pos_0 , end_str );
00495 if ( !pos_1 )
00496 pos_1 = str_end-end_len;
00497
00498
00499 if ( rec_data )
00500 {
00501 new_line = g_strndup( pos_0 , pos_1-pos_0 );
00502 eh_strv_append( rec_data , new_line );
00503 g_strstrip( new_line );
00504 }
00505
00506
00507 pos_0 = pos_1 + end_len;
00508 for ( ; g_ascii_isspace(*pos_0) ; pos_0++ );
00509
00510
00511 pos_1 = strstr( pos_0 , start_str );
00512 if ( !pos_1 )
00513 pos_1 = str_end;
00514
00515 new_line = g_strndup( pos_0 , pos_1-pos_0 );
00516 g_strstrip( new_line );
00517
00518 eh_strv_append( &split_str , new_line );
00519
00520 pos_0 = pos_1+start_len;
00521 for ( ; pos_0<str_end && g_ascii_isspace(*pos_0) ; pos_0++ );
00522 }
00523 }
00524 }
00525
00526 return split_str;
00527 }
00528
00529 gint
00530 eh_dlm_print( const gchar* file , const gchar* delim , const double** data , const gint n_rows , const gint n_cols , GError** error )
00531 {
00532 return eh_dlm_print_full( file , delim , data , n_rows , n_cols , FALSE , error );
00533 }
00534
00535 gint
00536 eh_dlm_print_swap( const gchar* file , const gchar* delim , const double** data , const gint n_rows , const gint n_cols , GError** error )
00537 {
00538 return eh_dlm_print_full( file , delim , data , n_rows , n_cols , TRUE , error );
00539 }
00540
00541 gint
00542 eh_dlm_print_full( const gchar* file , const gchar* delim , const double** data , const gint n_rows , const gint n_cols , gboolean swap , GError** error )
00543 {
00544 gint n = 0;
00545
00546 eh_return_val_if_fail( error==NULL || *error==NULL , 0 );
00547 eh_require( data );
00548 eh_require( n_rows>0 );
00549 eh_require( n_cols>0 );
00550
00551 if ( data )
00552 {
00553 FILE* fp;
00554 GError* tmp_err = NULL;
00555
00556 if ( file ) fp = eh_fopen_error( file , "w" , &tmp_err );
00557 else fp = stdout;
00558
00559 if ( fp )
00560 {
00561 gint i, j;
00562
00563 if ( !delim ) delim = " ";
00564
00565 if ( swap )
00566 {
00567 const gint top_row = n_rows-1;
00568 for ( j=0 ; j<n_cols ; j++ )
00569 {
00570 for ( i=0 ; i<top_row ; i++ )
00571 n += fprintf( fp , "%f%s" , data[i][j] , delim );
00572 n += fprintf( fp , "%f" , data[i][j] );
00573 n += fprintf( fp , "\n" );
00574 }
00575 }
00576 else
00577 {
00578 const gint top_col = n_cols-1;
00579 for ( i=0 ; i<n_rows ; i++ )
00580 {
00581 for ( j=0 ; j<top_col ; j++ )
00582 n += fprintf( fp , "%f%s" , data[i][j] , delim );
00583 n += fprintf( fp , "%f" , data[i][j] );
00584 n += fprintf( fp , "\n" );
00585 }
00586 }
00587 }
00588 else
00589 g_propagate_error( error , tmp_err );
00590 }
00591
00592 return n;
00593 }
00594
00595 gint
00596 eh_dlm_print_dbl_grid( const gchar* file , const gchar* delim , Eh_dbl_grid g , GError** error )
00597 {
00598 gint n = 0;
00599
00600 eh_return_val_if_fail( error==NULL || *error==NULL , 0 );
00601 eh_require( g );
00602
00603 if ( g )
00604 {
00605 GError* tmp_err = NULL;
00606
00607 n = eh_dlm_print( file , delim , (double**)eh_dbl_grid_data(g) , eh_grid_n_x(g) , eh_grid_n_y(g) , &tmp_err );
00608
00609 if ( tmp_err )
00610 g_propagate_error( error , tmp_err );
00611 }
00612
00613 return n;
00614 }
00615