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,v 1.1 2006/05/19 16:55:02 paulf Exp $
    00007  *
    00008  *    Revision history:
    00009  *     $Log: parse__trig_8c-source.html,v $
    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() ----------------------------------------- */