📄 rcssyn.c
字号:
*/{ getkeystring(Kdesc); if (prdesc) printstring(); /*echo string*/ else readstring(); /*skip string*/} static char const *getkeyval(keyword, token, optional) char const *keyword; enum tokens token; int optional;/* reads a pair of the form * <keyword> <token> ; * where token is one of <id> or <num>. optional indicates whether * <token> is optional. A pointer to * the actual character string of <id> or <num> is returned. */{ register char const *val = nil; getkey(keyword); if (nexttok==token) { val = NextString; nextlex(); } else { if (!optional) fatserror("missing %s", keyword); } getsemi(keyword); return(val);} voidputadmin(fout)register FILE * fout;/* Function: Print the <admin> node read with getadmin() to file fout. * Assumption: Variables AccessList, Symbols, Locks, StrictLocks, * and Head have been set. */{ struct assoc const *curassoc; struct lock const *curlock; struct access const *curaccess; aprintf(fout, "%s\t%s;\n", Khead, Head?Head->num:""); if (Dbranch && VERSION(4)<=RCSversion) aprintf(fout, "%s\t%s;\n", Kbranch, Dbranch); aputs(Kaccess, fout); curaccess = AccessList; while (curaccess) { aprintf(fout, "\n\t%s", curaccess->login); curaccess = curaccess->nextaccess; } aprintf(fout, ";\n%s", Ksymbols); curassoc = Symbols; while (curassoc) { aprintf(fout, "\n\t%s:%s", curassoc->symbol, curassoc->num); curassoc = curassoc->nextassoc; } aprintf(fout, ";\n%s", Klocks); curlock = Locks; while (curlock) { aprintf(fout, "\n\t%s:%s", curlock->login, curlock->delta->num); curlock = curlock->nextlock; } if (StrictLocks) aprintf(fout, "; %s", Kstrict); aprintf(fout, ";\n"); if (Comment.size) { aprintf(fout, "%s\t", Kcomment); putstring(fout, true, Comment, false); aprintf(fout, ";\n"); } if (Expand != KEYVAL_EXPAND) aprintf(fout, "%s\t%c%s%c;\n", Kexpand, SDELIM, expand_names[Expand], SDELIM ); awrite(Ignored.string, Ignored.size, fout); aputc('\n', fout);} static voidputdelta(node,fout)register struct hshentry const *node;register FILE * fout;/* Function: prints a <delta> node to fout; */{ struct branchhead const *nextbranch; if (node == nil) return; aprintf(fout, "\n%s\n%s\t%s;\t%s %s;\t%s %s;\nbranches", node->num, Kdate, node->date, Kauthor, node->author, Kstate, node->state?node->state:"" ); nextbranch = node->branches; while (nextbranch) { aprintf(fout, "\n\t%s", nextbranch->hsh->num); nextbranch = nextbranch->nextbranch; } aprintf(fout, ";\n%s\t%s;\n", Knext, node->next?node->next->num:""); awrite(node->ig.string, node->ig.size, fout);} voidputtree(root,fout)struct hshentry const *root;register FILE * fout;/* Function: prints the delta tree in preorder to fout, starting with root. */{ struct branchhead const *nextbranch; if (root==nil) return; if (root->selector) putdelta(root,fout); puttree(root->next,fout); nextbranch = root->branches; while (nextbranch) { puttree(nextbranch->hsh,fout); nextbranch = nextbranch->nextbranch; }} static exiting voidunexpected_EOF(){ faterror("unexpected EOF in diff output");}int putdtext(num,log,srcfilename,fout,diffmt) char const *num, *srcfilename; struct cbuf log; FILE *fout; int diffmt;/* Function: write a deltatext-node to fout. * num points to the deltanumber, log to the logmessage, and * sourcefile contains the text. Doubles up all SDELIMs in both the * log and the text; Makes sure the log message ends in \n. * returns false on error. * If diffmt is true, also checks that text is valid diff -n output. */{ RILE *fin; int result; if (!(fin = Iopen(srcfilename, "r", (struct stat*)0))) { eerror(srcfilename); return false; } result = putdftext(num,log,fin,fout,diffmt); Ifclose(fin); return result;} voidputstring(out, delim, s, log) register FILE *out; struct cbuf s; int delim, log;/* * Output to OUT one SDELIM if DELIM, then the string S with SDELIMs doubled. * If LOG is set then S is a log string; append a newline if S is nonempty. */{ register char const *sp; register size_t ss; if (delim) aputc(SDELIM, out); sp = s.string; for (ss = s.size; ss; --ss) { if (*sp == SDELIM) aputc(SDELIM, out); aputc(*sp++, out); } if (s.size && log) aputc('\n', out); aputc(SDELIM, out);} intputdftext(num,log,finfile,foutfile,diffmt) char const *num; struct cbuf log; RILE *finfile; FILE *foutfile; int diffmt;/* like putdtext(), except the source file is already open */{ declarecache; register FILE *fout; register int c; register RILE *fin; int ed; struct diffcmd dc; fout = foutfile; aprintf(fout,DELNUMFORM,num,Klog); /* put log */ putstring(fout, true, log, true); /* put text */ aprintf(fout, "\n%s\n%c", Ktext, SDELIM); fin = finfile; setupcache(fin); if (!diffmt) { /* Copy the file */ cache(fin); for (;;) { cachegeteof(c, break;); if (c==SDELIM) aputc(SDELIM,fout); /*double up SDELIM*/ aputc(c,fout); } } else { initdiffcmd(&dc); while (0 <= (ed = getdiffcmd(fin,false,fout,&dc))) if (ed) { cache(fin); while (dc.nlines--) do { cachegeteof(c, { if (!dc.nlines) goto OK_EOF; unexpected_EOF(); }); if (c == SDELIM) aputc(SDELIM,fout); aputc(c,fout); } while (c != '\n'); uncache(fin); } } OK_EOF: aprintf(fout, "%c\n", SDELIM); return true;} voidinitdiffcmd(dc) register struct diffcmd *dc;/* Initialize *dc suitably for getdiffcmd(). */{ dc->adprev = 0; dc->dafter = 0;} static exiting voidbadDiffOutput(buf) char const *buf;{ faterror("bad diff output line: %s", buf);} static exiting voiddiffLineNumberTooLarge(buf) char const *buf;{ faterror("diff line number too large: %s", buf);} intgetdiffcmd(finfile, delimiter, foutfile, dc) RILE *finfile; FILE *foutfile; int delimiter; struct diffcmd *dc;/* Get a editing command output by 'diff -n' from fin. * The input is delimited by SDELIM if delimiter is set, EOF otherwise. * Copy a clean version of the command to fout (if nonnull). * Yield 0 for 'd', 1 for 'a', and -1 for EOF. * Store the command's line number and length into dc->line1 and dc->nlines. * Keep dc->adprev and dc->dafter up to date. */{ register int c; declarecache; register FILE *fout; register char *p; register RILE *fin; unsigned long line1, nlines, t; char buf[BUFSIZ]; fin = finfile; fout = foutfile; setupcache(fin); cache(fin); cachegeteof(c, { if (delimiter) unexpected_EOF(); return -1; } ); if (delimiter) { if (c==SDELIM) { cacheget(c); if (c==SDELIM) { buf[0] = c; buf[1] = 0; badDiffOutput(buf); } uncache(fin); nextc = c; if (fout) aprintf(fout, "%c%c", SDELIM, c); return -1; } } p = buf; do { if (buf+BUFSIZ-2 <= p) { faterror("diff output command line too long"); } *p++ = c; cachegeteof(c, unexpected_EOF();) ; } while (c != '\n'); uncache(fin); if (delimiter) ++rcsline; *p = '\0'; for (p = buf+1; (c = *p++) == ' '; ) ; line1 = 0; while (isdigit(c)) { t = line1 * 10; if ( ULONG_MAX/10 < line1 || (line1 = t + (c - '0')) < t ) diffLineNumberTooLarge(buf); c = *p++; } while (c == ' ') c = *p++; nlines = 0; while (isdigit(c)) { t = nlines * 10; if ( ULONG_MAX/10 < nlines || (nlines = t + (c - '0')) < t ) diffLineNumberTooLarge(buf); c = *p++; } if (c || !nlines) { badDiffOutput(buf); } if (line1+nlines < line1) diffLineNumberTooLarge(buf); switch (buf[0]) { case 'a': if (line1 < dc->adprev) { faterror("backward insertion in diff output: %s", buf); } dc->adprev = line1 + 1; break; case 'd': if (line1 < dc->adprev || line1 < dc->dafter) { faterror("backward deletion in diff output: %s", buf); } dc->adprev = line1; dc->dafter = line1 + nlines; break; default: badDiffOutput(buf); } if (fout) { aprintf(fout, "%s\n", buf); } dc->line1 = line1; dc->nlines = nlines; return buf[0] == 'a';}#ifdef SYNTESTchar const cmdid[] = "syntest"; intmain(argc,argv)int argc; char * argv[];{ 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(); putadmin(stdout); gettree(); puttree(Head,stdout); getdesc(true); nextlex(); if (!eoflex()) { fatserror("expecting EOF"); } exitmain(EXIT_SUCCESS);}exiting void exiterr() { _exit(EXIT_FAILURE); }#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -