📄 rcsrev.c
字号:
} *store = nil; return next; } /* length >=2 */ /* find revision; may go low if length==2*/ while ((result=cmpnumfld(revno,next->num,2)) < 0 && (cmpnumfld(revno,next->num,1)==0) ) { store1(&store, next); next = next->next; if (!next) break; } if ((next==nil) || (cmpnumfld(revno,next->num,1)!=0)) { error("revision number %s too low", partialno(&t,revno,2)); goto norev; } if ((length>2) && (result!=0)) { absent(revno, 2); goto norev; } /* print last one */ store1(&store, next); if (length>2) return genbranch(next,revno,length,date,author,state,store); else { /* length == 2*/ if ((date!=nil) && (cmpnum(date,next->date)<0)){ error("Revision %s has date %s.", next->num, date2str(next->date, datebuf) ); return nil; } if ((author!=nil)&&(strcmp(author,next->author)!=0)) { error("Revision %s has author %s.",next->num,next->author); return nil; } if ((state!=nil)&&(strcmp(state,next->state)!=0)) { error("Revision %s has state %s.",next->num, next->state==nil?"<empty>":next->state); return nil; } *store=nil; return next; } norev: bufautoend(&t); return nil;} static struct hshentry *genbranch(bpoint, revno, length, date, author, state, store) struct hshentry const *bpoint; char const *revno; unsigned length; char const *date, *author, *state; struct hshentries **store;/* Function: given a branchpoint, a revision number, date, author, and state, * genbranch finds the deltas necessary to reconstruct the given revision * from the branch point on. * Pointers to the found deltas are stored in a list beginning with store. * revno must be on a side branch. * return nil on error */{ unsigned field; register struct hshentry * next, * trail; register struct branchhead const *bhead; int result; struct buf t; char datebuf[datesize]; field = 3; bhead = bpoint->branches; do { if (!bhead) { bufautobegin(&t); error("no side branches present for %s", partialno(&t,revno,field-1)); bufautoend(&t); return nil; } /*find branch head*/ /*branches are arranged in increasing order*/ while (0 < (result=cmpnumfld(revno,bhead->hsh->num,field))) { bhead = bhead->nextbranch; if (!bhead) { bufautobegin(&t); error("branch number %s too high",partialno(&t,revno,field)); bufautoend(&t); return nil; } } if (result<0) { absent(revno, field); return nil; } next = bhead->hsh; if (length==field) { /* pick latest one on that branch */ trail=nil; do { if ((date==nil?1:(cmpnum(date,next->date)>=0)) && (author==nil?1:(strcmp(author,next->author)==0)) && (state ==nil?1:(strcmp(state, next->state) ==0)) ) trail = next; next=next->next; } while (next!=nil); if (trail==nil) { cantfindbranch(revno, date, author, state); return nil; } else { /* print up to last one suitable */ next = bhead->hsh; while (next!=trail) { store1(&store, next); next=next->next; } store1(&store, next); } *store = nil; return next; } /* length > field */ /* find revision */ /* check low */ if (cmpnumfld(revno,next->num,field+1)<0) { bufautobegin(&t); error("revision number %s too low", partialno(&t,revno,field+1)); bufautoend(&t); return(nil); } do { store1(&store, next); trail = next; next = next->next; } while ((next!=nil) && (cmpnumfld(revno,next->num,field+1) >=0)); if ((length>field+1) && /*need exact hit */ (cmpnumfld(revno,trail->num,field+1) !=0)){ absent(revno, field+1); return(nil); } if (length == field+1) { if ((date!=nil) && (cmpnum(date,trail->date)<0)){ error("Revision %s has date %s.", trail->num, date2str(trail->date, datebuf) ); return nil; } if ((author!=nil)&&(strcmp(author,trail->author)!=0)) { error("Revision %s has author %s.",trail->num,trail->author); return nil; } if ((state!=nil)&&(strcmp(state,trail->state)!=0)) { error("Revision %s has state %s.",trail->num, trail->state==nil?"<empty>":trail->state); return nil; } } bhead = trail->branches; } while ((field+=2) <= length); * store = nil; return trail;} static char const *lookupsym(id) char const *id;/* Function: looks up id in the list of symbolic names starting * with pointer SYMBOLS, and returns a pointer to the corresponding * revision number. Returns nil if not present. */{ register struct assoc const *next; next = Symbols; while (next!=nil) { if (strcmp(id, next->symbol)==0) return next->num; else next=next->nextassoc; } return nil;}int expandsym(source, target) char const *source; struct buf *target;/* Function: Source points to a revision number. Expandsym copies * the number to target, but replaces all symbolic fields in the * source number with their numeric values. * Expand a branch followed by `.' to the latest revision on that branch. * Ignore `.' after a revision. Remove leading zeros. * returns false on error; */{ return fexpandsym(source, target, (RILE*)0);} intfexpandsym(source, target, fp) char const *source; struct buf *target; RILE *fp;/* Same as expandsym, except if FP is nonzero, it is used to expand KDELIM. */{ register char const *sp, *bp; register char *tp; char const *tlim; register enum tokens d; unsigned dots; sp = source; bufalloc(target, 1); tp = target->string; if (!sp || !*sp) { /*accept nil pointer as a legal value*/ *tp='\0'; return true; } if (sp[0] == KDELIM && !sp[1]) { if (!getoldkeys(fp)) return false; if (!*prevrev.string) { error("working file lacks revision number"); return false; } bufscpy(target, prevrev.string); return true; } tlim = tp + target->size; dots = 0; for (;;) { switch (ctab[(unsigned char)*sp]) { case DIGIT: while (*sp=='0' && isdigit(sp[1])) /* skip leading zeroes */ sp++; do { if (tlim <= tp) tp = bufenlarge(target, &tlim); } while (isdigit(*tp++ = *sp++)); --sp; tp[-1] = '\0'; break; case LETTER: case Letter: { register char *p = tp; register size_t s = tp - target->string; do { if (tlim <= p) p = bufenlarge(target, &tlim); *p++ = *sp++; } while ((d=ctab[(unsigned char)*sp])==LETTER || d==Letter || d==DIGIT || (d==IDCHAR)); if (tlim <= p) p = bufenlarge(target, &tlim); *p = 0; tp = target->string + s; } bp = lookupsym(tp); if (bp==nil) { error("Symbolic number %s is undefined.", tp); return false; } do { if (tlim <= tp) tp = bufenlarge(target, &tlim); } while ((*tp++ = *bp++)); break; default: goto improper; } switch (*sp++) { case '\0': return true; case '.': break; default: goto improper; } if (!*sp) { if (dots & 1) goto improper; if (!(bp = branchtip(target->string))) return false; bufscpy(target, bp); return true; } ++dots; tp[-1] = '.'; } improper: error("improper revision number: %s", source); return false;} static char const *branchtip(branch) char const *branch;{ struct hshentry *h; struct hshentries *hs; h = genrevs(branch, (char*)0, (char*)0, (char*)0, &hs); return h ? h->num : (char const*)0;} char const *tiprev(){ return Dbranch ? branchtip(Dbranch) : Head ? Head->num : (char const*)0;}#ifdef REVTESTchar const cmdid[] = "revtest"; intmain(argc,argv)int argc; char * argv[];{ static struct buf numricrevno; char symrevno[100]; /* used for input of revision numbers */ char author[20]; char state[20]; char date[20]; struct hshentries *gendeltas; struct hshentry * target; int i; if (argc<2) { aputs("No input file\n",stderr); exitmain(EXIT_FAILURE); } if (!(finptr=Iopen(argv[1], FOPEN_R, (struct stat*)0))) { faterror("can't open input file %s", argv[1]); } Lexinit(); getadmin(); gettree(); getdesc(false); do { /* all output goes to stderr, to have diagnostics and */ /* errors in sequence. */ aputs("\nEnter revision number or <return> or '.': ",stderr); if (!gets(symrevno)) break; if (*symrevno == '.') break; aprintf(stderr,"%s;\n",symrevno); expandsym(symrevno,&numricrevno); aprintf(stderr,"expanded number: %s; ",numricrevno.string); aprintf(stderr,"Date: "); gets(date); aprintf(stderr,"%s; ",date); aprintf(stderr,"Author: "); gets(author); aprintf(stderr,"%s; ",author); aprintf(stderr,"State: "); gets(state); aprintf(stderr, "%s;\n", state); target = genrevs(numricrevno.string, *date?date:(char *)nil, *author?author:(char *)nil, *state?state:(char*)nil, &gendeltas); if (target!=nil) { while (gendeltas) { aprintf(stderr,"%s\n",gendeltas->first->num); gendeltas = gendeltas->next; } } } while (true); aprintf(stderr,"done\n"); exitmain(EXIT_SUCCESS);}exiting void exiterr() { _exit(EXIT_FAILURE); }#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -