Annotation of 43BSD/contrib/rcs/src/rcsrev.c, revision 1.1

1.1     ! root        1: 
        !             2: /*
        !             3:  *                     RCS revision number handling
        !             4:  */
        !             5:  static char rcsid[]=
        !             6:  "$Header: /usr/wft/RCS/SRC/RCS/rcsrev.c,v 3.4 82/12/04 13:24:08 wft Exp $ Purdue CS";
        !             7: /*********************************************************************************
        !             8:  *********************************************************************************
        !             9:  *
        !            10:  * Copyright (C) 1982 by Walter F. 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:       rcsrev.c,v $
        !            23:  * Revision 3.4  82/12/04  13:24:08  wft
        !            24:  * Replaced getdelta() with gettree().
        !            25:  * 
        !            26:  * Revision 3.3  82/11/28  21:33:15  wft
        !            27:  * fixed compartial() and compnum() for nil-parameters; fixed nils
        !            28:  * in error messages. Testprogram output shortenend.
        !            29:  *
        !            30:  * Revision 3.2  82/10/18  21:19:47  wft
        !            31:  * renamed compnum->cmpnum, compnumfld->cmpnumfld,
        !            32:  * numericrevno->numricrevno.
        !            33:  *
        !            34:  * Revision 3.1  82/10/11  19:46:09  wft
        !            35:  * changed expandsym() to check for source==nil; returns zero length string
        !            36:  * in that case.
        !            37:  */
        !            38: 
        !            39: 
        !            40: 
        !            41: /*
        !            42: #define REVTEST
        !            43: /* version REVTEST is for testing the routines that generate a sequence
        !            44:  * of delta numbers needed to regenerate a given delta.
        !            45:  */
        !            46: 
        !            47: #include "rcsbase.h"
        !            48: 
        !            49: extern FILE * finptr;   /* RCS input file */
        !            50: extern char * getid();
        !            51: extern struct hshentry * getnum();
        !            52: extern int    getkey();
        !            53: extern int    getlex();
        !            54: 
        !            55: extern char * getkeyval();
        !            56: extern int delta(), deltatext();
        !            57: struct hshentry * genbranch(); /* forward */
        !            58: 
        !            59: 
        !            60: 
        !            61: int countnumflds(s)
        !            62: char * s;
        !            63: /* Given a pointer s to a dotted number (date or revision number),
        !            64:  * countnumflds returns the number of digitfields in s.
        !            65:  */
        !            66: {       register char * sp;
        !            67:         register int    count;
        !            68:         if ((sp=s)==nil) return(0);
        !            69:         if (*sp == '\0') return(0);
        !            70:         count = 1;
        !            71:         while (*sp) {
        !            72:                 if (*sp++ == '.') count++;
        !            73:         }
        !            74:         if (*(--sp) == '.') count--; /*trailing periods don't count*/
        !            75:         return(count);
        !            76: }
        !            77: 
        !            78: getbranchno(revno,branchno)
        !            79: char * revno, * branchno;
        !            80: /* Given a non-nil revision number revno, getbranchno copies the number of the branch
        !            81:  * on which revno is into branchnumber. If revno itself is a branch number,
        !            82:  * it is copied unchanged.
        !            83:  */
        !            84: {
        !            85:         register int i, numflds;
        !            86:         register char * tp, * sp;
        !            87: 
        !            88:         numflds=countnumflds(revno);
        !            89:         if (numflds%2 == 1)
        !            90:                 strcpy(branchno,revno);
        !            91:         else {
        !            92:                 sp=revno; tp=branchno;
        !            93:                 for (i=1;i<numflds;i++) {
        !            94:                         while(*sp!='.') *tp++ = *sp++;
        !            95:                         *tp++ = *sp++;
        !            96:                 }
        !            97:                 *(tp-1)='\0';
        !            98:         }
        !            99: }
        !           100: 
        !           101: 
        !           102: 
        !           103: int cmpnum(num1, num2)
        !           104: char * num1, * num2;
        !           105: /* compares the two dotted numbers num1 and num2 lexicographically
        !           106:  * by field. Individual fields are compared numerically.
        !           107:  * returns <0, 0, >0 if num1<num2, num1==num2, and num1>num2, resp.
        !           108:  * omitted fields are assumed to be higher than the existing ones.
        !           109: */
        !           110: {
        !           111:         register char * s1, *s2;
        !           112:         register int n1, n2;
        !           113: 
        !           114:         s1=num1==nil?"":num1;
        !           115:         s2=num2==nil?"":num2;
        !           116: 
        !           117:         do {
        !           118:                 n1 = 0;
        !           119:                 while (('0' <= *s1) && (*s1 <= '9')) {
        !           120:                         n1 = n1*10 + (*s1 - '0');
        !           121:                         s1++;
        !           122:                 }
        !           123:                 /* skip '.' */
        !           124:                 if (*s1=='.') s1++;
        !           125: 
        !           126:                 n2 = 0;
        !           127:                 while (('0' <= *s2) && (*s2 <= '9')) {
        !           128:                         n2 = n2*10 + (*s2 - '0');
        !           129:                         s2++;
        !           130:                 }
        !           131:                 /* skip '.' */
        !           132:                 if (*s2=='.') s2++;
        !           133: 
        !           134:         } while ((n1==n2) && (*s1!='\0') && (*s2!='\0'));
        !           135: 
        !           136:         if (((*s1=='\0') && (*s2=='\0')) || (n1!=n2))
        !           137:                 return (n1 - n2);
        !           138:         /*now n1==n2 and one of s1 or s2 is shorter*/
        !           139:         /*give precedence to shorter one*/
        !           140:         if (*s1=='\0') return 1;
        !           141:         else           return -1;
        !           142: 
        !           143: }
        !           144: 
        !           145: 
        !           146: 
        !           147: int cmpnumfld(num1, num2, fld)
        !           148: char * num1, * num2; int fld;
        !           149: /* compares the two dotted numbers at field fld and returns
        !           150:  * num1[fld]-num2[fld]. Assumes that num1 and num2 have at least fld fields.
        !           151: */
        !           152: {
        !           153:         register char * s1, *s2;
        !           154:         register int n1, n2;
        !           155: 
        !           156:         s1=num1; n1=fld-1;
        !           157:         /* skip fld-1 fields */
        !           158:         while (n1) {
        !           159:                 while(*s1 != '.') s1++;
        !           160:                 n1--; s1++;
        !           161:         }
        !           162:         s2 = num2; n2=fld-1;
        !           163:         while (n2) {
        !           164:                 while(*s2 != '.') s2++;
        !           165:                 n2--; s2++;
        !           166:         }
        !           167:         /* Don't put the above into a single loop! */
        !           168:         /* Now s1 and s2 point to the beginning of the respective fields */
        !           169:         /* compute numerical value and compare */
        !           170:         n1 = 0;
        !           171:         while (('0' <= *s1) && (*s1 <= '9')) {
        !           172:                 n1 = n1*10 + (*s1 - '0');
        !           173:                 s1++;
        !           174:         }
        !           175:         n2 = 0;
        !           176:         while (('0' <= *s2) && (*s2 <= '9')) {
        !           177:                 n2 = n2*10 + (*s2 - '0');
        !           178:                 s2++;
        !           179:         }
        !           180:         return (n1 - n2);
        !           181: }
        !           182: 
        !           183: 
        !           184: int compartial(num1, num2, length)
        !           185: char    * num1;
        !           186: char    * num2;
        !           187: int     length;
        !           188: 
        !           189: /*   compare the first "length" fields of two dot numbers;
        !           190:      the omitted field is considered to be larger than any number  */
        !           191: /*   restriction:  at least one number has length or more fields   */
        !           192: 
        !           193: {
        !           194:         register        char    *s1, *s2;
        !           195:         register        int     n1, n2;
        !           196: 
        !           197: 
        !           198:         s1 = num1;      s2 = num2;
        !           199:         if ( s1==nil || *s1 == '\0' ) return 1;
        !           200:         if ( s2==nil || *s2 == '\0' ) return -1;
        !           201: 
        !           202:         do {
        !           203:             n1 = 0;
        !           204:             while( ('0' <= *s1) && (*s1 <= '9') ) {
        !           205:                 n1 = n1 * 10 + (*s1 - '0') ;
        !           206:                 s1++;
        !           207:             }
        !           208:             if ( *s1 == '.' ) s1++;    /*  skip .   */
        !           209: 
        !           210:             n2 = 0;
        !           211:             while( ( '0' <= *s2) && ( *s2 <= '9' ) ) {
        !           212:                    n2 = n2 * 10 + ( *s2 - '0' ) ;
        !           213:                 s2++;
        !           214:             }
        !           215:             if (*s2 == '.') s2++;
        !           216:         }   while(  ( n1 == n2) && ((--length) != 0) &&
        !           217:                     ( *s1 != '\0') && (*s2 != '\0')  );
        !           218: 
        !           219:         if ( (n1 != n2) || (length == 0) ){
        !           220:                 return(n1-n2);   }
        !           221: 
        !           222:         if ( *s1 == '\0' ) return 1;
        !           223:         if ( *s2 == '\0' ) return -1;
        !           224: }
        !           225: 
        !           226: 
        !           227: 
        !           228: incnum(onum,nnum)
        !           229: char * onum, *nnum;
        !           230: /* increments the last field of revision number onum by one and
        !           231:  * places the result into nnum
        !           232:  */
        !           233: {
        !           234:         register char * sp, *tp;
        !           235:         register int i;
        !           236: 
        !           237:         sp = onum; tp = nnum;
        !           238:         for (i=countnumflds(onum)-1; i>0; i--) {
        !           239:                 while (*sp != '.') *tp++ = *sp++;
        !           240:                 *tp++ = *sp++;  /* copy dot also */
        !           241:         }
        !           242:         sprintf(tp,"%d",atoi(sp)+1);
        !           243: }
        !           244: 
        !           245: 
        !           246: char * partialno(rev1,rev2,length)
        !           247: char * rev1, * rev2; register int length;
        !           248: /* Function: Copies length fields of revision number rev2 into rev1.
        !           249:  * returns rev1.
        !           250:  */
        !           251: {       register char * r1,* r2;
        !           252: 
        !           253:         r1=rev1; r2=rev2;
        !           254:         while (length) {
        !           255:                 while(*r2 != '.' && *r2!='\0') *r1++ = *r2++;
        !           256:                 *r1++ = *r2++;
        !           257:                 length--;
        !           258:         }
        !           259:         /* eliminate last '.'*/
        !           260:         *(r1-1)='\0';
        !           261:         return rev1;
        !           262: }
        !           263: 
        !           264: 
        !           265: 
        !           266: char * getancestor(r1, r2, r3)
        !           267: char * r1, *r2, *r3;
        !           268: /* function: finds the common ancestor of r1 and r2 and
        !           269:  * places it into r3.
        !           270:  * returns r3 if successful, false otherwise.
        !           271:  * works reliably only if r1 and r2 are not branch numbers.
        !           272:  */
        !           273: {       int l1, l2, l3;
        !           274:         char t1[revlength], t2[revlength];
        !           275: 
        !           276:         l1=countnumflds(r1); l2=countnumflds(r2);
        !           277:         if ((l1<=2 && l2<=2)||(cmpnum(r1,r2)==0)) {
        !           278:                 /* on main trunk or identical */
        !           279:                 error("Common ancestor of %s and %s undefined.", r1, r2);
        !           280:                 return false;
        !           281:         }
        !           282: 
        !           283:         l3=0;
        !           284:         while ((cmpnumfld(r1, r2, l3+1)==0) && (cmpnumfld(r1, r2, l3+2)==0)){
        !           285:                 l3=l3+2;
        !           286:         }
        !           287:         /* This will terminate since r1 and r2 are not the same; see above*/
        !           288:         if (l3==0) {
        !           289:                 /* no common prefix. Common ancestor on main trunk. */
        !           290:                 partialno(t1,r1,l1>2?2:l1);partialno(t2,r2,l2>2?2:l2);
        !           291:                 if (cmpnum(t1,t2)<0)
        !           292:                         strcpy(r3,t1);
        !           293:                 else    strcpy(r3,t2);
        !           294:                 if ((cmpnum(r3,r1)==0)||(cmpnum(r3,r2)==0)) {
        !           295:                         error("Ancestor for %s and %s undefined.",r1,r2);
        !           296:                         return false;
        !           297:                 }
        !           298:                 return r3;
        !           299:         } else {
        !           300:                if (cmpnumfld(r1,r2,l3+1)==0) {
        !           301:                         error("Ancestor for %s and %s undefined.",r1,r2);
        !           302:                         return false;
        !           303:                 }
        !           304:                 return(partialno(r3,r1,l3));
        !           305:         }
        !           306: }
        !           307: 
        !           308: 
        !           309: 
        !           310: 
        !           311: struct hshentry * genrevs(revno,date,author,state,store)
        !           312: char * revno, * date, * author, * state;
        !           313: struct hshentry * * store;
        !           314: /* Function: finds the deltas needed for reconstructing the
        !           315:  * revision given by revno, date, author, and state, and stores pointers
        !           316:  * to these deltas into an array whose starting address is given by store.
        !           317:  * The last pointer stored is nil. The last delta (target delta) is returned.
        !           318:  * If the proper delta could not be found, nil is returned.
        !           319:  */
        !           320: {
        !           321:         int length;
        !           322:         register struct hshentry * next;
        !           323:         int result;
        !           324:         char * branchnum;
        !           325:         char t[revlength];
        !           326: 
        !           327:         if (Head == nil) {
        !           328:                 error("RCSfile empty.");
        !           329:                 return nil;
        !           330:         }
        !           331: 
        !           332:         length = countnumflds(revno);
        !           333:         next=Head;
        !           334: 
        !           335:         if (length >= 1) {
        !           336:                 /* at least one field; find branch exactly */
        !           337:                 while ((next!=nil) &&
        !           338:                        ((result=cmpnumfld(revno,next->num,1))<0)) {
        !           339:                         /*puts(next->num);*/
        !           340:                         *store++ = next;
        !           341:                         next = next->next;
        !           342:                 }
        !           343: 
        !           344:                 if (next==nil) {error("Branch number %s too low.",partialno(t,revno,1));return nil;}
        !           345:                 if (result>0)  {error("Branch number %s not present.",partialno(t,revno,1));return nil;}
        !           346:         }
        !           347:         if (length<=1){
        !           348:                 /* pick latest one on given branch */
        !           349:                 branchnum = next->num; /* works even for empty revno*/
        !           350:                 while ((next!=nil) &&
        !           351:                        (cmpnumfld(branchnum,next->num,1)==0) &&
        !           352:                        !(
        !           353:                         (date==nil?1:(cmpnum(date,next->date)>=0)) &&
        !           354:                         (author==nil?1:(strcmp(author,next->author)==0)) &&
        !           355:                         (state ==nil?1:(strcmp(state, next->state) ==0))
        !           356:                         )
        !           357:                        )
        !           358:                 {       /*puts(next->num);*/
        !           359:                         *store ++ = next;
        !           360:                         next=next->next;
        !           361:                 }
        !           362:                 if ((next==nil) ||
        !           363:                     (cmpnumfld(branchnum,next->num,1)!=0))/*overshot*/ {
        !           364:                         error("Cannot find revision on branch %s with a date before %s, author %s, and state %s.",
        !           365:                                 length==0?partialno(t,branchnum,1):revno,date==nil?"<now>":date,
        !           366:                                 author==nil?"<any>":author, state==nil?"<any>":state);
        !           367:                         return nil;
        !           368:                 } else {
        !           369:                         /*puts(next->num);*/
        !           370:                         *store++ = next;
        !           371:                 }
        !           372:                 *store = nil;
        !           373:                 return next;
        !           374:         }
        !           375: 
        !           376:         /* length >=2 */
        !           377:         /* find revision; may go low if length==2*/
        !           378:         while ((next!=nil) &&
        !           379:                ((result =cmpnumfld(revno,next->num,2)) <0) &&
        !           380:                (cmpnumfld(revno,next->num,1)==0) ) {
        !           381:                 /*puts(next->num);*/
        !           382:                 *store++ = next;
        !           383:                 next = next->next;
        !           384:         }
        !           385: 
        !           386:         if ((next==nil) || (cmpnumfld(revno,next->num,1)!=0)) {
        !           387:                 error("Revision number %s too low.",partialno(t,revno,2));
        !           388:                 return nil;
        !           389:         }
        !           390:         if ((length>2) && (result!=0)) {
        !           391:                 error("Revision %s not present.",partialno(t,revno,2));
        !           392:                 return nil;
        !           393:         }
        !           394: 
        !           395:         /* print last one */
        !           396:         /*puts(next->num);*/
        !           397:         *store++ = next;
        !           398: 
        !           399:         if (length>2)
        !           400:                 return genbranch(next,revno,length,date,author,state,store);
        !           401:         else { /* length == 2*/
        !           402:                 if ((date!=nil) && (cmpnum(date,next->date)<0)){
        !           403:                         error("Revision %s has date %s.",next->num, next->date);
        !           404:                         return nil;
        !           405:                 }
        !           406:                 if ((author!=nil)&&(strcmp(author,next->author)!=0)) {
        !           407:                         error("Revision %s has author %s.",next->num,next->author);
        !           408:                         return nil;
        !           409:                 }
        !           410:                 if ((state!=nil)&&(strcmp(state,next->state)!=0)) {
        !           411:                         error("Revision %s has state %s.",next->num,
        !           412:                                next->state==nil?"<empty>":next->state);
        !           413:                         return nil;
        !           414:                 }
        !           415:                 *store=nil;
        !           416:                 return next;
        !           417:         }
        !           418: }
        !           419: 
        !           420: 
        !           421: 
        !           422: 
        !           423: struct hshentry * genbranch(bpoint, revno, length,date,author,state,store)
        !           424: struct hshentry * bpoint;
        !           425: char * revno; int length;
        !           426: char * date, * author, * state;
        !           427: struct hshentry ** store;
        !           428: /* Function: given a branchpoint, a revision number, date, author, and state,
        !           429:  * genbranch finds the deltas necessary to reconstruct the given revision
        !           430:  * from the branch point on.
        !           431:  * Pointers to the found deltas are stored in an array beginning with store.
        !           432:  * revno must be on a side branch.
        !           433:  * return nil on error
        !           434:  */
        !           435: {
        !           436:         int field;
        !           437:         register struct hshentry * next, * trail;
        !           438:         register struct branchhead * bhead;
        !           439:         int result;
        !           440:         char t[revlength];
        !           441: 
        !           442:         bhead = bpoint->branches;
        !           443: 
        !           444:         for (field=3; field<=length; field=field+2) {
        !           445: 
        !           446:                 if (bhead==nil) {error("No side branches present for %s.",partialno(t,revno,field-1));return nil;}
        !           447: 
        !           448:                 /*find branch head*/
        !           449:                 /*branches are arranged in increasing order*/
        !           450:                 while ((bhead!=nil) &&
        !           451:                        ((result=cmpnumfld(revno,bhead->hsh->num,field))>0)) {
        !           452:                         bhead = bhead->nextbranch;
        !           453:                 }
        !           454: 
        !           455:                 if (bhead==nil) {error("Branch number %s too high.",partialno(t,revno,field));return nil;}
        !           456:                 if (result<0)   {error("Branch number %s not present.",partialno(t,revno,field));return nil;}
        !           457: 
        !           458:                 next = bhead->hsh;
        !           459:                 if (length==field) {
        !           460:                         /* pick latest one on that branch */
        !           461:                         trail=nil;
        !           462:                         do { if ((date==nil?1:(cmpnum(date,next->date)>=0)) &&
        !           463:                                  (author==nil?1:(strcmp(author,next->author)==0)) &&
        !           464:                                  (state ==nil?1:(strcmp(state, next->state) ==0))
        !           465:                              ) trail = next;
        !           466:                              next=next->next;
        !           467:                         } while (next!=nil);
        !           468: 
        !           469:                         if (trail==nil) {
        !           470:                              error("Cannot find revision on branch %s with a date before %s, author %s, and state %s.",
        !           471:                                         revno, date==nil?"<now>":date, 
        !           472:                                         author==nil?"<any>":author, state==nil?"<any>":state);
        !           473:                              return nil;
        !           474:                         } else { /* print up to last one suitable */
        !           475:                              next = bhead->hsh;
        !           476:                              while (next!=trail) {
        !           477:                                   /*puts(next->num);*/
        !           478:                                   *store++ = next;
        !           479:                                   next=next->next;
        !           480:                              }
        !           481:                              /*puts(next->num);*/
        !           482:                              *store++ = next;
        !           483:                         }
        !           484:                         *store = nil;
        !           485:                         return next;
        !           486:                 }
        !           487: 
        !           488:                 /* length > field */
        !           489:                 /* find revision */
        !           490:                 /* check low */
        !           491:                 if (cmpnumfld(revno,next->num,field+1)<0) {
        !           492:                         error("Revision number %s too low.",partialno(t,revno,field+1));
        !           493:                         return(nil);
        !           494:                 }
        !           495:                 do {    /*puts(next->num);*/
        !           496:                         *store++ = next;
        !           497:                         trail = next;
        !           498:                         next = next->next;
        !           499:                 } while ((next!=nil) &&
        !           500:                        (cmpnumfld(revno,next->num,field+1) >=0));
        !           501: 
        !           502:                 if ((length>field+1) &&  /*need exact hit */
        !           503:                     (cmpnumfld(revno,trail->num,field+1) !=0)){
        !           504:                         error("Revision %s not present.",partialno(t,revno,field+1));
        !           505:                         return(nil);
        !           506:                 }
        !           507:                 if (length == field+1) {
        !           508:                         if ((date!=nil) && (cmpnum(date,trail->date)<0)){
        !           509:                                 error("Revision %s has date %s.",trail->num, trail->date);
        !           510:                                 return nil;
        !           511:                         }
        !           512:                         if ((author!=nil)&&(strcmp(author,trail->author)!=0)) {
        !           513:                                 error("Revision %s has author %s.",trail->num,trail->author);
        !           514:                                 return nil;
        !           515:                         }
        !           516:                         if ((state!=nil)&&(strcmp(state,trail->state)!=0)) {
        !           517:                                 error("Revision %s has state %s.",trail->num,
        !           518:                                        trail->state==nil?"<empty>":trail->state);
        !           519:                                 return nil;
        !           520:                         }
        !           521:                 }
        !           522:                 bhead = trail->branches;
        !           523: 
        !           524:         }
        !           525:         * store = nil;
        !           526:         return trail;
        !           527: }
        !           528: 
        !           529: 
        !           530: char * lookupsym(id)
        !           531: char * id;
        !           532: /* Function: looks up id in the list of symbolic names starting
        !           533:  * with pointer SYMBOLS, and returns a pointer to the corresponding
        !           534:  * revision number. Returns nil if not present.
        !           535:  */
        !           536: {
        !           537:         register struct assoc * next;
        !           538:         next = Symbols;
        !           539:         while (next!=nil) {
        !           540:                 if (strcmp(id, next->symbol)==0)
        !           541:                         return(next->delta->num);
        !           542:                 else    next=next->nextassoc;
        !           543:         }
        !           544:         return nil;
        !           545: }
        !           546: 
        !           547: int expandsym(source, target)
        !           548: char * source, * target;
        !           549: /* Function: Source points to a revision number. Expandsym copies
        !           550:  * the number to target, but replaces all symbolic fields in the
        !           551:  * source number with their numeric values.
        !           552:  * A trailing '.' is omitted; leading zeroes are compressed.
        !           553:  * returns false on error;
        !           554:  */
        !           555: {       register char * sp, * tp, *bp;
        !           556:         char symbuf[30];
        !           557:         register enum tokens d;
        !           558: 
        !           559:         sp = source; tp=target;
        !           560:         if (sp == nil) { /*accept nil pointer as a legal value*/
        !           561:                 *tp='\0';
        !           562:                 return true;
        !           563:         }
        !           564: 
        !           565:         while (*sp != '\0') {
        !           566:                 if (ctab[*sp] == DIGIT) {
        !           567:                         if (*sp=='0') {
        !           568:                                 /* skip leading zeroes */
        !           569:                                 sp++;
        !           570:                                 while(*sp == '0') sp++;
        !           571:                                 if (*sp=='\0' || *sp=='.') *tp++ = '0'; /*single zero*/
        !           572:                         }
        !           573:                         while(ctab[*sp] == DIGIT) *tp++ = *sp++;
        !           574:                         if ((*sp == '\0') || ((*sp=='.')&&(*(sp+1)=='\0'))) {
        !           575:                                 *tp='\0'; return true;
        !           576:                         }
        !           577:                         if (*sp == '.') *tp++ = *sp++;
        !           578:                         else {
        !           579:                             error("Improper revision number: %s",source);
        !           580:                             *tp = '\0';
        !           581:                             return false;
        !           582:                         }
        !           583:                 } elsif (ctab[*sp] == LETTER) {
        !           584:                         bp = symbuf;
        !           585:                         do {    *bp++ = *sp++;
        !           586:                         } while(((d=ctab[*sp])==LETTER) || (d==DIGIT) ||
        !           587:                               (d==IDCHAR));
        !           588:                         *bp= '\0';
        !           589:                         bp=lookupsym(symbuf);
        !           590:                         if (bp==nil) {
        !           591:                                 error("Symbolic number %s is undefined.",symbuf);
        !           592:                                 *tp='\0';
        !           593:                                 return false;
        !           594:                         } else { /* copy number */
        !           595:                                 while (*tp++ = *bp++); /* copies the trailing \0*/
        !           596:                         }
        !           597:                         if ((*sp == '\0') || ((*sp=='.')&&(*(sp+1)=='\0')))
        !           598:                                 return true;
        !           599:                         if (*sp == '.')  {
        !           600:                                 *(tp-1) = *sp++;
        !           601:                         } else {
        !           602:                                 error("Improper revision number: %s",source);
        !           603:                                 return false;
        !           604:                         }
        !           605:                 }else {
        !           606:                         error("Improper revision number: %s", source);
        !           607:                         *tp = '\0';
        !           608:                         return false;
        !           609:                 }
        !           610:         }
        !           611:         *tp = '\0';
        !           612:         return true;
        !           613: }
        !           614: 
        !           615: 
        !           616: 
        !           617: #ifdef REVTEST
        !           618: 
        !           619: main(argc,argv)
        !           620: int argc; char * argv[];
        !           621: {
        !           622:         char symrevno[revlength];       /* used for input of revision numbers */
        !           623:         char numricrevno[revlength];
        !           624:         char author[20];
        !           625:         char state[20];
        !           626:         char date[20];
        !           627:         struct hshentry * gendeltas[hshsize/2];
        !           628:         struct hshentry * target;
        !           629:         int i;
        !           630: 
        !           631:         cmdid = "revtest";
        !           632:         if (argc<2) {
        !           633:                 fputs("No input file\n",stderr);
        !           634:                 exit(-1);
        !           635:         }
        !           636:         if ((finptr=fopen(argv[1], "r")) == NULL) {
        !           637:                 faterror("Can't open input file %s\n",argv[1]);
        !           638:         }
        !           639:         Lexinit();
        !           640:         getadmin();
        !           641: 
        !           642:         gettree();
        !           643: 
        !           644:         getdesc(false);
        !           645: 
        !           646:         do {
        !           647:                 /* all output goes to stderr, to have diagnostics and       */
        !           648:                 /* errors in sequence.                                      */
        !           649:                 fprintf(stderr,"\nEnter revision number or <return> or '.': ");
        !           650:                 if(gets(symrevno)==NULL) break;
        !           651:                 if (*symrevno == '.') break;
        !           652:                 fprintf(stderr,"%s;\n",symrevno);
        !           653:                 expandsym(symrevno,numricrevno);
        !           654:                 fprintf(stderr,"expanded number: %s; ",numricrevno);
        !           655:                 fprintf(stderr,"Date: ");
        !           656:                 gets(date); fprintf(stderr,"%s; ",date);
        !           657:                 fprintf(stderr,"Author: ");
        !           658:                 gets(author);fprintf(stderr,"%s; ",author);
        !           659:                 fprintf(stderr,"State: ");
        !           660:                 gets(state); fprintf(stderr, "%s;\n", state);
        !           661:                 target=genrevs(numricrevno,*date=='\0'?nil:date, *author=='\0'?nil:author,
        !           662:                               *state=='\0'?nil:state,gendeltas);
        !           663:                 if (target!=nil) {
        !           664:                         i=0;
        !           665:                         while (gendeltas[i]!=nil) {
        !           666:                                 fprintf(stderr,"%s\n",gendeltas[i++]->num);
        !           667:                         }
        !           668:                 }
        !           669:         } while (true);
        !           670:        clearerr(stdin);
        !           671:         fprintf(stderr,"done\n");
        !           672: 
        !           673: }
        !           674: 
        !           675: cleanup(){}
        !           676: /*dummy*/
        !           677: 
        !           678: #endif REVTEST

unix.superglobalmegacorp.com

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