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 <stdio.h>
00037 #include <stdlib.h>
00038 #include <string.h>
00039 #include <ctype.h>
00040
00041 #include <tpi_IDs.h>
00042
00043 #if defined __cplusplus
00044 namespace GIDI {
00045 using namespace GIDI;
00046 #endif
00047
00048 static tpi_channelID *_tpi_channelID_parse2( statusMessageReporting *smr, char const *str, char const *origStr, int isDecayChannel, char **EOP );
00049 static tpi_spectralID *_tpi_spectralID_parse2( statusMessageReporting *smr, char const *str, char const *origStr, char **EOP );
00050
00051
00052
00053 tpi_channelID *tpi_channelID_allocate( statusMessageReporting *smr ) {
00054
00055 tpi_channelID *channelID;
00056
00057
00058 if( ( channelID = (tpi_channelID*) xData_malloc2( smr, sizeof( tpi_channelID ), 0, "channelID" ) ) == NULL ) return( NULL );
00059 tpi_channelID_initialize( smr, channelID );
00060 return( channelID );
00061 }
00062
00063
00064
00065
00066 int tpi_channelID_initialize( statusMessageReporting *, tpi_channelID *channelID ) {
00067
00068 memset( channelID, 0, sizeof( tpi_channelID ) );
00069 return( 0 );
00070 }
00071
00072
00073
00074 void *tpi_channelID_free( statusMessageReporting *smr, tpi_channelID *channelID ) {
00075
00076 if( channelID != NULL ) {
00077 tpi_channelID_release( smr, channelID );
00078 xData_free( smr, channelID );
00079 }
00080 return( NULL );
00081 }
00082
00083
00084
00085 int tpi_channelID_release( statusMessageReporting *smr, tpi_channelID *channelID ) {
00086
00087 tpi_spectralID *spectralID, *next;
00088
00089 for( spectralID = channelID->spectralIDs; spectralID != NULL; spectralID = next ) {
00090 next = spectralID->next;
00091 tpi_spectralID_free( smr, spectralID );
00092 }
00093 tpi_channelID_initialize( smr, channelID );
00094 return( 0 );
00095 }
00096
00097
00098
00099 tpi_channelID *tpi_channelID_parse( statusMessageReporting *smr, char const *str, char **EOP ) {
00100
00101 return( _tpi_channelID_parse2( smr, str, str, 0, EOP ) );
00102 }
00103
00104
00105
00106 static tpi_channelID *_tpi_channelID_parse2( statusMessageReporting *smr, char const *str, char const *origStr, int isDecayChannel, char **EOP ) {
00107
00108 tpi_channelID *channelID;
00109 tpi_spectralID *spectralID, *priorSpectral;
00110
00111 *EOP = (char *) tpi_misc_firstNonWhiteSpace( smr, (char *) str );
00112 if( **EOP == 0 ) {
00113 smr_setMessageError( smr, NULL, __FILE__, __LINE__, 1, "Empty channel string to parse for '%s'", origStr );
00114 return( NULL );
00115 }
00116 if( ( channelID = tpi_channelID_allocate( smr ) ) == NULL ) return( NULL );
00117 priorSpectral= (tpi_spectralID *) &(channelID->spectralIDs);
00118 while( 1 ) {
00119
00120 if( ( spectralID = _tpi_spectralID_parse2( smr, *EOP, origStr, EOP ) ) == NULL ) return( (tpi_channelID*)tpi_channelID_free( smr, channelID ) );
00121 priorSpectral->next = spectralID;
00122 priorSpectral = spectralID;
00123 *EOP = (char *) tpi_misc_firstNonWhiteSpace( smr, *EOP );
00124 if( **EOP == 0 ) break;
00125 if( isDecayChannel && ( **EOP == ')' ) ) break;
00126 if( **EOP != '+' ) {
00127 smr_setMessageError( smr, NULL, __FILE__, __LINE__, 1, "Missing '+' (or maybe ')') in channelID at '%s' of '%s'", *EOP, origStr );
00128
00129 return( (tpi_channelID*)tpi_channelID_free( smr, channelID ) );
00130 }
00131 (*EOP)++;
00132 }
00133 return( channelID );
00134 }
00135
00136
00137
00138 int tpi_channelID_toString( statusMessageReporting *smr, tpi_channelID *channelID, gString *gStr ) {
00139
00140 return( tpi_channelID_toStringSans( smr, channelID, gStr, NULL ) );
00141 }
00142
00143
00144
00145 int tpi_channelID_toStringSanRevision( statusMessageReporting *smr, tpi_channelID *channelID, gString *gStr ) {
00146
00147
00148 char *sans[] = { (char*)"revision", NULL };
00149
00150 return( tpi_channelID_toStringSans( smr, channelID, gStr, sans ) );
00151 }
00152
00153
00154
00155 int tpi_channelID_toStringSans( statusMessageReporting *smr, tpi_channelID *channelID, gString *gStr, char *sans[] ) {
00156
00157 tpi_spectralID *spectralID;
00158
00159 for( spectralID = channelID->spectralIDs; spectralID != NULL; spectralID = spectralID->next ) {
00160 if( ( tpi_spectralID_toStringSans( smr, spectralID, gStr, sans ) ) != 0 ) return( 1 );
00161 if( spectralID->next != NULL ) {
00162 if( ( gString_addTo( smr, gStr, " + " ) ) != 0 ) return( 1 );
00163 }
00164 }
00165 return( 0 );
00166 }
00167
00168
00169
00170 tpi_spectralID *tpi_spectralID_allocate( statusMessageReporting *smr ) {
00171
00172 tpi_spectralID *spectralID;
00173
00174
00175 if( ( spectralID = (tpi_spectralID*) xData_malloc2( smr, sizeof( tpi_spectralID ), 1, "spectralID" ) ) == NULL ) return( NULL );
00176 tpi_spectralID_initialize( smr, spectralID );
00177 return( spectralID );
00178 }
00179
00180
00181
00182
00183 int tpi_spectralID_initialize( statusMessageReporting *, tpi_spectralID *spectralID ) {
00184
00185 memset( spectralID, 0, sizeof( tpi_spectralID ) );
00186 return( 0 );
00187 }
00188
00189
00190
00191 void *tpi_spectralID_free( statusMessageReporting *smr, tpi_spectralID *spectralID ) {
00192
00193 if( spectralID != NULL ) {
00194 tpi_spectralID_release( smr, spectralID );
00195 xData_free( smr, spectralID );
00196 }
00197 return( NULL );
00198 }
00199
00200
00201
00202 int tpi_spectralID_release( statusMessageReporting *smr, tpi_spectralID *spectralID ) {
00203
00204 tpi_spectralIDQualifier *qualifier, *next;
00205
00206 if( spectralID->name != NULL ) free( spectralID->name );
00207 for( qualifier = spectralID->qualifiers; qualifier != NULL; qualifier = next ) {
00208 next = qualifier->next;
00209 xData_free( smr, qualifier );
00210 }
00211 if( spectralID->decayChannel != NULL ) tpi_channelID_free( smr, spectralID->decayChannel );
00212 tpi_spectralID_initialize( smr, spectralID );
00213 return( 0 );
00214 }
00215
00216
00217
00218 tpi_spectralID *tpi_spectralID_parse( statusMessageReporting *smr, char const *str, char **EOP ) {
00219
00220 return( _tpi_spectralID_parse2( smr, str, str, EOP ) );
00221 }
00222
00223
00224
00225 static tpi_spectralID *_tpi_spectralID_parse2( statusMessageReporting *smr, char const *str, char const *origStr, char **EOP ) {
00226
00227 int breakup = 0, i1, i2, m;
00228 double d;
00229 char const *s, *q;
00230 char *e;
00231 char c, bOrC;
00232 tpi_spectralID *spectralID;
00233 tpi_spectralIDQualifier *qualifier, *priorQualifier = NULL;
00234
00235 *EOP = (char *) tpi_misc_firstNonWhiteSpace( smr, str );
00236 if( **EOP == 0 ) {
00237 smr_setMessageError( smr, NULL, __FILE__, __LINE__, 1, "Empty spectralID string to parse for '%s'", origStr );
00238 return( NULL );
00239 }
00240 if( **EOP == '(' ) {
00241 breakup = 1;
00242 (*EOP)++;
00243 *EOP = (char *) tpi_misc_firstNonWhiteSpace( smr, *EOP );
00244 }
00245 if( !isalpha( **EOP ) ) {
00246 smr_setMessageError( smr, NULL, __FILE__, __LINE__, 1, "Invalid spectralID name '%s' in '%s'", *EOP, origStr );
00247 return( NULL );
00248 }
00249 for( s = *EOP, i1 = 0; ( isalnum( **EOP ) ) || ( **EOP == '_' ); (*EOP)++ ) i1++;
00250 if( ( spectralID = tpi_spectralID_allocate( smr ) ) == NULL ) return( NULL );
00251
00252 if( ( spectralID->name = tpi_misc_allocateAndCopyNCharacters( smr, s, i1 ) ) == NULL ) return( (tpi_spectralID*) tpi_spectralID_free( smr, spectralID ) );
00253 *EOP = (char *) tpi_misc_firstNonWhiteSpace( smr, *EOP );
00254 if( **EOP == '[' ) {
00255 priorQualifier = (tpi_spectralIDQualifier *) &(spectralID->qualifiers);
00256 bOrC = '[';
00257 while( **EOP == bOrC ) {
00258 bOrC = ',';
00259 (*EOP)++;
00260 *EOP = (char *) tpi_misc_firstNonWhiteSpace( smr, *EOP );
00261 if( !isalpha( **EOP ) ) {
00262 smr_setMessageError( smr, NULL, __FILE__, __LINE__, 1, "Invalid qualifier name '%s' in '%s'", *EOP, origStr );
00263
00264 return( (tpi_spectralID*) tpi_spectralID_free( smr, spectralID ) );
00265 }
00266 for( s = *EOP, i1 = 0; ( isalnum( **EOP ) ) || ( **EOP == '_' ); (*EOP)++ ) i1++;
00267
00268 *EOP = (char *) tpi_misc_firstNonWhiteSpace( smr, *EOP );
00269 if( **EOP != ':' ) {
00270 smr_setMessageError( smr, NULL, __FILE__, __LINE__, 1, "Missing ':' in qualifier defintion at '%s' in '%s'", *EOP, origStr );
00271
00272 return( (tpi_spectralID*) tpi_spectralID_free( smr, spectralID ) );
00273 }
00274
00275 (*EOP)++;
00276 *EOP = (char *) tpi_misc_firstNonWhiteSpace( smr, *EOP );
00277 if( ( **EOP != '"' ) && ( **EOP != '\'' ) ) {
00278 smr_setMessageError( smr, NULL, __FILE__, __LINE__, 1, "Missing start quote in qualifier defintion at '%s' in '%s'", *EOP, origStr );
00279
00280 return( (tpi_spectralID*) tpi_spectralID_free( smr, spectralID ) );
00281 }
00282 c = **EOP;
00283 (*EOP)++;
00284 for( q = *EOP, i2 = 0; ( **EOP != c ) && ( **EOP != 0 ); (*EOP)++ ) i2++;
00285 if( **EOP != c ) {
00286 smr_setMessageError( smr, NULL, __FILE__, __LINE__, 1, "Missing end quote in qualifier defintion at '%s' in '%s'", *EOP, origStr );
00287
00288 return( (tpi_spectralID*) tpi_spectralID_free( smr, spectralID ) );
00289 }
00290 (*EOP)++;
00291 *EOP = (char *) tpi_misc_firstNonWhiteSpace( smr, *EOP );
00292
00293
00294 if( ( qualifier = (tpi_spectralIDQualifier*) xData_malloc2( smr, sizeof( tpi_spectralIDQualifier ) + i1 + i2 + 2, 1, "qualifier" ) ) == NULL )
00295
00296 return( (tpi_spectralID*) tpi_spectralID_free( smr, spectralID ) );
00297 qualifier->next = NULL;
00298 qualifier->name = (char *) &(qualifier[1]);
00299 qualifier->value = &(qualifier->name[i1+1]);
00300 strncpy( qualifier->name, s, i1 );
00301 qualifier->name[i1] = 0;
00302 strncpy( qualifier->value, q, i2 );
00303 qualifier->value[i2] = 0;
00304
00305 if( strcmp( qualifier->name, "revision" ) == 0 ) {
00306 spectralID->revision = qualifier->value; }
00307 else if( strcmp( qualifier->name, "multiplicity" ) == 0 ) {
00308 spectralID->multiplicityStr = qualifier->value; }
00309 else if( strcmp( qualifier->name, "level" ) == 0 ) {
00310 spectralID->levelStr = qualifier->value;
00311 }
00312 priorQualifier->next = qualifier;
00313 priorQualifier = qualifier;
00314 }
00315 if( **EOP != ']' ) {
00316 smr_setMessageError( smr, NULL, __FILE__, __LINE__, 1, "Missing ']' for qualifier at '%s' in '%s'", *EOP, origStr );
00317
00318 return( (tpi_spectralID*) tpi_spectralID_free( smr, spectralID ) );
00319 }
00320 (*EOP)++;
00321 if( spectralID->multiplicityStr != NULL ) {
00322 m = strtol( spectralID->multiplicityStr, &e, 10 );
00323 if( ( *e == 0 ) && ( e != spectralID->multiplicityStr ) ) spectralID->multiplicity = m;
00324 }
00325 if( spectralID->levelStr != NULL ) {
00326 d = strtod( spectralID->levelStr, &e );
00327 if( ( *e == 0 ) && ( e != spectralID->levelStr ) ) spectralID->level = d;
00328 }
00329 }
00330 if( breakup ) {
00331 *EOP = (char *) tpi_misc_firstNonWhiteSpace( smr, *EOP );
00332 if( ( **EOP != '-' ) || ( (*EOP)[1] != '>' ) ) {
00333 smr_setMessageError( smr, NULL, __FILE__, __LINE__, 1, "Missing '->' for breakup at '%s' in '%s'", *EOP, origStr );
00334
00335 return( (tpi_spectralID*) tpi_spectralID_free( smr, spectralID ) );
00336 }
00337 *EOP += 2;
00338 if( (spectralID->decayChannel = _tpi_channelID_parse2( smr, *EOP, origStr, breakup, EOP )) == NULL )
00339
00340 return( (tpi_spectralID*) tpi_spectralID_free(smr, spectralID) );
00341 if( **EOP != ')' ) {
00342 smr_setMessageError( smr, NULL, __FILE__, __LINE__, 1, "Missing ')' for breakup at '%s' in '%s'", *EOP, origStr );
00343
00344 return( (tpi_spectralID*) tpi_spectralID_free( smr, spectralID ) );
00345 }
00346 (*EOP)++;
00347 }
00348 return( spectralID );
00349 }
00350
00351
00352
00353 int tpi_spectralID_toString( statusMessageReporting *smr, tpi_spectralID *spectralID, gString *gStr ) {
00354
00355 return( tpi_spectralID_toStringSans( smr, spectralID, gStr, NULL ) );
00356 }
00357
00358
00359
00360 int tpi_spectralID_toStringSanRevision( statusMessageReporting *smr, tpi_spectralID *spectralID, gString *gStr ) {
00361
00362
00363 char *sans[] = { (char*)"revision", NULL };
00364
00365 return( tpi_spectralID_toStringSans( smr, spectralID, gStr, sans ) );
00366 }
00367
00368
00369
00370
00371 int tpi_spectralID_toStringSans( statusMessageReporting *smr, tpi_spectralID *spectralID, gString *gStr, char *sans[] ) {
00372
00373 tpi_spectralIDQualifier *qualifier;
00374 int i;
00375 char **san, *sSan[] = { NULL };
00376
00377 if( sans == NULL ) sans = sSan;
00378 if( spectralID->decayChannel != NULL ) if( gString_addTo( smr, gStr, "(" ) != 0 ) return( 1 );
00379 if( ( gString_addTo( smr, gStr, spectralID->name ) ) != 0 ) return( 1 );
00380 if( spectralID->qualifiers != NULL ) {
00381 for( qualifier = spectralID->qualifiers, i = 0; qualifier != NULL; qualifier = qualifier->next ) i++;
00382 for( qualifier = spectralID->qualifiers; qualifier != NULL; qualifier = qualifier->next ) {
00383 for( san = (char **) sans; *san != NULL; san++ ) {
00384 if( strcmp( *san, qualifier->name ) == 0 ) {
00385 i--;
00386 break;
00387 }
00388 }
00389 }
00390 if( i > 0 ) {
00391 if( gString_addTo( smr, gStr, "[" ) != 0 ) return( 1 );
00392 for( qualifier = spectralID->qualifiers; qualifier != NULL; qualifier = qualifier->next ) {
00393 for( san = (char **) sans; *san != NULL; san++ ) if( strcmp( *san, qualifier->name ) == 0 ) break;
00394 if( *san != NULL ) continue;
00395 if( gString_addTo( smr, gStr, qualifier->name ) != 0 ) return( 1 );
00396 if( gString_addTo( smr, gStr, ":'" ) != 0 ) return( 1 );
00397 if( gString_addTo( smr, gStr, qualifier->value ) != 0 ) return( 1 );
00398 if( gString_addTo( smr, gStr, "'") != 0 ) return( 1 );
00399 if( i == 1 ) {
00400 if( gString_addTo( smr, gStr, "]" ) != 0 ) return( 1 ); }
00401 else {
00402 if( gString_addTo( smr, gStr, ", " ) != 0 ) return( 1 );
00403 }
00404 i--;
00405 }
00406 }
00407 }
00408 if( spectralID->decayChannel != NULL ) {
00409 if( ( gString_addTo( smr, gStr, " -> " ) ) != 0 ) return( 1 );
00410 if( ( tpi_channelID_toStringSans( smr, spectralID->decayChannel, gStr, sans ) ) != 0 ) return( 1 );
00411 if( ( gString_addTo( smr, gStr, ")" ) ) != 0 ) return( 1 );
00412 }
00413 return( 0 );
00414 }
00415
00416
00417
00418
00419 char const *tpi_misc_firstNonWhiteSpace( statusMessageReporting *, char const *str ) {
00420
00421 char const *s;
00422
00423 for( s = str; ( *s != 0 ) && isspace( *s ); s++ ) ;
00424 return( s );
00425 }
00426
00427
00428
00429 char *tpi_misc_allocateAndCopyNCharacters( statusMessageReporting *smr, char const *str, int n ) {
00430
00431 char *s;
00432
00433
00434 if( ( s = (char*) xData_malloc2( smr, n + 1, 0, "s" ) ) == NULL ) return( NULL );
00435 strncpy( s, str, n );
00436 s[n] = 0;
00437 return( s );
00438 }
00439
00440 #if defined __cplusplus
00441 }
00442 #endif