1*2149Seric # include "../hdr/defines.h" 2*2149Seric # include "../hdr/had.h" 3*2149Seric 4*2149Seric SCCSID(@(#)prt.c 4.1); 5*2149Seric 6*2149Seric /* 7*2149Seric Program to print parts or all of an SCCS file. 8*2149Seric Arguments to the program may appear in any order 9*2149Seric and consist of keyletters, which begin with '-', 10*2149Seric and named files. 11*2149Seric 12*2149Seric If a direcory is given as an argument, each 13*2149Seric SCCS file within the directory is processed as if 14*2149Seric it had been specifically named. If a name of '-' 15*2149Seric is given, the standard input is read for a list 16*2149Seric of names of SCCS files to be processed. 17*2149Seric Non-SCCS files are ignored. 18*2149Seric */ 19*2149Seric 20*2149Seric # define NOEOF 0 21*2149Seric # define BLANK(p) while (!(*p == ' ' || *p == '\t')) p++; 22*2149Seric 23*2149Seric char had[26]; 24*2149Seric FILE *iptr; 25*2149Seric char line[512]; 26*2149Seric char statistics[25]; 27*2149Seric struct delent { 28*2149Seric char type; 29*2149Seric char *osid; 30*2149Seric char *datetime; 31*2149Seric char *pgmr; 32*2149Seric char *serial; 33*2149Seric char *pred; 34*2149Seric } del; 35*2149Seric int num_files; 36*2149Seric int prefix; 37*2149Seric long cutoff; 38*2149Seric long revcut; 39*2149Seric int linenum; 40*2149Seric char *ysid; 41*2149Seric char *flagdesc[26] { "", 42*2149Seric "branch", 43*2149Seric "ceiling", 44*2149Seric "default SID", 45*2149Seric "", 46*2149Seric "floor", 47*2149Seric "", 48*2149Seric "", 49*2149Seric "id keywd err/warn", 50*2149Seric "", 51*2149Seric "", 52*2149Seric "", 53*2149Seric "module", 54*2149Seric "null delta", 55*2149Seric "", 56*2149Seric "", 57*2149Seric "", 58*2149Seric "", 59*2149Seric "", 60*2149Seric "type", 61*2149Seric "", 62*2149Seric "validate MRs", 63*2149Seric "", 64*2149Seric "", 65*2149Seric "", 66*2149Seric "" 67*2149Seric }; 68*2149Seric 69*2149Seric main(argc,argv) 70*2149Seric int argc; 71*2149Seric char *argv[]; 72*2149Seric { 73*2149Seric register int j; 74*2149Seric register char *p; 75*2149Seric char c; 76*2149Seric int testklt; 77*2149Seric extern prt(); 78*2149Seric extern int Fcnt; 79*2149Seric 80*2149Seric /* 81*2149Seric Set flags for 'fatal' to issue message, call clean-up 82*2149Seric routine, and terminate processing. 83*2149Seric */ 84*2149Seric Fflags = FTLMSG | FTLCLN | FTLEXIT; 85*2149Seric 86*2149Seric testklt = 1; 87*2149Seric 88*2149Seric /* 89*2149Seric The following loop processes keyletters and arguments. 90*2149Seric Note that these are processed only once for each 91*2149Seric invocation of 'main'. 92*2149Seric */ 93*2149Seric for (j = 1; j < argc; j++) 94*2149Seric if (argv[j][0] == '-' && (c = argv[j][1])) { 95*2149Seric p = &argv[j][2]; 96*2149Seric switch (c) { 97*2149Seric case 'e': /* print everything but body */ 98*2149Seric case 's': /* print only delta desc. and stats */ 99*2149Seric case 'd': /* print whole delta table */ 100*2149Seric case 'a': /* print all deltas */ 101*2149Seric case 'i': /* print inc, exc, and ignore info */ 102*2149Seric case 'u': /* print users allowed to do deltas */ 103*2149Seric case 'f': /* print flags */ 104*2149Seric case 't': /* print descriptive user-text */ 105*2149Seric case 'b': /* print body */ 106*2149Seric break; 107*2149Seric 108*2149Seric case 'y': /* delta cutoff */ 109*2149Seric ysid = p; 110*2149Seric prefix++; 111*2149Seric break; 112*2149Seric 113*2149Seric case 'c': /* time cutoff */ 114*2149Seric if (*p && date_ab(p,&cutoff)) 115*2149Seric fatal("bad date/time (cm5)"); 116*2149Seric prefix++; 117*2149Seric break; 118*2149Seric 119*2149Seric case 'r': /* reverse time cutoff */ 120*2149Seric if (*p && date_ab(p,&revcut)) 121*2149Seric fatal ("bad date/time (cm5)"); 122*2149Seric prefix++; 123*2149Seric break; 124*2149Seric 125*2149Seric default: 126*2149Seric fatal("unknown key letter (cm1)"); 127*2149Seric } 128*2149Seric 129*2149Seric if (had[c - 'a']++ && testklt++) 130*2149Seric fatal("key letter twice (cm2)"); 131*2149Seric argv[j] = 0; 132*2149Seric } 133*2149Seric else 134*2149Seric num_files++; 135*2149Seric 136*2149Seric if (num_files == 0) 137*2149Seric fatal("missing file arg (cm3)"); 138*2149Seric 139*2149Seric if (HADC && HADR) 140*2149Seric fatal("both 'c' and 'r' keyletters specified (pr2)"); 141*2149Seric 142*2149Seric setsig(); 143*2149Seric 144*2149Seric /* 145*2149Seric Change flags for 'fatal' so that it will return to this 146*2149Seric routine (main) instead of terminating processing. 147*2149Seric */ 148*2149Seric Fflags =& ~FTLEXIT; 149*2149Seric Fflags =| FTLJMP; 150*2149Seric 151*2149Seric /* 152*2149Seric Call 'prt' routine for each file argument. 153*2149Seric */ 154*2149Seric for (j = 1; j < argc; j++) 155*2149Seric if (p = argv[j]) 156*2149Seric do_file(p,prt); 157*2149Seric 158*2149Seric exit(Fcnt ? 1 : 0); 159*2149Seric } 160*2149Seric 161*2149Seric 162*2149Seric /* 163*2149Seric Routine that actually performs the 'prt' functions. 164*2149Seric */ 165*2149Seric 166*2149Seric prt(file) 167*2149Seric char *file; 168*2149Seric { 169*2149Seric int stopdel; 170*2149Seric int user, flag, text; 171*2149Seric char *p; 172*2149Seric long bindate; 173*2149Seric 174*2149Seric if (setjmp(Fjmp)) /* set up to return here from 'fatal' */ 175*2149Seric return; /* and return to caller of prt */ 176*2149Seric 177*2149Seric if (HADE) 178*2149Seric HADD = HADI = HADU = HADF = HADT = 1; 179*2149Seric 180*2149Seric if (!HADU && !HADF && !HADT && !HADB) 181*2149Seric HADD = 1; 182*2149Seric 183*2149Seric if (!HADD) 184*2149Seric HADR = HADS = HADA = HADI = HADY = HADC = 0; 185*2149Seric 186*2149Seric if (HADS && HADI) 187*2149Seric fatal("s and i conflict (pr1)"); 188*2149Seric 189*2149Seric iptr = xfopen(file,0); 190*2149Seric 191*2149Seric p = lineread(NOEOF); 192*2149Seric if (*p++ != CTLCHAR || *p != HEAD) 193*2149Seric fatal("not an sccs file (co2)"); 194*2149Seric 195*2149Seric stopdel = 0; 196*2149Seric 197*2149Seric if (!prefix) 198*2149Seric printf("\n%s:\n",file); 199*2149Seric 200*2149Seric if (HADD) { 201*2149Seric while ((p = lineread(NOEOF)) && *p++ == CTLCHAR && 202*2149Seric *p++ == STATS && !stopdel) { 203*2149Seric NONBLANK(p); 204*2149Seric copy(p,statistics); 205*2149Seric 206*2149Seric p = lineread(NOEOF); 207*2149Seric getdel(&del,p); 208*2149Seric 209*2149Seric if (!HADA && del.type != 'D') { 210*2149Seric read_to(EDELTAB); 211*2149Seric continue; 212*2149Seric } 213*2149Seric if (HADC) { 214*2149Seric date_ab(del.datetime,&bindate); 215*2149Seric if (bindate < cutoff) { 216*2149Seric stopdel = 1; 217*2149Seric break; 218*2149Seric } 219*2149Seric } 220*2149Seric if (HADR) { 221*2149Seric date_ab(del.datetime,&bindate); 222*2149Seric if (bindate >= revcut) { 223*2149Seric read_to(EDELTAB); 224*2149Seric continue; 225*2149Seric } 226*2149Seric } 227*2149Seric if (HADY && (equal(del.osid,ysid) || !(*ysid))) 228*2149Seric stopdel = 1; 229*2149Seric 230*2149Seric printdel(file,&del); 231*2149Seric 232*2149Seric while ((p = lineread(NOEOF)) && *p++ == CTLCHAR) { 233*2149Seric if (*p == EDELTAB) 234*2149Seric break; 235*2149Seric switch (*p) { 236*2149Seric case INCLUDE: 237*2149Seric if (HADI) 238*2149Seric printit(file,"Included:\t",p); 239*2149Seric break; 240*2149Seric 241*2149Seric case EXCLUDE: 242*2149Seric if (HADI) 243*2149Seric printit(file,"Excluded:\t",p); 244*2149Seric break; 245*2149Seric 246*2149Seric case IGNORE: 247*2149Seric if (HADI) 248*2149Seric printit(file,"Ignored:\t",p); 249*2149Seric break; 250*2149Seric 251*2149Seric case MRNUM: 252*2149Seric if (!HADS) 253*2149Seric printit(file,"MRs:\t",p); 254*2149Seric break; 255*2149Seric 256*2149Seric case COMMENTS: 257*2149Seric if (!HADS) 258*2149Seric printit(file,"",p); 259*2149Seric break; 260*2149Seric 261*2149Seric default: 262*2149Seric fatal(sprintf(Error, 263*2149Seric "format error at line %d (co4)",linenum)); 264*2149Seric } 265*2149Seric } 266*2149Seric } 267*2149Seric if (prefix) 268*2149Seric printf("\n"); 269*2149Seric 270*2149Seric if (stopdel && !(line[0] == CTLCHAR && line[1] == BUSERNAM)) 271*2149Seric read_to(BUSERNAM); 272*2149Seric } 273*2149Seric else 274*2149Seric read_to(BUSERNAM); 275*2149Seric 276*2149Seric if (HADU) { 277*2149Seric user = 0; 278*2149Seric printf("\nUsers allowed to make deltas --\n"); 279*2149Seric while ((p = lineread(NOEOF)) && *p != CTLCHAR) { 280*2149Seric user = 1; 281*2149Seric printf("\t%s",p); 282*2149Seric } 283*2149Seric if (!user) 284*2149Seric printf("\teveryone\n"); 285*2149Seric } 286*2149Seric else 287*2149Seric read_to(EUSERNAM); 288*2149Seric 289*2149Seric if (HADF) { 290*2149Seric flag = 0; 291*2149Seric printf("\nFlags --\n"); 292*2149Seric while ((p = lineread(NOEOF)) && *p++ == CTLCHAR && 293*2149Seric *p++ == FLAG) { 294*2149Seric flag = 1; 295*2149Seric NONBLANK(p); 296*2149Seric printf("\t%s",flagdesc[*p - 'a']); 297*2149Seric 298*2149Seric if (*++p) { 299*2149Seric NONBLANK(p); 300*2149Seric printf("\t%s",p); 301*2149Seric } 302*2149Seric } 303*2149Seric if (!flag) 304*2149Seric printf("\tnone\n"); 305*2149Seric } 306*2149Seric else 307*2149Seric read_to(BUSERTXT); 308*2149Seric 309*2149Seric if (HADT) { 310*2149Seric text = 0; 311*2149Seric printf("\nDescription --\n"); 312*2149Seric while ((p = lineread(NOEOF)) && *p != CTLCHAR) { 313*2149Seric text = 1; 314*2149Seric printf("\t%s",p); 315*2149Seric } 316*2149Seric if (!text) 317*2149Seric printf("\tnone\n"); 318*2149Seric } 319*2149Seric else 320*2149Seric read_to(EUSERTXT); 321*2149Seric 322*2149Seric if (HADB) { 323*2149Seric printf("\n"); 324*2149Seric while (p = lineread(EOF)) 325*2149Seric if (*p == CTLCHAR) 326*2149Seric printf("*** %s", ++p); 327*2149Seric else 328*2149Seric printf("\t%s", p); 329*2149Seric } 330*2149Seric 331*2149Seric fclose(iptr); 332*2149Seric } 333*2149Seric 334*2149Seric 335*2149Seric getdel(delp,lp) 336*2149Seric register struct delent *delp; 337*2149Seric register char *lp; 338*2149Seric { 339*2149Seric lp =+ 2; 340*2149Seric NONBLANK(lp); 341*2149Seric delp->type = *lp++; 342*2149Seric NONBLANK(lp); 343*2149Seric delp->osid = lp; 344*2149Seric BLANK(lp); 345*2149Seric *lp++ = '\0'; 346*2149Seric NONBLANK(lp); 347*2149Seric delp->datetime = lp; 348*2149Seric BLANK(lp); 349*2149Seric NONBLANK(lp); 350*2149Seric BLANK(lp); 351*2149Seric *lp++ = '\0'; 352*2149Seric NONBLANK(lp); 353*2149Seric delp->pgmr = lp; 354*2149Seric BLANK(lp); 355*2149Seric *lp++ = '\0'; 356*2149Seric NONBLANK(lp); 357*2149Seric delp->serial = lp; 358*2149Seric BLANK(lp); 359*2149Seric *lp++ = '\0'; 360*2149Seric NONBLANK(lp); 361*2149Seric delp->pred = lp; 362*2149Seric repl(lp,'\n','\0'); 363*2149Seric } 364*2149Seric 365*2149Seric 366*2149Seric read_to(ch) 367*2149Seric register char ch; 368*2149Seric { 369*2149Seric char *n; 370*2149Seric 371*2149Seric while ((n = lineread(NOEOF)) && 372*2149Seric !(*n++ == CTLCHAR && *n == ch)) 373*2149Seric ; 374*2149Seric 375*2149Seric return(n); 376*2149Seric } 377*2149Seric 378*2149Seric 379*2149Seric lineread(eof) 380*2149Seric register int eof; 381*2149Seric { 382*2149Seric char *k; 383*2149Seric 384*2149Seric k = fgets(line,512,iptr); 385*2149Seric 386*2149Seric if (k == NULL && !eof) 387*2149Seric fatal("premature eof (co5)"); 388*2149Seric 389*2149Seric linenum++; 390*2149Seric 391*2149Seric return(k); 392*2149Seric } 393*2149Seric 394*2149Seric 395*2149Seric printdel(file,delp) 396*2149Seric register char *file; 397*2149Seric register struct delent *delp; 398*2149Seric { 399*2149Seric printf("\n"); 400*2149Seric 401*2149Seric if (prefix) { 402*2149Seric statistics[length(statistics) - 1] = '\0'; 403*2149Seric printf("%s:\t",file); 404*2149Seric } 405*2149Seric 406*2149Seric printf("%c %s\t%s\t%s\t%s\t%s\t%s",delp->type,delp->osid, 407*2149Seric delp->datetime,delp->pgmr,delp->serial,delp->pred,statistics); 408*2149Seric } 409*2149Seric 410*2149Seric 411*2149Seric printit(file,str,cp) 412*2149Seric register char *file; 413*2149Seric register char *str, *cp; 414*2149Seric { 415*2149Seric cp++; 416*2149Seric NONBLANK(cp); 417*2149Seric 418*2149Seric if (prefix) { 419*2149Seric cp[length(cp) - 1] = '\0'; 420*2149Seric printf(" "); 421*2149Seric } 422*2149Seric 423*2149Seric printf("%s%s",str,cp); 424*2149Seric } 425