📄 rlog.c
字号:
/* * RLOG operation *//***************************************************************************** * print contents of RCS files ***************************************************************************** *//* Copyright (C) 1982, 1988, 1989 Walter Tichy Copyright 1990, 1991 by 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 modifyit under the terms of the GNU General Public License as published bythe 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 ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See theGNU General Public License for more details.You should have received a copy of the GNU General Public Licensealong with RCS; see the file COPYING. If not, write tothe Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.Report problems and direct all questions to: rcs-bugs@cs.purdue.edu*//* $Log: rlog.c,v $ * 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 lockers { /* lockers in locker option; stored */ char const * login; /* lockerlist */ struct lockers * 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 */ unsigned numfld; /* option; stored in revlist */ char const * strtrev; char const * endrev; struct Revpairs * rnext; } ;struct Datepairs{ /* date range in -d option; stored in */ char strtdate[datesize]; /* duelst and datelist */ char enddate[datesize]; struct Datepairs * dnext; };static char extractdelta P((struct hshentry const*));static int checkrevpair P((char const*,char const*));static struct hshentry const *readdeltalog P((void));static unsigned extdate P((struct hshentry*));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 getnumericrev P((void));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 lockers *lockerlist;static struct stateattri *statelist;mainProg(rlogId, "rlog", "$Id: rlog.c,v 5.9 1991/09/17 19:07:40 eggert Exp $"){ static char const cmdusage[] = "\nrlog usage: rlog -{bhLRt} -ddates -l[lockers] -rrevs -sstates -w[logins] -Vn file ..."; register FILE *out; char *a, **newargv; struct Datepairs *currdate; char const *accessListString, *accessFormat, *commentFormat; char const *headFormat, *symbolFormat; struct access const *curaccess; struct assoc const *curassoc; struct hshentry const *delta; struct lock const *currlock; int descflag, selectflag; int onlylockflag; /* print only files with locks */ int onlyRCSflag; /* print only RCS file name */ unsigned revno; descflag = selectflag = true; onlylockflag = onlyRCSflag = false; 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 '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 'V': setRCSversion(*argv); break; default: faterror("unknown option: %s%s", *argv, cmdusage); }; } /* end of option processing */ if (argc<1) faterror("no input file%s", cmdusage); if (! (descflag|selectflag)) { warn("-t overrides -h."); descflag = true; } if (RCSversion < VERSION(5)) { accessListString = "\naccess list: "; accessFormat = " %s"; commentFormat = "\ncomment leader: \""; headFormat = "\nRCS file: %s; Working file: %s\nhead: %s%s\nbranch: %s%s\nlocks: "; insDelFormat = " lines added/del: %lu/%lu"; symbolFormat = " %s: %s;"; } else { accessListString = "\naccess list:"; accessFormat = "\n\t%s"; commentFormat = "\ncomment leader: \""; headFormat = "\nRCS file: %s\nWorking file: %s\nhead:%s%s\nbranch:%s%s\nlocks:%s"; insDelFormat = " lines: +%lu -%lu"; symbolFormat = "\n\t%s: %s"; } /* now handle all filenames */ do { ffree(); if (pairfilenames(argc, argv, rcsreadopen, true, false) <= 0) continue; /* now RCSfilename contains the name of the RCS file, and finptr * the file descriptor. Workfilename 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 ( onlyRCSflag ) { aprintf(out, "%s\n", RCSfilename); continue; } /* print RCS filename , working filename and optional administrative information */ /* could use getfullRCSname() here, but that is very slow */ aprintf(out, headFormat, RCSfilename, workfilename, 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 && RCSversion<VERSION(5)) aputs(" strict", out); aputs(accessListString, out); /* print access list */ curaccess = AccessList; while(curaccess) { aprintf(out, accessFormat, curaccess->login); curaccess = curaccess->nextaccess; } aputs("\nsymbolic names:", out); /* print symbolic names */ for (curassoc=Symbols; curassoc; curassoc=curassoc->nextassoc) aprintf(out, symbolFormat, curassoc->symbol, curassoc->num); aputs(commentFormat, out); awrite(Comment.string, Comment.size, out); aputs("\"\n", out); if (VERSION(5)<=RCSversion || Expand != KEYVAL_EXPAND) aprintf(out, "keyword substitution: %s\n", expand_names[Expand] ); gettree(); aprintf(out, "total revisions: %u", TotalDeltas); revno = 0; if (Head && selectflag & descflag) { getnumericrev(); /* get numeric revision or branch names */ exttree(Head); /* get most recently date of the dates pointed by duelst */ currdate = duelst; while( currdate) { VOID sprintf(currdate->strtdate,DATEFORM,0,0,0,0,0,0); recentdate(Head, currdate); currdate = currdate->dnext; } revno = extdate(Head); aprintf(out, ";\tselected revisions: %u", revno); } afputc('\n',out); if (descflag) { aputs("description:\n", out); getdesc(true); } if (revno) { while (! (delta = readdeltalog())->selector || --revno) ; if (delta->next && countnumflds(delta->num)==2) /* Read through delta->next to get its insertlns. */ while (readdeltalog() != delta->next) ; putrunk();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -