Annotation of coherent/g/usr/lib/uucp/tay104/uuconf/time.c, revision 1.1.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.