Annotation of coherent/g/usr/lib/uucp/tay104/uuconf/time.c, revision 1.1

1.1     ! root        1: /* time.c
        !             2:    Parse a time string into a uuconf_timespan structure.
        !             3: 
        !             4:    Copyright (C) 1992 Ian Lance Taylor
        !             5: 
        !             6:    This file is part of the Taylor UUCP uuconf library.
        !             7: 
        !             8:    This library is free software; you can redistribute it and/or
        !             9:    modify it under the terms of the GNU Library General Public License
        !            10:    as published by the Free Software Foundation; either version 2 of
        !            11:    the License, or (at your option) any later version.
        !            12: 
        !            13:    This library is distributed in the hope that it will be useful, but
        !            14:    WITHOUT ANY WARRANTY; without even the implied warranty of
        !            15:    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
        !            16:    Library General Public License for more details.
        !            17: 
        !            18:    You should have received a copy of the GNU Library General Public
        !            19:    License along with this library; if not, write to the Free Software
        !            20:    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
        !            21: 
        !            22:    The author of the program may be contacted at [email protected] or
        !            23:    c/o Infinity Development Systems, P.O. Box 520, Waltham, MA 02254.
        !            24:    */
        !            25: 
        !            26: #include "uucnfi.h"
        !            27: 
        !            28: #if USE_RCS_ID
        !            29: const char _uuconf_time_rcsid[] = "$Id: time.c,v 1.1 93/07/30 08:07:59 bin Exp Locker: bin $";
        !            30: #endif
        !            31: 
        !            32: #include <ctype.h>
        !            33: #include <errno.h>
        !            34: 
        !            35: static int itadd_span P((struct sglobal *qglobal, int istart, int iend,
        !            36:                         long ival, int cretry,
        !            37:                         int (*picmp) P((long, long)),
        !            38:                         struct uuconf_timespan **pqspan,
        !            39:                         pointer pblock));
        !            40: static int itnew P((struct sglobal *qglobal, struct uuconf_timespan **pqset,
        !            41:                    struct uuconf_timespan *qnext, int istart, int iend,
        !            42:                    long ival, int cretry, pointer pblock));
        !            43: 
        !            44: /* An array of weekday abbreviations.  The code below assumes that
        !            45:    each one starts with a lower case letter.  */
        !            46: 
        !            47: static const struct
        !            48: {
        !            49:   const char *zname;
        !            50:   int imin;
        !            51:   int imax;
        !            52: } asTdays[] =
        !            53: {
        !            54:   { "any", 0, 6 },
        !            55:   { "wk", 1, 5 },
        !            56:   { "su", 0, 0 },
        !            57:   { "mo", 1, 1 },
        !            58:   { "tu", 2, 2 },
        !            59:   { "we", 3, 3 },
        !            60:   { "th", 4, 4 },
        !            61:   { "fr", 5, 5 },
        !            62:   { "sa", 6, 6 },
        !            63:   { "never", -1, -2 },
        !            64:   { NULL, 0, 0 }
        !            65: };
        !            66: 
        !            67: /* Parse a time string and add it to a span list.  This function is
        !            68:    given the value, the retry time, and the comparison function to
        !            69:    use.  */
        !            70: 
        !            71: int
        !            72: _uuconf_itime_parse (qglobal, ztime, ival, cretry, picmp, pqspan, pblock)
        !            73:      struct sglobal *qglobal;
        !            74:      char *ztime;
        !            75:      long ival;
        !            76:      int cretry;
        !            77:      int (*picmp) P((long, long));
        !            78:      struct uuconf_timespan **pqspan;
        !            79:      pointer pblock;
        !            80: {
        !            81:   struct uuconf_timespan *qlist;
        !            82:   char bfirst;
        !            83:   const char *z;
        !            84: 
        !            85:   qlist = *pqspan;
        !            86:   if (qlist == (struct uuconf_timespan *) &_uuconf_unset)
        !            87:     qlist = NULL;
        !            88: 
        !            89:   /* Expand the string using a timetable.  Keep rechecking the string
        !            90:      until it does not match.  */
        !            91:   while (TRUE)
        !            92:     {
        !            93:       char **pz;
        !            94:       char *zfound;
        !            95: 
        !            96:       bfirst = *ztime;
        !            97:       if (isupper (BUCHAR (bfirst)))
        !            98:        bfirst = tolower (BUCHAR (bfirst));
        !            99: 
        !           100:       zfound = NULL;
        !           101:       pz = qglobal->qprocess->pztimetables;
        !           102: 
        !           103:       /* We want the last timetable to have been defined with this
        !           104:         name, so we always look through the entire table.  */
        !           105:       while (*pz != NULL)
        !           106:        {
        !           107:          if ((bfirst == (*pz)[0]
        !           108:               || (isupper (BUCHAR ((*pz)[0]))
        !           109:                   && bfirst == tolower (BUCHAR ((*pz)[0]))))
        !           110:              && strcasecmp (ztime, *pz) == 0)
        !           111:            zfound = pz[1];
        !           112:          pz += 2;
        !           113:        }
        !           114:       if (zfound == NULL)
        !           115:        break;
        !           116:       ztime = zfound;
        !           117:     }
        !           118: 
        !           119:   /* Look through the time string.  */
        !           120:   z = ztime;
        !           121:   while (*z != '\0')
        !           122:     {
        !           123:       int iday;
        !           124:       boolean afday[7];
        !           125:       int istart, iend;
        !           126: 
        !           127:       if (*z == ',' || *z == '|')
        !           128:        ++z;
        !           129:       if (*z == '\0' || *z == ';')
        !           130:        break;
        !           131: 
        !           132:       for (iday = 0; iday < 7; iday++)
        !           133:        afday[iday] = FALSE;
        !           134: 
        !           135:       /* Get the days.  */
        !           136:       do
        !           137:        {
        !           138:          bfirst = *z;
        !           139:          if (isupper (BUCHAR (bfirst)))
        !           140:            bfirst = tolower (BUCHAR (bfirst));
        !           141:          for (iday = 0; asTdays[iday].zname != NULL; iday++)
        !           142:            {
        !           143:              size_t clen;
        !           144: 
        !           145:              if (bfirst != asTdays[iday].zname[0])
        !           146:                continue;
        !           147: 
        !           148:              clen = strlen (asTdays[iday].zname);
        !           149:              if (strncasecmp (z, asTdays[iday].zname, clen) == 0)
        !           150:                {
        !           151:                  int iset;
        !           152: 
        !           153:                  for (iset = asTdays[iday].imin;
        !           154:                       iset <= asTdays[iday].imax;
        !           155:                       iset++)
        !           156:                    afday[iset] = TRUE;
        !           157:                  z += clen;
        !           158:                  break;
        !           159:                }
        !           160:            }
        !           161:          if (asTdays[iday].zname == NULL)
        !           162:            return UUCONF_SYNTAX_ERROR;
        !           163:        }
        !           164:       while (isalpha (BUCHAR (*z)));
        !           165: 
        !           166:       /* Get the hours.  */
        !           167:       if (! isdigit (BUCHAR (*z)))
        !           168:        {
        !           169:          istart = 0;
        !           170:          iend = 24 * 60;
        !           171:        }
        !           172:       else
        !           173:        {
        !           174:          char *zendnum;
        !           175: 
        !           176:          istart = (int) strtol ((char *) z, &zendnum, 10);
        !           177:          if (*zendnum != '-' || ! isdigit (BUCHAR (zendnum[1])))
        !           178:            return UUCONF_SYNTAX_ERROR;
        !           179:          z = zendnum + 1;
        !           180:          iend = (int) strtol ((char *) z, &zendnum, 10);
        !           181:          z = zendnum;
        !           182: 
        !           183:          istart = (istart / 100) * 60 + istart % 100;
        !           184:          iend = (iend / 100) * 60 + iend % 100;
        !           185:        }
        !           186: 
        !           187:       /* Add the times we've found onto the list.  */
        !           188:       for (iday = 0; iday < 7; iday++)
        !           189:        {
        !           190:          if (afday[iday])
        !           191:            {
        !           192:              int iminute, iret;
        !           193: 
        !           194:              iminute = iday * 24 * 60;
        !           195:              if (istart < iend)
        !           196:                iret = itadd_span (qglobal, iminute + istart,
        !           197:                                   iminute + iend, ival, cretry, picmp,
        !           198:                                   &qlist, pblock);
        !           199:              else
        !           200:                {
        !           201:                  /* Wrap around midnight.  */
        !           202:                  iret = itadd_span (qglobal, iminute, iminute + iend,
        !           203:                                     ival, cretry, picmp, &qlist, pblock);
        !           204:                  if (iret == UUCONF_SUCCESS)
        !           205:                    iret = itadd_span (qglobal, iminute + istart,
        !           206:                                       iminute + 24 * 60, ival, cretry,
        !           207:                                       picmp, &qlist, pblock);
        !           208:                }
        !           209: 
        !           210:              if (iret != UUCONF_SUCCESS)
        !           211:                return iret;
        !           212:            }
        !           213:        }
        !           214:     }
        !           215: 
        !           216:   *pqspan = qlist;
        !           217: 
        !           218:   return UUCONF_SUCCESS;
        !           219: }
        !           220: 
        !           221: /* Add a time span to an existing list of time spans.  We keep the
        !           222:    list sorted by time to make this operation easier.  This modifies
        !           223:    the existing list, and returns the modified version.  It takes a
        !           224:    comparison function which should return < 0 if the first argument
        !           225:    should take precedence over the second argument and == 0 if they
        !           226:    are the same (for grades this is igradecmp; for sizes it is minus
        !           227:    (the binary operator)).  */
        !           228: 
        !           229: static int
        !           230: itadd_span (qglobal, istart, iend, ival, cretry, picmp, pqspan, pblock)
        !           231:      struct sglobal *qglobal;
        !           232:      int istart;
        !           233:      int iend;
        !           234:      long ival;
        !           235:      int cretry;
        !           236:      int (*picmp) P((long, long));
        !           237:      struct uuconf_timespan **pqspan;
        !           238:      pointer pblock;
        !           239: {
        !           240:   struct uuconf_timespan **pq;
        !           241:   int iret;
        !           242: 
        !           243:   /* istart < iend  */
        !           244:   for (pq = pqspan; *pq != NULL; pq = &(*pq)->uuconf_qnext)
        !           245:     {
        !           246:       int icmp;
        !           247: 
        !           248:       /* Invariant: PREV (*pq) == NULL || PREV (*pq)->iend <= istart  */
        !           249:       /* istart < iend && (*pq)->istart < (*pq)->iend  */
        !           250: 
        !           251:       if (iend <= (*pq)->uuconf_istart)
        !           252:        {
        !           253:          /* istart < iend <= (*pq)->istart < (*pq)->iend  */
        !           254:          /* No overlap, and we're at the right spot.  See if we can
        !           255:             combine these spans.  */
        !           256:          if (iend == (*pq)->uuconf_istart
        !           257:              && cretry == (*pq)->uuconf_cretry
        !           258:              && (*picmp) (ival, (*pq)->uuconf_ival) == 0)
        !           259:            {
        !           260:              (*pq)->uuconf_istart = istart;
        !           261:              return UUCONF_SUCCESS;
        !           262:            }
        !           263:          /* We couldn't combine them.  */
        !           264:          break;
        !           265:        }
        !           266: 
        !           267:       if ((*pq)->uuconf_iend <= istart)
        !           268:        {
        !           269:          /* (*pq)->istart < (*pq)->iend <= istart < iend  */
        !           270:          /* No overlap.  Try attaching this span.  */
        !           271:          if ((*pq)->uuconf_iend == istart
        !           272:              && (*pq)->uuconf_cretry == cretry
        !           273:              && ((*pq)->uuconf_qnext == NULL
        !           274:                  || iend <= (*pq)->uuconf_qnext->uuconf_istart)
        !           275:              && (*picmp) (ival, (*pq)->uuconf_ival) == 0)
        !           276:            {
        !           277:              (*pq)->uuconf_iend = iend;
        !           278:              return UUCONF_SUCCESS;
        !           279:            }
        !           280:          /* Couldn't attach; keep looking for the right spot.  We
        !           281:             might be able to combine part of the new span onto an
        !           282:             existing span, but it's probably not worth it.  */
        !           283:          continue;
        !           284:        }
        !           285: 
        !           286:       /* istart < iend
        !           287:         && (*pq)->istart < (*pq)->iend
        !           288:         && istart < (*pq)->iend
        !           289:         && (*pq)->istart < iend  */
        !           290:       /* Overlap.  */
        !           291: 
        !           292:       icmp = (*picmp) (ival, (*pq)->uuconf_ival);
        !           293: 
        !           294:       if (icmp == 0)
        !           295:        {
        !           296:          /* Just expand the old span to include the new span.  */
        !           297:          if (istart < (*pq)->uuconf_istart)
        !           298:            (*pq)->uuconf_istart = istart;
        !           299:          if ((*pq)->uuconf_iend >= iend)
        !           300:            return UUCONF_SUCCESS;
        !           301:          if ((*pq)->uuconf_qnext == NULL
        !           302:              || iend <= (*pq)->uuconf_qnext->uuconf_istart)
        !           303:            {
        !           304:              (*pq)->uuconf_iend = iend;
        !           305:              return UUCONF_SUCCESS;
        !           306:            }
        !           307:          /* The span we are adding overlaps the next span as well.
        !           308:             Expand the old span up to the next old span, and keep
        !           309:             trying to add the new span.  */
        !           310:          (*pq)->uuconf_iend = (*pq)->uuconf_qnext->uuconf_istart;
        !           311:          istart = (*pq)->uuconf_iend;
        !           312:        }
        !           313:       else if (icmp < 0)
        !           314:        {
        !           315:          /* Replace the old span with the new span.  */
        !           316:          if ((*pq)->uuconf_istart < istart)
        !           317:            {
        !           318:              /* Save the initial portion of the old span.  */
        !           319:              iret = itnew (qglobal, pq, *pq, (*pq)->uuconf_istart, istart,
        !           320:                            (*pq)->uuconf_ival, (*pq)->uuconf_cretry,
        !           321:                            pblock);
        !           322:              if (iret != UUCONF_SUCCESS)
        !           323:                return iret;
        !           324:              pq = &(*pq)->uuconf_qnext;
        !           325:            }
        !           326:          if (iend < (*pq)->uuconf_iend)
        !           327:            {
        !           328:              /* Save the final portion of the old span.  */
        !           329:              iret = itnew (qglobal, &(*pq)->uuconf_qnext,
        !           330:                            (*pq)->uuconf_qnext, iend, (*pq)->uuconf_iend,
        !           331:                            (*pq)->uuconf_ival, (*pq)->uuconf_cretry,
        !           332:                            pblock);
        !           333:              if (iret != UUCONF_SUCCESS)
        !           334:                return iret;
        !           335:            }
        !           336:          (*pq)->uuconf_ival = ival;
        !           337:          (*pq)->uuconf_istart = istart;
        !           338:          (*pq)->uuconf_cretry = cretry;
        !           339:          if ((*pq)->uuconf_qnext == NULL
        !           340:              || iend <= (*pq)->uuconf_qnext->uuconf_istart)
        !           341:            {
        !           342:              (*pq)->uuconf_iend = iend;
        !           343:              return UUCONF_SUCCESS;
        !           344:            }
        !           345:          /* Move this span up to the next one, and keep trying to add
        !           346:             the new span.  */
        !           347:          (*pq)->uuconf_iend = (*pq)->uuconf_qnext->uuconf_istart;
        !           348:          istart = (*pq)->uuconf_iend;
        !           349:        }
        !           350:       else
        !           351:        {
        !           352:          /* Leave the old span untouched.  */
        !           353:          if (istart < (*pq)->uuconf_istart)
        !           354:            {
        !           355:              /* Put in the initial portion of the new span.  */
        !           356:              iret = itnew (qglobal, pq, *pq, istart, (*pq)->uuconf_istart,
        !           357:                            ival, cretry, pblock);
        !           358:              if (iret != UUCONF_SUCCESS)
        !           359:                return iret;
        !           360:              pq = &(*pq)->uuconf_qnext;
        !           361:            }
        !           362:          if (iend <= (*pq)->uuconf_iend)
        !           363:            return UUCONF_SUCCESS;
        !           364:          /* Keep trying to add the new span.  */
        !           365:          istart = (*pq)->uuconf_iend;
        !           366:        }
        !           367:     }
        !           368: 
        !           369:   /* This is the spot for the new span, and there's no overlap.  */
        !           370: 
        !           371:   return itnew (qglobal, pq, *pq, istart, iend, ival, cretry, pblock);
        !           372: }
        !           373: 
        !           374: /* A utility function to create a new uuconf_timespan structure.  */
        !           375: 
        !           376: static int
        !           377: itnew (qglobal, pqset, qnext, istart, iend, ival, cretry, pblock)
        !           378:      struct sglobal *qglobal;
        !           379:      struct uuconf_timespan **pqset;
        !           380:      struct uuconf_timespan *qnext;
        !           381:      int istart;
        !           382:      int iend;
        !           383:      long ival;
        !           384:      int cretry;
        !           385:      pointer pblock;
        !           386: {
        !           387:   register struct uuconf_timespan *qnew;
        !           388: 
        !           389:   qnew = ((struct uuconf_timespan *)
        !           390:          uuconf_malloc (pblock, sizeof (struct uuconf_timespan)));
        !           391:   if (qnew == NULL)
        !           392:     {
        !           393:       qglobal->ierrno = errno;
        !           394:       return UUCONF_MALLOC_FAILED | UUCONF_ERROR_ERRNO;
        !           395:     }
        !           396: 
        !           397:   qnew->uuconf_qnext = qnext;
        !           398:   qnew->uuconf_istart = istart;
        !           399:   qnew->uuconf_iend = iend;
        !           400:   qnew->uuconf_ival = ival;
        !           401:   qnew->uuconf_cretry = cretry;
        !           402: 
        !           403:   *pqset = qnew;
        !           404: 
        !           405:   return UUCONF_SUCCESS;
        !           406: }

unix.superglobalmegacorp.com

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