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

unix.superglobalmegacorp.com

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