tpi_IDs.cc

Go to the documentation of this file.
00001 /*
00002 # <<BEGIN-copyright>>
00003 # Copyright (c) 2010, Lawrence Livermore National Security, LLC. 
00004 # Produced at the Lawrence Livermore National Laboratory 
00005 # Written by Bret R. Beck, beck6@llnl.gov. 
00006 # CODE-461393
00007 # All rights reserved. 
00008 #  
00009 # This file is part of GIDI. For details, see nuclear.llnl.gov. 
00010 # Please also read the "Additional BSD Notice" at nuclear.llnl.gov. 
00011 # 
00012 # Redistribution and use in source and binary forms, with or without modification, 
00013 # are permitted provided that the following conditions are met: 
00014 #
00015 #      1) Redistributions of source code must retain the above copyright notice, 
00016 #         this list of conditions and the disclaimer below.
00017 #      2) Redistributions in binary form must reproduce the above copyright notice, 
00018 #         this list of conditions and the disclaimer (as noted below) in the 
00019 #          documentation and/or other materials provided with the distribution.
00020 #      3) Neither the name of the LLNS/LLNL nor the names of its contributors may be 
00021 #         used to endorse or promote products derived from this software without 
00022 #         specific prior written permission. 
00023 #
00024 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 
00025 # EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
00026 # OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT 
00027 # SHALL LAWRENCE LIVERMORE NATIONAL SECURITY, LLC, THE U.S. DEPARTMENT OF ENERGY OR 
00028 # CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 
00029 # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 
00030 # OR SERVICES;  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 
00031 # AND ON  ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
00032 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 
00033 # EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
00034 # <<END-copyright>>
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     //if( ( channelID = xData_malloc2( smr, sizeof( tpi_channelID ), 0, "channelID" ) ) == NULL ) return( NULL );
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 //int tpi_channelID_initialize( statusMessageReporting *smr, tpi_channelID *channelID ) {
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         //if( ( spectralID = _tpi_spectralID_parse2( smr, *EOP, origStr, EOP ) ) == NULL ) return( tpi_channelID_free( smr, channelID ) );
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             //return( tpi_channelID_free( smr, channelID ) );
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     //char *sans[] = { "revision", NULL };
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     //if( ( spectralID = xData_malloc2( smr, sizeof( tpi_spectralID ), 1, "spectralID" ) ) == NULL ) return( NULL );
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 //int tpi_spectralID_initialize( statusMessageReporting *smr, tpi_spectralID *spectralID ) {
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 == '(' ) {               /* Breakup spectralID, like '(Be_8 -> He_4[multipliticy:"2"])' */
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     //if( ( spectralID->name = tpi_misc_allocateAndCopyNCharacters( smr, s, i1 ) ) == NULL ) return( tpi_spectralID_free( smr, spectralID ) );
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 == '[' ) {               /* Spectral has qualifiers. */
00255         priorQualifier = (tpi_spectralIDQualifier *) &(spectralID->qualifiers);
00256         bOrC = '[';
00257         while( **EOP == bOrC ) {
00258             bOrC = ',';
00259             (*EOP)++;                                                   /* Get qualifier's name. */
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                 //return( tpi_spectralID_free( smr, spectralID ) );
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 );                  /* Skip qualifier's separator. */
00269             if( **EOP != ':' ) {
00270                 smr_setMessageError( smr, NULL, __FILE__, __LINE__, 1, "Missing ':' in qualifier defintion at '%s' in '%s'", *EOP, origStr );
00271                 //return( tpi_spectralID_free( smr, spectralID ) );
00272                 return( (tpi_spectralID*) tpi_spectralID_free( smr, spectralID ) );
00273             }
00274 
00275             (*EOP)++;                                                    /* Get qualifier's value. */
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                 //return( tpi_spectralID_free( smr, spectralID ) );
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                 //return( tpi_spectralID_free( smr, spectralID ) );
00288                 return( (tpi_spectralID*) tpi_spectralID_free( smr, spectralID ) );
00289             }
00290             (*EOP)++;
00291             *EOP = (char *) tpi_misc_firstNonWhiteSpace( smr, *EOP );
00292 
00293             //if( ( qualifier = xData_malloc2( smr, sizeof( tpi_spectralIDQualifier ) + i1 + i2 + 2, 1, "qualifier" ) ) == NULL ) 
00294             if( ( qualifier = (tpi_spectralIDQualifier*) xData_malloc2( smr, sizeof( tpi_spectralIDQualifier ) + i1 + i2 + 2, 1, "qualifier" ) ) == NULL ) 
00295                 //return( tpi_spectralID_free( smr, spectralID ) );
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             //return( tpi_spectralID_free( smr, spectralID ) );
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             //return( tpi_spectralID_free( smr, spectralID ) );
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             //return( tpi_spectralID_free(smr, spectralID) );
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             //return( tpi_spectralID_free( smr, spectralID ) );
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     //char *sans[] = { "revision", NULL };
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 //char const *tpi_misc_firstNonWhiteSpace( statusMessageReporting *smr, char const *str ) {
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     //if( ( s = xData_malloc2( smr, n + 1, 0, "s" ) ) == NULL ) return( NULL );
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

Generated on Mon May 27 17:50:35 2013 for Geant4 by  doxygen 1.4.7