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

1.1     ! root        1: /*
        !             2:  *                       RLOG    operation
        !             3:  */
        !             4: #ifndef lint
        !             5: static char rcsid[]=
        !             6: "$Header: /usr/src/local/bin/rcs/src/RCS/rlog.c,v 4.7 89/05/01 15:13:48 narten Exp $ Purdue CS";
        !             7: #endif
        !             8: /*****************************************************************************
        !             9:  *                       print contents of RCS files
        !            10:  *****************************************************************************
        !            11:  */
        !            12: 
        !            13: /* Copyright (C) 1982, 1988, 1989 Walter Tichy
        !            14:  * All rights reserved.
        !            15:  *
        !            16:  * Redistribution and use in source and binary forms are permitted
        !            17:  * provided that the above copyright notice and this paragraph are
        !            18:  * duplicated in all such forms and that any documentation,
        !            19:  * advertising materials, and other materials related to such
        !            20:  * distribution and use acknowledge that the software was developed
        !            21:  * by Walter Tichy.
        !            22:  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
        !            23:  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
        !            24:  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
        !            25:  *
        !            26:  * Report all problems and direct all questions to:
        !            27:  *   [email protected]
        !            28:  * 
        !            29: 
        !            30: 
        !            31: 
        !            32: 
        !            33: 
        !            34: 
        !            35: 
        !            36: */
        !            37: 
        !            38: 
        !            39: 
        !            40: 
        !            41: /* $Log:       rlog.c,v $
        !            42:  * Revision 4.7  89/05/01  15:13:48  narten
        !            43:  * changed copyright header to reflect current distribution rules
        !            44:  * 
        !            45:  * Revision 4.6  88/11/08  11:59:40  narten
        !            46:  * changes from  [email protected] (Paul Eggert)
        !            47:  * 
        !            48:  * Revision 4.6  88/08/09  19:13:28  eggert
        !            49:  * Check for memory exhaustion; don't access freed storage.
        !            50:  * Shrink stdio code size; remove lint.
        !            51:  * 
        !            52:  * Revision 4.5  87/12/18  11:46:38  narten
        !            53:  * more lint cleanups (Guy Harris)
        !            54:  * 
        !            55:  * Revision 4.4  87/10/18  10:41:12  narten
        !            56:  * Updating version numbers
        !            57:  * Changes relative to 1.1 actually relative to 4.2
        !            58:  * 
        !            59:  * Revision 1.3  87/09/24  14:01:10  narten
        !            60:  * Sources now pass through lint (if you ignore printf/sprintf/fprintf 
        !            61:  * warnings)
        !            62:  * 
        !            63:  * Revision 1.2  87/03/27  14:22:45  jenkins
        !            64:  * Port to suns
        !            65:  * 
        !            66:  * Revision 1.1  84/01/23  14:50:45  kcs
        !            67:  * Initial revision
        !            68:  * 
        !            69:  * Revision 4.2  83/12/05  09:18:09  wft
        !            70:  * changed rewriteflag to external.
        !            71:  * 
        !            72:  * Revision 4.1  83/05/11  16:16:55  wft
        !            73:  * Added -b, updated getnumericrev() accordingly.
        !            74:  * Replaced getpwuid() with getcaller().
        !            75:  * 
        !            76:  * Revision 3.7  83/05/11  14:24:13  wft
        !            77:  * Added options -L and -R;
        !            78:  * Fixed selection bug with -l on multiple files.
        !            79:  * Fixed error on dates of the form -d'>date' (rewrote getdatepair()).
        !            80:  * 
        !            81:  * Revision 3.6  82/12/24  15:57:53  wft
        !            82:  * shortened output format.
        !            83:  *
        !            84:  * Revision 3.5  82/12/08  21:45:26  wft
        !            85:  * removed call to checkaccesslist(); used DATEFORM to format all dates;
        !            86:  * removed unused variables.
        !            87:  *
        !            88:  * Revision 3.4  82/12/04  13:26:25  wft
        !            89:  * Replaced getdelta() with gettree(); removed updating of field lockedby.
        !            90:  *
        !            91:  * Revision 3.3  82/12/03  14:08:20  wft
        !            92:  * Replaced getlogin with getpwuid(), %02d with %.2d, fancydate with PRINTDATE.
        !            93:  * Fixed printing of nil, removed printing of Suffix,
        !            94:  * added shortcut if no revisions are printed, disambiguated struct members.
        !            95:  *
        !            96:  * Revision 3.2  82/10/18  21:09:06  wft
        !            97:  * call to curdir replaced with getfullRCSname(),
        !            98:  * fixed call to getlogin(), cosmetic changes on output,
        !            99:  * changed conflicting long identifiers.
        !           100:  *
        !           101:  * Revision 3.1  82/10/13  16:07:56  wft
        !           102:  * fixed type of variables receiving from getc() (char -> int).
        !           103:  */
        !           104: 
        !           105: 
        !           106: 
        !           107: #include "time.h"
        !           108: #include "rcsbase.h"
        !           109: #ifndef lint
        !           110: static char rcsbaseid[] = RCSBASE;
        !           111: #endif
        !           112: 
        !           113: extern char * partialno();
        !           114: extern char * getcaller();          /*get login of caller                   */
        !           115: extern        free();
        !           116: extern int    countnumflds();
        !           117: extern int    compartial();
        !           118: extern int    expandsym();          /*get numeric name of a revision        */
        !           119: extern int nextc;                   /*next input character                  */
        !           120: extern char Klog[];
        !           121: extern char Ktext[];
        !           122: extern int  partime();
        !           123: extern long maketime();             /*convert parsed time to unix time.     */
        !           124: extern struct tm * localtime();     /*convert unixtime into a tm-structure  */
        !           125: extern int  pairfilenames();
        !           126: extern struct hshentry  * getnum();
        !           127: extern FILE * finptr;               /* RCS input file                       */
        !           128: extern FILE * frewrite;             /* new RCS file                         */
        !           129: extern int    rewriteflag;          /* indicates whether input should be    */
        !           130:                                    /* echoed to frewrite */
        !           131: extern int    nerror;               /* error counter                        */
        !           132: 
        !           133: char * RCSfilename, * workfilename;
        !           134: 
        !           135: char * caller;                        /* caller's login;                    */
        !           136: int  descflag, selectflag, selectop;  /* option to print access list, symbolic  */
        !           137:                                       /* names, descriptive text, locks and */
        !           138:                                       /* Head                               */
        !           139: int  onlylockflag;                   /* option to print only files         */
        !           140:                                      /* with locks                         */
        !           141: int  onlyRCSflag;                     /* option to print only RCS file name */
        !           142: int  lockflag;                        /* whether locker option is set       */
        !           143: int  revno;                           /* number of revision chosen          */
        !           144: 
        !           145: struct  lockers {                     /* lockers in locker option; stored   */
        !           146:      char               * login;      /* lockerlist                         */
        !           147:      struct     lockers * lockerlink;
        !           148:      }  ;
        !           149: 
        !           150: struct  stateattri {                  /* states in state option; stored in  */
        !           151:      char               * status;     /* statelist                          */
        !           152:      struct  stateattri * nextstate;
        !           153:      }  ;
        !           154: 
        !           155: struct  authors {                     /* login names in author option;      */
        !           156:      char               * login;      /* stored in authorlist               */
        !           157:      struct     authors * nextauthor;
        !           158:      }  ;
        !           159: 
        !           160: struct Revpairs{                      /* revision or branch range in -r     */
        !           161:      int                  numfld;     /* option; stored in revlist          */
        !           162:      char               * strtrev;
        !           163:      char               * endrev;
        !           164:      struct  Revpairs   * rnext;
        !           165:      } ;
        !           166: 
        !           167: struct Datepairs{                     /* date range in -d option; stored in */
        !           168:      char               strtdate[datelength];   /* duelst and datelist      */
        !           169:      char               enddate[datelength];
        !           170:      struct  Datepairs  * dnext;
        !           171:      };
        !           172: 
        !           173: char   Dotstring[200];                /* string of numeric revision name    */
        !           174: char   * Nextdotstring;               /* next available place of Dotstring  */
        !           175: struct  Datepairs       * datelist,  * duelst;
        !           176: struct  Revpairs        * revlist, * Revlst;
        !           177: int                     branchflag; /* set on -b */
        !           178: struct  lockers         * lockerlist;
        !           179: struct  stateattri      * statelist;
        !           180: struct  authors         * authorlist;
        !           181: 
        !           182: 
        !           183: 
        !           184: main (argc, argv)
        !           185: int argc;
        !           186: char * argv[];
        !           187: {
        !           188:         struct  Datepairs       * currdate;
        !           189:         struct  assoc         * curassoc;
        !           190:         struct  access        * curaccess;
        !           191:         struct  lock          * currlock;
        !           192:         char * cmdusage;
        !           193: 
        !           194:        cmdusage = "command format:\nrlog -L -R -h -t -b -ddates -l[lockers] -rrevisions -sstates -w[logins] file ...";
        !           195:         cmdid = "rlog";
        !           196:         descflag = selectflag = true;
        !           197:         lockflag = onlylockflag = selectop = false;
        !           198:        onlyRCSflag = false;
        !           199:         lockerlist = nil;
        !           200:         authorlist = nil;
        !           201:         statelist = nil;
        !           202:         Revlst = revlist = nil;
        !           203:         branchflag= false;
        !           204:         duelst = datelist = nil;
        !           205:        caller=getcaller();
        !           206: 
        !           207:         while (--argc,++argv, argc>=1 && ((*argv)[0] == '-')) {
        !           208:                 switch ((*argv)[1]) {
        !           209: 
        !           210:                case 'L':
        !           211:                        onlylockflag = true;
        !           212:                        break;
        !           213: 
        !           214:                case 'R':
        !           215:                        onlyRCSflag =true;
        !           216:                        break;
        !           217: 
        !           218:                 case 'l':
        !           219:                         selectop = true;
        !           220:                         lockflag = true;
        !           221:                         getlocker( (*argv)+2 );
        !           222:                         break;
        !           223: 
        !           224:                 case 'b':
        !           225:                         selectop = true;
        !           226:                         branchflag = true;
        !           227:                         break;
        !           228: 
        !           229:                 case 'r':
        !           230:                         selectop = true;
        !           231:                         getrevpairs( (*argv)+2 );
        !           232:                         break;
        !           233: 
        !           234:                 case 'd':
        !           235:                         selectop = true;
        !           236:                         getdatepair( (*argv)+2 );
        !           237:                         break;
        !           238: 
        !           239:                 case 's':
        !           240:                         selectop = true;
        !           241:                         getstate( (*argv)+2);
        !           242:                         break;
        !           243: 
        !           244:                 case 'w':
        !           245:                         selectop = true;
        !           246:                         getauthor( (*argv)+2);
        !           247:                         break;
        !           248: 
        !           249:                 case 'h':
        !           250:                         if ( ! selectflag ) warn("option -t overrides -h");
        !           251:                         else    descflag = false;
        !           252:                         break;
        !           253: 
        !           254:                 case 't':
        !           255:                         selectflag = false;
        !           256:                         if ( ! descflag ) warn("option -t overrides -h");
        !           257:                         descflag = true;
        !           258:                         break;
        !           259: 
        !           260:                 default:
        !           261:                         faterror("unknown option: %s\n%s", *argv,cmdusage);
        !           262: 
        !           263:                 };
        !           264:         } /* end of option processing */
        !           265: 
        !           266:         if (argc<1) faterror("No input file\n%s",cmdusage);
        !           267: 
        !           268: 
        !           269:         /* now handle all filenames */
        !           270:         do {
        !           271:             rewriteflag=false;
        !           272:             finptr=frewrite=nil;
        !           273: 
        !           274: 
        !           275:             if (!pairfilenames(argc, argv, true,false)) continue;
        !           276: 
        !           277:             /* now RCSfilename contains the name of the RCS file, and finptr
        !           278:              * the file descriptor. Workfilename contains the name of the
        !           279:              * working file.
        !           280:              */
        !           281: 
        !           282:             if ( !trysema(RCSfilename, false)) goto loopend; /*  give up */
        !           283: 
        !           284:             /* do nothing if -L is given and there are no locks*/
        !           285:            if ( onlylockflag && Locks == nil ) goto loopend;
        !           286: 
        !           287:            if ( onlyRCSflag ) {
        !           288:                VOID fprintf(stdout, "%s\n", RCSfilename);
        !           289:                goto loopend;
        !           290:            }
        !           291:             /*   print RCS filename , working filename and optional
        !           292:                  administrative information                         */
        !           293:             VOID fprintf(stdout, "\nRCS file:        %s;   ",RCSfilename);
        !           294:             /* could use getfullRCSname() here, but that is very slow */
        !           295:             VOID fprintf(stdout, "Working file:    %s\n", workfilename);
        !           296:             VOID fprintf(stdout, "head:            %s\n", Head==nil?"":Head->num);
        !           297:             VOID fprintf(stdout, "branch:          %s\n", Dbranch==nil?"":Dbranch->num);
        !           298: 
        !           299:             VOID fputs("locks:         ", stdout);  /*  print locker list   */
        !           300:             currlock = Locks;
        !           301:             while( currlock ) {
        !           302:                 VOID fprintf(stdout,"  %s: %s;", currlock->login,
        !           303:                                 currlock->delta->num);
        !           304:                 currlock = currlock->nextlock;
        !           305:             }
        !           306:             if ( StrictLocks )
        !           307:                 VOID fputs(Locks==nil?"  ;  strict":"  strict",stdout);
        !           308: 
        !           309:             VOID fputs("\naccess list:   ", stdout);      /*  print access list  */
        !           310:             curaccess = AccessList;
        !           311:             while(curaccess) {
        !           312:                 VOID fputs("  ",stdout);
        !           313:                 VOID fputs(curaccess->login, stdout);
        !           314:                 curaccess = curaccess->nextaccess;
        !           315:             }
        !           316: 
        !           317:             VOID fputs("\nsymbolic names:", stdout);   /*  print symbolic names   */
        !           318:             curassoc = Symbols;
        !           319:             while( curassoc ) {
        !           320:                 VOID fprintf(stdout, "  %s: %s;",curassoc->symbol,
        !           321:                            curassoc->delta->num);
        !           322:                 curassoc = curassoc->nextassoc;
        !           323:             }
        !           324: 
        !           325:             VOID fprintf(stdout,"\ncomment leader:  \"%s\"\n",Comment);
        !           326: 
        !           327:             gettree();
        !           328:             VOID fprintf(stdout, "total revisions: %d;    ", TotalDeltas);
        !           329:             if ( Head == nil || !selectflag || !descflag) {
        !           330:                 VOID putc('\n',stdout);
        !           331:                 if (descflag) VOID fputs("description:\n", stdout);
        !           332:                 getdesc(descflag);
        !           333:                 VOID fputs("=============================================================================\n",stdout);
        !           334:                 goto loopend;
        !           335:             }
        !           336: 
        !           337: 
        !           338:             /*  keep only those locks given by -l */
        !           339:             if (lockflag)
        !           340:                 trunclocks();
        !           341:             getnumericrev();    /* get numeric revision or branch names */
        !           342:             revno = 0;
        !           343: 
        !           344:             exttree(Head);
        !           345: 
        !           346:             /*  get most recently date of the dates pointed by duelst  */
        !           347:             currdate = duelst;
        !           348:             while( currdate) {
        !           349:                 recentdate(Head, currdate);
        !           350:                 currdate = currdate->dnext;
        !           351:            }
        !           352: 
        !           353:             extdate(Head);
        !           354: 
        !           355:             /*  reinitialize the date specification list   */
        !           356:             currdate = duelst;
        !           357:             while(currdate) {
        !           358:                 VOID sprintf(currdate->strtdate,DATEFORM,0,0,0,0,0,0);
        !           359:                 currdate = currdate->dnext;
        !           360:             }
        !           361: 
        !           362:             if ( selectop || ( selectflag && descflag) )
        !           363:                 VOID fprintf(stdout, "selected revisions: %d", revno);
        !           364:             VOID putc('\n', stdout);
        !           365:             if (descflag) VOID fputs("description:\n", stdout);
        !           366:             getdesc(descflag);
        !           367:             while( (nexttok != EOFILE) && readdeltalog());
        !           368:             if (selectflag && descflag && revno) {
        !           369:                 putrunk();
        !           370:                 putree(Head);
        !           371:                 if (nextlex(), nexttok != EOFILE)
        !           372:                     fatserror("syntax error; expecting EOF");
        !           373:             }
        !           374:             VOID fputs("=============================================================================\n",stdout);
        !           375:         loopend:
        !           376:             VOID fclose(finptr);
        !           377:         } while( ++argv, --argc >= 1);
        !           378:         exit(nerror!=0);
        !           379: }
        !           380: 
        !           381: 
        !           382: 
        !           383: putrunk()
        !           384: /*  function:  print revisions chosen, which are in trunk      */
        !           385: 
        !           386: {
        !           387:         struct  hshentry        * ptr, * pre;
        !           388: 
        !           389:         if (Head == nil) return;   /*  empty tree  */
        !           390: 
        !           391:         pre = Head;
        !           392:         ptr = Head->next;
        !           393:         while( ptr ) {
        !           394:             putadelta(pre,ptr,true);
        !           395:             pre = ptr;
        !           396:             ptr = ptr->next;
        !           397:         }
        !           398:         putadelta(pre,ptr,true);
        !           399: }
        !           400: 
        !           401: 
        !           402: 
        !           403: putree(root)
        !           404: struct  hshentry  *root;
        !           405: /*   function: print delta tree( not include trunck) in reversed calender
        !           406:                order on each branch                                        */
        !           407: 
        !           408: {
        !           409:         if ( root == nil ) return;
        !           410: 
        !           411:         putree(root->next);
        !           412: 
        !           413:         putforest(root->branches);
        !           414: }
        !           415: 
        !           416: 
        !           417: 
        !           418: 
        !           419: putforest(branchroot)
        !           420: struct   branchhead     * branchroot;
        !           421: /*   function:  print branches that has the same direct ancestor    */
        !           422: {
        !           423: 
        !           424:         if ( branchroot == nil ) return;
        !           425: 
        !           426:         putforest(branchroot->nextbranch);
        !           427: 
        !           428:         putabranch(branchroot->hsh);
        !           429:         putree(branchroot->hsh);
        !           430: }
        !           431: 
        !           432: 
        !           433: 
        !           434: 
        !           435: putabranch(root)
        !           436: struct      hshentry   *root;
        !           437: /*   function  :  print one branch     */
        !           438: 
        !           439: {
        !           440: 
        !           441:         if ( root == nil) return;
        !           442: 
        !           443:         putabranch(root->next);
        !           444: 
        !           445:         putadelta(root, root, false);
        !           446: }
        !           447: 
        !           448: 
        !           449: 
        !           450: 
        !           451: 
        !           452: putadelta(node,editscript,trunk)
        !           453: register  struct   hshentry    * node;
        !           454: register  struct   hshentry    * editscript;
        !           455: int                              trunk;
        !           456: /*  function: print delta node if node->selector is 's'.        */
        !           457: /*      editscript indicates where the editscript is stored     */
        !           458: /*      trunk indicated whether this node is in trunk           */
        !           459: {
        !           460:         struct  branchhead      * newbranch;
        !           461:         char                    * branchnum,  branch[40];
        !           462: 
        !           463:         if ( ( node == nil) || ( node->selector == 'u'))
        !           464:             return;
        !           465: 
        !           466:         VOID fprintf(stdout,"----------------------------\n");
        !           467:         VOID fprintf(stdout, "revision %s        ",node->num);
        !           468:         if ( node->lockedby )
        !           469:            VOID fprintf(stdout, "locked by: %s;       ", node->lockedby);
        !           470:         VOID putc('\n', stdout);
        !           471: 
        !           472:         VOID fputs("date: ",stdout);
        !           473:         VOID PRINTDATE(stdout,node->date); VOID putc(' ',stdout);
        !           474:         VOID PRINTTIME(stdout,node->date);
        !           475:         VOID fprintf(stdout, ";  author: %s;  ", node->author);
        !           476:         VOID fprintf(stdout, "state: %s;  ", node->state);
        !           477: 
        !           478:         if ( editscript )
        !           479:            if(trunk)
        !           480:               VOID fprintf(stdout,"lines added/del: %d/%d",
        !           481:                              editscript->deletelns, editscript->insertlns);
        !           482:            else
        !           483:               VOID fprintf(stdout,"lines added/del: %d/%d",
        !           484:                              editscript->insertlns, editscript->deletelns);
        !           485: 
        !           486:         VOID putc('\n', stdout);
        !           487: 
        !           488:         branchnum = & (branch[0]);
        !           489:         newbranch = node->branches;
        !           490:         if ( newbranch ) {
        !           491:            VOID fputs("branches:  ", stdout);
        !           492:            while( newbranch ) {
        !           493:                 getbranchno(newbranch->hsh->num, branchnum);
        !           494:                 VOID fprintf(stdout, "%s;  ", branchnum);
        !           495:                 newbranch = newbranch->nextbranch;
        !           496:            }
        !           497:            VOID putc('\n', stdout);
        !           498:         }
        !           499: 
        !           500:         VOID fputs(node->log,stdout);
        !           501: }
        !           502: 
        !           503: 
        !           504: 
        !           505: 
        !           506: 
        !           507: readdeltalog()
        !           508: /*  Function : get the log message and skip the text of a deltatext node.
        !           509:  *             Return false if current block does not start with a number.
        !           510:  *             Assumes the current lexeme is not yet in nexttok; does not
        !           511:  *             advance nexttok.
        !           512:  */
        !           513: {
        !           514:         register struct  hshentry  * Delta;
        !           515: 
        !           516:         nextlex();
        !           517:         if ( !(Delta = getnum() )) return(false);
        !           518:         if ( ! getkey(Klog) || ( nexttok != STRING ) )
        !           519:                 fatserror("Missing log entry");
        !           520:         Delta->log = talloc(logsize);
        !           521:         VOID savestring(Delta->log, logsize);
        !           522:         nextlex();
        !           523:         if ( ! getkey(Ktext) || (nexttok != STRING) )
        !           524:                 fatserror("Missing delta text");
        !           525:         Delta->insertlns = Delta->deletelns = 0;
        !           526:         if ( Delta != Head)
        !           527:                 getscript(Delta);
        !           528:         else
        !           529:                 readstring();
        !           530:         return true;
        !           531: }
        !           532: 
        !           533: 
        !           534: 
        !           535: getscript(Delta)
        !           536: struct    hshentry   * Delta;
        !           537: /*   function:  read edit script of Delta and count how many lines added  */
        !           538: /*              and deleted in the script                                 */
        !           539: 
        !           540: {
        !           541:         int ed;   /*  editor command  */
        !           542:        register FILE * fin;
        !           543:         register  int   c;
        !           544:         register  int   i;
        !           545:         int             length;
        !           546: 
        !           547:        fin = finptr;
        !           548:        while( (ed = getc(fin)) != EOF) {
        !           549:            /*  assume first none white character is command name  */
        !           550:             while( ed == '\n' || ed == ' ' || ed == '\t')
        !           551:                ed = getc(fin);
        !           552:             if (ed == SDELIM) break;  /*  script text is ended   */
        !           553:            while( ( c = getc(fin)) == ' ' );  /*  skip blank  */
        !           554:             if ( ! ('0' <= c && c <= '9')) {
        !           555:                 faterror("Missing line number in edit script");
        !           556:                 break;
        !           557:             }
        !           558:            while( '0' <= (c = getc(fin)) && c <= '9' ) ;
        !           559: 
        !           560:            while( c == ' ')c = getc(fin);  /*  skip blanks  */
        !           561:             if ( !('0' <= c && c <= '9' ) ) {
        !           562:                 faterror("Incorrect range in edit script");
        !           563:                 break;
        !           564:             }
        !           565:             length = c - '0';
        !           566:            while( '0' <= (c = getc(fin)) && c <= '9' )
        !           567:                 length = length * 10 + c - '0';
        !           568:            while( c != '\n' && c != EOF) c = getc(fin);
        !           569:             switch (ed) {
        !           570:             case 'd' :
        !           571:                  Delta->deletelns += length;
        !           572:                  break;
        !           573: 
        !           574:             case 'a' :
        !           575:                  /*  skip scripted lines  */
        !           576:                  for ( i=length; i > 0 && c != EOF; i--){
        !           577:                     while( (c=getc(fin)) != '\n' && c != EOF);
        !           578:                      Delta->insertlns++;
        !           579:                  }
        !           580:                  break;
        !           581: 
        !           582:             default:
        !           583:                  faterror("Unknown command in edit script: %c", ed);
        !           584:                  break;
        !           585:             }
        !           586:         }
        !           587:        nextc = getc(fin);
        !           588: }
        !           589: 
        !           590: 
        !           591: 
        !           592: 
        !           593: 
        !           594: 
        !           595: 
        !           596: exttree(root)
        !           597: struct hshentry  *root;
        !           598: /*  function: select revisions , starting with root             */
        !           599: 
        !           600: {
        !           601:         struct branchhead       * newbranch;
        !           602: 
        !           603:         if (root == nil) return;
        !           604: 
        !           605:         extractdelta(root);
        !           606:         exttree(root->next);
        !           607: 
        !           608:         newbranch = root->branches;
        !           609:         while( newbranch ) {
        !           610:             exttree(newbranch->hsh);
        !           611:             newbranch = newbranch->nextbranch;
        !           612:         }
        !           613: }
        !           614: 
        !           615: 
        !           616: 
        !           617: 
        !           618: getlocker(argv)
        !           619: char    * argv;
        !           620: /*   function : get the login names of lockers from command line   */
        !           621: /*              and store in lockerlist.                           */
        !           622: 
        !           623: {
        !           624:         register char c;
        !           625:         struct   lockers   * newlocker;
        !           626:         argv--;
        !           627:         while( ( c = (*++argv)) == ',' || c == ' ' || c == '\t' ||
        !           628:                  c == '\n' || c == ';')  ;
        !           629:         if (  c == '\0') {
        !           630:             lockerlist=nil;
        !           631:             return;
        !           632:         }
        !           633: 
        !           634:         while( c != '\0' ) {
        !           635:             newlocker = ( struct lockers *)talloc( sizeof(struct lockers) );
        !           636:             newlocker->lockerlink = lockerlist;
        !           637:             newlocker->login = argv;
        !           638:             lockerlist = newlocker;
        !           639:             while ( ( c = (*++argv)) != ',' && c != '\0' && c != ' '
        !           640:                        && c != '\t' && c != '\n' && c != ';') ;
        !           641:             *argv = '\0';
        !           642:             if ( c == '\0' ) return;
        !           643:             while( ( c = (*++argv)) == ',' || c == ' ' || c == '\t' ||
        !           644:                      c == '\n' || c == ';')  ;
        !           645:         }
        !           646: }
        !           647: 
        !           648: 
        !           649: 
        !           650: getauthor(argv)
        !           651: char   *argv;
        !           652: /*   function:  get the author's name form command line   */
        !           653: /*              and store in aauthorlist                  */
        !           654: 
        !           655: {
        !           656:         register    c;
        !           657:         struct     authors  * newauthor;
        !           658: 
        !           659:         argv--;
        !           660:         while( ( c = (*++argv)) == ',' || c == ' ' || c == '\t' ||
        !           661:                  c == '\n' || c == ';')  ;
        !           662:         if ( c == '\0' ) {
        !           663:             authorlist = (struct authors *)talloc(sizeof(struct authors));
        !           664:             authorlist->login = caller;
        !           665:             authorlist->nextauthor  = nil;
        !           666:             return;
        !           667:         }
        !           668: 
        !           669:         while( c != '\0' ) {
        !           670:             newauthor = (struct authors *)talloc(sizeof(struct authors));
        !           671:             newauthor->nextauthor = authorlist;
        !           672:             newauthor->login = argv;
        !           673:             authorlist = newauthor;
        !           674:             while( ( c = *++argv) != ',' && c != '\0' && c != ' '
        !           675:                      && c != '\t' && c != '\n' && c != ';') ;
        !           676:             * argv = '\0';
        !           677:             if ( c == '\0') return;
        !           678:             while( ( c = (*++argv)) == ',' || c == ' ' || c == '\t' ||
        !           679:                      c == '\n' || c == ';')  ;
        !           680:         }
        !           681: }
        !           682: 
        !           683: 
        !           684: 
        !           685: 
        !           686: getstate(argv)
        !           687: char   * argv;
        !           688: /*   function :  get the states of revisions from command line  */
        !           689: /*               and store in statelist                         */
        !           690: 
        !           691: {
        !           692:         register  char  c;
        !           693:         struct    stateattri    *newstate;
        !           694: 
        !           695:         argv--;
        !           696:         while( ( c = (*++argv)) == ',' || c == ' ' || c == '\t' ||
        !           697:                  c == '\n' || c == ';')  ;
        !           698:         if ( c == '\0'){
        !           699:             warn(" Missing state attributes after -s options");
        !           700:             return;
        !           701:         }
        !           702: 
        !           703:         while( c != '\0' ) {
        !           704:             newstate = (struct stateattri *)talloc(sizeof(struct stateattri));
        !           705:             newstate->nextstate = statelist;
        !           706:             newstate->status = argv;
        !           707:             statelist = newstate;
        !           708:             while( (c = (*++argv)) != ',' && c != '\0' && c != ' '
        !           709:                     && c != '\t' && c != '\n' && c != ';')  ;
        !           710:             *argv = '\0';
        !           711:             if ( c == '\0' ) return;
        !           712:             while( ( c = (*++argv)) == ',' || c == ' ' || c == '\t' ||
        !           713:                      c == '\n' || c == ';')  ;
        !           714:         }
        !           715: }
        !           716: 
        !           717: 
        !           718: 
        !           719: trunclocks()
        !           720: /*  Function:  Truncate the list of locks to those that are held by the  */
        !           721: /*             id's on lockerlist. Do not truncate if lockerlist empty.  */
        !           722: 
        !           723: {
        !           724:         struct lockers  * plocker;
        !           725:         struct lock     * plocked,  * nextlocked;
        !           726: 
        !           727:         if ( (lockerlist == nil) || (Locks == nil)) return;
        !           728: 
        !           729:         /* shorten Locks to those contained in lockerlist */
        !           730:         plocked = Locks;
        !           731:         Locks = nil;
        !           732:         while( plocked != nil) {
        !           733:             plocker = lockerlist;
        !           734:             while((plocker != nil) && ( strcmp(plocker->login, plocked->login)!=0))
        !           735:                 plocker = plocker->lockerlink;
        !           736:             nextlocked = plocked->nextlock;
        !           737:             if ( plocker != nil) {
        !           738:                 plocked->nextlock = Locks;
        !           739:                 Locks = plocked;
        !           740:             }
        !           741:             plocked = nextlocked;
        !           742:         }
        !           743: }
        !           744: 
        !           745: 
        !           746: 
        !           747: recentdate(root, pd)
        !           748: struct         hshentry        * root;
        !           749: struct Datepairs       * pd;
        !           750: /*  function:  Finds the delta that is closest to the cutoff date given by   */
        !           751: /*             pd among the revisions selected by exttree.                   */
        !           752: /*             Successively narrows down the interfal given by pd,           */
        !           753: /*             and sets the strtdate of pd to the date of the selected delta */
        !           754: {
        !           755:         struct  branchhead      * newbranch;
        !           756: 
        !           757:        if ( root == nil) return;
        !           758:         if ( root->selector == 's') {
        !           759:              if ( cmpnum(root->date, pd->strtdate) >= 0 &&
        !           760:                   cmpnum(root->date, pd->enddate) <= 0)
        !           761:                VOID strcpy(pd->strtdate, root->date);
        !           762:         }
        !           763: 
        !           764:         recentdate(root->next, pd);
        !           765:         newbranch = root->branches;
        !           766:         while( newbranch) {
        !           767:            recentdate(newbranch->hsh, pd);
        !           768:            newbranch = newbranch->nextbranch;
        !           769:        }
        !           770: }
        !           771: 
        !           772: 
        !           773: 
        !           774: 
        !           775: 
        !           776: 
        !           777: extdate(root)
        !           778: struct  hshentry        * root;
        !           779: /*  function:  select revisions which are in the date range specified     */
        !           780: /*             in duelst  and datelist, start at root                     */
        !           781: 
        !           782: {
        !           783:         struct  branchhead      * newbranch;
        !           784:         struct  Datepairs       * pdate;
        !           785: 
        !           786:         if ( root == nil) return;
        !           787: 
        !           788:         if ( datelist || duelst) {
        !           789:             pdate = datelist;
        !           790:             while( pdate ) {
        !           791:                 if ( (pdate->strtdate)[0] == '\0' || cmpnum(root->date,pdate->strtdate) >= 0){
        !           792:                    if ((pdate->enddate)[0] == '\0' || cmpnum(pdate->enddate,root->date) >= 0)
        !           793:                         break;
        !           794:                 }
        !           795:                 pdate = pdate->dnext;
        !           796:             }
        !           797:             if ( pdate == nil) {
        !           798:                 pdate = duelst;
        !           799:                 while(pdate) {
        !           800:                    if ( cmpnum(root->date, pdate->strtdate) == 0)
        !           801:                       break;
        !           802:                    pdate = pdate->dnext;
        !           803:                 }
        !           804:             }
        !           805:             if ( pdate == nil)
        !           806:                 root->selector = 'u';
        !           807:         }
        !           808:         if (root->selector == 's') revno++;
        !           809: 
        !           810:         extdate(root->next);
        !           811: 
        !           812:         newbranch = root->branches;
        !           813:         while( newbranch ) {
        !           814:            extdate(newbranch->hsh);
        !           815:            newbranch = newbranch->nextbranch;
        !           816:         }
        !           817: }
        !           818: 
        !           819: 
        !           820: 
        !           821: extractdelta(pdelta)
        !           822: struct  hshentry        * pdelta;
        !           823: /*  function:  compare information of pdelta to the authorlst, lockerlist, */
        !           824: /*             statelist, revlist and mark 's' on selector if pdelta is    */
        !           825: /*             selected; otherwise, mark 'u'                               */
        !           826: 
        !           827: {
        !           828:         struct  lock            * plock;
        !           829:         struct  stateattri      * pstate;
        !           830:         struct  authors         * pauthor;
        !           831:         struct  Revpairs        * prevision;
        !           832:         int                       length;
        !           833: 
        !           834:         pdelta->selector = 's';
        !           835:         if ( authorlist ) {  /*  certain author's revisions wanted only  */
        !           836:             pauthor = authorlist;
        !           837:             while((pauthor != nil) && ( strcmp(pauthor->login, pdelta->author)!=0))
        !           838:                 pauthor = pauthor->nextauthor;
        !           839:             if ( pauthor == nil ) {
        !           840:                 pdelta->selector = 'u';
        !           841:                 return;
        !           842:             }
        !           843:         }
        !           844:         if ( statelist ) {   /* revisions with certain state wanted  */
        !           845:             pstate = statelist;
        !           846:             while((pstate != nil) && (strcmp(pstate->status, pdelta->state)!=0))
        !           847:                 pstate = pstate->nextstate;
        !           848:             if ( pstate == nil ) {
        !           849:                 pdelta->selector = 'u';
        !           850:                 return;
        !           851:             }
        !           852:         }
        !           853:         if ( lockflag ) {    /*  locked revisions   */
        !           854:             plock = Locks;
        !           855:             while( plock && (plock->delta != pdelta))
        !           856:                 plock = plock->nextlock;
        !           857:             if (plock == nil ) {
        !           858:                 pdelta->selector = 'u';
        !           859:                 return;
        !           860:             }
        !           861:         }
        !           862:         if ( Revlst ) {   /*  revisions or branches selected  */
        !           863: 
        !           864:             prevision = Revlst;
        !           865:             while( prevision != nil ) {
        !           866:                 length = prevision->numfld;
        !           867:                 if ( length % 2 == 1) { /*  a branch number  */
        !           868:                      if ( countnumflds(pdelta->num) ==(length+1))
        !           869:                         if ( (compartial(pdelta->num, prevision->strtrev,length) >= 0)&&
        !           870:                              (compartial(prevision->endrev, pdelta->num, length) >= 0) )
        !           871:                              break;
        !           872:                 }
        !           873:                 else if ( countnumflds(pdelta->num ) == length)  /*  a revision */
        !           874:                     if ( (compartial(pdelta->num, prevision->strtrev, length) >= 0) &&
        !           875:                          (compartial(prevision->endrev, pdelta->num, length) >= 0) )
        !           876:                         break;
        !           877:                 prevision = prevision->rnext;
        !           878:             }
        !           879:             if (prevision == nil)  {
        !           880:                 pdelta->selector = 'u';
        !           881:                 return;
        !           882:             }
        !           883:         }
        !           884: }
        !           885: 
        !           886: 
        !           887: 
        !           888: char * procdate(target, source)
        !           889: char * target, * source;
        !           890: /* Function: Parses a free-format date in target, converts it
        !           891:  * into RCS internal format, and stores the result into source.
        !           892:  * Returns target on success, nil otherwise.
        !           893:  */
        !           894: {
        !           895:        long            unixtime;
        !           896:        struct     tm   parseddate,  *ftm;
        !           897: 
        !           898:        if ( partime(source, &parseddate) == 0) {
        !           899:            error("Can't parse date/time: %s", source);
        !           900:            *target= '\0';
        !           901:            return nil;
        !           902:        }
        !           903:        if ( (unixtime = maketime(&parseddate)) == 0L) {
        !           904:            error("Inconsistent date/time: %s", source);
        !           905:            *target='\0';
        !           906:            return nil;
        !           907:        }
        !           908:        ftm = localtime(&unixtime);
        !           909:        VOID sprintf(target,DATEFORM,
        !           910:        ftm->tm_year,ftm->tm_mon+1,ftm->tm_mday,ftm->tm_hour,ftm->tm_min,ftm->tm_sec);
        !           911:        return target;
        !           912: }
        !           913: 
        !           914: 
        !           915: 
        !           916: getdatepair(argv)
        !           917:    char   * argv;
        !           918: /*  function:  get time range from command line and store in datelist if    */
        !           919: /*             a time range specified or in duelst if a time spot specified */
        !           920: 
        !           921: {
        !           922:         register   char         c;
        !           923:         struct     Datepairs    * nextdate;
        !           924:         char                    * rawdate;
        !           925:        int                     switchflag;
        !           926: 
        !           927:         argv--;
        !           928:         while( ( c = (*++argv)) == ',' || c == ' ' || c == '\t' ||
        !           929:                  c == '\n' || c == ';')  ;
        !           930:         if ( c == '\0' ) {
        !           931:             warn("Missing date/time after -d");
        !           932:             return;
        !           933:         }
        !           934: 
        !           935:         while( c != '\0' )  {
        !           936:            switchflag = false;
        !           937:            nextdate = (struct Datepairs *) talloc(sizeof(struct Datepairs));
        !           938:             if ( c == '<' ) {   /*   case: -d <date   */
        !           939:                 c = *++argv;
        !           940:                 (nextdate->strtdate)[0] = '\0';
        !           941:            } elsif (c == '>') {        /*  case:  -d >date     */
        !           942:                c = *++argv;
        !           943:                (nextdate->enddate)[0] = '\0';
        !           944:                switchflag = true;
        !           945:            } else {
        !           946:                 rawdate = argv;
        !           947:                while( c != '<' && c != '>' && c != ';' && c != '\0')
        !           948:                     c = *++argv;
        !           949:                 *argv = '\0';
        !           950:                if ( c == '>' ) switchflag=true;
        !           951:                if (procdate(switchflag?nextdate->enddate:nextdate->strtdate,
        !           952:                             rawdate)==nil) continue;
        !           953:                if ( c == ';' || c == '\0') {  /*  case: -d date  */
        !           954:                    VOID strcpy(nextdate->enddate,nextdate->strtdate);
        !           955:                    VOID sprintf(nextdate->strtdate,DATEFORM,0,0,0,0,0,0);
        !           956:                     nextdate->dnext = duelst;
        !           957:                     duelst = nextdate;
        !           958:                    goto end;
        !           959:                } else {
        !           960:                    /*   case:   -d date<  or -d  date>; see switchflag */
        !           961:                    while ( (c= *++argv) == ' ' || c=='\t' || c=='\n');
        !           962:                    if ( c == ';' || c == '\0') {
        !           963:                        /* second date missing */
        !           964:                        if (switchflag)
        !           965:                            *nextdate->strtdate= '\0';
        !           966:                        else
        !           967:                            *nextdate->enddate= '\0';
        !           968:                        nextdate->dnext = datelist;
        !           969:                        datelist = nextdate;
        !           970:                        goto end;
        !           971:                    }
        !           972:                 }
        !           973:             }
        !           974:             rawdate = argv;
        !           975:            while( c != '>' && c != '<' && c != ';' && c != '\0')
        !           976:                c = *++argv;
        !           977:             *argv = '\0';
        !           978:            if (procdate(switchflag?nextdate->strtdate:nextdate->enddate,
        !           979:                         rawdate)==nil) continue;
        !           980:             nextdate->dnext = datelist;
        !           981:            datelist = nextdate;
        !           982:      end:
        !           983: /*
        !           984:            VOID printf("startdate: %s; enddate: %s;\n", nextdate->strtdate,nextdate->enddate);
        !           985: */
        !           986:            if ( c == '\0')  return;
        !           987:             while( (c = *++argv) == ';' || c == ' ' || c == '\t' || c =='\n');
        !           988:         }
        !           989: }
        !           990: 
        !           991: 
        !           992: 
        !           993: 
        !           994: 
        !           995: getnumericrev()
        !           996: /*  function:  get the numeric name of revisions which stored in revlist  */
        !           997: /*             and then stored the numeric names in Revlst                */
        !           998: /*             if branchflag, also add default branch                     */
        !           999: 
        !          1000: {
        !          1001:         struct  Revpairs        * ptr, *pt;
        !          1002:         int     flag;
        !          1003:         char    *temprev;
        !          1004: 
        !          1005:         /*  free the previous numeric revision list  */
        !          1006:         pt = Revlst;
        !          1007:         while( pt) {
        !          1008:           ptr = pt->rnext;
        !          1009:            free((char *)pt);
        !          1010:            pt = ptr;
        !          1011:         }
        !          1012:         Nextdotstring = &Dotstring[0]; /* reset buffer */
        !          1013: 
        !          1014: 
        !          1015:         Revlst = nil;
        !          1016:         ptr = revlist;
        !          1017:         while( ptr ) {
        !          1018:             pt = (struct Revpairs *) talloc(sizeof(struct Revpairs));
        !          1019:             if ( ptr->numfld == 1 ){ /*  case:  -r rev   */
        !          1020:                 if ( (flag = expandsym(ptr->strtrev, Nextdotstring)) == true ) {
        !          1021:                     pt->numfld = countnumflds(Nextdotstring);
        !          1022:                     pt->strtrev = pt->endrev = Nextdotstring;
        !          1023:                     while( *Nextdotstring++ != '\0' )  ;
        !          1024:                 }
        !          1025:             }
        !          1026:             else if( ptr->numfld == 2){ /*  case: -r rev-   */
        !          1027:                 if ( (flag = expandsym(ptr->strtrev, Nextdotstring)) == true) {
        !          1028:                     pt->numfld = countnumflds(Nextdotstring);
        !          1029:                     pt->strtrev = Nextdotstring;
        !          1030:                     while( *Nextdotstring++ != '\0' ) ;
        !          1031:                     pt->endrev = Nextdotstring;
        !          1032:                     if ( pt->numfld > 2) choptail(pt->strtrev);
        !          1033:                     * Nextdotstring++ = '\0';
        !          1034:                 }
        !          1035:              }
        !          1036:              else if(ptr->numfld == 3)  { /*  case: -r -rev   */
        !          1037:                 if ( (flag = expandsym(ptr->endrev, Nextdotstring)) == true) {
        !          1038:                     pt->endrev = Nextdotstring;
        !          1039:                     while( *Nextdotstring++ != '\0' )  ;
        !          1040:                     pt->numfld = countnumflds(pt->endrev);
        !          1041:                     pt->strtrev = Nextdotstring;
        !          1042:                     if ( pt->numfld == 2)
        !          1043:                         *Nextdotstring++ = '1';
        !          1044:                     else
        !          1045:                         choptail(pt->endrev);
        !          1046:                     *Nextdotstring++ = '.';
        !          1047:                     *Nextdotstring++ = '1';
        !          1048:                     *Nextdotstring++ = '\0';
        !          1049:                 }
        !          1050:              }
        !          1051:              else  {     /*   case:  -r rev1-rev2   */
        !          1052:                 if ( (flag = expandsym(ptr->strtrev, Nextdotstring)) == true ) {
        !          1053:                     pt->strtrev = Nextdotstring;
        !          1054:                     while( *Nextdotstring++ != '\0' )  ;
        !          1055:                     if ( ( flag = expandsym(ptr->endrev, Nextdotstring)) == true)  {
        !          1056:                         pt->numfld = countnumflds(pt->strtrev);
        !          1057:                         pt->endrev = Nextdotstring;
        !          1058:                         while( *Nextdotstring++ != '\0' ) ;
        !          1059:                         if((flag = checkrevpair(pt->strtrev, pt->endrev)) == true)
        !          1060:                            /*  switch pt->strtrev with pt->endrev, if pt->strtrev > pt->endre  */
        !          1061:                             if (compartial(pt->strtrev, pt->endrev, pt->numfld) > 0 ) {
        !          1062:                                 temprev = pt->strtrev;
        !          1063:                                 pt->strtrev = pt->endrev;
        !          1064:                                 pt->endrev = temprev;
        !          1065:                             }
        !          1066:                      }
        !          1067:                 }
        !          1068:              }
        !          1069: 
        !          1070:              if ( flag ){
        !          1071:                 pt->rnext = Revlst;
        !          1072:                 Revlst = pt;
        !          1073:              }
        !          1074:              else
        !          1075:                 free((char *)pt);
        !          1076:              ptr = ptr->rnext;
        !          1077:         }
        !          1078:         /* Now take care of branchflag */
        !          1079:         if (branchflag) {
        !          1080:             flag =true;
        !          1081:             pt = (struct Revpairs *) talloc(sizeof(struct Revpairs));
        !          1082:             if (Dbranch) {
        !          1083:                 pt->strtrev = pt->endrev = Dbranch->num;
        !          1084:             } elsif (Head!=nil) {
        !          1085:                 pt->strtrev = pt->endrev = /* branch number of head */
        !          1086:                     partialno(Nextdotstring,Head->num,1);
        !          1087:                 while( *Nextdotstring++ != '\0' ) ;
        !          1088:             } else flag = false;
        !          1089:             if (flag) { /* prepend new node */
        !          1090:                 pt->rnext=Revlst; Revlst=pt;
        !          1091:                 pt->numfld = countnumflds(pt->strtrev);
        !          1092:             }
        !          1093:         }
        !          1094: 
        !          1095: }
        !          1096: 
        !          1097: 
        !          1098: 
        !          1099: checkrevpair(num1,num2)
        !          1100: char    *num1,  *num2;
        !          1101: /*  function:  check whether num1, num2 are legal pair,i.e.
        !          1102:     only the last field are different and have same number of
        !          1103:     feilds( if length <= 2, may be different if first field)   */
        !          1104: 
        !          1105: {
        !          1106:         int    length;
        !          1107: 
        !          1108:         if ( (length = countnumflds(num1)) != countnumflds(num2) ) {
        !          1109:             error(" Invalid branch or revision pair %s : %s", num1, num2);
        !          1110:             return false;
        !          1111:         }
        !          1112:         if ( length > 2 )
        !          1113:             if (compartial(num1, num2, length-1) != 0) {
        !          1114:                 error("Invalid branch or revision pair %s : %s", num1, num2);
        !          1115:                 return false;
        !          1116:             }
        !          1117: 
        !          1118:         return true;
        !          1119: }
        !          1120: 
        !          1121: 
        !          1122: 
        !          1123: getrevpairs(argv)
        !          1124: register     char    * argv;
        !          1125: /*  function:  get revision or branch range from command line, and   */
        !          1126: /*             store in revlist                                      */
        !          1127: 
        !          1128: {
        !          1129:         register    char    c;
        !          1130:         struct      Revpairs  * nextrevpair;
        !          1131:         int         flag;
        !          1132: 
        !          1133:         argv--;
        !          1134:         while( ( c = (*++argv)) == ',' || c == ' ' || c == '\t' ||
        !          1135:                  c == '\n' || c == ';')  ;
        !          1136:         if ( c == '\0' ) {
        !          1137:             warn(" Missing revision or branch number after -r");
        !          1138:             return;
        !          1139:         }
        !          1140: 
        !          1141:         while( c != '\0') {
        !          1142:             while(  c  == ',' || c == ' ' || c == '\t' ||
        !          1143:                      c == '\n' || c == ';') c = *++argv;
        !          1144:             if (c == '\0')  return;
        !          1145:             nextrevpair = (struct Revpairs *) talloc(sizeof(struct Revpairs));
        !          1146:             nextrevpair->rnext = revlist;
        !          1147:             revlist = nextrevpair;
        !          1148:             nextrevpair->numfld  = nil;
        !          1149:             nextrevpair->strtrev = nil;
        !          1150:             nextrevpair->endrev  = nil;
        !          1151:             flag = false;
        !          1152:             if (  c == '<' || c == '-' ) {  /*  case: -r -rev  or -r <rev  */
        !          1153:                 flag = true;
        !          1154:                 while( (c =(*++argv)) == ' ' || c == '\t' || c =='\n') ;
        !          1155:             }
        !          1156:             else {
        !          1157:                 nextrevpair->strtrev = argv;
        !          1158:                 /*   get a revision or branch name  */
        !          1159:                 while( c != ',' && c != ';' && c != ' ' && c != '\0' && c != '-'
        !          1160:                         && c != '\t' && c != '\n' && c != '<') c = *++argv;
        !          1161: 
        !          1162:                 *argv = '\0';
        !          1163: 
        !          1164:                 if ( c != '<' && c != '-') {    /*  case: rev  */
        !          1165:                     nextrevpair->numfld = 1;
        !          1166:                     continue;
        !          1167:                 }
        !          1168: 
        !          1169:                 if ( (c =(*++argv)) == ',' || c == '\0' || c == ' '
        !          1170:                       || c == '\t' || c == '\n' || c == ';') {/*  case: rev_  */
        !          1171:                     nextrevpair->numfld = 2;
        !          1172:                     continue;
        !          1173:                 }
        !          1174:             }
        !          1175:             nextrevpair->endrev = argv;
        !          1176:             while( c != ',' && c != ' ' && c != '\0' && c != '\t' && c != '<'
        !          1177:                    && c != '\n' && c != '-' && c != ';')  c = *++argv;
        !          1178: 
        !          1179:             * argv = '\0';
        !          1180:             if ( c == '<'){
        !          1181:                 error("separator expected near %s", nextrevpair->endrev);
        !          1182:                 while( (c = *++argv) != ',' && c != ' ' && c != '\0' &&
        !          1183:                         c != '\t' && c != '\n' && c != ';' ) ;
        !          1184:                 revlist = nextrevpair->rnext;
        !          1185:                 continue;
        !          1186:             }
        !          1187:             else  {
        !          1188:                 if (flag)   /*  case:  -rev   */
        !          1189:                     nextrevpair->numfld  = 3;
        !          1190: 
        !          1191:                 else     /*   rev1-rev2  appears  */
        !          1192:                     nextrevpair->numfld = 4;
        !          1193:             }
        !          1194:         }
        !          1195: }
        !          1196: 
        !          1197: 
        !          1198: 
        !          1199: choptail(strhead)
        !          1200: char     * strhead;
        !          1201: /*   function : chop off the last field of a branch or a revision number  */
        !          1202: 
        !          1203: {
        !          1204:         char    *pt, *sp;
        !          1205: 
        !          1206:         for(pt = Nextdotstring-1; pt != strhead && *pt != '.'; pt--) ;
        !          1207:         for(sp = strhead; sp < pt; sp++) *Nextdotstring++ = *sp;
        !          1208: }
        !          1209: 

unix.superglobalmegacorp.com

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