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