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