Annotation of 43BSDReno/contrib/rcs/src/partime.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * PARTIME             parse date/time string into a TM structure
        !             3:  *
        !             4:  * Usage:
        !             5:  *      #include "time.h"             -- expanded tm structure
        !             6:  *     char *str; struct tm *tp;
        !             7:  *     partime(str,tp);
        !             8:  * Returns:
        !             9:  *     0 if parsing failed
        !            10:  *     else time values in specified TM structure (unspecified values
        !            11:  *             set to TMNULL)
        !            12:  * Notes:
        !            13:  *     This code is quasi-public; it may be used freely in like software.
        !            14:  *     It is not to be sold, nor used in licensed software without
        !            15:  *     permission of the author.
        !            16:  *     For everyone's benefit, please report bugs and improvements!
        !            17:  *     Copyright 1980 by Ken Harrenstien, SRI International.
        !            18:  *     (ARPANET: KLH @ SRI)
        !            19:  */
        !            20: 
        !            21: /* Hacknotes:
        !            22:  *     If parsing changed so that no backup needed, could perhaps modify
        !            23:  *             to use a FILE input stream.  Need terminator, though.
        !            24:  *     Perhaps should return 0 on success, else a non-zero error val?
        !            25:  *     Flush AMPM from TM structure and handle locally within PARTIME,
        !            26:  *             like midnight/noon?
        !            27:  */
        !            28: 
        !            29: #ifndef lint
        !            30: static char rcsid[]=
        !            31: "$Header: /usr/src/local/bin/rcs/src/RCS/partime.c,v 1.4 89/05/01 14:48:46 narten Exp $";
        !            32: #endif
        !            33: 
        !            34: /* $Log:       partime.c,v $
        !            35:  * Revision 1.4  89/05/01  14:48:46  narten
        !            36:  * fixed #ifdef DEBUG construct
        !            37:  * 
        !            38:  * Revision 1.3  88/11/08  12:02:15  narten
        !            39:  * changes from  [email protected] (Paul Eggert)
        !            40:  * 
        !            41:  * Revision 1.3  88/08/28  14:53:40  eggert
        !            42:  * Remove unportable "#endif XXX"s.
        !            43:  * 
        !            44:  * Revision 1.2  87/03/27  14:21:53  jenkins
        !            45:  * Port to suns
        !            46:  * 
        !            47:  * Revision 1.1  84/01/23  14:50:07  kcs
        !            48:  * Initial revision
        !            49:  * 
        !            50:  * Revision 1.1  82/05/06  11:38:26  wft
        !            51:  * Initial revision
        !            52:  * 
        !            53:  */
        !            54: 
        !            55: #include <stdio.h>
        !            56: #include <ctype.h>
        !            57: #include "time.h"
        !            58: 
        !            59: #ifndef lint
        !            60: static char timeid[] = TIMEID;
        !            61: #endif
        !            62: 
        !            63: struct tmwent {
        !            64:        char *went;
        !            65:        long wval;      /* must be big enough to hold pointer or integer */
        !            66:        char wflgs;
        !            67:        char wtype;
        !            68: };
        !            69:        /* wflgs */
        !            70: #define TWSPEC 01      /* Word wants special processing */
        !            71: #define TWTIME 02      /* Word is a time value (absence implies date) */
        !            72: #define TWDST  04      /* Word is a DST-type timezone */
        !            73: #define TW1200 010     /* Word is NOON or MIDNIGHT (sigh) */
        !            74: 
        !            75: int pt12hack();
        !            76: int ptnoise();
        !            77: struct tmwent tmwords [] = {
        !            78:        {"january",      0, 0, TM_MON},
        !            79:        {"february",     1, 0, TM_MON},
        !            80:        {"march",        2, 0, TM_MON},
        !            81:        {"april",        3, 0, TM_MON},
        !            82:        {"may",          4, 0, TM_MON},
        !            83:        {"june",         5, 0, TM_MON},
        !            84:        {"july",         6, 0, TM_MON},
        !            85:        {"august",       7, 0, TM_MON},
        !            86:        {"september",    8, 0, TM_MON},
        !            87:        {"october",      9, 0, TM_MON},
        !            88:        {"november",     10, 0, TM_MON},
        !            89:        {"december",     11, 0, TM_MON},
        !            90: 
        !            91:        {"sunday",       0, 0, TM_WDAY},
        !            92:        {"monday",       1, 0, TM_WDAY},
        !            93:        {"tuesday",      2, 0, TM_WDAY},
        !            94:        {"wednesday",    3, 0, TM_WDAY},
        !            95:        {"thursday",     4, 0, TM_WDAY},
        !            96:        {"friday",       5, 0, TM_WDAY},
        !            97:        {"saturday",     6, 0, TM_WDAY},
        !            98: 
        !            99:        {"gmt",          0*60, TWTIME, TM_ZON},   /* Greenwich */
        !           100:        {"gst",          0*60, TWTIME, TM_ZON},
        !           101:        {"gdt",          0*60, TWTIME+TWDST, TM_ZON},     /* ?? */
        !           102: 
        !           103:        {"ast",          4*60, TWTIME, TM_ZON},   /* Atlantic */
        !           104:        {"est",          5*60, TWTIME, TM_ZON},   /* Eastern */
        !           105:        {"cst",          6*60, TWTIME, TM_ZON},   /* Central */
        !           106:        {"mst",          7*60, TWTIME, TM_ZON},   /* Mountain */
        !           107:        {"pst",          8*60, TWTIME, TM_ZON},   /* Pacific */
        !           108:        {"yst",          9*60, TWTIME, TM_ZON},   /* Yukon */
        !           109:        {"hst",          10*60, TWTIME, TM_ZON},  /* Hawaii */
        !           110:        {"bst",          11*60, TWTIME, TM_ZON},  /* Bering */
        !           111: 
        !           112:        {"adt",          4*60, TWTIME+TWDST, TM_ZON},     /* Atlantic */
        !           113:        {"edt",          5*60, TWTIME+TWDST, TM_ZON},     /* Eastern */
        !           114:        {"cdt",          6*60, TWTIME+TWDST, TM_ZON},     /* Central */
        !           115:        {"mdt",          7*60, TWTIME+TWDST, TM_ZON},     /* Mountain */
        !           116:        {"pdt",          8*60, TWTIME+TWDST, TM_ZON},     /* Pacific */
        !           117:        {"ydt",          9*60, TWTIME+TWDST, TM_ZON},     /* Yukon */
        !           118:        {"hdt",          10*60, TWTIME+TWDST, TM_ZON},    /* Hawaii */
        !           119:        {"bdt",          11*60, TWTIME+TWDST, TM_ZON},    /* Bering */
        !           120: 
        !           121:        {"daylight",     1, TWTIME+TWDST, TM_ZON},        /* Local Daylight */
        !           122:        {"standard",     1, TWTIME, TM_ZON},      /* Local Standard */
        !           123:        {"std",          1, TWTIME, TM_ZON},      /*   "       "    */
        !           124: 
        !           125:        {"am",           1, TWTIME, TM_AMPM},
        !           126:        {"pm",           2, TWTIME, TM_AMPM},
        !           127:        {"noon",         12,TWTIME+TW1200, 0},    /* Special frobs */
        !           128:        {"midnight",     0, TWTIME+TW1200, 0},
        !           129:        {"at",           (long)ptnoise, TWSPEC, 0},    /* Noise word */
        !           130: 
        !           131:        {0, 0, 0, 0},             /* Zero entry to terminate searches */
        !           132: };
        !           133: 
        !           134: #define TMWILD (-2)    /* Value meaning item specified as wild-card */
        !           135:                        /* (May use someday...) */
        !           136: 
        !           137: struct token {
        !           138:        char *tcp;      /* pointer to string */
        !           139:        int tcnt;       /* # chars */
        !           140:        char tbrk;      /* "break" char */
        !           141:        char tbrkl;     /* last break char */
        !           142:        char tflg;      /* 0 = alpha, 1 = numeric */
        !           143:        union {         /* Resulting value; */
        !           144:                int tnum;/* either a #, or */
        !           145:                struct tmwent *ttmw;/* ptr to a tmwent. */
        !           146:        } tval;
        !           147: };
        !           148: 
        !           149: partime(astr, atm)
        !           150: char *astr;
        !           151: struct tm *atm;
        !           152: {      register int *tp;
        !           153:        register struct tmwent *twp;
        !           154:        register int i;
        !           155:        struct token btoken, atoken;
        !           156:        char *cp, ch;
        !           157:        int ord, midnoon;
        !           158:        int (*aproc)();
        !           159: 
        !           160:        tp = (int *)atm;
        !           161:        zaptime(tp);                     /* Initialize the TM structure */
        !           162:        midnoon = TMNULL;               /* and our own temp stuff */
        !           163:        btoken.tcnt = btoken.tbrkl = 0;
        !           164:        btoken.tcp = astr;
        !           165: 
        !           166: domore:
        !           167:        if(!ptitoken(btoken.tcp+btoken.tcnt,&btoken))   /* Get a token */
        !           168:          {     if(btoken.tval.tnum) return(0);         /* Read error? */
        !           169:                if(midnoon != TMNULL)                   /* EOF, wrap up */
        !           170:                        return(pt12hack(tp, midnoon));
        !           171:                return(1);                              /* Win return! */
        !           172:          }
        !           173:        if(btoken.tflg == 0)            /* Alpha? */
        !           174:          {     twp = btoken.tval.ttmw;         /* Yes, get ptr to entry */
        !           175:                if(twp->wflgs&TWSPEC)           /* Special alpha crock */
        !           176:                  {     aproc = (int (*) ()) (twp->wval);
        !           177:                        if(!(*aproc)(tp, twp, &btoken))
        !           178:                                return(0);      /* ERR: special word err */
        !           179:                        goto domore;
        !           180:                  }
        !           181:                if(twp->wflgs&TW1200)
        !           182:                        if(ptstash(&midnoon,(int)twp->wval))
        !           183:                                return(0);      /* ERR: noon/midnite clash */
        !           184:                        else goto domore;
        !           185:                if(ptstash(&tp[twp->wtype],(int)twp->wval))
        !           186:                        return(0);              /* ERR: val already set */
        !           187:                if(twp->wtype == TM_ZON)        /* If was zone, hack DST */
        !           188:                        if(ptstash(&tp[TM_ISDST],(twp->wflgs&TWDST)))
        !           189:                                return(0);      /* ERR: DST conflict */
        !           190:                goto domore;
        !           191:          }
        !           192: 
        !           193:        /* Token is number.  Lots of hairy heuristics. */
        !           194:        if(btoken.tcnt >= 7)    /* More than 6 digits in string? */
        !           195:                return(0);      /* ERR: number too big */
        !           196:        if(btoken.tcnt == 6)    /* 6 digits = HHMMSS.  Needs special crock */
        !           197:          {                     /* since 6 digits are too big for integer! */
        !           198:                i = (btoken.tcp[0]-'0')*10      /* Gobble 1st 2 digits */
        !           199:                   + btoken.tcp[1]-'0';
        !           200:                btoken.tcnt = 2;                /* re-read last 4 chars */
        !           201:                goto coltime;
        !           202:          }
        !           203: 
        !           204:        i = btoken.tval.tnum;   /* Value now known to be valid; get it. */
        !           205:        if( btoken.tcnt == 5    /*  5 digits = HMMSS */
        !           206:         || btoken.tcnt == 3)   /*  3 digits = HMM   */
        !           207:          {     if(btoken.tcnt != 3)
        !           208:                        if(ptstash(&tp[TM_SEC], i%100))
        !           209:                                return(0);      /* ERR: sec conflict */
        !           210:                        else i /= 100;
        !           211: hhmm4:         if(ptstash(&tp[TM_MIN], i%100))
        !           212:                        return(0);              /* ERR: min conflict */
        !           213:                i /= 100;
        !           214: hh2:            if(ptstash(&tp[TM_HOUR], i))
        !           215:                        return(0);              /* ERR: hour conflict */
        !           216:                goto domore;
        !           217:          }
        !           218: 
        !           219:        if(btoken.tcnt == 4)    /* 4 digits = YEAR or HHMM */
        !           220:          {     if(tp[TM_YEAR] != TMNULL) goto hhmm4;   /* Already got yr? */
        !           221:                if(tp[TM_HOUR] != TMNULL) goto year4;   /* Already got hr? */
        !           222:                if((i%100) > 59) goto year4;            /* MM >= 60? */
        !           223:                if(btoken.tbrk == ':')                  /* HHMM:SS ? */
        !           224:                        if( ptstash(&tp[TM_HOUR],i/100)
        !           225:                         || ptstash(&tp[TM_MIN], i%100))
        !           226:                                return(0);              /* ERR: hr/min clash */
        !           227:                        else goto coltm2;               /* Go handle SS */
        !           228:                if(btoken.tbrk != ',' && btoken.tbrk != '/'
        !           229:                  && ptitoken(btoken.tcp+btoken.tcnt,&atoken)   /* Peek */
        !           230:                  && atoken.tflg == 0                   /* alpha */
        !           231:                  && (atoken.tval.ttmw->wflgs&TWTIME))  /* HHMM-ZON */
        !           232:                        goto hhmm4;
        !           233:                if(btoken.tbrkl == '-'          /* DD-Mon-YYYY */
        !           234:                  || btoken.tbrkl == ','        /* Mon DD, YYYY */
        !           235:                  || btoken.tbrkl == '/'        /* MM/DD/YYYY */
        !           236:                  || btoken.tbrkl == '.'        /* DD.MM.YYYY */
        !           237:                  || btoken.tbrk == '-'         /* YYYY-MM-DD */
        !           238:                        ) goto year4;
        !           239:                goto hhmm4;                     /* Give up, assume HHMM. */
        !           240:          }
        !           241: 
        !           242:        /* From this point on, assume tcnt == 1 or 2 */
        !           243:        /* 2 digits = YY, MM, DD, or HH (MM and SS caught at coltime) */
        !           244:        if(btoken.tbrk == ':')          /* HH:MM[:SS] */
        !           245:                goto coltime;           /*  must be part of time. */
        !           246:        if(i > 31) goto yy2;            /* If >= 32, only YY poss. */
        !           247: 
        !           248:        /* Check for numerical-format date */
        !           249:        for (cp = "/-."; ch = *cp++;)
        !           250:          {     ord = (ch == '.' ? 0 : 1);      /* n/m = D/M or M/D */
        !           251:                if(btoken.tbrk == ch)                   /* "NN-" */
        !           252:                  {     if(btoken.tbrkl != ch)
        !           253:                          {     if(ptitoken(btoken.tcp+btoken.tcnt,&atoken)
        !           254:                                  && atoken.tflg == 0
        !           255:                                  && atoken.tval.ttmw->wtype == TM_MON)
        !           256:                                        goto dd2;
        !           257:                                if(ord)goto mm2; else goto dd2; /* "NN-" */
        !           258:                          }                             /* "-NN-" */
        !           259:                        if(tp[TM_DAY] == TMNULL
        !           260:                        && tp[TM_YEAR] != TMNULL)       /* If "YY-NN-" */
        !           261:                                goto mm2;               /* then always MM */
        !           262:                        if(ord)goto dd2; else goto mm2;
        !           263:                  }
        !           264:                if(btoken.tbrkl == ch                   /* "-NN" */
        !           265:                  && tp[ord ? TM_MON : TM_DAY] != TMNULL)
        !           266:                        if(tp[ord ? TM_DAY : TM_MON] == TMNULL) /* MM/DD */
        !           267:                                if(ord)goto dd2; else goto mm2;
        !           268:                        else goto yy2;                  /* "-YY" */
        !           269:          }
        !           270: 
        !           271:        /* At this point only YY, DD, and HH are left.
        !           272:         * YY is very unlikely since value is <= 32 and there was
        !           273:         * no numerical format date.  Make one last try at YY
        !           274:         * before dropping through to DD vs HH code.
        !           275:         */
        !           276:        if(btoken.tcnt == 2             /* If 2 digits */
        !           277:          && tp[TM_HOUR] != TMNULL      /* and already have hour */
        !           278:          && tp[TM_DAY] != TMNULL       /* and day, but  */
        !           279:          && tp[TM_YEAR] == TMNULL)     /* no year, then assume */
        !           280:                goto yy2;               /* that's what we have. */
        !           281: 
        !           282:        /* Now reduced to choice between HH and DD */
        !           283:        if(tp[TM_HOUR] != TMNULL) goto dd2;     /* Have hour? Assume day. */
        !           284:        if(tp[TM_DAY] != TMNULL) goto hh2;      /* Have day? Assume hour. */
        !           285:        if(i > 24) goto dd2;                    /* Impossible HH means DD */
        !           286:        if(!ptitoken(btoken.tcp+btoken.tcnt, &atoken))  /* Read ahead! */
        !           287:                if(atoken.tval.tnum) return(0); /* ERR: bad token */
        !           288:                else goto dd2;                  /* EOF, assume day. */
        !           289:        if( atoken.tflg == 0            /* If next token is an alpha */
        !           290:         && atoken.tval.ttmw->wflgs&TWTIME)  /* time-spec, assume hour */
        !           291:                goto hh2;               /* e.g. "3 PM", "11-EDT"  */
        !           292: 
        !           293: dd2:   if(ptstash(&tp[TM_DAY],i))      /* Store day (1 based) */
        !           294:                return(0);
        !           295:        goto domore;
        !           296: 
        !           297: mm2:   if(ptstash(&tp[TM_MON], i-1))   /* Store month (make zero based) */
        !           298:                return(0);
        !           299:        goto domore;
        !           300: 
        !           301: yy2:   i += 1900;
        !           302: year4: if(ptstash(&tp[TM_YEAR],i))     /* Store year (full number) */
        !           303:                return(0);              /* ERR: year conflict */
        !           304:        goto domore;
        !           305: 
        !           306:        /* Hack HH:MM[[:]SS] */
        !           307: coltime:
        !           308:        if(ptstash(&tp[TM_HOUR],i)) return(0);
        !           309:        if(!ptitoken(btoken.tcp+btoken.tcnt,&btoken))
        !           310:                return(!btoken.tval.tnum);
        !           311:        if(!btoken.tflg) return(0);     /* ERR: HH:<alpha> */
        !           312:        if(btoken.tcnt == 4)            /* MMSS */
        !           313:                if(ptstash(&tp[TM_MIN],btoken.tval.tnum/100)
        !           314:                  || ptstash(&tp[TM_SEC],btoken.tval.tnum%100))
        !           315:                        return(0);
        !           316:                else goto domore;
        !           317:        if(btoken.tcnt != 2
        !           318:          || ptstash(&tp[TM_MIN],btoken.tval.tnum))
        !           319:                return(0);              /* ERR: MM bad */
        !           320:        if(btoken.tbrk != ':') goto domore;     /* Seconds follow? */
        !           321: coltm2:        if(!ptitoken(btoken.tcp+btoken.tcnt,&btoken))
        !           322:                return(!btoken.tval.tnum);
        !           323:        if(!btoken.tflg || btoken.tcnt != 2     /* Verify SS */
        !           324:          || ptstash(&tp[TM_SEC], btoken.tval.tnum))
        !           325:                return(0);              /* ERR: SS bad */
        !           326:        goto domore;
        !           327: }
        !           328: 
        !           329: /* Store date/time value, return 0 if successful.
        !           330:  * Fails if entry already set to a different value.
        !           331:  */
        !           332: ptstash(adr,val)
        !           333: int *adr;
        !           334: {      register int *a;
        !           335:        if( *(a=adr) != TMNULL)
        !           336:                return(*a != val);
        !           337:        *a = val;
        !           338:        return(0);
        !           339: }
        !           340: 
        !           341: /* This subroutine is invoked for NOON or MIDNIGHT when wrapping up
        !           342:  * just prior to returning from partime.
        !           343:  */
        !           344: pt12hack(atp, aval)
        !           345: int *atp, aval;
        !           346: {      register int *tp, i, h;
        !           347:        tp = atp;
        !           348:        if (((i=tp[TM_MIN]) && i != TMNULL)     /* Ensure mins, secs */
        !           349:         || ((i=tp[TM_SEC]) && i != TMNULL))    /* are 0 or unspec'd */
        !           350:                return(0);                      /* ERR: MM:SS not 00:00 */
        !           351:        i = aval;                       /* Get 0 or 12 (midnite or noon) */
        !           352:        if ((h = tp[TM_HOUR]) == TMNULL /* If hour unspec'd, win */
        !           353:         || h == 12)                    /* or if 12:00 (matches either) */
        !           354:                tp[TM_HOUR] = i;        /* Then set time */
        !           355:        else if(!(i == 0                /* Nope, but if midnight and */
        !           356:                &&(h == 0 || h == 24))) /* time matches, can pass. */
        !           357:                        return(0);      /* ERR: HH conflicts */
        !           358:        tp[TM_AMPM] = TMNULL;           /* Always reset this value if won */
        !           359:        return(1);
        !           360: }
        !           361: 
        !           362: /* Null routine for no-op tokens */
        !           363: 
        !           364: ptnoise() { return(1); }
        !           365: 
        !           366: /* Get a token and identify it to some degree.
        !           367:  * Returns 0 on failure; token.tval will be 0 for normal EOF, otherwise
        !           368:  * hit error of some sort
        !           369:  */
        !           370: 
        !           371: ptitoken(astr, tkp)
        !           372: register struct token *tkp;
        !           373: char *astr;
        !           374: {
        !           375:        register char *cp;
        !           376:        register int i;
        !           377: 
        !           378:        tkp->tval.tnum = 0;
        !           379:        if(pttoken(astr,tkp) == 0)
        !           380: #ifdef DEBUG
        !           381:            {
        !           382:                VOID printf("EOF\n");
        !           383:                return(0);
        !           384:            }
        !           385: #else
        !           386:                return(0);
        !           387: #endif 
        !           388:        cp = tkp->tcp;
        !           389: 
        !           390: #ifdef DEBUG
        !           391:        i = cp[tkp->tcnt];
        !           392:        cp[tkp->tcnt] = 0;
        !           393:        VOID printf("Token: \"%s\" ",cp);
        !           394:        cp[tkp->tcnt] = i;
        !           395: #endif
        !           396: 
        !           397:        if(tkp->tflg)
        !           398:                for(i = tkp->tcnt; i > 0; i--)
        !           399:                        tkp->tval.tnum = (int)tkp->tval.tnum*10 + ((*cp++)-'0');
        !           400:        else
        !           401:          {     i = ptmatchstr(cp, tkp->tcnt, tmwords);
        !           402:                tkp->tval.tnum = i ? i : -1;         /* Set -1 for error */
        !           403: 
        !           404: #ifdef DEBUG
        !           405:                if(!i) VOID printf("Not found!\n");
        !           406: #endif
        !           407: 
        !           408:                if(!i) return(0);
        !           409:          }
        !           410: 
        !           411: #ifdef DEBUG
        !           412:        if(tkp->tflg)
        !           413:                VOID printf("Val: %d.\n",tkp->tval.tnum);
        !           414:        else VOID printf("Found: \"%s\", val: %d., type %d\n",
        !           415:                tkp->tval.ttmw->went,tkp->tval.ttmw->wval,tkp->tval.ttmw->wtype);
        !           416: #endif
        !           417: 
        !           418:        return(1);
        !           419: }
        !           420: 
        !           421: /* Read token from input string into token structure */
        !           422: pttoken(astr,tkp)
        !           423: register struct token *tkp;
        !           424: char *astr;
        !           425: {
        !           426:        register char *cp;
        !           427:        register int c;
        !           428: 
        !           429:        tkp->tcp = cp = astr;
        !           430:        tkp->tbrkl = tkp->tbrk;         /* Set "last break" */
        !           431:        tkp->tcnt = tkp->tbrk = tkp->tflg = 0;
        !           432: 
        !           433:        while(c = *cp++)
        !           434:          {     switch(c)
        !           435:                  {     case ' ': case '\t':    /* Flush all whitespace */
        !           436:                                while((c = *cp++) && isspace(c));
        !           437:                                cp--;           /* Drop thru to handle brk */
        !           438:                        case '(': case ')':     /* Perhaps any non-alphanum */
        !           439:                        case '-': case ',':     /* shd qualify as break? */
        !           440:                        case '/': case ':': case '.':   /* Break chars */
        !           441:                                if(tkp->tcnt == 0)      /* If no token yet */
        !           442:                                  {     tkp->tcp = cp;  /* ignore the brk */
        !           443:                                        tkp->tbrkl = c;
        !           444:                                        continue;       /* and go on. */
        !           445:                                  }
        !           446:                                tkp->tbrk = c;
        !           447:                                return(tkp->tcnt);
        !           448:                  }
        !           449:                if(tkp->tcnt == 0)              /* If first char of token, */
        !           450:                        tkp->tflg = isdigit(c); /*    determine type */
        !           451:                if(( isdigit(c) &&  tkp->tflg)  /* If not first, make sure */
        !           452:                 ||(!isdigit(c) && !tkp->tflg)) /*    char matches type */
        !           453:                        tkp->tcnt++;            /* Win, add to token. */
        !           454:                else {
        !           455:                        cp--;                   /* Wrong type, back up */
        !           456:                        tkp->tbrk = c;
        !           457:                        return(tkp->tcnt);
        !           458:                  }
        !           459:          }
        !           460:        return(tkp->tcnt);              /* When hit EOF */
        !           461: }
        !           462: 
        !           463: 
        !           464: ptmatchstr(astr,cnt,astruc)
        !           465: char *astr;
        !           466: int cnt;
        !           467: struct tmwent *astruc;
        !           468: {      register char *cp, *mp;
        !           469:        register int c;
        !           470:        struct tmwent *lastptr;
        !           471:        struct integ { int word; };   /* For getting at array ptr */
        !           472:        int i;
        !           473: 
        !           474:        lastptr = 0;
        !           475:        for(;mp = (char *)((struct integ *)astruc)->word; astruc += 1)
        !           476:          {     cp = astr;
        !           477:                for(i = cnt; i > 0; i--)
        !           478:                  {     switch((c = *cp++) ^ *mp++)     /* XOR the chars */
        !           479:                          {     case 0: continue;       /* Exact match */
        !           480:                                case 040: if(isalpha(c))
        !           481:                                        continue;
        !           482:                          }
        !           483:                        break;
        !           484:                  }
        !           485:                if(i==0)
        !           486:                        if(*mp == 0) return((unsigned int)astruc);    /* Exact match */
        !           487:                        else if(lastptr) return(0);     /* Ambiguous */
        !           488:                        else lastptr = astruc;          /* 1st ambig */
        !           489:          }
        !           490:        return((unsigned int)lastptr);
        !           491: }
        !           492: 
        !           493: 
        !           494: 
        !           495: zaptime(tp)
        !           496: register int *tp;
        !           497: /* clears tm structure pointed to by tp */
        !           498: {      register int i;
        !           499:        i = (sizeof (struct tm))/(sizeof (int));
        !           500:        do *tp++ = TMNULL;              /* Set entry to "unspecified" */
        !           501:        while(--i);                     /* Faster than FOR */
        !           502: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.