00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036 #include <string.h>
00037 #include <limits.h>
00038 #ifdef WIN32
00039 #include <Shlwapi.h>
00040 #endif
00041 #include <tpia_map.h>
00042
00043 #if defined __cplusplus
00044 namespace GIDI {
00045 using namespace GIDI;
00046 #endif
00047
00048 static tpia_mapEntry *_tpia_map_addEntry( statusMessageReporting *smr, tpia_map *map, enum tpia_mapEntry_type type, const char *schema, const char *path,
00049 const char *evaluation, const char *projectile, const char *target );
00050 static char *_tpia_map_findTarget2( statusMessageReporting *smr, tpia_map *map, const char *evaluation, const char *projectile, const char *target );
00051 static int _tpia_map_findAllOfTarget2( statusMessageReporting *smr, tpia_map *mapAllOfTarget, tpia_map *map, const char *projectile, const char *targetName );
00052 static int _tpia_map_walkTree2( statusMessageReporting *smr, tpia_map *map, int level, int (*handler)( tpia_mapEntry *entry, int level, void *userData),
00053 void *userData );
00054 static void _tpia_map_simpleWrite2( FILE *f, tpia_map *map, int level );
00055 static int _tpia_map_smrUserInterface( void *userData, char **str );
00056
00057
00058
00059 tpia_map *tpia_map_create( statusMessageReporting *smr ) {
00060
00061 tpia_map *map;
00062
00063
00064 if( ( map = (tpia_map*) xData_malloc2( smr, sizeof( tpia_map ), 0, "map" ) ) == NULL ) return( NULL );
00065
00066 if( tpia_map_initialize( smr, map ) ) map = (tpia_map*) tpia_map_free( NULL, map );
00067 return( map );
00068 }
00069
00070
00071
00072
00073 int tpia_map_initialize( statusMessageReporting *, tpia_map *map ) {
00074
00075 memset( map, 0, sizeof( tpia_map ) );
00076 map->status = tpia_map_status_Ok;
00077 map->smrUserInterface.smrUserInterface = _tpia_map_smrUserInterface;
00078 map->smrUserInterface.map = map;
00079 map->path = NULL;
00080 map->mapFileName = NULL;
00081 map->numberOfEntries = 0;
00082 map->mapEntries = NULL;
00083 return( 0 );
00084 }
00085
00086
00087
00088 tpia_map *tpia_map_readFile( statusMessageReporting *smr, const char *basePath, const char *mapFileName ) {
00089
00090
00091
00092 int n = 0;
00093 xData_document *doc;
00094 xData_element *element;
00095 xData_element *child;
00096 tpia_map *map;
00097 const char *evaluation, *projectile, *targetName, *path, *schema;
00098 #ifndef WIN32
00099 char realPath[2 * ( PATH_MAX + 1 )], *p = &(realPath[PATH_MAX+1]);
00100 #endif
00101 #ifdef WIN32
00102 char realPath[2 * ( _MAX_PATH + 1 )], *p = &(realPath[_MAX_PATH+1]);
00103 #endif
00104
00105 if( ( map = tpia_map_create( smr ) ) == NULL ) return( NULL );
00106
00107 if( ( basePath == NULL ) || ( mapFileName[0] == '/' ) ) {
00108 strcpy( realPath, mapFileName ); }
00109 else {
00110 strcpy( realPath, basePath );
00111 strcat( realPath, "/" );
00112 strcat( realPath, mapFileName );
00113 }
00114 #ifndef WIN32
00115 if( realpath( realPath, p ) == NULL ) {
00116 smr_setMessageError( smr, NULL, __FILE__, __LINE__, tpia_map_status_mapParsing, "No map file %s\n", mapFileName );
00117
00118 return( (tpia_map*) tpia_map_free( NULL, map ) );
00119 }
00120 #endif
00121 n = strlen( p ) + 2;
00122
00123
00124 if( ( map->path = (char*) xData_malloc2( smr, 2 * n, 0, "map->path" ) ) == NULL ) return( (tpia_map*) tpia_map_free( NULL, map ) );
00125 map->mapFileName = &(map->path[n + 1]);
00126 strcpy( map->mapFileName, p );
00127 strcpy( map->path, p );
00128 if( ( p = strrchr( map->path, '/' ) ) != NULL ) {
00129 *p = 0; }
00130 else {
00131 strcpy( map->path, "." );
00132 }
00133
00134
00135 if( ( doc = xData_parseReadFile( smr, map->mapFileName, NULL, NULL ) ) == NULL ) return( (tpia_map*) tpia_map_free( NULL, map ) );
00136
00137 element = xData_getDocumentsElement( doc );
00138 for( child = xData_getFirstElement( element ); child != NULL; child = xData_getNextElement( child ) ) {
00139 if( !strcmp( child->name, "path" ) ) {
00140 if( ( path = xData_getAttributesValueInElement( child , "path" ) ) == NULL ) {
00141 smr_setMessageError( smr, &(map->smrUserInterface), __FILE__, __LINE__, tpia_map_status_mapParsing, "path missing path attribute" );
00142 break;
00143 }
00144 if( ( projectile = xData_getAttributesValueInElement( child , "projectile" ) ) == NULL ) {
00145 smr_setMessageError( smr, &(map->smrUserInterface), __FILE__, __LINE__, tpia_map_status_mapParsing, "path missing projectile attribute" );
00146 break;
00147 }
00148 tpia_map_addPath( smr, map, path, projectile ); }
00149 else if( !strcmp( child->name, "target" ) ) {
00150 if( ( schema = xData_getAttributesValueInElement( child , "schema" ) ) == NULL ) {
00151 smr_setMessageError( smr, &(map->smrUserInterface), __FILE__, __LINE__, tpia_map_status_mapParsing, "target missing 'schema' attribute" );
00152 break;
00153 }
00154 if( ( path = xData_getAttributesValueInElement( child , "path" ) ) == NULL ) {
00155 smr_setMessageError( smr, &(map->smrUserInterface), __FILE__, __LINE__, tpia_map_status_mapParsing, "target missing 'path' attribute" );
00156 break;
00157 }
00158 if( ( evaluation = xData_getAttributesValueInElement( child , "evaluation" ) ) == NULL ) {
00159 smr_setMessageError( smr, &(map->smrUserInterface), __FILE__, __LINE__, tpia_map_status_mapParsing, "target missing 'evaluation' attribute" );
00160 break;
00161 }
00162 if( ( projectile = xData_getAttributesValueInElement( child , "projectile" ) ) == NULL ) {
00163 smr_setMessageError( smr, &(map->smrUserInterface), __FILE__, __LINE__, tpia_map_status_mapParsing, "target missing 'projectile' attribute" );
00164 break;
00165 }
00166 if( ( targetName = xData_getAttributesValueInElement( child , "target" ) ) == NULL ) {
00167 smr_setMessageError( smr, &(map->smrUserInterface), __FILE__, __LINE__, tpia_map_status_mapParsing, "target missing 'target' attribute" );
00168 break;
00169 }
00170 tpia_map_addTarget( smr, map, schema, path, evaluation, projectile, targetName ); }
00171 else {
00172 smr_setMessageError( smr, &(map->smrUserInterface), __FILE__, __LINE__, tpia_map_status_mapParsing, "invalid element = %s", child->name );
00173 }
00174 if( !smr_isOk( smr ) ) break;
00175 }
00176 xData_parseFree( smr, doc );
00177
00178 if( !smr_isOk( smr ) ) map = (tpia_map*) tpia_map_free( NULL, map );
00179 return( map );
00180 }
00181
00182
00183
00184 void *tpia_map_free( statusMessageReporting *smr, tpia_map *map ) {
00185
00186 tpia_map_release( smr, map );
00187 xData_free( smr, map );
00188 return( NULL );
00189 }
00190
00191
00192
00193 void tpia_map_release( statusMessageReporting *smr, tpia_map *map ) {
00194
00195 tpia_mapEntry *entry, *next;
00196
00197 if( map->path != NULL ) xData_free( NULL, map->path );
00198 for( entry = map->mapEntries; entry != NULL; entry = next ) {
00199 next = entry->next;
00200 if( entry->schema != NULL ) xData_free( NULL, entry->schema );
00201 if( entry->path != NULL ) xData_free( NULL, entry->path );
00202 if( entry->evaluation != NULL ) xData_free( NULL, entry->evaluation );
00203 if( entry->projectile != NULL ) xData_free( NULL, entry->projectile );
00204 if( entry->targetName != NULL ) xData_free( NULL, entry->targetName );
00205 if( entry->map != NULL ) tpia_map_free( smr, entry->map );
00206 xData_free( NULL, entry );
00207 }
00208 map->numberOfEntries = 0;
00209 map->mapEntries = NULL;
00210 map->status = tpia_map_status_Ok;
00211 }
00212
00213
00214
00215 tpia_mapEntry *tpia_map_getFirstEntry( tpia_map *map ) {
00216
00217 return( map->mapEntries );
00218 }
00219
00220
00221
00222 tpia_mapEntry *tpia_map_getNextEntry( tpia_mapEntry *entry ) {
00223
00224 return( entry->next );
00225 }
00226
00227
00228
00229 int tpia_map_addTarget( statusMessageReporting *smr, tpia_map *map, const char *schema, const char *path, const char *evaluation, const char *projectile, const char *target ) {
00230
00231 return( _tpia_map_addEntry( smr, map, tpia_mapEntry_type_target, schema, path, evaluation, projectile, target ) != NULL );
00232 }
00233
00234
00235
00236 int tpia_map_addPath( statusMessageReporting *smr, tpia_map *map, const char *path, const char *projectile ) {
00237
00238 tpia_mapEntry *entry = _tpia_map_addEntry( smr, map, tpia_mapEntry_type_path, NULL, path, NULL, projectile, NULL );
00239
00240 if( entry != NULL ) {
00241 if( ( entry->map = tpia_map_readFile( smr, map->path, entry->path ) ) == NULL ) entry = NULL;
00242 }
00243 return( entry != NULL );
00244 }
00245
00246
00247
00248 static tpia_mapEntry *_tpia_map_addEntry( statusMessageReporting *smr, tpia_map *map, enum tpia_mapEntry_type type, const char *schema, const char *path,
00249 const char *evaluation, const char *projectile, const char *targetName ) {
00250
00251 tpia_mapEntry *p;
00252 tpia_mapEntry *entry;
00253
00254
00255 if( ( entry = (tpia_mapEntry*) xData_malloc2( smr, sizeof( tpia_mapEntry ), 1, "entry" ) ) == NULL ) return( NULL );
00256 entry->next = NULL;
00257 entry->type = type;
00258 entry->path = NULL;
00259 entry->map = NULL;
00260 if( path != NULL ) {
00261
00262 if( ( entry->path = (char*) xData_malloc2( smr, strlen( path ) + 1, 0, "path" ) ) == NULL ) {
00263 xData_free( smr, entry );
00264 return( NULL );
00265 }
00266 strcpy( entry->path, path );
00267 }
00268 entry->evaluation = NULL;
00269 if( evaluation != NULL ) {
00270
00271 if( ( entry->evaluation = (char*) xData_malloc2( smr, strlen( evaluation ) + 1, 0, "evaluation" ) ) == NULL ) {
00272 xData_free( smr, entry->path );
00273 xData_free( smr, entry );
00274 return( NULL );
00275 }
00276 strcpy( entry->evaluation, evaluation );
00277 }
00278 entry->projectile = NULL;
00279 if( projectile != NULL ) {
00280
00281 if( ( entry->projectile = (char*) xData_malloc2( smr, strlen( projectile ) + 1, 0, "projectile" ) ) == NULL ) {
00282 xData_free( smr, entry->evaluation );
00283 xData_free( smr, entry->path );
00284 xData_free( smr, entry );
00285 return( NULL );
00286 }
00287 strcpy( entry->projectile, projectile );
00288 }
00289 entry->targetName = NULL;
00290 if( targetName != NULL ) {
00291
00292 if( ( entry->targetName = (char*) xData_malloc2( smr, strlen( targetName ) + 1, 0, "target" ) ) == NULL ) {
00293 xData_free( smr, entry->path );
00294 xData_free( smr, entry->evaluation );
00295 xData_free( smr, entry->projectile );
00296 xData_free( smr, entry );
00297 return( NULL );
00298 }
00299 strcpy( entry->targetName, targetName );
00300 }
00301 entry->schema = NULL;
00302 if( schema != NULL ) {
00303
00304 if( ( entry->schema = (char*) xData_malloc2( smr, strlen( schema ) + 1, 0, "schema" ) ) == NULL ) {
00305 xData_free( smr, entry->path );
00306 xData_free( smr, entry->evaluation );
00307 xData_free( smr, entry->projectile );
00308 xData_free( smr, entry->targetName );
00309 xData_free( smr, entry );
00310 return( NULL );
00311 }
00312 strcpy( entry->schema, schema );
00313 }
00314
00315 if( map->mapEntries == NULL ) {
00316 map->mapEntries = entry; }
00317 else {
00318 for( p = map->mapEntries; p->next != NULL; p = p->next ){;}
00319 p->next = entry;
00320 }
00321 map->numberOfEntries++;
00322 return( entry );
00323 }
00324
00325
00326
00327 char *tpia_map_findTarget( statusMessageReporting *smr, tpia_map *map, const char *evaluation, const char *projectile, const char *targetName ) {
00328
00329
00330
00331 char *path;
00332
00333 if( map->status != tpia_map_status_Ok ) return( NULL );
00334
00335 path = _tpia_map_findTarget2( smr, map, evaluation, projectile, targetName );
00336 if( ( path == NULL ) && smr_isOk( smr ) ) {
00337 if( evaluation == NULL ) {
00338 smr_setMessageInfo( smr, &(map->smrUserInterface), __FILE__, __LINE__, 1, "target %s for projectile %s not found", targetName, projectile ); }
00339 else {
00340 smr_setMessageInfo( smr, &(map->smrUserInterface), __FILE__, __LINE__, 1, "target %s for projectile %s and evaluation %s not found", targetName, projectile, evaluation );
00341 }
00342 }
00343 return( path );
00344 }
00345
00346
00347
00348 static char *_tpia_map_findTarget2( statusMessageReporting *smr, tpia_map *map, const char *evaluation, const char *projectile, const char *targetName ) {
00349
00350 tpia_mapEntry *entry;
00351 char *path = NULL;
00352 int n, status;
00353
00354 for( entry = map->mapEntries; entry != NULL; entry = entry->next ) {
00355 switch( entry->type ) {
00356 case tpia_mapEntry_type_target :
00357 if( !strcmp( projectile, entry->projectile ) && ( !strcmp( targetName, entry->targetName ) ) ) {
00358 if( evaluation == NULL ) {
00359 status = 1; }
00360 else {
00361 status = !strcmp( evaluation, entry->evaluation );
00362 }
00363 if( status ) {
00364 n = strlen( map->path ) + 1 + strlen( entry->path ) + 1;
00365
00366 if( ( path = (char*) xData_malloc2( smr, n, 0, "path" ) ) == NULL ) return( NULL );
00367 strcpy( path, map->path );
00368 strcat( path, "/" );
00369 if( entry->path[0] == '/' ) {
00370 strcpy( path, entry->path ); }
00371 else {
00372 strcat( path, entry->path );
00373 }
00374 return( path );
00375 }
00376 }
00377 break;
00378 case tpia_mapEntry_type_path :
00379 if( !strcmp( projectile, entry->projectile ) ) {
00380 if( ( path = _tpia_map_findTarget2( smr, entry->map, evaluation, projectile, targetName ) ) != NULL ) return( path );
00381 }
00382 break;
00383 default :
00384 smr_setMessageInfo( smr, &(map->smrUserInterface), __FILE__, __LINE__, tpia_map_status_UnknownType, "unknown type = %d", entry->type );
00385 return( NULL );
00386 }
00387 }
00388 return( NULL );
00389 }
00390
00391
00392
00393 tpia_map *tpia_map_findAllOfTarget( statusMessageReporting *smr, tpia_map *map, const char *projectile, const char *targetName ) {
00394
00395
00396
00397 int status;
00398 tpia_map *mapAllOfTarget;
00399
00400 if( map->status != tpia_map_status_Ok ) return( NULL );
00401 if( ( mapAllOfTarget = tpia_map_create( smr ) ) == NULL ) return( NULL );
00402 status = _tpia_map_findAllOfTarget2( smr, mapAllOfTarget, map, projectile, targetName );
00403
00404 if( ( status != 0 ) ) mapAllOfTarget = (tpia_map*) tpia_map_free( smr, mapAllOfTarget );
00405 return( mapAllOfTarget );
00406 }
00407
00408
00409
00410 static int _tpia_map_findAllOfTarget2( statusMessageReporting *smr, tpia_map *mapAllOfTarget, tpia_map *map, const char *projectile, const char *targetName ) {
00411
00412 tpia_mapEntry *entry;
00413
00414 for( entry = map->mapEntries; entry != NULL; entry = entry->next ) {
00415 switch( entry->type ) {
00416 case tpia_mapEntry_type_target :
00417 if( !strcmp( projectile, entry->projectile ) && ( !strcmp( targetName, entry->targetName ) ) ) {
00418 if( _tpia_map_addEntry( smr, mapAllOfTarget, entry->type, entry->schema, entry->path, entry->evaluation, entry->projectile,
00419 entry->targetName ) == NULL ) return( 1 );
00420 }
00421 break;
00422 case tpia_mapEntry_type_path :
00423 if( !strcmp( projectile, entry->projectile ) ) {
00424 if( _tpia_map_findAllOfTarget2( smr, mapAllOfTarget, entry->map, projectile, targetName ) != 0 ) return( 1 );
00425 }
00426 break;
00427 default :
00428 smr_setMessageInfo( smr, &(map->smrUserInterface), __FILE__, __LINE__, tpia_map_status_UnknownType, "unknown type = %d", entry->type );
00429 return( 1 );
00430 }
00431 }
00432 return( 0 );
00433 }
00434
00435
00436
00437 char *tpia_map_getFullPath( statusMessageReporting *smr, tpia_map *map, const char *endPath ) {
00438
00439 char *path;
00440
00441 if( endPath[0] == '/' ) {
00442
00443 if( ( path = (char*) xData_malloc2( smr, strlen( endPath ) + 1, 0, "path" ) ) == NULL ) return( NULL );
00444 path[0] = 0; }
00445 else {
00446
00447 if( ( path = (char*) xData_malloc2( smr, strlen( map->path ) + strlen( endPath ) + 2, 0, "path" ) ) == NULL ) return( NULL );
00448 strcpy( path, map->path );
00449 strcat( path, "/" );
00450 }
00451 strcat( path, endPath );
00452 return( path );
00453 }
00454
00455
00456
00457 int tpia_map_walkTree( statusMessageReporting *smr, tpia_map *map, int (*handler)( tpia_mapEntry *entry, int level, void *userData), void *userData ) {
00458
00459 return( _tpia_map_walkTree2( smr, map, 0, handler, userData ) );
00460 }
00461
00462
00463
00464 static int _tpia_map_walkTree2( statusMessageReporting *smr, tpia_map *map, int level, int (*handler)( tpia_mapEntry *entry, int level, void *userData),
00465 void *userData ) {
00466
00467 tpia_mapEntry *entry;
00468
00469 for( entry = map->mapEntries; entry != NULL; entry = entry->next ) {
00470 if( handler( entry, level, userData ) != 0 ) return( 1 );
00471 if( entry->type == tpia_mapEntry_type_path ) if( _tpia_map_walkTree2( smr, entry->map, level + 1, handler, userData ) != 0 ) return( 1 );
00472 }
00473 return( 0 );
00474 }
00475
00476
00477
00478 char *tpia_map_toXMLString( statusMessageReporting *smr, tpia_map *map ) {
00479
00480 tpia_mapEntry *entry;
00481 char *s, *p;
00482 char targetFormat[] = "<target schema=\"%s\" evaluation=\"%s\" projectile=\"%s\" target=\"%s\" path=\"%s\"/>\n";
00483 char pathFormat[] = "<path projectile=\"%s\" path=\"%s\"/>\n";
00484 char start[] = "<map>\n";
00485 char end[] = "</map>";
00486 int n = 0, nStart = strlen( start ), nEnd = strlen( end );
00487 int nTarget = strlen( targetFormat ) - 10, nPath = strlen( pathFormat ) - 4;
00488
00489 if( map->status != tpia_map_status_Ok ) return( NULL );
00490
00491 n = nStart + nEnd + 1;
00492 for( entry = map->mapEntries; entry != NULL; entry = entry->next ) {
00493 switch( entry->type ) {
00494 case tpia_mapEntry_type_target :
00495 n += strlen( entry->schema ) + strlen( entry->path ) + strlen( entry->evaluation ) + strlen( entry->projectile ) + strlen( entry->targetName ) + nTarget;
00496 break;
00497 case tpia_mapEntry_type_path :
00498 n += strlen( entry->path ) + strlen( entry->projectile ) + nPath;
00499 break;
00500 default :
00501 smr_setMessageInfo( smr, &(map->smrUserInterface), __FILE__, __LINE__, tpia_map_status_UnknownType, "unknown type = %d", entry->type );
00502 return( NULL );
00503 }
00504 }
00505
00506 if( ( s = (char *) xData_malloc2( smr, n, 0, "xml string" ) ) == NULL ) return( NULL );
00507 p = s;
00508 strcpy( p, start );
00509 while( *p ) p++;
00510 for( entry = map->mapEntries; entry != NULL; entry = entry->next ) {
00511 switch( entry->type ) {
00512 case tpia_mapEntry_type_target :
00513 sprintf( p, targetFormat, entry->schema, entry->evaluation, entry->projectile, entry->targetName, entry->path );
00514 break;
00515 case tpia_mapEntry_type_path :
00516 sprintf( p, pathFormat, entry->projectile, entry->path );
00517 break;
00518 }
00519 while( *p ) p++;
00520 }
00521 strcpy( p, end );
00522 return( s );
00523 }
00524
00525
00526
00527 void tpia_map_simpleWrite( FILE *f, tpia_map *map ) { _tpia_map_simpleWrite2( f, map, 0 ); }
00528
00529
00530
00531 static void _tpia_map_simpleWrite2( FILE *f, tpia_map *map, int level ) {
00532
00533 tpia_mapEntry *entry;
00534 char sLevel[] = " ";
00535 int n = strlen( sLevel ) / 4;
00536
00537 if( map->status != tpia_map_status_Ok ) {
00538 fprintf( f, "Bad map status = %d\n", map->status );
00539 return;
00540 }
00541 if( level < n ) sLevel[4 * level] = 0;
00542 fprintf( f, "%smap->path = %s\n", sLevel, map->path );
00543 fprintf( f, "%smap->mapFileName = %s\n", sLevel, map->mapFileName );
00544 for( entry = map->mapEntries; entry != NULL; entry = entry->next ) {
00545 switch( entry->type ) {
00546 case tpia_mapEntry_type_target :
00547 fprintf( f, "%sType = target: schema = %s: evaluation = %s: projectile = %s: target = %s: path = %s\n", sLevel, entry->schema,
00548 entry->evaluation, entry->projectile, entry->targetName, entry->path );
00549 break;
00550 case tpia_mapEntry_type_path :
00551 fprintf( f, "%sType = path: projectile = %s: path = %s\n", sLevel, entry->projectile, entry->path );
00552 _tpia_map_simpleWrite2( f, entry->map, level + 1 );
00553 break;
00554 default :
00555 fprintf( f, "%sUnknown type = %d\n", sLevel, entry->type );
00556 }
00557 }
00558 }
00559
00560
00561
00562 static int _tpia_map_smrUserInterface( void *userData, char **str ) {
00563
00564 tpia_map_smr *smrUserInterface = (tpia_map_smr *) userData;
00565 char fnl[] = "map file = ";
00566 int size = strlen( fnl ) + strlen( smrUserInterface->map->mapFileName ) + 1;
00567
00568 if( str != NULL ) {
00569
00570 if( ( *str = (char*) xData_malloc2( NULL, size, 0, "mapFileName" ) ) == NULL ) return( -1 );
00571 strcpy( *str, fnl );
00572 strcat( *str, smrUserInterface->map->mapFileName );
00573 }
00574 return( size );
00575 }
00576
00577 #if defined __cplusplus
00578 }
00579 #endif