aboutsummaryrefslogtreecommitdiff
path: root/gnu/usr.bin/rcs/rlog/rlog.c
diff options
context:
space:
mode:
Diffstat (limited to 'gnu/usr.bin/rcs/rlog/rlog.c')
-rw-r--r--gnu/usr.bin/rcs/rlog/rlog.c1290
1 files changed, 0 insertions, 1290 deletions
diff --git a/gnu/usr.bin/rcs/rlog/rlog.c b/gnu/usr.bin/rcs/rlog/rlog.c
deleted file mode 100644
index f8872febb971..000000000000
--- a/gnu/usr.bin/rcs/rlog/rlog.c
+++ /dev/null
@@ -1,1290 +0,0 @@
-/* Print log messages and other information about RCS files. */
-
-/* Copyright 1982, 1988, 1989 Walter Tichy
- Copyright 1990, 1991, 1992, 1993, 1994, 1995 Paul Eggert
- Distributed under license by the Free Software Foundation, Inc.
-
-This file is part of RCS.
-
-RCS is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2, or (at your option)
-any later version.
-
-RCS is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with RCS; see the file COPYING.
-If not, write to the Free Software Foundation,
-59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-Report problems and direct all questions to:
-
- rcs-bugs@cs.purdue.edu
-
-*/
-
-/*
- * Revision 5.18 1995/06/16 06:19:24 eggert
- * Update FSF address.
- *
- * Revision 5.17 1995/06/01 16:23:43 eggert
- * (struct rcslockers): Renamed from `struct lockers'.
- * (getnumericrev): Return error indication instead of ignoring errors.
- * (main): Check it. Don't use dateform.
- * (recentdate, extdate): cmpnum -> cmpdate
- *
- * Revision 5.16 1994/04/13 16:30:34 eggert
- * Fix bug; `rlog -lxxx' inverted the sense of -l.
- *
- * Revision 5.15 1994/03/17 14:05:48 eggert
- * -d'<DATE' now excludes DATE; the new syntax -d'<=DATE' includes it.
- * Emulate -V4's white space generation more precisely.
- * Work around SVR4 stdio performance bug. Remove lint.
- *
- * Revision 5.14 1993/11/09 17:40:15 eggert
- * -V now prints version on stdout and exits.
- *
- * Revision 5.13 1993/11/03 17:42:27 eggert
- * Add -N, -z. Ignore -T.
- *
- * Revision 5.12 1992/07/28 16:12:44 eggert
- * Don't miss B.0 when handling branch B. Diagnose missing `,' in -r.
- * Add -V. Avoid `unsigned'. Statement macro names now end in _.
- *
- * Revision 5.11 1992/01/24 18:44:19 eggert
- * Don't duplicate unexpected_EOF's function. lint -> RCS_lint
- *
- * Revision 5.10 1992/01/06 02:42:34 eggert
- * Update usage string.
- * while (E) ; -> while (E) continue;
- *
- * Revision 5.9 1991/09/17 19:07:40 eggert
- * Getscript() didn't uncache partial lines.
- *
- * Revision 5.8 1991/08/19 03:13:55 eggert
- * Revision separator is `:', not `-'.
- * Check for missing and duplicate logs. Tune.
- * Permit log messages that do not end in newline (including empty logs).
- *
- * Revision 5.7 1991/04/21 11:58:31 eggert
- * Add -x, RCSINIT, MS-DOS support.
- *
- * Revision 5.6 1991/02/26 17:07:17 eggert
- * Survive RCS files with missing logs.
- * strsave -> str_save (DG/UX name clash)
- *
- * Revision 5.5 1990/11/01 05:03:55 eggert
- * Permit arbitrary data in logs and comment leaders.
- *
- * Revision 5.4 1990/10/04 06:30:22 eggert
- * Accumulate exit status across files.
- *
- * Revision 5.3 1990/09/11 02:41:16 eggert
- * Plug memory leak.
- *
- * Revision 5.2 1990/09/04 08:02:33 eggert
- * Count RCS lines better.
- *
- * Revision 5.0 1990/08/22 08:13:48 eggert
- * Remove compile-time limits; use malloc instead. Add setuid support.
- * Switch to GMT.
- * Report dates in long form, to warn about dates past 1999/12/31.
- * Change "added/del" message to make room for the longer dates.
- * Don't generate trailing white space. Add -V. Ansify and Posixate.
- *
- * Revision 4.7 89/05/01 15:13:48 narten
- * changed copyright header to reflect current distribution rules
- *
- * Revision 4.6 88/08/09 19:13:28 eggert
- * Check for memory exhaustion; don't access freed storage.
- * Shrink stdio code size; remove lint.
- *
- * Revision 4.5 87/12/18 11:46:38 narten
- * more lint cleanups (Guy Harris)
- *
- * Revision 4.4 87/10/18 10:41:12 narten
- * Updating version numbers
- * Changes relative to 1.1 actually relative to 4.2
- *
- * Revision 1.3 87/09/24 14:01:10 narten
- * Sources now pass through lint (if you ignore printf/sprintf/fprintf
- * warnings)
- *
- * Revision 1.2 87/03/27 14:22:45 jenkins
- * Port to suns
- *
- * Revision 4.2 83/12/05 09:18:09 wft
- * changed rewriteflag to external.
- *
- * Revision 4.1 83/05/11 16:16:55 wft
- * Added -b, updated getnumericrev() accordingly.
- * Replaced getpwuid() with getcaller().
- *
- * Revision 3.7 83/05/11 14:24:13 wft
- * Added options -L and -R;
- * Fixed selection bug with -l on multiple files.
- * Fixed error on dates of the form -d'>date' (rewrote getdatepair()).
- *
- * Revision 3.6 82/12/24 15:57:53 wft
- * shortened output format.
- *
- * Revision 3.5 82/12/08 21:45:26 wft
- * removed call to checkaccesslist(); used DATEFORM to format all dates;
- * removed unused variables.
- *
- * Revision 3.4 82/12/04 13:26:25 wft
- * Replaced getdelta() with gettree(); removed updating of field lockedby.
- *
- * Revision 3.3 82/12/03 14:08:20 wft
- * Replaced getlogin with getpwuid(), %02d with %.2d, fancydate with PRINTDATE.
- * Fixed printing of nil, removed printing of Suffix,
- * added shortcut if no revisions are printed, disambiguated struct members.
- *
- * Revision 3.2 82/10/18 21:09:06 wft
- * call to curdir replaced with getfullRCSname(),
- * fixed call to getlogin(), cosmetic changes on output,
- * changed conflicting long identifiers.
- *
- * Revision 3.1 82/10/13 16:07:56 wft
- * fixed type of variables receiving from getc() (char -> int).
- */
-
-
-
-#include "rcsbase.h"
-
-struct rcslockers { /* lockers in locker option; stored */
- char const * login; /* lockerlist */
- struct rcslockers * lockerlink;
- } ;
-
-struct stateattri { /* states in state option; stored in */
- char const * status; /* statelist */
- struct stateattri * nextstate;
- } ;
-
-struct authors { /* login names in author option; */
- char const * login; /* stored in authorlist */
- struct authors * nextauthor;
- } ;
-
-struct Revpairs{ /* revision or branch range in -r */
- int numfld; /* option; stored in revlist */
- char const * strtrev;
- char const * endrev;
- struct Revpairs * rnext;
- } ;
-
-struct Datepairs{ /* date range in -d option; stored in */
- struct Datepairs *dnext;
- char strtdate[datesize]; /* duelst and datelist */
- char enddate[datesize];
- char ne_date; /* datelist only; distinguishes < from <= */
- };
-
-static char extractdelta P((struct hshentry const*));
-static int checkrevpair P((char const*,char const*));
-static int extdate P((struct hshentry*));
-static int getnumericrev P((void));
-static struct hshentry const *readdeltalog P((void));
-static void cleanup P((void));
-static void exttree P((struct hshentry*));
-static void getauthor P((char*));
-static void getdatepair P((char*));
-static void getlocker P((char*));
-static void getrevpairs P((char*));
-static void getscript P((struct hshentry*));
-static void getstate P((char*));
-static void putabranch P((struct hshentry const*));
-static void putadelta P((struct hshentry const*,struct hshentry const*,int));
-static void putforest P((struct branchhead const*));
-static void putree P((struct hshentry const*));
-static void putrunk P((void));
-static void recentdate P((struct hshentry const*,struct Datepairs*));
-static void trunclocks P((void));
-
-static char const *insDelFormat;
-static int branchflag; /*set on -b */
-static int exitstatus;
-static int lockflag;
-static struct Datepairs *datelist, *duelst;
-static struct Revpairs *revlist, *Revlst;
-static struct authors *authorlist;
-static struct rcslockers *lockerlist;
-static struct stateattri *statelist;
-
-
-mainProg(rlogId, "rlog", "$FreeBSD$")
-{
- static char const cmdusage[] =
- "\nrlog usage: rlog -{bhLNRt} -v[string] -ddates -l[lockers] -r[revs] -sstates -Vn -w[logins] -xsuff -zzone file ...";
-
- register FILE *out;
- char *a, **newargv;
- struct Datepairs *currdate;
- char const *accessListString, *accessFormat;
- char const *headFormat, *symbolFormat;
- struct access const *curaccess;
- struct assoc const *curassoc;
- struct hshentry const *delta;
- struct rcslock const *currlock;
- int descflag, selectflag;
- int onlylockflag; /* print only files with locks */
- int onlyRCSflag; /* print only RCS pathname */
- int pre5;
- int shownames;
- int revno;
- int versionlist;
- char *vstring;
-
- descflag = selectflag = shownames = true;
- versionlist = onlylockflag = onlyRCSflag = false;
- vstring=0;
- out = stdout;
- suffixes = X_DEFAULT;
-
- argc = getRCSINIT(argc, argv, &newargv);
- argv = newargv;
- while (a = *++argv, 0<--argc && *a++=='-') {
- switch (*a++) {
-
- case 'L':
- onlylockflag = true;
- break;
-
- case 'N':
- shownames = false;
- break;
-
- case 'R':
- onlyRCSflag =true;
- break;
-
- case 'l':
- lockflag = true;
- getlocker(a);
- break;
-
- case 'b':
- branchflag = true;
- break;
-
- case 'r':
- getrevpairs(a);
- break;
-
- case 'd':
- getdatepair(a);
- break;
-
- case 's':
- getstate(a);
- break;
-
- case 'w':
- getauthor(a);
- break;
-
- case 'h':
- descflag = false;
- break;
-
- case 't':
- selectflag = false;
- break;
-
- case 'q':
- /* This has no effect; it's here for consistency. */
- quietflag = true;
- break;
-
- case 'x':
- suffixes = a;
- break;
-
- case 'z':
- zone_set(a);
- break;
-
- case 'T':
- /* Ignore -T, so that RCSINIT can contain -T. */
- if (*a)
- goto unknown;
- break;
-
- case 'V':
- setRCSversion(*argv);
- break;
-
- case 'v':
- versionlist = true;
- vstring = a;
- break;
-
- default:
- unknown:
- error("unknown option: %s%s", *argv, cmdusage);
-
- };
- } /* end of option processing */
-
- if (! (descflag|selectflag)) {
- warn("-t overrides -h.");
- descflag = true;
- }
-
- pre5 = RCSversion < VERSION(5);
- if (pre5) {
- accessListString = "\naccess list: ";
- accessFormat = " %s";
- headFormat = "RCS file: %s; Working file: %s\nhead: %s%s\nbranch: %s%s\nlocks: ";
- insDelFormat = " lines added/del: %ld/%ld";
- symbolFormat = " %s: %s;";
- } else {
- accessListString = "\naccess list:";
- accessFormat = "\n\t%s";
- headFormat = "RCS file: %s\nWorking file: %s\nhead:%s%s\nbranch:%s%s\nlocks:%s";
- insDelFormat = " lines: +%ld -%ld";
- symbolFormat = "\n\t%s: %s";
- }
-
- /* Now handle all pathnames. */
- if (nerror)
- cleanup();
- else if (argc < 1)
- faterror("no input file%s", cmdusage);
- else
- for (; 0 < argc; cleanup(), ++argv, --argc) {
- ffree();
-
- if (pairnames(argc, argv, rcsreadopen, true, false) <= 0)
- continue;
-
- /*
- * RCSname contains the name of the RCS file,
- * and finptr the file descriptor;
- * workname contains the name of the working file.
- */
-
- /* Keep only those locks given by -l. */
- if (lockflag)
- trunclocks();
-
- /* do nothing if -L is given and there are no locks*/
- if (onlylockflag && !Locks)
- continue;
-
- if ( versionlist ) {
- gettree();
- aprintf(out, "%s%s %s\n", vstring, workname, tiprev());
- continue;
- }
-
- if ( onlyRCSflag ) {
- aprintf(out, "%s\n", RCSname);
- continue;
- }
-
- gettree();
-
- if (!getnumericrev())
- continue;
-
- /*
- * Output the first character with putc, not printf.
- * Otherwise, an SVR4 stdio bug buffers output inefficiently.
- */
- aputc_('\n', out)
-
- /* print RCS pathname, working pathname and optional
- administrative information */
- /* could use getfullRCSname() here, but that is very slow */
- aprintf(out, headFormat, RCSname, workname,
- Head ? " " : "", Head ? Head->num : "",
- Dbranch ? " " : "", Dbranch ? Dbranch : "",
- StrictLocks ? " strict" : ""
- );
- currlock = Locks;
- while( currlock ) {
- aprintf(out, symbolFormat, currlock->login,
- currlock->delta->num);
- currlock = currlock->nextlock;
- }
- if (StrictLocks && pre5)
- aputs(" ; strict" + (Locks?3:0), out);
-
- aputs(accessListString, out); /* print access list */
- curaccess = AccessList;
- while(curaccess) {
- aprintf(out, accessFormat, curaccess->login);
- curaccess = curaccess->nextaccess;
- }
-
- if (shownames) {
- aputs("\nsymbolic names:", out); /* print symbolic names */
- for (curassoc=Symbols; curassoc; curassoc=curassoc->nextassoc)
- aprintf(out, symbolFormat, curassoc->symbol, curassoc->num);
- }
- if (pre5) {
- aputs("\ncomment leader: \"", out);
- awrite(Comment.string, Comment.size, out);
- afputc('\"', out);
- }
- if (!pre5 || Expand != KEYVAL_EXPAND)
- aprintf(out, "\nkeyword substitution: %s",
- expand_names[Expand]
- );
-
- aprintf(out, "\ntotal revisions: %d", TotalDeltas);
-
- revno = 0;
-
- if (Head && selectflag & descflag) {
-
- exttree(Head);
-
- /* get most recently date of the dates pointed by duelst */
- currdate = duelst;
- while( currdate) {
- VOID strcpy(currdate->strtdate, "0.0.0.0.0.0");
- recentdate(Head, currdate);
- currdate = currdate->dnext;
- }
-
- revno = extdate(Head);
-
- aprintf(out, ";\tselected revisions: %d", revno);
- }
-
- afputc('\n',out);
- if (descflag) {
- aputs("description:\n", out);
- getdesc(true);
- }
- if (revno) {
- while (! (delta = readdeltalog())->selector || --revno)
- continue;
- if (delta->next && countnumflds(delta->num)==2)
- /* Read through delta->next to get its insertlns. */
- while (readdeltalog() != delta->next)
- continue;
- putrunk();
- putree(Head);
- }
- aputs("----------------------------\n", out);
- aputs("=============================================================================\n",out);
- }
- Ofclose(out);
- exitmain(exitstatus);
-}
-
- static void
-cleanup()
-{
- if (nerror) exitstatus = EXIT_FAILURE;
- Izclose(&finptr);
-}
-
-#if RCS_lint
-# define exiterr rlogExit
-#endif
- void
-exiterr()
-{
- _exit(EXIT_FAILURE);
-}
-
-
-
- static void
-putrunk()
-/* function: print revisions chosen, which are in trunk */
-
-{
- register struct hshentry const *ptr;
-
- for (ptr = Head; ptr; ptr = ptr->next)
- putadelta(ptr, ptr->next, true);
-}
-
-
-
- static void
-putree(root)
- struct hshentry const *root;
-/* function: print delta tree (not including trunk) in reverse
- order on each branch */
-
-{
- if (!root) return;
-
- putree(root->next);
-
- putforest(root->branches);
-}
-
-
-
-
- static void
-putforest(branchroot)
- struct branchhead const *branchroot;
-/* function: print branches that has the same direct ancestor */
-{
- if (!branchroot) return;
-
- putforest(branchroot->nextbranch);
-
- putabranch(branchroot->hsh);
- putree(branchroot->hsh);
-}
-
-
-
-
- static void
-putabranch(root)
- struct hshentry const *root;
-/* function : print one branch */
-
-{
- if (!root) return;
-
- putabranch(root->next);
-
- putadelta(root, root, false);
-}
-
-
-
-
-
- static void
-putadelta(node,editscript,trunk)
- register struct hshentry const *node, *editscript;
- int trunk;
-/* function: Print delta node if node->selector is set. */
-/* editscript indicates where the editscript is stored */
-/* trunk indicated whether this node is in trunk */
-{
- static char emptych[] = EMPTYLOG;
-
- register FILE *out;
- char const *s;
- size_t n;
- struct branchhead const *newbranch;
- struct buf branchnum;
- char datebuf[datesize + zonelenmax];
- int pre5 = RCSversion < VERSION(5);
-
- if (!node->selector)
- return;
-
- out = stdout;
- aprintf(out,
- "----------------------------\nrevision %s%s",
- node->num, pre5 ? " " : ""
- );
- if ( node->lockedby )
- aprintf(out, pre5+"\tlocked by: %s;", node->lockedby);
-
- aprintf(out, "\ndate: %s; author: %s; state: %s;",
- date2str(node->date, datebuf),
- node->author, node->state
- );
-
- if ( editscript )
- if(trunk)
- aprintf(out, insDelFormat,
- editscript->deletelns, editscript->insertlns);
- else
- aprintf(out, insDelFormat,
- editscript->insertlns, editscript->deletelns);
-
- newbranch = node->branches;
- if ( newbranch ) {
- bufautobegin(&branchnum);
- aputs("\nbranches:", out);
- while( newbranch ) {
- getbranchno(newbranch->hsh->num, &branchnum);
- aprintf(out, " %s;", branchnum.string);
- newbranch = newbranch->nextbranch;
- }
- bufautoend(&branchnum);
- }
-
- afputc('\n', out);
- s = node->log.string;
- if (!(n = node->log.size)) {
- s = emptych;
- n = sizeof(emptych)-1;
- }
- awrite(s, n, out);
- if (s[n-1] != '\n')
- afputc('\n', out);
-}
-
-
- static struct hshentry const *
-readdeltalog()
-/* Function : get the log message and skip the text of a deltatext node.
- * Return the delta found.
- * Assumes the current lexeme is not yet in nexttok; does not
- * advance nexttok.
- */
-{
- register struct hshentry * Delta;
- struct buf logbuf;
- struct cbuf cb;
-
- if (eoflex())
- fatserror("missing delta log");
- nextlex();
- if (!(Delta = getnum()))
- fatserror("delta number corrupted");
- getkeystring(Klog);
- if (Delta->log.string)
- fatserror("duplicate delta log");
- bufautobegin(&logbuf);
- cb = savestring(&logbuf);
- Delta->log = bufremember(&logbuf, cb.size);
-
- ignorephrases(Ktext);
- getkeystring(Ktext);
- Delta->insertlns = Delta->deletelns = 0;
- if ( Delta != Head)
- getscript(Delta);
- else
- readstring();
- return Delta;
-}
-
-
- static void
-getscript(Delta)
-struct hshentry * Delta;
-/* function: read edit script of Delta and count how many lines added */
-/* and deleted in the script */
-
-{
- int ed; /* editor command */
- declarecache;
- register RILE *fin;
- register int c;
- register long i;
- struct diffcmd dc;
-
- fin = finptr;
- setupcache(fin);
- initdiffcmd(&dc);
- while (0 <= (ed = getdiffcmd(fin,true,(FILE *)0,&dc)))
- if (!ed)
- Delta->deletelns += dc.nlines;
- else {
- /* skip scripted lines */
- i = dc.nlines;
- Delta->insertlns += i;
- cache(fin);
- do {
- for (;;) {
- cacheget_(c)
- switch (c) {
- default:
- continue;
- case SDELIM:
- cacheget_(c)
- if (c == SDELIM)
- continue;
- if (--i)
- unexpected_EOF();
- nextc = c;
- uncache(fin);
- return;
- case '\n':
- break;
- }
- break;
- }
- ++rcsline;
- } while (--i);
- uncache(fin);
- }
-}
-
-
-
-
-
-
-
- static void
-exttree(root)
-struct hshentry *root;
-/* function: select revisions , starting with root */
-
-{
- struct branchhead const *newbranch;
-
- if (!root) return;
-
- root->selector = extractdelta(root);
- root->log.string = 0;
- exttree(root->next);
-
- newbranch = root->branches;
- while( newbranch ) {
- exttree(newbranch->hsh);
- newbranch = newbranch->nextbranch;
- }
-}
-
-
-
-
- static void
-getlocker(argv)
-char * argv;
-/* function : get the login names of lockers from command line */
-/* and store in lockerlist. */
-
-{
- register char c;
- struct rcslockers *newlocker;
- argv--;
- while ((c = *++argv)==',' || c==' ' || c=='\t' || c=='\n' || c==';')
- continue;
- if ( c == '\0') {
- lockerlist = 0;
- return;
- }
-
- while( c != '\0' ) {
- newlocker = talloc(struct rcslockers);
- newlocker->lockerlink = lockerlist;
- newlocker->login = argv;
- lockerlist = newlocker;
- while ((c = *++argv) && c!=',' && c!=' ' && c!='\t' && c!='\n' && c!=';')
- continue;
- *argv = '\0';
- if ( c == '\0' ) return;
- while ((c = *++argv)==',' || c==' ' || c=='\t' || c=='\n' || c==';')
- continue;
- }
-}
-
-
-
- static void
-getauthor(argv)
-char *argv;
-/* function: get the author's name from command line */
-/* and store in authorlist */
-
-{
- register c;
- struct authors * newauthor;
-
- argv--;
- while ((c = *++argv)==',' || c==' ' || c=='\t' || c=='\n' || c==';')
- continue;
- if ( c == '\0' ) {
- authorlist = talloc(struct authors);
- authorlist->login = getusername(false);
- authorlist->nextauthor = 0;
- return;
- }
-
- while( c != '\0' ) {
- newauthor = talloc(struct authors);
- newauthor->nextauthor = authorlist;
- newauthor->login = argv;
- authorlist = newauthor;
- while ((c = *++argv) && c!=',' && c!=' ' && c!='\t' && c!='\n' && c!=';')
- continue;
- * argv = '\0';
- if ( c == '\0') return;
- while ((c = *++argv)==',' || c==' ' || c=='\t' || c=='\n' || c==';')
- continue;
- }
-}
-
-
-
-
- static void
-getstate(argv)
-char * argv;
-/* function : get the states of revisions from command line */
-/* and store in statelist */
-
-{
- register char c;
- struct stateattri *newstate;
-
- argv--;
- while ((c = *++argv)==',' || c==' ' || c=='\t' || c=='\n' || c==';')
- continue;
- if ( c == '\0'){
- error("missing state attributes after -s options");
- return;
- }
-
- while( c != '\0' ) {
- newstate = talloc(struct stateattri);
- newstate->nextstate = statelist;
- newstate->status = argv;
- statelist = newstate;
- while ((c = *++argv) && c!=',' && c!=' ' && c!='\t' && c!='\n' && c!=';')
- continue;
- *argv = '\0';
- if ( c == '\0' ) return;
- while ((c = *++argv)==',' || c==' ' || c=='\t' || c=='\n' || c==';')
- continue;
- }
-}
-
-
-
- static void
-trunclocks()
-/* Function: Truncate the list of locks to those that are held by the */
-/* id's on lockerlist. Do not truncate if lockerlist empty. */
-
-{
- struct rcslockers const *plocker;
- struct rcslock *p, **pp;
-
- if (!lockerlist) return;
-
- /* shorten Locks to those contained in lockerlist */
- for (pp = &Locks; (p = *pp); )
- for (plocker = lockerlist; ; )
- if (strcmp(plocker->login, p->login) == 0) {
- pp = &p->nextlock;
- break;
- } else if (!(plocker = plocker->lockerlink)) {
- *pp = p->nextlock;
- break;
- }
-}
-
-
-
- static void
-recentdate(root, pd)
- struct hshentry const *root;
- struct Datepairs *pd;
-/* function: Finds the delta that is closest to the cutoff date given by */
-/* pd among the revisions selected by exttree. */
-/* Successively narrows down the interval given by pd, */
-/* and sets the strtdate of pd to the date of the selected delta */
-{
- struct branchhead const *newbranch;
-
- if (!root) return;
- if (root->selector) {
- if ( cmpdate(root->date, pd->strtdate) >= 0 &&
- cmpdate(root->date, pd->enddate) <= 0)
- VOID strcpy(pd->strtdate, root->date);
- }
-
- recentdate(root->next, pd);
- newbranch = root->branches;
- while( newbranch) {
- recentdate(newbranch->hsh, pd);
- newbranch = newbranch->nextbranch;
- }
-}
-
-
-
-
-
-
- static int
-extdate(root)
-struct hshentry * root;
-/* function: select revisions which are in the date range specified */
-/* in duelst and datelist, start at root */
-/* Yield number of revisions selected, including those already selected. */
-{
- struct branchhead const *newbranch;
- struct Datepairs const *pdate;
- int revno, ne;
-
- if (!root)
- return 0;
-
- if ( datelist || duelst) {
- pdate = datelist;
- while( pdate ) {
- ne = pdate->ne_date;
- if (
- (!pdate->strtdate[0]
- || ne <= cmpdate(root->date, pdate->strtdate))
- &&
- (!pdate->enddate[0]
- || ne <= cmpdate(pdate->enddate, root->date))
- )
- break;
- pdate = pdate->dnext;
- }
- if (!pdate) {
- pdate = duelst;
- for (;;) {
- if (!pdate) {
- root->selector = false;
- break;
- }
- if (cmpdate(root->date, pdate->strtdate) == 0)
- break;
- pdate = pdate->dnext;
- }
- }
- }
- revno = root->selector + extdate(root->next);
-
- newbranch = root->branches;
- while( newbranch ) {
- revno += extdate(newbranch->hsh);
- newbranch = newbranch->nextbranch;
- }
- return revno;
-}
-
-
-
- static char
-extractdelta(pdelta)
- struct hshentry const *pdelta;
-/* function: compare information of pdelta to the authorlist, lockerlist,*/
-/* statelist, revlist and yield true if pdelta is selected. */
-
-{
- struct rcslock const *plock;
- struct stateattri const *pstate;
- struct authors const *pauthor;
- struct Revpairs const *prevision;
- int length;
-
- if ((pauthor = authorlist)) /* only certain authors wanted */
- while (strcmp(pauthor->login, pdelta->author) != 0)
- if (!(pauthor = pauthor->nextauthor))
- return false;
- if ((pstate = statelist)) /* only certain states wanted */
- while (strcmp(pstate->status, pdelta->state) != 0)
- if (!(pstate = pstate->nextstate))
- return false;
- if (lockflag) /* only locked revisions wanted */
- for (plock = Locks; ; plock = plock->nextlock)
- if (!plock)
- return false;
- else if (plock->delta == pdelta)
- break;
- if ((prevision = Revlst)) /* only certain revs or branches wanted */
- for (;;) {
- length = prevision->numfld;
- if (
- countnumflds(pdelta->num) == length+(length&1) &&
- 0 <= compartial(pdelta->num, prevision->strtrev, length) &&
- 0 <= compartial(prevision->endrev, pdelta->num, length)
- )
- break;
- if (!(prevision = prevision->rnext))
- return false;
- }
- return true;
-}
-
-
-
- static void
-getdatepair(argv)
- char * argv;
-/* function: get time range from command line and store in datelist if */
-/* a time range specified or in duelst if a time spot specified */
-
-{
- register char c;
- struct Datepairs * nextdate;
- char const * rawdate;
- int switchflag;
-
- argv--;
- while ((c = *++argv)==',' || c==' ' || c=='\t' || c=='\n' || c==';')
- continue;
- if ( c == '\0' ) {
- error("missing date/time after -d");
- return;
- }
-
- while( c != '\0' ) {
- switchflag = false;
- nextdate = talloc(struct Datepairs);
- if ( c == '<' ) { /* case: -d <date */
- c = *++argv;
- if (!(nextdate->ne_date = c!='='))
- c = *++argv;
- (nextdate->strtdate)[0] = '\0';
- } else if (c == '>') { /* case: -d'>date' */
- c = *++argv;
- if (!(nextdate->ne_date = c!='='))
- c = *++argv;
- (nextdate->enddate)[0] = '\0';
- switchflag = true;
- } else {
- rawdate = argv;
- while( c != '<' && c != '>' && c != ';' && c != '\0')
- c = *++argv;
- *argv = '\0';
- if ( c == '>' ) switchflag=true;
- str2date(rawdate,
- switchflag ? nextdate->enddate : nextdate->strtdate);
- if ( c == ';' || c == '\0') { /* case: -d date */
- VOID strcpy(nextdate->enddate,nextdate->strtdate);
- nextdate->dnext = duelst;
- duelst = nextdate;
- goto end;
- } else {
- /* case: -d date< or -d date>; see switchflag */
- int eq = argv[1]=='=';
- nextdate->ne_date = !eq;
- argv += eq;
- while ((c = *++argv) == ' ' || c=='\t' || c=='\n')
- continue;
- if ( c == ';' || c == '\0') {
- /* second date missing */
- if (switchflag)
- *nextdate->strtdate= '\0';
- else
- *nextdate->enddate= '\0';
- nextdate->dnext = datelist;
- datelist = nextdate;
- goto end;
- }
- }
- }
- rawdate = argv;
- while( c != '>' && c != '<' && c != ';' && c != '\0')
- c = *++argv;
- *argv = '\0';
- str2date(rawdate,
- switchflag ? nextdate->strtdate : nextdate->enddate);
- nextdate->dnext = datelist;
- datelist = nextdate;
- end:
- if (RCSversion < VERSION(5))
- nextdate->ne_date = 0;
- if ( c == '\0') return;
- while ((c = *++argv) == ';' || c == ' ' || c == '\t' || c =='\n')
- continue;
- }
-}
-
-
-
- static int
-getnumericrev()
-/* function: get the numeric name of revisions which stored in revlist */
-/* and then stored the numeric names in Revlst */
-/* if branchflag, also add default branch */
-
-{
- struct Revpairs * ptr, *pt;
- int n;
- struct buf s, e;
- char const *lrev;
- struct buf const *rstart, *rend;
-
- Revlst = 0;
- ptr = revlist;
- bufautobegin(&s);
- bufautobegin(&e);
- while( ptr ) {
- n = 0;
- rstart = &s;
- rend = &e;
-
- switch (ptr->numfld) {
-
- case 1: /* -rREV */
- if (!expandsym(ptr->strtrev, &s))
- goto freebufs;
- rend = &s;
- n = countnumflds(s.string);
- if (!n && (lrev = tiprev())) {
- bufscpy(&s, lrev);
- n = countnumflds(lrev);
- }
- break;
-
- case 2: /* -rREV: */
- if (!expandsym(ptr->strtrev, &s))
- goto freebufs;
- bufscpy(&e, s.string);
- n = countnumflds(s.string);
- (n<2 ? e.string : strrchr(e.string,'.'))[0] = 0;
- break;
-
- case 3: /* -r:REV */
- if (!expandsym(ptr->endrev, &e))
- goto freebufs;
- if ((n = countnumflds(e.string)) < 2)
- bufscpy(&s, ".0");
- else {
- bufscpy(&s, e.string);
- VOID strcpy(strrchr(s.string,'.'), ".0");
- }
- break;
-
- default: /* -rREV1:REV2 */
- if (!(
- expandsym(ptr->strtrev, &s)
- && expandsym(ptr->endrev, &e)
- && checkrevpair(s.string, e.string)
- ))
- goto freebufs;
- n = countnumflds(s.string);
- /* Swap if out of order. */
- if (compartial(s.string,e.string,n) > 0) {
- rstart = &e;
- rend = &s;
- }
- break;
- }
-
- if (n) {
- pt = ftalloc(struct Revpairs);
- pt->numfld = n;
- pt->strtrev = fstr_save(rstart->string);
- pt->endrev = fstr_save(rend->string);
- pt->rnext = Revlst;
- Revlst = pt;
- }
- ptr = ptr->rnext;
- }
- /* Now take care of branchflag */
- if (branchflag && (Dbranch||Head)) {
- pt = ftalloc(struct Revpairs);
- pt->strtrev = pt->endrev =
- Dbranch ? Dbranch : fstr_save(partialno(&s,Head->num,1));
- pt->rnext=Revlst; Revlst=pt;
- pt->numfld = countnumflds(pt->strtrev);
- }
-
- freebufs:
- bufautoend(&s);
- bufautoend(&e);
- return !ptr;
-}
-
-
-
- static int
-checkrevpair(num1,num2)
- char const *num1, *num2;
-/* function: check whether num1, num2 are legal pair,i.e.
- only the last field are different and have same number of
- fields( if length <= 2, may be different if first field) */
-
-{
- int length = countnumflds(num1);
-
- if (
- countnumflds(num2) != length
- || (2 < length && compartial(num1, num2, length-1) != 0)
- ) {
- rcserror("invalid branch or revision pair %s : %s", num1, num2);
- return false;
- }
-
- return true;
-}
-
-
-
- static void
-getrevpairs(argv)
-register char * argv;
-/* function: get revision or branch range from command line, and */
-/* store in revlist */
-
-{
- register char c;
- struct Revpairs * nextrevpair;
- int separator;
-
- c = *argv;
-
- /* Support old ambiguous '-' syntax; this will go away. */
- if (strchr(argv,':'))
- separator = ':';
- else {
- if (strchr(argv,'-') && VERSION(5) <= RCSversion)
- warn("`-' is obsolete in `-r%s'; use `:' instead", argv);
- separator = '-';
- }
-
- for (;;) {
- while (c==' ' || c=='\t' || c=='\n')
- c = *++argv;
- nextrevpair = talloc(struct Revpairs);
- nextrevpair->rnext = revlist;
- revlist = nextrevpair;
- nextrevpair->numfld = 1;
- nextrevpair->strtrev = argv;
- for (;; c = *++argv) {
- switch (c) {
- default:
- continue;
- case '\0': case ' ': case '\t': case '\n':
- case ',': case ';':
- break;
- case ':': case '-':
- if (c == separator)
- break;
- continue;
- }
- break;
- }
- *argv = '\0';
- while (c==' ' || c=='\t' || c=='\n')
- c = *++argv;
- if (c == separator) {
- while ((c = *++argv) == ' ' || c == '\t' || c =='\n')
- continue;
- nextrevpair->endrev = argv;
- for (;; c = *++argv) {
- switch (c) {
- default:
- continue;
- case '\0': case ' ': case '\t': case '\n':
- case ',': case ';':
- break;
- case ':': case '-':
- if (c == separator)
- break;
- continue;
- }
- break;
- }
- *argv = '\0';
- while (c==' ' || c=='\t' || c =='\n')
- c = *++argv;
- nextrevpair->numfld =
- !nextrevpair->endrev[0] ? 2 /* -rREV: */ :
- !nextrevpair->strtrev[0] ? 3 /* -r:REV */ :
- 4 /* -rREV1:REV2 */;
- }
- if (!c)
- break;
- else if (c==',' || c==';')
- c = *++argv;
- else
- error("missing `,' near `%c%s'", c, argv+1);
- }
-}