Annotation of 43BSD/contrib/rcs/src/rlog.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

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