]> diplodocus.org Git - nmh/blob - docs/historical/SRI-NOSC/pr.c
Added start_test/finish_test to a bunch of tests.
[nmh] / docs / historical / SRI-NOSC / pr.c
1 #
2 /*
3 * print file with headings
4 * precl[2]+head+2+page[56]+endl[5]
5 */
6
7 /*
8 * NOTE: Defaults are set in the routine dflts()
9 * and not in these declares.
10 */
11
12 int errno;
13 char *sys_errlst[];
14
15 int ncol 1; /* number of columns */
16 char *header; /* header text */
17 int col;
18 int icol;
19 int file;
20 char *bufp;
21 #define BUFS 5120
22 char buffer[BUFS];
23 #define FF 014
24 int line; /* current line on page */
25 int linum; /* current text line */
26 int ftext; /* first text line on page */
27 char *colp[72];
28 int nofile; /* number of current file */
29 char isclosed[10];
30 int peekc;
31 int swval; /* value for next switch */
32 int fpage; /* first page to print */
33 int page; /* current page number */
34 int oheadr; /* use old header format */
35 int colw; /* column width */
36 int nspace;
37 int width 65; /* line width */
38 int pwidth 65; /* width of physical line */
39 int length 66; /* length of physical page */
40 int plength 61; /* last print line */
41 int margin 10;
42 int prone 1; /* print header on page one */
43 int ntflg; /* no header or trailer */
44 int nuflg; /* not header line */
45 int mflg;
46 int tabc; /* print this as column separator */
47 char *tty;
48 int mode;
49 int precl 2; /* # blank lines preceding hdr */
50 int endl 5; /* min # blank lines end of page */
51 int indent; /* spaces preceding each line */
52 int ff; /* use ff, not blank lines */
53 int wasff; /* page break caused by ff */
54 int blankl; /* # blank lines between lines */
55 int count; /* whether to count linums */
56 int tab2sp; /* change tabs => spaces */
57 int queeze; /* squeeze blank lines from top */
58 /* of each page */
59 int jnamflg; /* print just file and not path */
60 int rapflg; /* wrap-around line overflow */
61 int spaftfil 0; /* space between files */
62
63
64 struct inode
65 {
66 int dev;
67 int inum;
68 int flags;
69 char nlink;
70 char uid;
71 char gid;
72 char siz0;
73 int size;
74 int ptr[8];
75 int atime[2];
76 int mtime[2];
77 };
78
79 main (argc, argv)
80 char **argv;
81 {
82 int nfdone;
83 int onintr ();
84 extern fout;
85
86 tty = "/dev/ttyx";
87 fout = dup (1);
88 close (1);
89 if ((signal (2, 1) & 01) == 0)
90 signal (2, onintr);
91 fixtty ();
92 dflts (0);
93 for (nfdone = 0; argc > 1; argc--)
94 {
95 argv++;
96 if (**argv == '-')
97 {
98 swval = 1; /* default to on */
99 setsw:
100 switch (*++*argv)
101 {
102 case 'b':
103 blankl = getn (++*argv);
104 continue;
105
106 case 'c':
107 count = swval;
108 continue;
109
110 case 'd':
111 dflts (*++*argv);
112 continue;
113
114 case 'e':
115 endl = getn (++*argv);
116 continue;
117
118 case 'f':
119 ff = swval;
120 continue;
121
122 case 'h':
123 if (argc >= 2)
124 {
125 header = *++argv;
126 argc--;
127 }
128 continue;
129
130 case 'i':
131 indent = getn (++*argv);
132 continue;
133
134 case 'j':
135 jnamflg = swval;
136 continue;
137
138 case 'l':
139 length = getn (++*argv);
140 continue;
141
142 case 'm':
143 mflg = swval;
144 continue;
145
146 case 'n':
147 prone = (swval ^ 1);
148 /* Yes => no */
149 continue;
150
151 case 'o':
152 oheadr = swval;
153 continue;
154
155 case 'p':
156 precl = getn (++*argv);
157 continue;
158
159 case 'q':
160 queeze = swval;
161 continue;
162
163 case 'r':
164 rapflg = swval;
165 continue;
166
167 case 's':
168 spaftfil = getn( ++*argv);
169 continue;
170
171 case 't':
172 ntflg = swval;
173 continue;
174
175 case 'u':
176 nuflg = swval;
177 continue;
178
179 case 'w':
180 width = getn (++*argv);
181 continue;
182
183 case 'x':
184 tab2sp = swval;
185 continue;
186
187 case '-':
188 swval = 0;
189 goto setsw;
190
191 default:
192 ncol = getn (*argv);
193 continue;
194 }
195 }
196 else
197 if (**argv == '+')
198 {
199 fpage = getn (++*argv);
200 }
201 else
202 {
203 col = 0;
204 icol = 0;
205 line = 0;
206 nspace = 0;
207 print (*argv, argv);
208 nfdone++;
209 if (mflg)
210 break;
211 }
212 }
213 if (nfdone == 0)
214 print (0);
215 flush ();
216 onintr ();
217 }
218
219 onintr ()
220 {
221
222 chmod (tty, mode);
223 exit (0);
224 }
225
226 fixtty ()
227 {
228 struct inode sbuf;
229 extern fout;
230
231 tty[8] = ttyn (fout);
232 fstat (fout, &sbuf);
233 mode = sbuf.flags & 0777;
234 chmod (tty, 0600);
235 }
236
237 dflts (dfltpkg)
238 {
239 switch (dfltpkg)
240 {
241 case 'd':
242 ncol = 1; /* number of columns */
243 width = 65; /* line width */
244 length = 60; /* length of physical page */
245 plength = 61; /* last print line */
246 margin = 10;
247 precl = 1; /* # blank lines preceding hdr */
248 endl = 5; /* min # blank lines end of page */
249 indent = 5; /* spaces preceding each line */
250 ff = 1; /* use ff, not blank lines */
251 blankl = 0; /* # blank lines between lines */
252 count = 0; /* whether to count linums */
253 prone = 0; /* print header on page one */
254 tab2sp = 0; /* change tabs into spaces */
255 queeze = 1; /* squeeze beginning of pages */
256 jnamflg = 0; /* print full pathname */
257 rapflg = 1; /* wrap around long lines */
258 oheadr = 0; /* nothin' but the best... */
259 break;
260
261 case 'l':
262 ncol = 1; /* number of columns */
263 width = 77; /* line width */
264 length = 60; /* length of physical page */
265 plength = 61; /* last print line */
266 margin = 10;
267 precl = 2; /* # blank lines preceding hdr */
268 endl = 5; /* min # blank lines end of page */
269 indent = 5; /* spaces preceding each line */
270 ff = 1; /* use ff, not blank lines */
271 blankl = 0; /* # blank lines between lines */
272 count = 0; /* whether to count linums */
273 prone = 1; /* print header on page one */
274 tab2sp = 0; /* change tabs into spaces */
275 queeze = 0; /* preserve start of each page */
276 jnamflg = 0; /* print full pathname */
277 rapflg = 1; /* wrap around long lines */
278 oheadr = 0; /* nothin' but the best... */
279 break;
280
281 case 'n':
282 ncol = 1; /* number of columns */
283 width = 80; /* line width */
284 length = 60; /* length of physical page */
285 plength = 61; /* last print line */
286 margin = 10;
287 precl = 2; /* # blank lines preceding hdr */
288 endl = 5; /* min # blank lines end of page */
289 indent = 5; /* spaces preceding each line */
290 ff = 1; /* use ff, not blank lines */
291 blankl = 0; /* # blank lines between lines */
292 count = 1; /* whether to count linums */
293 prone = 1; /* print header on page one */
294 tab2sp = 0; /* don't change tabs into spaces */
295 queeze = 0; /* preserve start of each page */
296 jnamflg = 0; /* print full pathname */
297 rapflg = 1; /* wrap around long lines */
298 oheadr = 0; /* nothin' but the best... */
299 break;
300
301 case 0:
302 default:
303 ncol = 0; /* number of columns */
304 width = 72; /* line width */
305 length = 66; /* length of physical page */
306 plength = 61; /* last print line */
307 margin = 10;
308 precl = 2; /* # blank lines preceding hdr */
309 endl = 5; /* min # blank lines end of page */
310 indent = 0; /* spaces preceding each line */
311 ff = 0; /* use ff, not blank lines */
312 blankl = 0; /* # blank lines between lines */
313 count = 0; /* whether to count linums */
314 prone = 1; /* print header on page one */
315 tab2sp = 0; /* don't change tabs into spaces */
316 queeze = 0; /* preserve start of each page */
317 jnamflg = 1; /* don't print full pathname */
318 rapflg = 0; /* don't wrap around long lines */
319 oheadr = 1; /* nothin' but the worst... */
320 break;
321 }
322 }
323
324
325 print (fp, argp)
326 char *fp;
327 char **argp;
328 {
329 struct inode sbuf;
330 int tmp1;
331 register int sncol,
332 sheader;
333 register char *cbuf;
334 extern fout;
335
336 linum = 1;
337 if (ntflg)
338 margin = 0;
339 else
340 margin = precl + endl + (nuflg ? 0 : 3);
341 if (length <= margin)
342 length = 66;
343 if (width <= 0)
344 width = 65;
345 if (ncol > 72 || ncol > width)
346 {
347 write (2, "Very funny.\n", 12);
348 exit ();
349 }
350 if (mflg)
351 {
352 mopen (argp);
353 ncol = nofile;
354 }
355 if (ncol > 1)
356 rapflg = 0;
357 colw = width / ncol;
358 sncol = ncol;
359 sheader = header;
360 plength = length - endl;
361 pwidth = width + indent;
362 if (ntflg)
363 plength = length;
364 if (--ncol < 0)
365 ncol = 0;
366 if (mflg)
367 fp = 0;
368 if (fp)
369 {
370 file = open (fp, 0);
371 if (file < 0)
372 {
373 errrpt (fp, sys_errlst[errno]);
374 return;
375 }
376 fstat (file, &sbuf);
377 }
378 else
379 {
380 file = 0;
381 time (sbuf.mtime);
382 }
383 if ((header == 0) && (file != 0))
384 header = jnamflg ? fp
385 : getpath (fp);
386 cbuf = ctime (sbuf.mtime);
387 cbuf[16] = '\0';
388 cbuf[24] = '\0';
389 page = 1;
390 icol = 0;
391 colp[ncol] = bufp = buffer;
392 if (mflg == 0)
393 nexbuf ();
394 while (mflg && nofile || (!mflg) && tpgetc (ncol) > 0)
395 {
396 if (mflg == 0)
397 {
398 colp[ncol]--;
399 if (colp[ncol] < buffer)
400 colp[ncol] = &buffer[BUFS];
401 }
402 line = 0;
403 if (ntflg == 0)
404 {
405 for (tmp1 = precl; tmp1--;)
406 put ('\n');
407 if ((nuflg == 0) &&
408 (prone || (page > 1)))
409 {
410 for (tmp1 = indent; tmp1--;)
411 put (' ');
412 if (!oheadr && header)
413 {
414 puts (header);
415 puts (" ");
416 }
417 puts (cbuf + 4);
418 put (' ');
419 puts (cbuf + 20);
420 if (oheadr)
421 {
422 puts (" ");
423 if (header)
424 {
425 puts (header);
426 put (' ');
427 }
428 }
429 else
430 do
431 put (' ');
432 while (col < (pwidth - 9));
433 puts ("Page ");
434 if (oheadr)
435 putd (page);
436 else
437 putrd (page);
438 puts ("\n\n\n");
439 }
440 }
441 ftext = line; /* # of first text line */
442 putpage ();
443
444 if (ff)
445 put ('\014');
446 else
447 if (ntflg == 0)
448 while (line < length)
449 put ('\n');
450 page++;
451 }
452 if ( (ntflg != 0) && (spaftfil > 0))
453 for (tmp1 = spaftfil; tmp1--;)
454 put('\n');
455 if (file)
456 close (file);
457 ncol = sncol;
458 header = sheader;
459 }
460
461 mopen (ap)
462 char **ap;
463 {
464 register char **p,
465 *p1;
466
467 p = ap;
468 while ((p1 = *p++) && p1 != -1)
469 {
470 isclosed[nofile] = fopen (p1, &buffer[2 * 259 * nofile]);
471 if (++nofile >= 10)
472 {
473 write (2, "Too many args.\n", 15);
474 exit ();
475 }
476 }
477 }
478
479 putpage ()
480 {
481 register int lastcol,
482 i,
483 c;
484 int j;
485
486 if (ncol == 0)
487 {
488 i = 1; /* always starting on new line */
489 while (c = pgetc (0))
490 {
491 if (i) /* new line */
492 {
493 if ((queeze) &&
494 (c == '\n') &&
495 (line == ftext) &&
496 (!wasff) &&
497 (page > 1)
498 )
499 {
500 linum++;
501 continue;
502 }
503
504 for (i = indent; i--;)
505 put (' ');
506 if (count)
507 {
508 putrd (linum);
509 puts (" ");
510 };
511 i = 0;
512 };
513 switch (c)
514 {
515 case FF:
516 wasff = 1;
517 return;
518 case '\n':
519 linum++;
520 for ((i = (blankl + 1)); i--;)
521 {
522 put ('\n');
523 if (line >= plength)
524 {
525 wasff = 0;
526 return;
527 }
528 }
529 i = 1; /* signal new line */
530 break;
531 default:
532 put (c);
533 }
534
535 }
536 return;
537 }
538 colp[0] = colp[ncol];
539 if (mflg == 0)
540 for (i = 1; i <= ncol; i++)
541 {
542 colp[i] = colp[i - 1];
543 for (j = margin; j < length; j++)
544 while ((c = tpgetc (i)) != '\n')
545 if (c == 0)
546 break;
547 }
548 while (line < plength)
549 {
550 for (i = indent; i--;)
551 put (' ');
552 lastcol = colw + indent;
553 for (i = 0; i < ncol; i++)
554 {
555 while ((c = pgetc (i)) && c != '\n')
556 if (col < lastcol || tabc != 0)
557 put (c);
558 if (c == 0 && ntflg)
559 return;
560 if (tabc)
561 put (tabc);
562 else
563 while (col < lastcol)
564 put (' ');
565 lastcol =+ colw;
566 }
567 while ((c = pgetc (ncol)) && c != '\n')
568 put (c);
569 put ('\n');
570 }
571 }
572
573 nexbuf ()
574 {
575 register int n;
576 register char *rbufp;
577
578 rbufp = bufp;
579 n = &buffer[BUFS] - rbufp;
580 if (n > 512)
581 n = 512;
582 if ((n = read (file, rbufp, n)) <= 0)
583 *rbufp = 0376;
584 else
585 {
586 rbufp =+ n;
587 if (rbufp >= &buffer[BUFS])
588 rbufp = buffer;
589 *rbufp = 0375;
590 }
591 bufp = rbufp;
592 }
593
594 tpgetc (ai)
595 {
596 register char **p;
597 register int c,
598 i;
599
600 i = ai;
601 if (mflg)
602 {
603 if ((c = getc (&buffer[2 * 259 * i])) < 0)
604 {
605 if (isclosed[i] == 0)
606 {
607 isclosed[i] = 1;
608 if (--nofile <= 0)
609 return (0);
610 }
611 return ('\n');
612 }
613 if (c == FF && ncol > 0)
614 c = '\n';
615 return (c);
616 }
617 loop:
618 c = **(p = &colp[i]) & 0377;
619 if (c == 0375)
620 {
621 nexbuf ();
622 c = **p & 0377;
623 }
624 if (c == 0376)
625 return (0);
626 (*p)++;
627 if (*p >= &buffer[BUFS])
628 *p = buffer;
629 if (c == 0)
630 goto loop;
631 return (c);
632 }
633
634 pgetc (i)
635 {
636 register int c;
637
638 if (peekc)
639 {
640 c = peekc;
641 peekc = 0;
642 }
643 else
644 c = tpgetc (i);
645 if (tabc)
646 return (c);
647 switch (c)
648 {
649
650 case '\t':
651 icol++;
652 if ((icol & 07) != 0)
653 peekc = '\t';
654 return (' ');
655
656 case '\n':
657 icol = 0;
658 break;
659 }
660 if (c >= ' ')
661 icol++;
662 return (c);
663 }
664
665 puts (as)
666 char *as;
667 {
668 register int c;
669 register char *s;
670
671 if ((s = as) == 0)
672 return;
673 while (c = *s++)
674 put (c);
675 }
676
677 putrd (an)
678 {
679 register int mag;
680
681 for (mag = 1000; ((mag > 1) && (mag > an)); mag =/ 10)
682 put (' ');
683 putd (an);
684 }
685
686
687 putd (an)
688 {
689 register int a,
690 n;
691
692 n = an;
693 if (a = n / 10)
694 putd (a);
695 put (n % 10 + '0');
696 }
697
698 put (ac)
699 {
700 register c;
701 int tspace;
702
703 c = ac;
704 if (tabc)
705 {
706 putcp (c);
707 if (c == '\n')
708 line++;
709 return;
710 }
711 switch (c)
712 {
713
714 case ' ':
715 nspace++;
716 col++;
717 return;
718
719 /* case '\t': */
720 /* c = '~';
721 */
722 /* break;
723 */
724 /* nspace =& 0177770;
725 */
726 /* nspace =+ 010;
727 */
728 /* col =& 0177770;
729 */
730 /* col =+ 010;
731 */
732 /* return;
733 */
734
735 case '\n':
736 nspace = 0;
737 line++;
738 col = 0;
739 break;
740
741 case 010:
742 case 033:
743 if (--col < 0)
744 col = 0;
745 if (--nspace < 0)
746 nspace = 0;
747
748 }
749
750 if (rapflg && (col >= 84)) /* overflow */
751 {
752 putcp ('\n');
753 line++;
754 tspace = col - 84;
755 col = nspace = 62; /* 84 - 22 */
756 sppr ();
757 putcp ('*');
758 putcp ('*');
759 col =+ (2 + (nspace = tspace));
760 };
761
762 sppr ();
763
764 if (c >= ' ')
765 col++;
766 putcp (c);
767 }
768
769 sppr ()
770 {
771 register int c,
772 ns;
773
774 if ((c != '\n') && (c != FF))
775 while (nspace)
776 {
777 if (
778 (!tab2sp) &&
779 (nspace > 2) &&
780 (col > (ns = ((col - nspace) | 07)))
781 )
782 {
783 nspace = col - ns - 1;
784 putcp ('\t');
785 }
786 else
787 {
788 nspace--;
789 putcp (' ');
790 }
791 }
792 }
793
794 getn (ap)
795 char *ap;
796 {
797 register int n,
798 c;
799 register char *p;
800
801 p = ap;
802 n = 0;
803 if ((*p < '0') || (*p > '9'))
804 errrpt (p, "in parameter is supposed to be a number");
805
806 while ((c = *p++) >= '0' && c <= '9')
807 n = n * 10 + c - '0';
808 return (n);
809 }
810
811 putcp (c)
812 {
813 if (page >= fpage)
814 putchar (c);
815 }
816
817 int fout;
818
819 errrpt (str1, str2)
820 char *str1,
821 *str2;
822 {
823 int ofout;
824
825 flush ();
826 ofout = fout;
827 fout = 2;
828
829 printf ("pr: \"%s\" %s.\n", str1, str2);
830
831 flush ();
832 fout = ofout;
833 };
834
835
836 #define DOT "."
837 #define DOTDOT ".."
838 #define ROOT "/"
839 #define DEBUG
840
841 getpath (filestr)
842 char *filestr;
843 {
844 int n;
845 int gpfile;
846 char *fulpath;
847 struct statb
848 {
849 int devn,
850 inum,
851 i[18];
852 } x;
853 struct entry
854 {
855 int jnum;
856 char name[16];
857 } y;
858
859
860
861 if (*filestr == '/')
862 {
863 fulpath = filestr; /* already a full name */
864 return (fulpath);
865 }
866
867 fulpath = alloc (1); /* got to start somewhere */
868 *fulpath = 0;
869 setexit ();
870
871 if (*fulpath) /* been here before ? */
872 {
873 chdir (fulpath); /* get back to original dir */
874 rplstr (&fulpath,
875 dircat ("", fulpath));
876 rplstr (&fulpath,
877 dircat (fulpath, filestr));
878 return (fulpath);
879 }
880
881 while (1)
882 {
883 stat (DOT, &x);
884 if ((gpfile = open (DOTDOT, 0)) < 0)
885 reset ();
886 do
887 {
888 if ((n = read (gpfile, &y, 16)) < 16)
889 reset ();
890 /* printf("y.name = %s\n",y.name); */
891 }
892 while (y.jnum != x.inum);
893 close (gpfile);
894 /* printf("y.jnum = %d\n",y.jnum); */
895 if (y.jnum == 1)
896 ckroot (y.name, &fulpath);
897
898 rplstr (&fulpath,
899 dircat (y.name, fulpath));
900 /* printf("fulpath = %s\n",fulpath); */
901 chdir (DOTDOT);
902 }
903 }
904
905 ckroot (name, fulpath)
906 char *name,
907 **fulpath;
908 {
909 int i,
910 n;
911 int gpfile;
912 struct statb
913 {
914 int devn,
915 inum,
916 i[18];
917 } x;
918 struct entry
919 {
920 int jnum;
921 char name[16];
922 } y;
923
924
925 if ((n = stat (name, &x)) < 0)
926 reset ();
927 i = x.devn;
928
929 if (((n = chdir (ROOT)) < 0) ||
930 ((gpfile = open (ROOT, 0)) < 0))
931 reset ();
932
933 /* printf("fulpath = %s\n",*fulpath); */
934 while (1)
935 {
936 if ((n = read (gpfile, &y, 16)) < 16)
937 reset ();
938 if (y.jnum == 0)
939 continue;
940 if ((n = stat (y.name, &x)) < 0)
941 reset ();
942 if (x.devn != i)
943 continue;
944 x.i[0] =& 060000;
945 if (x.i[0] != 040000)
946 continue;
947 if ((strequ (y.name, ".")) ||
948 (strequ (y.name, "..")))
949 break;
950 /* printf("y.name = %s\n",y.name); */
951 rplstr (fulpath,
952 dircat (y.name, *fulpath));
953 /* printf("fulpath = %s\n",*fulpath); */
954 }
955 reset ();
956 }
957
958
959 /* */
960 /* Return the length of the given string. This length */
961 /* does not include the terminating null character. */
962
963 pstrlen (string)
964 char *string;
965 {
966 register char *rstring;
967 register int rlength; /* length of string */
968
969 rstring = string;
970
971 for (rlength = 0; *rstring++ != 0; ++rlength);
972 return (rlength);
973 }
974
975
976 /* */
977 /* Copy the given string to the given location. */
978 /* */
979
980 strcpy (from, to)
981 char *from,
982 *to;
983 {
984 register char *rfrom,
985 *rto;
986
987 rfrom = from;
988 rto = to;
989
990 while (*rto++ = *rfrom++);
991 }
992
993 /* */
994 /* Concatenate the first given string the the second */
995 /* given string. */
996
997 dircat (prefix, suffix)
998 char *prefix,
999 *suffix;
1000 {
1001 register char *rprefix,
1002 *rsuffix,
1003 *ptr;
1004 char *newstr;
1005
1006 if ((ptr = newstr =
1007 alloc (pstrlen (rprefix = prefix) +
1008 pstrlen (rsuffix = suffix) + 2))
1009 == -1)
1010 {
1011 write (1, "No more string storage!\n", 24);
1012 exit ();
1013 }
1014 while (*ptr++ = *rprefix++);
1015 ptr--;
1016 if (ptr[-1] != '/')
1017 *ptr++ = '/';
1018 while (*ptr++ = *rsuffix++);
1019 return (newstr);
1020 }
1021
1022 /* */
1023 /* Determine if the two given strings are equivalent. */
1024 /* */
1025
1026 strequ (str1, str2)
1027 char *str1,
1028 *str2;
1029 {
1030 register char *rstr1,
1031 *rstr2;
1032
1033 rstr1 = str1;
1034 rstr2 = str2;
1035
1036 while (*rstr1 == *rstr2++)
1037 if (*rstr1++ == 0)
1038 return (1);
1039 return (0);
1040 }
1041
1042 rplstr (oldstr, newstr)
1043 char **oldstr,
1044 *newstr;
1045 {
1046 /* printf("oldstr = %s\nnewstr =
1047 %s\n",*oldstr,newstr); */
1048 free (*oldstr);
1049 *oldstr = newstr;
1050 }