📄 rcsedit.c
字号:
* editline is incremented by the number of lines copied. * Assumption: next character read is first string character. */{ register c; declarecache; register FILE *frew, *fcop; register int amidline; register RILE *fin; fin = finptr; setupcache(fin); cache(fin); frew = foutptr; fcop = fcopy; amidline = false; for (;;) { GETC(frew,c); switch (c) { case '\n': ++editline; ++rcsline; amidline = false; break; case SDELIM: GETC(frew,c); if (c != SDELIM) { /* end of string */ nextc = c; editline += amidline; uncache(fin); return; } /* fall into */ default: amidline = true; break; } aputc(c,fcop); }} voidenterstring()/* Like copystring, except the string is put into the edit data structure. */{#if !large_memory editfile = 0; fedit = 0; editline = linecorr = 0; resultfile = maketemp(1); if (!(fcopy = fopen_update_truncate(resultfile))) efaterror(resultfile); copystring();#else register int c; declarecache; register FILE *frew; register unsigned long e, oe; register int amidline, oamidline; register Iptr_type optr; register RILE *fin; e = 0; gap = 0; gapsize = linelim; fin = finptr; setupcache(fin); cache(fin); advise_access(fin, MADV_NORMAL); frew = foutptr; amidline = false; for (;;) { optr = cachetell(); GETC(frew,c); oamidline = amidline; oe = e; switch (c) { case '\n': ++e; ++rcsline; amidline = false; break; case SDELIM: GETC(frew,c); if (c != SDELIM) { /* end of string */ nextc = c; editline = e + amidline; linecorr = 0; uncache(fin); return; } /* fall into */ default: amidline = true; break; } if (!oamidline) insertline(oe, optr); }#endif} void#if large_memoryedit_string()#else editstring(delta) struct hshentry const *delta;#endif/* * Read an edit script from finptr and applies it to the edit file.#if !large_memory * The result is written to fcopy. * If delta!=nil, keyword expansion is performed simultaneously. * If running out of lines in fedit, fedit and fcopy are swapped. * editfile is the name of the file that goes with fedit.#endif * If foutptr is set, the edit script is also copied verbatim to foutptr. * Assumes that all these files are open. * resultfile is the name of the file that goes with fcopy. * Assumes the next input character from finptr is the first character of * the edit script. Resets nextc on exit. */{ int ed; /* editor command */ register int c; declarecache; register FILE *frew;# if !large_memory register FILE *f; unsigned long line_lim = ULONG_MAX; register RILE *fe;# endif register unsigned long i; register RILE *fin;# if large_memory register unsigned long j;# endif struct diffcmd dc; editline += linecorr; linecorr=0; /*correct line number*/ frew = foutptr; fin = finptr; setupcache(fin); initdiffcmd(&dc); while (0 <= (ed = getdiffcmd(fin,true,frew,&dc)))#if !large_memory if (line_lim <= dc.line1) editLineNumberOverflow(); else#endif if (!ed) { copylines(dc.line1-1, delta); /* skip over unwanted lines */ i = dc.nlines; linecorr -= i; editline += i;# if large_memory deletelines(editline+linecorr, i);# else fe = fedit; do { /*skip next line*/ do { Igeteof(fe, c, { if (i!=1) editLineNumberOverflow(); line_lim = dc.dafter; break; } ); } while (c != '\n'); } while (--i);# endif } else { copylines(dc.line1, delta); /*copy only; no delete*/ i = dc.nlines;# if large_memory j = editline+linecorr;# endif linecorr += i;#if !large_memory f = fcopy; if (delta) do { switch (expandline(fin,f,delta,true,frew)) { case 0: case 1: if (i==1) return; /* fall into */ case -1: editEndsPrematurely(); } } while (--i); else#endif { cache(fin); do {# if large_memory insertline(j++, cachetell());# endif for (;;) { GETC(frew, c);# if !large_memory aputc(c, f);# endif if (c == '\n') break; if (c==SDELIM) { GETC(frew, c); if (c!=SDELIM) { if (--i) editEndsPrematurely(); nextc = c; uncache(fin); return; } } } ++rcsline; } while (--i); uncache(fin); } }}/* The rest is for keyword expansion */ intexpandline(infile, outfile, delta, delimstuffed, frewfile) RILE *infile; FILE *outfile, *frewfile; struct hshentry const *delta; int delimstuffed;/* * Read a line from INFILE and write it to OUTFILE. * If DELIMSTUFFED is true, double SDELIM is replaced with single SDELIM. * Keyword expansion is performed with data from delta. * If FREWFILE is set, copy the line unchanged to FREWFILE. * DELIMSTUFFED must be true if FREWFILE is set. * Yields -1 if no data is copied, 0 if an incomplete line is copied, * 2 if a complete line is copied; adds 1 to yield if expansion occurred. */{ register c; declarecache; register FILE *out, *frew; register char * tp; register int e, ds, r; char const *tlim; static struct buf keyval; enum markers matchresult; setupcache(infile); cache(infile); out = outfile; frew = frewfile; ds = delimstuffed; bufalloc(&keyval, keylength+3); e = 0; r = -1; for (;;) { if (ds) { GETC(frew, c); } else cachegeteof(c, goto uncache_exit;); for (;;) { switch (c) { case SDELIM: if (ds) { GETC(frew, c); if (c != SDELIM) { /* end of string */ nextc=c; goto uncache_exit; } } /* fall into */ default: aputc(c,out); r = 0; break; case '\n': rcsline += ds; aputc(c,out); r = 2; goto uncache_exit; case KDELIM: r = 0; /* check for keyword */ /* first, copy a long enough string into keystring */ tp = keyval.string; *tp++ = KDELIM; for (;;) { if (ds) { GETC(frew, c); } else cachegeteof(c, goto keystring_eof;); if (tp < keyval.string+keylength+1) switch (ctab[c]) { case LETTER: case Letter: *tp++ = c; continue; default: break; } break; } *tp++ = c; *tp = '\0'; matchresult = trymatch(keyval.string+1); if (matchresult==Nomatch) { tp[-1] = 0; aputs(keyval.string, out); continue; /* last c handled properly */ } /* Now we have a keyword terminated with a K/VDELIM */ if (c==VDELIM) { /* try to find closing KDELIM, and replace value */ tlim = keyval.string + keyval.size; for (;;) { if (ds) { GETC(frew, c); } else cachegeteof(c, goto keystring_eof;); if (c=='\n' || c==KDELIM) break; *tp++ =c; if (tlim <= tp) tp = bufenlarge(&keyval, &tlim); if (c==SDELIM && ds) { /*skip next SDELIM */ GETC(frew, c); if (c != SDELIM) { /* end of string before closing KDELIM or newline */ nextc = c; goto keystring_eof; } } } if (c!=KDELIM) { /* couldn't find closing KDELIM -- give up */ *tp = 0; aputs(keyval.string, out); continue; /* last c handled properly */ } } /* now put out the new keyword value */ keyreplace(matchresult,delta,out); e = 1; break; } break; } } keystring_eof: *tp = 0; aputs(keyval.string, out); uncache_exit: uncache(infile); return r + e;}char const ciklog[ciklogsize] = "checked in with -k by "; static voidkeyreplace(marker,delta,out) enum markers marker; register struct hshentry const *delta; register FILE *out;/* function: outputs the keyword value(s) corresponding to marker. * Attributes are derived from delta. */{ register char const *sp, *cp, *date; register char c; register size_t cs, cw, ls; char const *sp1; char datebuf[datesize]; int RCSv; sp = Keyword[(int)marker]; if (Expand == KEY_EXPAND) { aprintf(out, "%c%s%c", KDELIM, sp, KDELIM); return; } date= delta->date; RCSv = RCSversion; if (Expand == KEYVAL_EXPAND || Expand == KEYVALLOCK_EXPAND) aprintf(out, "%c%s%c%c", KDELIM, sp, VDELIM, marker==Log && RCSv<VERSION(5) ? '\t' : ' ' ); switch (marker) { case Author: aputs(delta->author, out); break; case Date: aputs(date2str(date,datebuf), out); break; case Id: case Header: aprintf(out, "%s %s %s %s %s", marker==Id || RCSv<VERSION(4) ? basename(RCSfilename) : getfullRCSname(), delta->num, date2str(date, datebuf), delta->author, RCSv==VERSION(3) && delta->lockedby ? "Locked" : delta->state ); if (delta->lockedby!=nil) if (VERSION(5) <= RCSv) { if (locker_expansion || Expand==KEYVALLOCK_EXPAND) aprintf(out, " %s", delta->lockedby); } else if (RCSv == VERSION(4)) aprintf(out, " Locker: %s", delta->lockedby); break; case Locker: if (delta->lockedby) if ( locker_expansion || Expand == KEYVALLOCK_EXPAND || RCSv <= VERSION(4) ) aputs(delta->lockedby, out); break; case Log: case RCSfile: aputs(basename(RCSfilename), out); break; case Revision: aputs(delta->num, out); break; case Source: aputs(getfullRCSname(), out); break; case State: aputs(delta->state, out); break; default: break; } if (Expand == KEYVAL_EXPAND || Expand == KEYVALLOCK_EXPAND) { afputc(' ', out); afputc(KDELIM, out); } if (marker == Log) { sp = delta->log.string; ls = delta->log.size; if (sizeof(ciklog)-1<=ls && !memcmp(sp,ciklog,sizeof(ciklog)-1)) return; afputc('\n', out); cp = Comment.string; cw = cs = Comment.size; awrite(cp, cs, out); /* oddity: 2 spaces between date and time, not 1 as usual */ sp1 = strchr(date2str(date,datebuf), ' '); aprintf(out, "Revision %s %.*s %s %s", delta->num, (int)(sp1-datebuf), datebuf, sp1, delta->author ); /* Do not include state: it may change and is not updated. */ /* Comment is the comment leader. */ if (VERSION(5) <= RCSv) for (; cw && (cp[cw-1]==' ' || cp[cw-1]=='\t'); --cw) ; for (;;) { afputc('\n', out); awrite(cp, cw, out); if (!ls) break; --ls; c = *sp++; if (c != '\n') { awrite(cp+cw, cs-cw, out); do { afputc(c,out); if (!ls) break; --ls; c = *sp++; } while (c != '\n'); } } }}#if has_readlink static intresolve_symlink(L) struct buf *L;/* * If L is a symbolic link, resolve it to the name that it points to. * If unsuccessful, set errno and yield -1. * If it points to an existing file, yield 1. * Otherwise, set errno=ENOENT and yield 0. */{ char *b, a[SIZEABLE_PATH]; int e; size_t s; ssize_t r; struct buf bigbuf; unsigned linkcount = MAXSYMLINKS + 1; b = a; s = sizeof(a); bufautobegin(&bigbuf); while ((r = readlink(L->string,b,s)) != -1) if (r == s) { bufalloc(&bigbuf, s<<1); b = bigbuf.string; s = bigbuf.size; } else if (!--linkcount) { errno = ELOOP; return -1; } else { /* Splice symbolic link into L. */ b[r] = '\0'; L->string[ROOTPATH(b) ? (size_t)0 : dirlen(L->string)] = '\0'; bufscat(L, b); } e = errno; bufautoend(&bigbuf); errno = e; switch (e) { case ENXIO: case EINVAL: return 1; case ENOENT: return 0; default: return -1; }}#endif RILE *rcswriteopen(RCSbuf, status, mustread) struct buf *RCSbuf; struct stat *status; int mustread;/* * Create the lock file corresponding to RCSNAME. * Then try to open RCSNAME for reading and yield its FILE* descriptor. * Put its status into *STATUS too. * MUSTREAD is true if the file must already exist, too.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -