00001 #include <eh_utils.h>
00002
00003 CLASS( Eh_project )
00004 {
00005 char *name;
00006 char *working_dir_name;
00007 GDir *working_dir;
00008 GTree *open_files;
00009 GKeyFile *info_file;
00010 };
00011
00012 char* construct_project_group_name( Eh_project p );
00013 int eh_sort_ptr( gconstpointer a , gconstpointer b , gpointer user_data );
00014
00015 Eh_project eh_create_project( const char *proj_name )
00016 {
00017 Eh_project new_proj;
00018
00019 NEW_OBJECT( Eh_project , new_proj );
00020
00021 new_proj->name = g_strdup( proj_name );
00022
00023 new_proj->working_dir = NULL;
00024
00025 new_proj->open_files = g_tree_new_full( &eh_sort_ptr ,
00026 NULL ,
00027 (GDestroyNotify)&fclose ,
00028 &eh_free_c_style );
00029
00030 new_proj->working_dir_name = NULL;
00031
00032
00033 new_proj->info_file = g_key_file_new();
00034
00035 eh_fill_project_info( new_proj );
00036
00037 return new_proj;
00038 }
00039
00040 char* eh_project_name( Eh_project p )
00041 {
00042 return p->name;
00043 }
00044
00045 char* eh_project_dir_name( Eh_project p )
00046 {
00047 return p->working_dir_name;
00048 }
00049
00050 GDir* eh_project_dir( Eh_project p )
00051 {
00052 return p->working_dir;
00053 }
00054
00055 GKeyFile* eh_project_info_file( Eh_project p )
00056 {
00057 return p->info_file;
00058 }
00059
00060 char* eh_project_info_file_full_name( Eh_project p )
00061 {
00062 char* base_name = g_strconcat( eh_project_name(p) , ".info" , NULL );
00063 char* name = g_build_filename( eh_project_dir_name(p) ,
00064 base_name ,
00065 NULL );
00066
00067 eh_free( base_name );
00068
00069 return name;
00070 }
00071
00072 gchar* eh_project_get_info_val( Eh_project p , const gchar* key )
00073 {
00074 gchar* group_name = construct_project_group_name( p );
00075 gchar* value;
00076
00077
00078
00079 value = g_key_file_get_value( p->info_file , group_name , key , NULL );
00080
00081 eh_free( group_name );
00082
00083 return value;
00084 }
00085
00086 Eh_project eh_project_set_info_val( Eh_project p ,
00087 const gchar* key ,
00088 const gchar* value )
00089 {
00090 char* group_name = construct_project_group_name( p );
00091
00092 eh_require( value!=NULL );
00093
00094
00095
00096 g_key_file_set_value( p->info_file , group_name , key , value );
00097
00098 eh_free( group_name );
00099
00100 return p;
00101 }
00102
00103 Eh_project
00104 eh_project_add_info_val( Eh_project p , char* key , const gchar* val )
00105 {
00106 char* group_name = construct_project_group_name( p );
00107
00108 eh_require( val!=NULL );
00109
00110
00111
00112
00113
00114
00115 if ( g_key_file_has_key( p->info_file , group_name , key , NULL ) )
00116 {
00117 gchar** cur_val;
00118 gsize n_vals;
00119
00120 cur_val = g_key_file_get_string_list( p->info_file ,
00121 group_name ,
00122 key ,
00123 &n_vals ,
00124 NULL );
00125
00126 n_vals = n_vals+1;
00127 cur_val = eh_renew( char* , cur_val , n_vals+1 );
00128 cur_val[n_vals-1] = g_strdup( val );
00129
00130 g_key_file_set_string_list( p->info_file ,
00131 group_name ,
00132 key ,
00133 cur_val ,
00134 n_vals );
00135
00136 g_strfreev( cur_val );
00137 }
00138 else
00139 g_key_file_set_value( p->info_file , group_name , key , val );
00140
00141 eh_free( group_name );
00142
00143 return p;
00144 }
00145
00146 #define DONT_ASK (TRUE)
00147
00148 Eh_project eh_set_project_dir( Eh_project proj , const char* dir_name )
00149 {
00150 GError *error = NULL;
00151
00152 if ( !dir_name )
00153 dir_name = ".";
00154
00155 if ( proj->working_dir_name )
00156 eh_free( proj->working_dir_name );
00157 if ( proj->working_dir )
00158 g_dir_close( proj->working_dir );
00159
00160 proj->working_dir_name = g_strdup ( dir_name );
00161 proj->working_dir = g_dir_open( dir_name , 0 , &error );
00162
00163 if ( error )
00164 {
00165 if ( ( DONT_ASK || eh_input_boolean( "Ok to create directory?" , TRUE ) )
00166 && g_mkdir( dir_name , S_ISUID|S_ISGID|S_IRWXU|S_IRWXG ) == 0
00167 && (proj->working_dir = g_dir_open( dir_name , 0 , &error )) )
00168 {
00169 g_error_free( error );
00170 }
00171 else
00172 {
00173 eh_error( "Unable to open project: %s\n" , error->message );
00174 }
00175 }
00176
00177 return proj;
00178 }
00179
00180 #include <time.h>
00181
00182 char* construct_project_group_name( Eh_project p )
00183 {
00184 return g_strconcat( p->name , " info entry" , NULL );
00185 }
00186
00187 #include <time.h>
00188
00189 Eh_project eh_set_project_current_time( Eh_project p )
00190 {
00191 GKeyFile *file = p->info_file;
00192 char *group_name = construct_project_group_name( p );
00193
00194
00195
00196
00197 eh_require( file )
00198 {
00199 time_t clock;
00200 char date_str[S_LINEMAX];
00201 char time_str[S_LINEMAX];
00202 struct tm now;
00203 GDate *today = g_date_new();
00204
00205 g_date_set_time( today , time(&clock) );
00206 localtime_r( &clock , &now );
00207 g_date_strftime( date_str , S_LINEMAX , "%d/%m/%Y" , today );
00208 sprintf( time_str , "%d:%d:%d" , now.tm_hour , now.tm_min , now.tm_sec );
00209
00210 eh_require( date_str!=NULL );
00211 eh_require( time_str!=NULL );
00212
00213 g_key_file_set_value( file , group_name , "CURRENT DATE" , date_str );
00214 g_key_file_set_value( file , group_name , "CURRENT TIME" , time_str );
00215
00216 g_date_free( today );
00217 }
00218
00219 return p;
00220 }
00221
00222 Eh_project eh_fill_project_info( Eh_project p )
00223 {
00224 GKeyFile *file = p->info_file;
00225 char *group_name = construct_project_group_name( p );
00226
00227
00228
00229
00230 g_key_file_set_comment( file ,
00231 NULL ,
00232 NULL ,
00233 "Automatically generated file. Please do not edit." ,
00234 NULL );
00235
00236
00237
00238
00239 eh_require( file )
00240 {
00241 time_t clock;
00242 char date_str[S_LINEMAX];
00243 char time_str[S_LINEMAX];
00244 struct tm now;
00245 GDate *today = g_date_new();
00246
00247 g_date_set_time( today , time(&clock) );
00248 localtime_r( &clock , &now );
00249 g_date_strftime( date_str , S_LINEMAX , "%d/%m/%Y" , today );
00250 sprintf( time_str , "%d:%d:%d" , now.tm_hour , now.tm_min , now.tm_sec );
00251
00252 eh_require( date_str!=NULL );
00253 eh_require( time_str!=NULL );
00254
00255 g_key_file_set_value( file , group_name , "RUN START DATE" , date_str );
00256 g_key_file_set_value( file , group_name , "RUN START TIME" , time_str );
00257
00258 g_date_free( today );
00259 }
00260
00261
00262
00263
00264 g_key_file_set_value( file , group_name , "USER" , g_get_user_name() );
00265 g_key_file_set_value( file , group_name , "HOST" , g_get_host_name() );
00266 g_key_file_set_value( file , group_name , "RUN DIRECTORY" , g_get_current_dir() );
00267
00268 eh_free( group_name );
00269
00270 return p;
00271 }
00272
00273 gint
00274 eh_write_project_info_file( Eh_project proj )
00275 {
00276 gint n = 0;
00277 char* info_file = eh_project_info_file_full_name( proj );
00278
00279 eh_require( info_file )
00280 {
00281 char *file_str;
00282 gsize file_len;
00283 FILE *fp = eh_fopen( info_file , "w" );
00284
00285 file_str = g_key_file_to_data( proj->info_file , &file_len , NULL );
00286 n += fprintf( fp , "%s" , file_str );
00287
00288 fclose( fp );
00289 eh_free( file_str );
00290 }
00291
00292 eh_free( info_file );
00293
00294 return n;
00295 }
00296
00297 gboolean eh_read_project_info_file( Eh_project proj )
00298 {
00299 char *file_name = g_strconcat( proj->name , ".info" , NULL );
00300 char *info_file = g_build_filename( proj->working_dir_name ,
00301 file_name ,
00302 NULL );
00303 gboolean read_ok;
00304
00305 read_ok = g_key_file_load_from_file( proj->info_file ,
00306 info_file ,
00307 G_KEY_FILE_NONE ,
00308 NULL );
00309
00310 eh_free( info_file );
00311 eh_free( file_name );
00312
00313 return read_ok;
00314 }
00315
00316 Eh_project eh_load_project( gchar* info_file )
00317 {
00318 Eh_project p;
00319
00320 if ( g_file_test( info_file , G_FILE_TEST_EXISTS ) )
00321 {
00322 gchar* project_name = g_path_get_basename( info_file );
00323 gboolean read_ok;
00324
00325 eh_require( project_name )
00326 {
00327 gchar* ext = g_strrstr( project_name , "." );
00328 if ( ext )
00329 ext[0] = '\0';
00330 }
00331
00332 p = eh_create_project( project_name );
00333
00334 read_ok = g_key_file_load_from_file( p->info_file ,
00335 info_file ,
00336 G_KEY_FILE_NONE ,
00337 NULL );
00338
00339 if ( !read_ok )
00340 p = eh_destroy_project( p );
00341
00342 eh_free( project_name );
00343 }
00344 else
00345 p = NULL;
00346
00347 return p;
00348 }
00349
00350 Eh_project eh_destroy_project( Eh_project proj )
00351 {
00352 if ( proj )
00353 {
00354 if ( proj->working_dir )
00355 g_dir_close( proj->working_dir );
00356 eh_free( proj->working_dir_name );
00357 g_key_file_free( proj->info_file );
00358 eh_free( proj->name );
00359 eh_free( proj );
00360 }
00361
00362 return NULL;
00363 }
00364
00365 int eh_sort_ptr( gconstpointer a , gconstpointer b , gpointer user_data )
00366 {
00367 return (a<b)?-1:((a==b)?0:1);
00368 }
00369
00370 FILE *eh_open_project_file( Eh_project proj ,
00371 const char *file ,
00372 const char *mode )
00373 {
00374 char *full_name;
00375 FILE *fp;
00376
00377 eh_require( proj );
00378 eh_require( proj->working_dir_name );
00379 eh_require( file );
00380 eh_require( mode );
00381
00382 full_name = g_build_filename( proj->working_dir_name , file , NULL );
00383
00384 fp = fopen( full_name , mode );
00385 if ( !fp )
00386 eh_error( "Unable to open file: %s\n" , file );
00387
00388 g_tree_insert( proj->open_files , fp , g_strdup( file ) );
00389
00390 return fp;
00391 }
00392
00393 void eh_close_project_file( Eh_project proj , FILE *fp )
00394 {
00395 g_tree_remove( proj->open_files , fp );
00396 }
00397
00398 void eh_close_project_file_all( Eh_project proj )
00399 {
00400 g_tree_destroy( proj->open_files );
00401 }
00402