prs.c
来自「<B>Digital的Unix操作系统VAX 4.2源码</B>」· C语言 代码 · 共 1,249 行 · 第 1/2 页
C
1,249 行
#ifndef lintstatic char *sccsid = "@(#)prs.c 4.1 (ULTRIX) 7/17/90";#endif lint/************************************************************************ * * * Copyright (c) 1984, 1988 by * * Digital Equipment Corporation, Maynard, MA * * All rights reserved. * * * * This software is furnished under a license and may be used and * * copied only in accordance with the terms of such license and * * with the inclusion of the above copyright notice. This * * software or any other copies thereof may not be provided or * * otherwise made available to any other person. No title to and * * ownership of the software is hereby transferred. * * * * This software is derived from software received from the * * University of California, Berkeley, and from Bell * * Laboratories. Use, duplication, or disclosure is subject to * * restrictions under license agreements with University of * * California and with AT&T. * * * * The information in this software is subject to change without * * notice and should not be construed as a commitment by Digital * * Equipment Corporation. * * * * Digital assumes no responsibility for the use or reliability * * of its software on equipment which is not supplied by Digital. * * * ************************************************************************//* * 11/10/89 KJL - Avoid null pointer deference in read_mod. * 5/12/89 KJL - Changed to name of tzset to match definition in date_ab.c. * 1/25/88 DAL - Changed to allow mr lines with no mr data. *//*************************************************************************//* *//* prs [-d<dataspec>] [-r<sid>] [-l] [-e] [-a] file ... *//* *//*************************************************************************//* Program to print parts or all of an SCCS file in user supplied format. Arguments to the program may appear in any order and consist of keyletters, which begin with '-', and named files. If a direcory is given as an argument, each SCCS file within the directory is processed as if it had been specifically named. If a name of '-' is given, the standard input is read for a list of names of SCCS files to be processed. Non-SCCS files are ignored.*/# include "../hdr/defines.h"# include "../hdr/had.h"SCCSID(@(#)prs.c 5.11);struct stat Statbuf;char Null[1];char Error[128];char had[26];char Getpgm[] = "get";static char defline[] = ":Dt:\t:DL:\nMRs:\n:MR:COMMENTS:\n:C:";char *sid_ba();char Sid[32];char Mod[16];char Olddir[BUFSIZ];char Pname[BUFSIZ];char Dir[BUFSIZ];char *Type;char *Qsect;char Deltadate[18];char *Deltatime;char tempskel[] = "/tmp/prXXXXXX"; /* used to generate temp file names */char untmp[32], uttmp[32], cmtmp[32];char mrtmp[32], bdtmp[32];FILE *UNiop;FILE *UTiop;FILE *CMiop;FILE *MRiop;FILE *BDiop;char line[BUFSIZ], *getline();int num_files;int HAD_CM, HAD_MR, HAD_FD, HAD_BD, HAD_UN;char dt_line[BUFSIZ];char *dataspec = &defline[0];char iline[BUFSIZ], xline[BUFSIZ], gline[BUFSIZ];FILE *maket();struct packet gpkt;struct sid sid;struct tm *Dtime;main(argc,argv)int argc;char *argv[];{ register int j; register char *p; char c; char *sid_ab(); extern process(); extern int Fcnt; /* Set flags for 'fatal' to issue message, call clean-up routine, and terminate processing. */ Fflags = FTLMSG | FTLCLN | FTLEXIT; /* The following loop processes keyletters and arguments. Note that these are processed only once for each invocation of 'main'. */ for (j = 1; j < argc; j++) if (argv[j][0] == '-' && (c = argv[j][1])) { p = &argv[j][2]; switch (c) { case 'r': /* specified SID */ if (*p) { if (invalid(p)) fatal("invalid sid (co8)"); sid_ab(p,&sid); } break; case 'l': /* later than specified SID */ case 'e': /* earlier than specified SID */ case 'a': /* print all delta types (R or D) */ if (*p) { sprintf(Error, "value after %c arg (cm7)",c); fatal(Error); } break; case 'd': /* dataspec line */ if (*p) dataspec = p; break; default: fatal("unknown key letter (cm1)"); } if (had[c - 'a']++) fatal("key letter twice (cm2)"); argv[j] = 0; } else num_files++; if (num_files == 0) fatal("missing file arg (cm3)"); /* check the dataspec line and determine if any tmp files need be created */ ck_spec(dataspec); setsig(); /* Change flags for 'fatal' so that it will return to this routine (main) instead of terminating processing. */ Fflags &= ~FTLEXIT; Fflags |= FTLJMP; /* Call 'process' routine for each file argument. */ for (j = 1; j < argc; j++) if (p = argv[j]) do_file(p,process); exit(Fcnt ? 1 : 0);}/* * This procedure opens the SCCS file and calls all subsequent * modules to perform 'prs'. Once the file is finished, process * returns to 'main' to process any other possible files.*/process(file)register char *file;{ extern char had_dir, had_standinp; static int pr_fname = 0; if (setjmp(Fjmp)) /* set up to return here from 'fatal' */ return; /* and return to caller of 'process' */ sinit(&gpkt,file,1); /* init packet and open SCCS file */ /* move value of global sid into gpkt.p_reqsid for later comparision. */ gpkt.p_reqsid = sid; gpkt.p_reopen = 1; /* set reopen flag to 1 for 'getline' */ /* Read delta table entries checking for format error and setting the value for the SID if none was specified. Also check to see if SID specified does in fact exists. */ deltblchk(&gpkt); /* create auxiliary file for User Name Section */ if (HAD_UN) aux_create(UNiop,untmp,EUSERNAM); else read_to(EUSERNAM,&gpkt); /* store flags (if any) into global array called 'Sflags' */ doflags(&gpkt); /* create auxiliary file for the User Text section */ if (HAD_FD) aux_create(UTiop,uttmp,EUSERTXT); else read_to(EUSERTXT,&gpkt); /* indicate to 'getline' that EOF is okay */ gpkt.p_chkeof = 1; /* read body of SCCS file and create temp file for it */ while(read_mod(&gpkt)) ; /* Here, file has already been re-opened (by 'getline' after EOF was encountered by 'read_mod' calling 'getline') */ getline(&gpkt); /* skip over header line */ if (!HADD && !HADR && !HADE && !HADL) HADE = pr_fname = 1; if (!HADD) printf("%s:\n\n",file); /* call 'dodeltbl' to read delta table entries and determine which deltas are to be considered */ dodeltbl(&gpkt); /* call 'clean_up' to remove any temporary file created during processing of the SCCS file passed as an argument from 'do_file' */ clean_up(); return; /* return to caller of 'process' */}/* * This procedure actually reads the delta table entries and * substitutes pre-defined strings and pointers with the information * needed during the scanning of the 'dataspec' line*/dodeltbl(pkt)register struct packet *pkt;{ char *n; int stopdel; int found; struct deltab dt; struct stats stats; /* flags used during determination of deltas to be considered */ found = stopdel = 0; /* Read entire delta table. */ while (getstats(pkt,&stats) && !stopdel) { if (getadel(pkt,&dt) != BDELTAB) fmterr(pkt); /* ignore 'removed' deltas if !HADA keyletter */ if (!HADA && dt.d_type != 'D') { read_to(EDELTAB,pkt); continue; } /* determine whether or not to consider current delta */ if (!(eqsid(&gpkt.p_reqsid, &dt.d_sid)) && !found) { /* if !HADL or HADE keyletter skip delta entry */ if ((!HADL) || HADE) { read_to(EDELTAB,pkt); continue; } } else { found = 1; stopdel = 1; } /* if HADE keyletter read remainder of delta table entries */ if (HADE && stopdel) stopdel = 0; /* create temp file for MRs and comments */ if (HAD_MR) MRiop = maket(mrtmp); if (HAD_CM) CMiop = maket(cmtmp); /* Read rest of delta entry. */ while ((n = getline(pkt)) != NULL) if (pkt->p_line[0] != CTLCHAR) break; else { switch (pkt->p_line[1]) { case INCLUDE: getit(iline,n); continue; case EXCLUDE: getit(xline,n); continue; case IGNORE: getit(gline,n); continue; case MRNUM: if (HAD_MR) putmr(n); continue; case COMMENTS: if (HAD_CM) putcom(n); continue; case EDELTAB: /* close temp files for MRs and comments */ if (HAD_MR) fclose(MRiop); if (HAD_CM) fclose(CMiop); scanspec(dataspec,&dt,&stats); /* remove temp files for MRs and comments */ unlink(mrtmp); unlink(cmtmp); break; default: fmterr(pkt); } break; } if (n == NULL || pkt->p_line[0] != CTLCHAR) fmterr(pkt); }}/* * The scanspec procedure scans the dataspec searching for ID keywords. * When a keyword is found the value is replaced and printed on the * standard output. Any character that is not an ID keyword is printed * immediately.*/extern char *Sflags[];static char Zkywd[5] = "@(#)";scanspec(spec,dtp,statp)char spec[];struct deltab *dtp;struct stats *statp;{ register char *lp; register char *k; union { char str[2]; int istr; } u; register char c; /* Zero union u (one int may be larger than two char's) */ u.istr = 0; /* call 'idsetup' to set certain data keywords for 'scanspec' substitution */ idsetup(&dtp->d_sid,&gpkt,&dtp->d_datetime); /* scan 'dataspec' line */ for(lp = spec; *lp != 0; lp++) { if(lp[0] == ':' && lp[1] != 0 && lp[2] == ':') { c = *++lp; switch (c) { case 'I': /* SID */ printf("%s",Sid); break; case 'R': /* Release number */ printf("%u",dtp->d_sid.s_rel); break; case 'L': /* Level number */ printf("%u",dtp->d_sid.s_lev); break; case 'B': /* Branch number */ if (dtp->d_sid.s_br != 0) printf("%u",dtp->d_sid.s_br); break; case 'S': /* Sequence number */ if (dtp->d_sid.s_seq != 0) printf("%u",dtp->d_sid.s_seq); break; case 'D': /* Date delta created */ printf("%s",Deltadate); break; case 'T': /* Time delta created */ printf("%s",Deltatime); break; case 'P': /* Programmer who created delta */ printf("%s",dtp->d_pgmr); break; case 'C': /* Comments */ if (exists(cmtmp)) printfile(cmtmp); break; case 'Y': /* Type flag */ printf("%s",Type); break; case 'Q': /* csect flag */ printf("%s",Qsect); break; case 'J': /* joint edit flag */ if (Sflags[JOINTFLAG - 'a']) printf("yes"); else printf("no"); break; case 'M': /* Module name */ printf("%s",Mod); break; case 'W': /* Form of what string */ printf("%s%s\t%s",Zkywd,Mod,Sid); break; case 'A': /* Form of what string */ printf("%s%s %s %s%s",Zkywd,Type,Mod,Sid,Zkywd); break; case 'Z': /* what string constructor */ printf("%s",Zkywd); break; case 'F': /* File name */ printf("%s",sname(gpkt.p_file)); break; default: putchar(':'); --lp; continue; } lp++; } else if(lp[0] == ':' && lp[1] != 0 && lp[2] !=0 && lp[3] == ':') { if (lp[1] == ':') { putchar(':'); continue; }#if u370 || u3b u.str[3] = *++lp; u.str[2] = *++lp;#else u.str[0] = *++lp; u.str[1] = *++lp;#endif switch (u.istr) { case 256*'L'+'D': /* :DL: Delta line statistics */ printf("%.05d",statp->s_ins); putchar('/'); printf("%.05d",statp->s_del); putchar('/'); printf("%.05d",statp->s_unc); break; case 256*'i'+'L': /* :Li: Lines inserted by delta */ printf("%.05d",statp->s_ins); break; case 256*'d'+'L': /* :Ld: Lines deleted by delta */ printf("%.05d",statp->s_del); break; case 256*'u'+'L': /* :Lu: Lines unchanged by delta */ printf("%.05d",statp->s_unc); break; case 256*'T'+'D': /* :DT: Delta type */ printf("%c",dtp->d_type); break; case 256*'y'+'D': /* :Dy: Year delta created */ printf("%02d",Dtime->tm_year); break; case 256*'m'+'D': /* :Dm: Month delta created */ printf("%02d",(Dtime->tm_mon + 1)); break; case 256*'d'+'D': /* :Dd: Day delta created */ printf("%02d",Dtime->tm_mday); break; case 256*'h'+'T': /* :Th: Hour delta created */ printf("%02d",Dtime->tm_hour); break; case 256*'m'+'T': /* :Tm: Minutes delta created */ printf("%02d",Dtime->tm_min); break; case 256*'s'+'T': /* :Ts: Seconds delta created */ printf("%02d",Dtime->tm_sec); break; case 256*'S'+'D': /* :DS: Delta sequence number */ printf("%d",dtp->d_serial); break; case 256*'P'+'D': /* :DP: Predecessor delta sequence number */ printf("%d",dtp->d_pred); break; case 256*'I'+'D': /* :DI: Deltas included,excluded,ignored */ printf("%s",iline); if (length(xline)) printf("/%s",xline); if (length(gline)) printf("/%s",gline); break; case 256*'n'+'D': /* :Dn: Deltas included */ printf("%s",iline); break; case 256*'x'+'D': /* :Dx: Deltas excluded */ printf("%s",xline); break; case 256*'g'+'D': /* :Dg: Deltas ignored */ printf("%s",gline); break; case 256*'K'+'L': /* :LK: locked releases */ if (k = Sflags[LOCKFLAG - 'a']) printf("%s",k); else printf("none"); break; case 256*'G'+'L': /* :LG: locked get releases */ if (k = Sflags[LOCKGET - 'a']) printf("%s",k); else printf("none"); break; case 256*'R'+'M': /* :MR: MR numbers */ if (exists(mrtmp)) printfile(mrtmp); break; case 256*'C'+'M': /* :MC: cmf flag yes or no */ if(Sflags[CMFFLAG - 'a']) printf("yes"); else printf("no"); break; case 256*'C'+'A': /* :AC: cmf application field */ if(!(k = Sflags[CMFFLAG - 'a'])) printf("none"); else printf("%s",k); break; case 256*'N'+'U': /* :UN: User names */ if (exists(untmp)) printfile(untmp); break; case 256*'F'+'M': /* :MF: MR validation flag */ if (Sflags[VALFLAG - 'a']) printf("yes"); else printf("no"); break; case 256*'P'+'M': /* :MP: MR validation program */ if (!(k = Sflags[VALFLAG - 'a'])) printf("none"); else printf("%s",k); break; case 256*'F'+'K': /* :KF: Keyword err/warn flag */ if (Sflags[IDFLAG - 'a']) printf("yes"); else printf("no"); break; case 256*'F'+'B': /* :BF: Branch flag */ if (Sflags[BRCHFLAG - 'a'])
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?