Main Page   Class Hierarchy   Compound List   File List   Compound Members   File Members  

parse_trig.c

Go to the documentation of this file.
00001 
00002 /*
00003  *   THIS FILE IS UNDER RCS - DO NOT MODIFY UNLESS YOU HAVE
00004  *   CHECKED IT OUT USING THE COMMAND CHECKOUT.
00005  *
00006  *    $Id: parse__trig_8c-source.html 2161 2006-05-19 16:55:03Z paulf $
00007  *
00008  *    Revision history:
00009  *     $Log$
00009  *     Revision 1.1  2006/05/19 16:55:02  paulf
00009  *     first inclusion
00009  *
00010  *     Revision 1.7  2002/02/12 04:38:36  davidk
00011  *     modded  to stop segfault on blank lines
00012  *     for trigfiles generated by arc2trig on solaris.
00013  *     The strtok appears to be returning NULL on a blank line,
00014  *     causing a segfault when evaluated by strcmp,
00015  *     so I separated the two calls.
00016  *
00017  *     Revision 1.6  2001/04/05 17:56:27  cjbryan
00018  *     *** empty log message ***
00019  *
00020  *     Revision 1.5  2001/03/22 16:13:28  alex
00021  *     *** empty log message ***
00022  *
00023  *     Revision 1.4  2001/03/21 18:50:27  alex
00024  *     subnet NULL fix as per Pete.
00025  *
00026  *     Revision 1.3  2001/03/21 02:20:04  alex
00027  *     Alex 3/20/1 added .subnet stuff for CVO
00028  *
00029  *     Revision 1.2  2000/03/31 18:26:03  lucky
00030  *     *** empty log message ***
00031  *
00032  *     Revision 1.1  2000/02/14 18:51:48  lucky
00033  *     Initial revision
00034  *
00035  *
00036  */
00037 
00038   /************************************************************
00039    *                       parse_trig.c                       *
00040    *                                                          *
00041    * 1/19/00 Alex: changed eventId from being an integer to   *
00042    *  a string.                                               *
00043    *                                                          *
00044    * Mon Nov  2 11:02:23 MST 1998 lucky                       *
00045    *  Y2K compliance:                                         *
00046    *   SNIPPET struct has been modified to include 8 digit    *
00047    *   date (YYYYMMDD), and corresponding changes have been   *
00048    *   made in parse_Snippet().                               *
00049    *                                                          *
00050    *   t_atodbl() changed to reflect YYYYMMDD. Introduced     *
00051    *   defines that hold string lengths in case these formats *
00052    *   ever need to be changed in the future. Call to         *
00053    *   epocchsec15() replaced by epochsec17().                *
00054    *                                                          *
00055    ************************************************************/  
00056 
00057 #include <stdio.h>
00058 #include <stdlib.h>
00059 #include <string.h>
00060 #include <time.h>
00061 
00062 #ifndef EARTHWORM_H
00063 #include <earthworm.h>
00064 #endif
00065 #include <parse_trig.h>
00066 
00067 
00068 #define LINE_LEN         500
00069 #define BAD_TIME_VALUE   5
00070 
00071 /* Function declarations */
00072 extern int epochsec17 (double *, char *);
00073 int getNextLine (char**, char*);
00074 int t_atodbl (char*, char*, double*); 
00075 
00076 /*
00077 Story:
00078         parseSnippet() parses a trigger message. Inspired by, and uses,
00079 strtok. Therefore,   IT IS NOT MULTI-THREAD SAFE. It must be mutex
00080 protected against concurrent calls to strtok.
00081 
00082 Arguments:
00083         msg:    pointer to the trigger message.
00084         pSnp:   pointer to a SNIPPET structure (see parse_trig.h)
00085         nxtLine:running pointer to current line to be parsed.
00086 
00087 Usage:
00088 For the first call, set nxtLine to msg. This tells parseSnippet that
00089 we're starting a new message. It will search for, and parse  the event
00090 id. It will also parse the first line, and stuff the elements of the
00091 SNIPPET structure.  It will then advance nxtLine to point to the next
00092 line to be parsed and return.  Subsequent calls, with the adjusted
00093 value of nxtLine, will result in the next line of the message being
00094 parsed.  When the last line has been parsed, a EW_FAILURE will be
00095 returned.  
00096 */
00097 
00098 
00099 /***********************************************************************
00100  *  parseSnippet() parses snippet parameters from next line of trigger *
00101  *                 message. Returns EW_FAILURE when nothing left.      *
00102  *                 Does its own error logging via logit.                       *
00103  ***********************************************************************/
00104 int parseSnippet( char* msg, SNIPPET* pSnp, char** nxtLine)
00105 {
00106    static char terminators[] = " \t\n"; /* we accept space, newline, and tab as terminators */
00107    char* nxttok;
00108    char line[LINE_LEN];
00109    static int startFresh=0;
00110 
00111    /* if pointer to next line points to start of message, start clean 
00112     *****************************************************************/
00113    if (*nxtLine == msg) startFresh  = 1;
00114    else goto GetNextStation;
00115 
00116    /* if event id is negative, search for new EVENT ID
00117     **************************************************/
00118 
00119 
00120    GetNextEvent:    /* we jump to here when we run off the end of an event (below) */
00121 
00122    /* we're looking for a line with the form shown below:
00123  EVENT DETECTED     19970729 03:01:13.22 UTC  EVENT ID: 123ABC AUTHOR: Harry SUBNET: redoubt
00124          *
00125          *************************  Y2K  ************************/
00126 
00127    if ( startFresh == 1)
00128         {
00129         /* get next non-zero length line from trigger message */
00130         while ( getNextLine(nxtLine, line) >= 0 ) /* it returns number of chars in line */
00131            {
00132            /* skip this line if it doesn't start with EVENT */
00133            /*** MULTI-THREAD WARNING: strtok is not safe (but it is ubiquitus) ***/
00134 
00135      /* modded by DK 013002 to stop segfault on blank lines 
00136         for trigfiles generated by arc2trig on solaris.
00137         The strtok appears to be returning NULL on a blank line,
00138         causing a segfault when evaluated by strcmp, so I separated
00139         the two calls.
00140       ******************************************************/
00141      if(!(nxttok = strtok( line, terminators))) continue;  
00142            if(strcmp( nxttok, "EVENT" ) != 0) continue;
00143      /* end DK 013002 mod
00144       ******************************************************/
00145 
00146            /* on this line, find "ID:" which is followed by the event id string */
00147            while ( (nxttok = strtok( (char*)NULL, terminators)) != NULL ) /* over tokens on this line */
00148                 {
00149                 if ( strcmp( nxttok, "ID:" ) != 0) continue;
00150                 nxttok = strtok( (char*)NULL, terminators); /* this had better be the event id */
00151                 if (nxttok == NULL) /* oops - there was nothing after ID: */
00152                    {
00153                    logit("et", "parse_trig: Bad syntax in trigger message."
00154                                " Cant find EVENT ID in:\n.%s.\n", line);
00155                    break;
00156                    }
00157                 strncpy(pSnp->eventId, nxttok, EVENTID_SIZE);
00158                 pSnp->eventId[EVENTID_SIZE-1] = '\0';           /* Ensure null termination */
00159 
00160                 /* Now search for author id */
00161                 nxttok = strtok( (char*)NULL, terminators); /* this had better be "AUTHOR:" */
00162                 if ( strcmp( nxttok, "AUTHOR:" ) != 0) 
00163                    {
00164                    logit("et", "parse_trig: Bad syntax in trigger message."
00165                                " Cant find AUTHOR:\n.%s.\n", line);
00166                    break;
00167                    }
00168                 nxttok = strtok( (char*)NULL, terminators); /* this had better be author's name */
00169                 strncpy(pSnp->author, nxttok, AUTHOR_FIELD_SIZE);
00170                 pSnp->author[AUTHOR_FIELD_SIZE-1] = '\0';           /* Ensure null termination */
00171 
00172                 /* Now search for optional subnet */
00173                 nxttok = strtok( (char*)NULL, terminators); /* this might be "SUBNET:" */
00174                 if(nxttok == NULL)
00175                         {
00176                         pSnp->subnet[0] = '\0';
00177                         startFresh = 0;
00178                         goto GotNextEvent;
00179                         }
00180                 if ( strcmp( nxttok, "SUBNET:" ) != 0) 
00181                    {
00182                         pSnp->subnet[0] = '\0';
00183                         startFresh = 0; /* SUBNET is optional; we're happy with the titile line. Ready for rest of message */
00184                         goto GotNextEvent;
00185                    }
00186                 nxttok = strtok( (char*)NULL, terminators); /* this had better be subnet name */
00187                 if(nxttok != NULL) strncpy(pSnp->subnet, nxttok, MAX_SUBNET_LEN); /* as per Pete: if there's
00188                                                 nothing there, nxttok will be NULL, which is on Solaris fatal for strncpy */
00189                 pSnp->subnet[MAX_SUBNET_LEN-1] = '\0';           /* Ensure null termination */
00190 
00191                 startFresh = 0; /* we're happy with the titile line. Ready for rest of message */
00192                 goto GotNextEvent;
00193                 }       /* end of loop over tokens in this line */
00194            }            /* end of loop over lines in message */
00195            return(EW_FAILURE);  /* no more lines */
00196         }               /* end of search for event id */
00197 
00198 
00199 
00200    GotNextEvent:
00201 
00202    /* So we have an event id. Now parse and return snippet parameters until a blank line
00203    *************************************************************************************/ 
00204    getNextLine(nxtLine, line); /* step over the blank line */
00205    getNextLine(nxtLine, line); /* step over the column titles line */
00206    getNextLine(nxtLine, line); /* step over the silly dashes line */
00207 
00208    /* Read the next station line
00209    *****************************/
00210    GetNextStation:
00211    if( getNextLine(nxtLine, line) <= 0 ) /* this should be a station trigger line */
00212         {
00213         return(EW_FAILURE);     /* no more lines */
00214         }
00215    if ( ( nxttok=strtok(line, terminators) ) == NULL ) /* first token should be station name */
00216         {
00217         logit("et","parse_trig: Bad syntax in trigger message:"
00218                    "Strange station line - no tokens in: \n.&s.\n",line);
00219         goto GetNextEvent;
00220         }
00221 
00222    /* Find SCN names
00223     ****************/
00224    if (nxttok ==NULL) /* oops - should have been the station name */
00225         {
00226         logit("et", "parse_trig: Bad syntax in trigger message."
00227                     " Cant find statio name in:\n.%s.\n", line);
00228         goto GetNextStation;
00229         }
00230    strncpy( pSnp->sta, nxttok, 7);      /* Put away the station name */
00231    pSnp->sta[6] = '\0';                 /* Ensure null termination */
00232 
00233    nxttok = strtok( (char*)NULL, terminators); /* should be the component */
00234    if (nxttok ==NULL) /* oops - there was nothing after station name */
00235         {
00236         logit("et", "parse_trig: Bad syntax in trigger message."
00237                     " Cant find comp name in:\n.%s.\n", line);
00238         goto GetNextStation;
00239         }
00240    strncpy( pSnp->chan, nxttok, 9 );    /* Put away the component */
00241    pSnp->chan[8] = '\0';                /* Ensure null termination */
00242 
00243    nxttok = strtok( (char*)NULL, terminators); /* should be the net */
00244    if (nxttok ==NULL) /* oops - there was nothing after component name */
00245         {
00246         logit("et", "parse_trig: Bad syntax in trigger message."
00247                     " Cant find net name in:\n.%s.\n", line);
00248         goto GetNextStation;
00249         }
00250    strncpy( pSnp->net, nxttok, 9 );     /* put away the net */
00251    pSnp->net[8] = '\0';                 /* Ensure null termination */
00252 
00253    /* And now, find "save:"  
00254    ***********************/
00255    while ( (nxttok=strtok((char*)NULL, terminators) ) != NULL )         /* run down the tokens */
00256         {
00257         if ( strcmp( nxttok, "save:" ) == 0 ) goto FoundSave; /* looking for 'save:' */
00258         }
00259    logit("et","parse_trig: Bad syntax in trigger message:"
00260            "Bad station line - no save token found: \n.%s.\n",line);
00261    goto GetNextStation;      
00262    FoundSave:
00263                 
00264    /* now find time strings
00265     ***********************/
00266    nxttok = strtok( (char*)NULL, terminators); /* should be the save start date */
00267    if (nxttok ==NULL) /* oops - there was nothing after save: */
00268         {
00269         logit("et", "parse_trig: Bad syntax in trigger message."
00270                     " Cant find save date in:\n.%s.\n", line);
00271         goto GetNextStation;
00272         }
00273    strcpy( pSnp->startYYYYMMDD, nxttok );       /* put away the date string */
00274 
00275    nxttok = strtok( (char*)NULL, terminators); /* sould be the save start time-of-day */
00276    if (nxttok ==NULL) /* oops - there was nothing after save: */
00277         {
00278         logit("et", "parse_trig: Bad syntax in trigger message."
00279                     " Cant find save time of day in:\n.%s.\n", line);
00280         goto GetNextStation;
00281         }
00282    strcpy( pSnp->startHHMMSS, nxttok );         /* put away the time-of-day string */
00283 
00284    /* Convert start time to double 
00285     ******************************/
00286    if( t_atodbl(pSnp->startYYYYMMDD, pSnp->startHHMMSS, &(pSnp->starttime) ) < 0)
00287         {
00288         logit("et", "parse_trig: Bad syntax in trigger message."
00289                     " Dont understand start-time in:\n.%s.\n", line);
00290         goto GetNextStation;
00291         }
00292    if ( pSnp->starttime < BAD_TIME_VALUE ) /* unreasonable time value */
00293         {
00294         logit("et", "parse_trig: Bad syntax in trigger message."
00295                     " Bad start time value in:\n.%s.\n", line);
00296         goto GetNextStation;
00297         }
00298 
00299    /* find duration to save
00300     ***********************/
00301    nxttok = strtok( (char*)NULL, terminators); /* should be the duration */
00302    if (nxttok ==NULL) /* oops - there was nothing after save: */
00303         {
00304         logit("et", "parse_trig: Bad syntax in trigger message."
00305                     " Cant find duration in:\n.%s.\n", line);
00306         goto GetNextStation;
00307         }
00308    pSnp->duration = atol( nxttok );
00309    if ( pSnp->duration <= 0 )
00310         {
00311         logit("et", "parse_trig: Bad syntax in trigger message."
00312                     " Bad duration value in:\n.%s.\n", line);
00313         goto GetNextStation;
00314         }
00315 
00316    return(EW_SUCCESS);
00317 }   
00318 /* ----------------------------------- end of parseSnippet() -------------------------------------- */
00319 
00320 /**************************************************************************
00321  *    getNextLine(msg, line) moves the next line from 'msg' into 'line    *
00322  *                           returns the number of characters in the line *
00323  *                           Returns negative if error.                   *
00324  **************************************************************************/
00325 int getNextLine ( char** pNxtLine, char* line)
00326 {
00327    int i;
00328    char* nxtLine;
00329 
00330    nxtLine=*pNxtLine;
00331 
00332    for (i =0; i< LINE_LEN; i++)
00333    {
00334      line[i] = *nxtLine++;
00335      if ( (int)line[i] == 0 )
00336      {
00337        return(-1); /*  Not good */
00338      }
00339      if (line[i] == '\n') goto normal;
00340    }
00341    logit("","getNextLine error: line too long \n");
00342    return(-1);
00343 
00344    normal:
00345    line[i+1]=0;
00346    *pNxtLine = nxtLine;
00347    return(i);
00348    
00349 }
00350 /* ----------------------------------- end of getNextLine() -------------------------------------- */
00351 
00352 
00353 /**************************************************************************
00354  *    t_atodbl() takes date and time strings, and converts to double      *
00355  *               seconds since 1970. Note  that the time of day string    *
00356  *               is of the form "hh:mm:ss.ss"                             *
00357  *               Returns negative if error.                               *
00358  **************************************************************************/
00359 
00361 #define TIMESTR_LEN             17      /* whole string */
00362 #define YMD_LEN                 8       /* date part: YYYYMMDD */
00363 #define HOUR_LEN                2       /* hours from HH:MM:SS.SS */
00364 #define MIN_LEN                 2       /* minutes from HH:MM:SS.SS */
00365 #define SEC_LEN                 5       /* seconds from HH:MM:SS.SS */
00366 
00367 int t_atodbl(char* YYYYMMDD, char* HHMMSS, double* starttime) 
00368 {
00369    char timestr[TIMESTR_LEN+1]; /* need space for the null-terminator */
00370    int ret;
00371    int tgtind, srcind;  /* indices for copying fields into timestr */
00372 
00373         /*************************  Y2K  ************************
00374          *
00375          * All instances of YYMMDD have been changed to YYYYMMDD
00376          *
00377          *************************  Y2K  ************************/
00378 
00379    /* we want a string of  the form yyyymmddhhmmss.ss */
00380    /*                               01234567890123456             */
00381 
00382    tgtind = 0;
00383    srcind = 0;
00384 
00385    /* Copy in the date */
00386    strcpy(timestr,YYYYMMDD);
00387 
00388    /* Append the hour */
00389    tgtind = tgtind + YMD_LEN;
00390    strncpy(&timestr[tgtind], HHMMSS, HOUR_LEN);
00391 
00392    /* Append the minute */
00393    tgtind = tgtind + HOUR_LEN;
00394    srcind = srcind + HOUR_LEN + 1; 
00395    strncpy(&timestr[tgtind] ,&HHMMSS[srcind], MIN_LEN); 
00396 
00397    /* Append the seconds */
00398    tgtind = tgtind + MIN_LEN;
00399    srcind = srcind + MIN_LEN + 1; 
00400    strncpy(&timestr[tgtind], &HHMMSS[srcind], SEC_LEN); 
00401 
00402    /* Null terminate the string */
00403    tgtind = tgtind + SEC_LEN;
00404    timestr[tgtind] = '\0';
00405 
00406 
00407    /* convert to double seconds */
00408    ret = epochsec17(starttime, timestr);
00409    if (ret < 0)
00410         {
00411         logit("t","bad return from epochsec17\n");
00412         return(-1);
00413         } 
00414    return(1);
00415 }
00416 /* ----------------------------------- end of t_atodbl() ----------------------------------------- */

Generated on Tue May 6 09:16:06 2003 for Earthworm Libs by doxygen1.3-rc3