Blame


1 53db2d0f 2004-04-21 devnull #include <u.h>
2 53db2d0f 2004-04-21 devnull #include <libc.h>
3 53db2d0f 2004-04-21 devnull #include <bio.h>
4 53db2d0f 2004-04-21 devnull #include <ctype.h>
5 53db2d0f 2004-04-21 devnull
6 53db2d0f 2004-04-21 devnull /*
7 53db2d0f 2004-04-21 devnull * PR command (print files in pages and columns, with headings)
8 53db2d0f 2004-04-21 devnull * 2+head+2+page[56]+5
9 53db2d0f 2004-04-21 devnull */
10 53db2d0f 2004-04-21 devnull
11 53db2d0f 2004-04-21 devnull #define ISPRINT(c) ((c) >= ' ')
12 53db2d0f 2004-04-21 devnull #define ESC '\033'
13 53db2d0f 2004-04-21 devnull #define LENGTH 66
14 53db2d0f 2004-04-21 devnull #define LINEW 72
15 53db2d0f 2004-04-21 devnull #define NUMW 5
16 53db2d0f 2004-04-21 devnull #define MARGIN 10
17 53db2d0f 2004-04-21 devnull #define DEFTAB 8
18 53db2d0f 2004-04-21 devnull #define NFILES 10
19 53db2d0f 2004-04-21 devnull #define HEAD "%12.12s %4.4s %s Page %d\n\n\n", date+4, date+24, head, Page
20 53db2d0f 2004-04-21 devnull #define TOLOWER(c) (isupper(c) ? tolower(c) : c) /* ouch! */
21 53db2d0f 2004-04-21 devnull #define cerror(S) fprint(2, "pr: %s", S)
22 53db2d0f 2004-04-21 devnull #define STDINNAME() nulls
23 53db2d0f 2004-04-21 devnull #define TTY "/dev/cons", 0
24 53db2d0f 2004-04-21 devnull #define PROMPT() fprint(2, "\a") /* BEL */
25 53db2d0f 2004-04-21 devnull #define TABS(N,C) if((N = intopt(argv, &C)) < 0) N = DEFTAB
26 53db2d0f 2004-04-21 devnull #define ETABS (Inpos % Etabn)
27 53db2d0f 2004-04-21 devnull #define ITABS (Itabn > 0 && Nspace > 1 && Nspace >= (nc = Itabn - Outpos % Itabn))
28 53db2d0f 2004-04-21 devnull #define NSEPC '\t'
29 53db2d0f 2004-04-21 devnull #define EMPTY 14 /* length of " -- empty file" */
30 53db2d0f 2004-04-21 devnull
31 53db2d0f 2004-04-21 devnull typedef struct Fils Fils;
32 53db2d0f 2004-04-21 devnull typedef struct Colp* Colp;
33 53db2d0f 2004-04-21 devnull typedef struct Err Err;
34 53db2d0f 2004-04-21 devnull
35 53db2d0f 2004-04-21 devnull struct Fils
36 53db2d0f 2004-04-21 devnull {
37 53db2d0f 2004-04-21 devnull Biobuf* f_f;
38 53db2d0f 2004-04-21 devnull char* f_name;
39 53db2d0f 2004-04-21 devnull long f_nextc;
40 53db2d0f 2004-04-21 devnull };
41 53db2d0f 2004-04-21 devnull struct Colp
42 53db2d0f 2004-04-21 devnull {
43 53db2d0f 2004-04-21 devnull Rune* c_ptr;
44 53db2d0f 2004-04-21 devnull Rune* c_ptr0;
45 53db2d0f 2004-04-21 devnull long c_lno;
46 53db2d0f 2004-04-21 devnull };
47 53db2d0f 2004-04-21 devnull struct Err
48 53db2d0f 2004-04-21 devnull {
49 53db2d0f 2004-04-21 devnull Err* e_nextp;
50 53db2d0f 2004-04-21 devnull char* e_mess;
51 53db2d0f 2004-04-21 devnull };
52 53db2d0f 2004-04-21 devnull
53 53db2d0f 2004-04-21 devnull int Balance = 0;
54 53db2d0f 2004-04-21 devnull Biobuf bout;
55 53db2d0f 2004-04-21 devnull Rune* Bufend;
56 53db2d0f 2004-04-21 devnull Rune* Buffer = 0;
57 53db2d0f 2004-04-21 devnull int C = '\0';
58 53db2d0f 2004-04-21 devnull Colp Colpts;
59 53db2d0f 2004-04-21 devnull int Colw;
60 53db2d0f 2004-04-21 devnull int Dblspace = 1;
61 53db2d0f 2004-04-21 devnull Err* err = 0;
62 53db2d0f 2004-04-21 devnull int error = 0;
63 53db2d0f 2004-04-21 devnull int Etabc = '\t';
64 53db2d0f 2004-04-21 devnull int Etabn = 0;
65 53db2d0f 2004-04-21 devnull Fils* Files;
66 53db2d0f 2004-04-21 devnull int Formfeed = 0;
67 53db2d0f 2004-04-21 devnull int Fpage = 1;
68 53db2d0f 2004-04-21 devnull char* Head = 0;
69 53db2d0f 2004-04-21 devnull int Inpos;
70 53db2d0f 2004-04-21 devnull int Itabc = '\t';
71 53db2d0f 2004-04-21 devnull int Itabn = 0;
72 53db2d0f 2004-04-21 devnull Err* Lasterr = (Err*)&err;
73 53db2d0f 2004-04-21 devnull int Lcolpos;
74 53db2d0f 2004-04-21 devnull int Len = LENGTH;
75 53db2d0f 2004-04-21 devnull int Line;
76 53db2d0f 2004-04-21 devnull int Linew = 0;
77 53db2d0f 2004-04-21 devnull long Lnumb = 0;
78 53db2d0f 2004-04-21 devnull int Margin = MARGIN;
79 53db2d0f 2004-04-21 devnull int Multi = 0;
80 53db2d0f 2004-04-21 devnull int Ncols = 1;
81 53db2d0f 2004-04-21 devnull int Nfiles = 0;
82 53db2d0f 2004-04-21 devnull int Nsepc = NSEPC;
83 53db2d0f 2004-04-21 devnull int Nspace;
84 53db2d0f 2004-04-21 devnull char nulls[] = "";
85 53db2d0f 2004-04-21 devnull int Numw;
86 53db2d0f 2004-04-21 devnull int Offset = 0;
87 53db2d0f 2004-04-21 devnull int Outpos;
88 53db2d0f 2004-04-21 devnull int Padodd;
89 53db2d0f 2004-04-21 devnull int Page;
90 53db2d0f 2004-04-21 devnull int Pcolpos;
91 53db2d0f 2004-04-21 devnull int Plength;
92 53db2d0f 2004-04-21 devnull int Sepc = 0;
93 53db2d0f 2004-04-21 devnull
94 53db2d0f 2004-04-21 devnull extern int atoix(char**);
95 53db2d0f 2004-04-21 devnull extern void balance(int);
96 53db2d0f 2004-04-21 devnull extern void die(char*);
97 53db2d0f 2004-04-21 devnull extern void errprint(void);
98 53db2d0f 2004-04-21 devnull extern char* ffiler(char*);
99 53db2d0f 2004-04-21 devnull extern int findopt(int, char**);
100 53db2d0f 2004-04-21 devnull extern int get(int);
101 53db2d0f 2004-04-21 devnull extern void* getspace(ulong);
102 53db2d0f 2004-04-21 devnull extern int intopt(char**, int*);
103 53db2d0f 2004-04-21 devnull extern void main(int, char**);
104 53db2d0f 2004-04-21 devnull extern Biobuf* mustopen(char*, Fils*);
105 53db2d0f 2004-04-21 devnull extern void nexbuf(void);
106 53db2d0f 2004-04-21 devnull extern int pr(char*);
107 53db2d0f 2004-04-21 devnull extern void put(long);
108 53db2d0f 2004-04-21 devnull extern void putpage(void);
109 53db2d0f 2004-04-21 devnull extern void putspace(void);
110 53db2d0f 2004-04-21 devnull
111 53db2d0f 2004-04-21 devnull /*
112 53db2d0f 2004-04-21 devnull * return date file was last modified
113 53db2d0f 2004-04-21 devnull */
114 1d14d0ab 2004-04-25 devnull #define getdate prgetdate
115 1d14d0ab 2004-04-25 devnull
116 53db2d0f 2004-04-21 devnull char*
117 53db2d0f 2004-04-21 devnull getdate(void)
118 53db2d0f 2004-04-21 devnull {
119 53db2d0f 2004-04-21 devnull static char *now = 0;
120 53db2d0f 2004-04-21 devnull static Dir *sbuf;
121 53db2d0f 2004-04-21 devnull ulong mtime;
122 53db2d0f 2004-04-21 devnull
123 53db2d0f 2004-04-21 devnull if(Nfiles > 1 || Files->f_name == nulls) {
124 53db2d0f 2004-04-21 devnull if(now == 0) {
125 53db2d0f 2004-04-21 devnull mtime = time(0);
126 53db2d0f 2004-04-21 devnull now = ctime(mtime);
127 53db2d0f 2004-04-21 devnull }
128 53db2d0f 2004-04-21 devnull return now;
129 53db2d0f 2004-04-21 devnull }
130 53db2d0f 2004-04-21 devnull mtime = 0;
131 53db2d0f 2004-04-21 devnull sbuf = dirstat(Files->f_name);
132 53db2d0f 2004-04-21 devnull if(sbuf){
133 53db2d0f 2004-04-21 devnull mtime = sbuf->mtime;
134 53db2d0f 2004-04-21 devnull free(sbuf);
135 53db2d0f 2004-04-21 devnull }
136 53db2d0f 2004-04-21 devnull return ctime(mtime);
137 53db2d0f 2004-04-21 devnull }
138 53db2d0f 2004-04-21 devnull
139 53db2d0f 2004-04-21 devnull char*
140 53db2d0f 2004-04-21 devnull ffiler(char *s)
141 53db2d0f 2004-04-21 devnull {
142 53db2d0f 2004-04-21 devnull return smprint("can't open %s\n", s);
143 53db2d0f 2004-04-21 devnull }
144 53db2d0f 2004-04-21 devnull
145 53db2d0f 2004-04-21 devnull void
146 53db2d0f 2004-04-21 devnull main(int argc, char *argv[])
147 53db2d0f 2004-04-21 devnull {
148 53db2d0f 2004-04-21 devnull Fils fstr[NFILES];
149 53db2d0f 2004-04-21 devnull int nfdone = 0;
150 53db2d0f 2004-04-21 devnull
151 53db2d0f 2004-04-21 devnull Binit(&bout, 1, OWRITE);
152 53db2d0f 2004-04-21 devnull Files = fstr;
153 53db2d0f 2004-04-21 devnull for(argc = findopt(argc, argv); argc > 0; --argc, ++argv)
154 53db2d0f 2004-04-21 devnull if(Multi == 'm') {
155 53db2d0f 2004-04-21 devnull if(Nfiles >= NFILES - 1)
156 53db2d0f 2004-04-21 devnull die("too many files");
157 53db2d0f 2004-04-21 devnull if(mustopen(*argv, &Files[Nfiles++]) == 0)
158 53db2d0f 2004-04-21 devnull nfdone++; /* suppress printing */
159 53db2d0f 2004-04-21 devnull } else {
160 53db2d0f 2004-04-21 devnull if(pr(*argv))
161 53db2d0f 2004-04-21 devnull Bterm(Files->f_f);
162 53db2d0f 2004-04-21 devnull nfdone++;
163 53db2d0f 2004-04-21 devnull }
164 53db2d0f 2004-04-21 devnull if(!nfdone) /* no files named, use stdin */
165 53db2d0f 2004-04-21 devnull pr(nulls); /* on GCOS, use current file, if any */
166 53db2d0f 2004-04-21 devnull errprint(); /* print accumulated error reports */
167 53db2d0f 2004-04-21 devnull exits(error? "error": 0);
168 53db2d0f 2004-04-21 devnull }
169 53db2d0f 2004-04-21 devnull
170 53db2d0f 2004-04-21 devnull int
171 53db2d0f 2004-04-21 devnull findopt(int argc, char *argv[])
172 53db2d0f 2004-04-21 devnull {
173 53db2d0f 2004-04-21 devnull char **eargv = argv;
174 53db2d0f 2004-04-21 devnull int eargc = 0, c;
175 53db2d0f 2004-04-21 devnull
176 53db2d0f 2004-04-21 devnull while(--argc > 0) {
177 53db2d0f 2004-04-21 devnull switch(c = **++argv) {
178 53db2d0f 2004-04-21 devnull case '-':
179 53db2d0f 2004-04-21 devnull if((c = *++*argv) == '\0')
180 53db2d0f 2004-04-21 devnull break;
181 53db2d0f 2004-04-21 devnull case '+':
182 53db2d0f 2004-04-21 devnull do {
183 53db2d0f 2004-04-21 devnull if(isdigit(c)) {
184 53db2d0f 2004-04-21 devnull --*argv;
185 53db2d0f 2004-04-21 devnull Ncols = atoix(argv);
186 53db2d0f 2004-04-21 devnull } else
187 53db2d0f 2004-04-21 devnull switch(c = TOLOWER(c)) {
188 53db2d0f 2004-04-21 devnull case '+':
189 53db2d0f 2004-04-21 devnull if((Fpage = atoix(argv)) < 1)
190 53db2d0f 2004-04-21 devnull Fpage = 1;
191 53db2d0f 2004-04-21 devnull continue;
192 53db2d0f 2004-04-21 devnull case 'd':
193 53db2d0f 2004-04-21 devnull Dblspace = 2;
194 53db2d0f 2004-04-21 devnull continue;
195 53db2d0f 2004-04-21 devnull case 'e':
196 53db2d0f 2004-04-21 devnull TABS(Etabn, Etabc);
197 53db2d0f 2004-04-21 devnull continue;
198 53db2d0f 2004-04-21 devnull case 'f':
199 53db2d0f 2004-04-21 devnull Formfeed++;
200 53db2d0f 2004-04-21 devnull continue;
201 53db2d0f 2004-04-21 devnull case 'h':
202 53db2d0f 2004-04-21 devnull if(--argc > 0)
203 53db2d0f 2004-04-21 devnull Head = argv[1];
204 53db2d0f 2004-04-21 devnull continue;
205 53db2d0f 2004-04-21 devnull case 'i':
206 53db2d0f 2004-04-21 devnull TABS(Itabn, Itabc);
207 53db2d0f 2004-04-21 devnull continue;
208 53db2d0f 2004-04-21 devnull case 'l':
209 53db2d0f 2004-04-21 devnull Len = atoix(argv);
210 53db2d0f 2004-04-21 devnull continue;
211 53db2d0f 2004-04-21 devnull case 'a':
212 53db2d0f 2004-04-21 devnull case 'm':
213 53db2d0f 2004-04-21 devnull Multi = c;
214 53db2d0f 2004-04-21 devnull continue;
215 53db2d0f 2004-04-21 devnull case 'o':
216 53db2d0f 2004-04-21 devnull Offset = atoix(argv);
217 53db2d0f 2004-04-21 devnull continue;
218 53db2d0f 2004-04-21 devnull case 's':
219 53db2d0f 2004-04-21 devnull if((Sepc = (*argv)[1]) != '\0')
220 53db2d0f 2004-04-21 devnull ++*argv;
221 53db2d0f 2004-04-21 devnull else
222 53db2d0f 2004-04-21 devnull Sepc = '\t';
223 53db2d0f 2004-04-21 devnull continue;
224 53db2d0f 2004-04-21 devnull case 't':
225 53db2d0f 2004-04-21 devnull Margin = 0;
226 53db2d0f 2004-04-21 devnull continue;
227 53db2d0f 2004-04-21 devnull case 'w':
228 53db2d0f 2004-04-21 devnull Linew = atoix(argv);
229 53db2d0f 2004-04-21 devnull continue;
230 53db2d0f 2004-04-21 devnull case 'n':
231 53db2d0f 2004-04-21 devnull Lnumb++;
232 53db2d0f 2004-04-21 devnull if((Numw = intopt(argv, &Nsepc)) <= 0)
233 53db2d0f 2004-04-21 devnull Numw = NUMW;
234 53db2d0f 2004-04-21 devnull case 'b':
235 53db2d0f 2004-04-21 devnull Balance = 1;
236 53db2d0f 2004-04-21 devnull continue;
237 53db2d0f 2004-04-21 devnull case 'p':
238 53db2d0f 2004-04-21 devnull Padodd = 1;
239 53db2d0f 2004-04-21 devnull continue;
240 53db2d0f 2004-04-21 devnull default:
241 53db2d0f 2004-04-21 devnull die("bad option");
242 53db2d0f 2004-04-21 devnull }
243 53db2d0f 2004-04-21 devnull } while((c = *++*argv) != '\0');
244 53db2d0f 2004-04-21 devnull if(Head == argv[1])
245 53db2d0f 2004-04-21 devnull argv++;
246 53db2d0f 2004-04-21 devnull continue;
247 53db2d0f 2004-04-21 devnull }
248 53db2d0f 2004-04-21 devnull *eargv++ = *argv;
249 53db2d0f 2004-04-21 devnull eargc++;
250 53db2d0f 2004-04-21 devnull }
251 53db2d0f 2004-04-21 devnull if(Len == 0)
252 53db2d0f 2004-04-21 devnull Len = LENGTH;
253 53db2d0f 2004-04-21 devnull if(Len <= Margin)
254 53db2d0f 2004-04-21 devnull Margin = 0;
255 53db2d0f 2004-04-21 devnull Plength = Len - Margin/2;
256 53db2d0f 2004-04-21 devnull if(Multi == 'm')
257 53db2d0f 2004-04-21 devnull Ncols = eargc;
258 53db2d0f 2004-04-21 devnull switch(Ncols) {
259 53db2d0f 2004-04-21 devnull case 0:
260 53db2d0f 2004-04-21 devnull Ncols = 1;
261 53db2d0f 2004-04-21 devnull case 1:
262 53db2d0f 2004-04-21 devnull break;
263 53db2d0f 2004-04-21 devnull default:
264 53db2d0f 2004-04-21 devnull if(Etabn == 0) /* respect explicit tab specification */
265 53db2d0f 2004-04-21 devnull Etabn = DEFTAB;
266 53db2d0f 2004-04-21 devnull }
267 53db2d0f 2004-04-21 devnull if(Linew == 0)
268 53db2d0f 2004-04-21 devnull Linew = Ncols != 1 && Sepc == 0? LINEW: 512;
269 53db2d0f 2004-04-21 devnull if(Lnumb)
270 53db2d0f 2004-04-21 devnull Linew -= Multi == 'm'? Numw: Numw*Ncols;
271 53db2d0f 2004-04-21 devnull if((Colw = (Linew - Ncols + 1)/Ncols) < 1)
272 53db2d0f 2004-04-21 devnull die("width too small");
273 53db2d0f 2004-04-21 devnull if(Ncols != 1 && Multi == 0) {
274 53db2d0f 2004-04-21 devnull ulong buflen = ((ulong)(Plength/Dblspace + 1))*(Linew+1)*sizeof(char);
275 53db2d0f 2004-04-21 devnull Buffer = getspace(buflen*sizeof(*Buffer));
276 53db2d0f 2004-04-21 devnull Bufend = &Buffer[buflen];
277 53db2d0f 2004-04-21 devnull Colpts = getspace((Ncols+1)*sizeof(*Colpts));
278 53db2d0f 2004-04-21 devnull }
279 53db2d0f 2004-04-21 devnull return eargc;
280 53db2d0f 2004-04-21 devnull }
281 53db2d0f 2004-04-21 devnull
282 53db2d0f 2004-04-21 devnull int
283 53db2d0f 2004-04-21 devnull intopt(char *argv[], int *optp)
284 53db2d0f 2004-04-21 devnull {
285 53db2d0f 2004-04-21 devnull int c;
286 53db2d0f 2004-04-21 devnull
287 53db2d0f 2004-04-21 devnull if((c = (*argv)[1]) != '\0' && !isdigit(c)) {
288 53db2d0f 2004-04-21 devnull *optp = c;
289 53db2d0f 2004-04-21 devnull (*argv)++;
290 53db2d0f 2004-04-21 devnull }
291 53db2d0f 2004-04-21 devnull c = atoix(argv);
292 53db2d0f 2004-04-21 devnull return c != 0? c: -1;
293 53db2d0f 2004-04-21 devnull }
294 53db2d0f 2004-04-21 devnull
295 53db2d0f 2004-04-21 devnull int
296 53db2d0f 2004-04-21 devnull pr(char *name)
297 53db2d0f 2004-04-21 devnull {
298 53db2d0f 2004-04-21 devnull char *date = 0, *head = 0;
299 53db2d0f 2004-04-21 devnull
300 53db2d0f 2004-04-21 devnull if(Multi != 'm' && mustopen(name, &Files[0]) == 0)
301 53db2d0f 2004-04-21 devnull return 0;
302 53db2d0f 2004-04-21 devnull if(Buffer)
303 53db2d0f 2004-04-21 devnull Bungetc(Files->f_f);
304 53db2d0f 2004-04-21 devnull if(Lnumb)
305 53db2d0f 2004-04-21 devnull Lnumb = 1;
306 53db2d0f 2004-04-21 devnull for(Page = 0;; putpage()) {
307 53db2d0f 2004-04-21 devnull if(C == -1)
308 53db2d0f 2004-04-21 devnull break;
309 53db2d0f 2004-04-21 devnull if(Buffer)
310 53db2d0f 2004-04-21 devnull nexbuf();
311 53db2d0f 2004-04-21 devnull Inpos = 0;
312 53db2d0f 2004-04-21 devnull if(get(0) == -1)
313 53db2d0f 2004-04-21 devnull break;
314 53db2d0f 2004-04-21 devnull Bflush(&bout);
315 53db2d0f 2004-04-21 devnull Page++;
316 53db2d0f 2004-04-21 devnull if(Page >= Fpage) {
317 53db2d0f 2004-04-21 devnull if(Margin == 0)
318 53db2d0f 2004-04-21 devnull continue;
319 53db2d0f 2004-04-21 devnull if(date == 0)
320 53db2d0f 2004-04-21 devnull date = getdate();
321 53db2d0f 2004-04-21 devnull if(head == 0)
322 53db2d0f 2004-04-21 devnull head = Head != 0 ? Head :
323 53db2d0f 2004-04-21 devnull Nfiles < 2? Files->f_name: nulls;
324 53db2d0f 2004-04-21 devnull Bprint(&bout, "\n\n");
325 53db2d0f 2004-04-21 devnull Nspace = Offset;
326 53db2d0f 2004-04-21 devnull putspace();
327 53db2d0f 2004-04-21 devnull Bprint(&bout, HEAD);
328 53db2d0f 2004-04-21 devnull }
329 53db2d0f 2004-04-21 devnull }
330 53db2d0f 2004-04-21 devnull if(Padodd && (Page&1) == 1) {
331 53db2d0f 2004-04-21 devnull Line = 0;
332 53db2d0f 2004-04-21 devnull if(Formfeed)
333 53db2d0f 2004-04-21 devnull put('\f');
334 53db2d0f 2004-04-21 devnull else
335 53db2d0f 2004-04-21 devnull while(Line < Len)
336 53db2d0f 2004-04-21 devnull put('\n');
337 53db2d0f 2004-04-21 devnull }
338 53db2d0f 2004-04-21 devnull C = '\0';
339 53db2d0f 2004-04-21 devnull return 1;
340 53db2d0f 2004-04-21 devnull }
341 53db2d0f 2004-04-21 devnull
342 53db2d0f 2004-04-21 devnull void
343 53db2d0f 2004-04-21 devnull putpage(void)
344 53db2d0f 2004-04-21 devnull {
345 53db2d0f 2004-04-21 devnull int colno;
346 53db2d0f 2004-04-21 devnull
347 53db2d0f 2004-04-21 devnull for(Line = Margin/2;; get(0)) {
348 53db2d0f 2004-04-21 devnull for(Nspace = Offset, colno = 0, Outpos = 0; C != '\f';) {
349 53db2d0f 2004-04-21 devnull if(Lnumb && C != -1 && (colno == 0 || Multi == 'a')) {
350 53db2d0f 2004-04-21 devnull if(Page >= Fpage) {
351 53db2d0f 2004-04-21 devnull putspace();
352 53db2d0f 2004-04-21 devnull Bprint(&bout, "%*ld", Numw, Buffer?
353 53db2d0f 2004-04-21 devnull Colpts[colno].c_lno++: Lnumb);
354 53db2d0f 2004-04-21 devnull Outpos += Numw;
355 53db2d0f 2004-04-21 devnull put(Nsepc);
356 53db2d0f 2004-04-21 devnull }
357 53db2d0f 2004-04-21 devnull Lnumb++;
358 53db2d0f 2004-04-21 devnull }
359 53db2d0f 2004-04-21 devnull for(Lcolpos=0, Pcolpos=0; C!='\n' && C!='\f' && C!=-1; get(colno))
360 53db2d0f 2004-04-21 devnull put(C);
361 53db2d0f 2004-04-21 devnull if(C==-1 || ++colno==Ncols || C=='\n' && get(colno)==-1)
362 53db2d0f 2004-04-21 devnull break;
363 53db2d0f 2004-04-21 devnull if(Sepc)
364 53db2d0f 2004-04-21 devnull put(Sepc);
365 53db2d0f 2004-04-21 devnull else
366 53db2d0f 2004-04-21 devnull if((Nspace += Colw - Lcolpos + 1) < 1)
367 53db2d0f 2004-04-21 devnull Nspace = 1;
368 53db2d0f 2004-04-21 devnull }
369 53db2d0f 2004-04-21 devnull /*
370 53db2d0f 2004-04-21 devnull if(C == -1) {
371 53db2d0f 2004-04-21 devnull if(Margin != 0)
372 53db2d0f 2004-04-21 devnull break;
373 53db2d0f 2004-04-21 devnull if(colno != 0)
374 53db2d0f 2004-04-21 devnull put('\n');
375 53db2d0f 2004-04-21 devnull return;
376 53db2d0f 2004-04-21 devnull }
377 53db2d0f 2004-04-21 devnull */
378 53db2d0f 2004-04-21 devnull if(C == -1 && colno == 0) {
379 53db2d0f 2004-04-21 devnull if(Margin != 0)
380 53db2d0f 2004-04-21 devnull break;
381 53db2d0f 2004-04-21 devnull return;
382 53db2d0f 2004-04-21 devnull }
383 53db2d0f 2004-04-21 devnull if(C == '\f')
384 53db2d0f 2004-04-21 devnull break;
385 53db2d0f 2004-04-21 devnull put('\n');
386 53db2d0f 2004-04-21 devnull if(Dblspace == 2 && Line < Plength)
387 53db2d0f 2004-04-21 devnull put('\n');
388 53db2d0f 2004-04-21 devnull if(Line >= Plength)
389 53db2d0f 2004-04-21 devnull break;
390 53db2d0f 2004-04-21 devnull }
391 53db2d0f 2004-04-21 devnull if(Formfeed)
392 53db2d0f 2004-04-21 devnull put('\f');
393 53db2d0f 2004-04-21 devnull else
394 53db2d0f 2004-04-21 devnull while(Line < Len)
395 53db2d0f 2004-04-21 devnull put('\n');
396 53db2d0f 2004-04-21 devnull }
397 53db2d0f 2004-04-21 devnull
398 53db2d0f 2004-04-21 devnull void
399 53db2d0f 2004-04-21 devnull nexbuf(void)
400 53db2d0f 2004-04-21 devnull {
401 53db2d0f 2004-04-21 devnull Rune *s = Buffer;
402 53db2d0f 2004-04-21 devnull Colp p = Colpts;
403 53db2d0f 2004-04-21 devnull int j, c, bline = 0;
404 53db2d0f 2004-04-21 devnull
405 53db2d0f 2004-04-21 devnull for(;;) {
406 53db2d0f 2004-04-21 devnull p->c_ptr0 = p->c_ptr = s;
407 53db2d0f 2004-04-21 devnull if(p == &Colpts[Ncols])
408 53db2d0f 2004-04-21 devnull return;
409 53db2d0f 2004-04-21 devnull (p++)->c_lno = Lnumb + bline;
410 53db2d0f 2004-04-21 devnull for(j = (Len - Margin)/Dblspace; --j >= 0; bline++)
411 53db2d0f 2004-04-21 devnull for(Inpos = 0;;) {
412 53db2d0f 2004-04-21 devnull if((c = Bgetrune(Files->f_f)) == -1) {
413 53db2d0f 2004-04-21 devnull for(*s = -1; p <= &Colpts[Ncols]; p++)
414 53db2d0f 2004-04-21 devnull p->c_ptr0 = p->c_ptr = s;
415 53db2d0f 2004-04-21 devnull if(Balance)
416 53db2d0f 2004-04-21 devnull balance(bline);
417 53db2d0f 2004-04-21 devnull return;
418 53db2d0f 2004-04-21 devnull }
419 53db2d0f 2004-04-21 devnull if(ISPRINT(c))
420 53db2d0f 2004-04-21 devnull Inpos++;
421 53db2d0f 2004-04-21 devnull if(Inpos <= Colw || c == '\n') {
422 53db2d0f 2004-04-21 devnull *s = c;
423 53db2d0f 2004-04-21 devnull if(++s >= Bufend)
424 53db2d0f 2004-04-21 devnull die("page-buffer overflow");
425 53db2d0f 2004-04-21 devnull }
426 53db2d0f 2004-04-21 devnull if(c == '\n')
427 53db2d0f 2004-04-21 devnull break;
428 53db2d0f 2004-04-21 devnull switch(c) {
429 53db2d0f 2004-04-21 devnull case '\b':
430 53db2d0f 2004-04-21 devnull if(Inpos == 0)
431 53db2d0f 2004-04-21 devnull s--;
432 53db2d0f 2004-04-21 devnull case ESC:
433 53db2d0f 2004-04-21 devnull if(Inpos > 0)
434 53db2d0f 2004-04-21 devnull Inpos--;
435 53db2d0f 2004-04-21 devnull }
436 53db2d0f 2004-04-21 devnull }
437 53db2d0f 2004-04-21 devnull }
438 53db2d0f 2004-04-21 devnull }
439 53db2d0f 2004-04-21 devnull
440 53db2d0f 2004-04-21 devnull /*
441 53db2d0f 2004-04-21 devnull * line balancing for last page
442 53db2d0f 2004-04-21 devnull */
443 53db2d0f 2004-04-21 devnull void
444 53db2d0f 2004-04-21 devnull balance(int bline)
445 53db2d0f 2004-04-21 devnull {
446 53db2d0f 2004-04-21 devnull Rune *s = Buffer;
447 53db2d0f 2004-04-21 devnull Colp p = Colpts;
448 53db2d0f 2004-04-21 devnull int colno = 0, j, c, l;
449 53db2d0f 2004-04-21 devnull
450 53db2d0f 2004-04-21 devnull c = bline % Ncols;
451 53db2d0f 2004-04-21 devnull l = (bline + Ncols - 1)/Ncols;
452 53db2d0f 2004-04-21 devnull bline = 0;
453 53db2d0f 2004-04-21 devnull do {
454 53db2d0f 2004-04-21 devnull for(j = 0; j < l; ++j)
455 53db2d0f 2004-04-21 devnull while(*s++ != '\n')
456 53db2d0f 2004-04-21 devnull ;
457 53db2d0f 2004-04-21 devnull (++p)->c_lno = Lnumb + (bline += l);
458 53db2d0f 2004-04-21 devnull p->c_ptr0 = p->c_ptr = s;
459 53db2d0f 2004-04-21 devnull if(++colno == c)
460 53db2d0f 2004-04-21 devnull l--;
461 53db2d0f 2004-04-21 devnull } while(colno < Ncols - 1);
462 53db2d0f 2004-04-21 devnull }
463 53db2d0f 2004-04-21 devnull
464 53db2d0f 2004-04-21 devnull int
465 53db2d0f 2004-04-21 devnull get(int colno)
466 53db2d0f 2004-04-21 devnull {
467 53db2d0f 2004-04-21 devnull static int peekc = 0;
468 53db2d0f 2004-04-21 devnull Colp p;
469 53db2d0f 2004-04-21 devnull Fils *q;
470 53db2d0f 2004-04-21 devnull long c;
471 53db2d0f 2004-04-21 devnull
472 53db2d0f 2004-04-21 devnull if(peekc) {
473 53db2d0f 2004-04-21 devnull peekc = 0;
474 53db2d0f 2004-04-21 devnull c = Etabc;
475 53db2d0f 2004-04-21 devnull } else
476 53db2d0f 2004-04-21 devnull if(Buffer) {
477 53db2d0f 2004-04-21 devnull p = &Colpts[colno];
478 53db2d0f 2004-04-21 devnull if(p->c_ptr >= (p+1)->c_ptr0)
479 53db2d0f 2004-04-21 devnull c = -1;
480 53db2d0f 2004-04-21 devnull else
481 53db2d0f 2004-04-21 devnull if((c = *p->c_ptr) != -1)
482 53db2d0f 2004-04-21 devnull p->c_ptr++;
483 53db2d0f 2004-04-21 devnull } else
484 53db2d0f 2004-04-21 devnull if((c = (q = &Files[Multi == 'a'? 0: colno])->f_nextc) == -1) {
485 53db2d0f 2004-04-21 devnull for(q = &Files[Nfiles]; --q >= Files && q->f_nextc == -1;)
486 53db2d0f 2004-04-21 devnull ;
487 53db2d0f 2004-04-21 devnull if(q >= Files)
488 53db2d0f 2004-04-21 devnull c = '\n';
489 53db2d0f 2004-04-21 devnull } else
490 53db2d0f 2004-04-21 devnull q->f_nextc = Bgetrune(q->f_f);
491 53db2d0f 2004-04-21 devnull if(Etabn != 0 && c == Etabc) {
492 53db2d0f 2004-04-21 devnull Inpos++;
493 53db2d0f 2004-04-21 devnull peekc = ETABS;
494 53db2d0f 2004-04-21 devnull c = ' ';
495 53db2d0f 2004-04-21 devnull } else
496 53db2d0f 2004-04-21 devnull if(ISPRINT(c))
497 53db2d0f 2004-04-21 devnull Inpos++;
498 53db2d0f 2004-04-21 devnull else
499 53db2d0f 2004-04-21 devnull switch(c) {
500 53db2d0f 2004-04-21 devnull case '\b':
501 53db2d0f 2004-04-21 devnull case ESC:
502 53db2d0f 2004-04-21 devnull if(Inpos > 0)
503 53db2d0f 2004-04-21 devnull Inpos--;
504 53db2d0f 2004-04-21 devnull break;
505 53db2d0f 2004-04-21 devnull case '\f':
506 53db2d0f 2004-04-21 devnull if(Ncols == 1)
507 53db2d0f 2004-04-21 devnull break;
508 53db2d0f 2004-04-21 devnull c = '\n';
509 53db2d0f 2004-04-21 devnull case '\n':
510 53db2d0f 2004-04-21 devnull case '\r':
511 53db2d0f 2004-04-21 devnull Inpos = 0;
512 53db2d0f 2004-04-21 devnull }
513 53db2d0f 2004-04-21 devnull return C = c;
514 53db2d0f 2004-04-21 devnull }
515 53db2d0f 2004-04-21 devnull
516 53db2d0f 2004-04-21 devnull void
517 53db2d0f 2004-04-21 devnull put(long c)
518 53db2d0f 2004-04-21 devnull {
519 53db2d0f 2004-04-21 devnull int move;
520 53db2d0f 2004-04-21 devnull
521 53db2d0f 2004-04-21 devnull switch(c) {
522 53db2d0f 2004-04-21 devnull case ' ':
523 53db2d0f 2004-04-21 devnull Nspace++;
524 53db2d0f 2004-04-21 devnull Lcolpos++;
525 53db2d0f 2004-04-21 devnull return;
526 53db2d0f 2004-04-21 devnull case '\b':
527 53db2d0f 2004-04-21 devnull if(Lcolpos == 0)
528 53db2d0f 2004-04-21 devnull return;
529 53db2d0f 2004-04-21 devnull if(Nspace > 0) {
530 53db2d0f 2004-04-21 devnull Nspace--;
531 53db2d0f 2004-04-21 devnull Lcolpos--;
532 53db2d0f 2004-04-21 devnull return;
533 53db2d0f 2004-04-21 devnull }
534 53db2d0f 2004-04-21 devnull if(Lcolpos > Pcolpos) {
535 53db2d0f 2004-04-21 devnull Lcolpos--;
536 53db2d0f 2004-04-21 devnull return;
537 53db2d0f 2004-04-21 devnull }
538 53db2d0f 2004-04-21 devnull case ESC:
539 53db2d0f 2004-04-21 devnull move = -1;
540 53db2d0f 2004-04-21 devnull break;
541 53db2d0f 2004-04-21 devnull case '\n':
542 53db2d0f 2004-04-21 devnull Line++;
543 53db2d0f 2004-04-21 devnull case '\r':
544 53db2d0f 2004-04-21 devnull case '\f':
545 53db2d0f 2004-04-21 devnull Pcolpos = 0;
546 53db2d0f 2004-04-21 devnull Lcolpos = 0;
547 53db2d0f 2004-04-21 devnull Nspace = 0;
548 53db2d0f 2004-04-21 devnull Outpos = 0;
549 53db2d0f 2004-04-21 devnull default:
550 53db2d0f 2004-04-21 devnull move = (ISPRINT(c) != 0);
551 53db2d0f 2004-04-21 devnull }
552 53db2d0f 2004-04-21 devnull if(Page < Fpage)
553 53db2d0f 2004-04-21 devnull return;
554 53db2d0f 2004-04-21 devnull if(Lcolpos > 0 || move > 0)
555 53db2d0f 2004-04-21 devnull Lcolpos += move;
556 53db2d0f 2004-04-21 devnull if(Lcolpos <= Colw) {
557 53db2d0f 2004-04-21 devnull putspace();
558 53db2d0f 2004-04-21 devnull Bputrune(&bout, c);
559 53db2d0f 2004-04-21 devnull Pcolpos = Lcolpos;
560 53db2d0f 2004-04-21 devnull Outpos += move;
561 53db2d0f 2004-04-21 devnull }
562 53db2d0f 2004-04-21 devnull }
563 53db2d0f 2004-04-21 devnull
564 53db2d0f 2004-04-21 devnull void
565 53db2d0f 2004-04-21 devnull putspace(void)
566 53db2d0f 2004-04-21 devnull {
567 53db2d0f 2004-04-21 devnull int nc;
568 53db2d0f 2004-04-21 devnull
569 53db2d0f 2004-04-21 devnull for(; Nspace > 0; Outpos += nc, Nspace -= nc)
570 53db2d0f 2004-04-21 devnull if(ITABS)
571 53db2d0f 2004-04-21 devnull Bputc(&bout, Itabc);
572 53db2d0f 2004-04-21 devnull else {
573 53db2d0f 2004-04-21 devnull nc = 1;
574 53db2d0f 2004-04-21 devnull Bputc(&bout, ' ');
575 53db2d0f 2004-04-21 devnull }
576 53db2d0f 2004-04-21 devnull }
577 53db2d0f 2004-04-21 devnull
578 53db2d0f 2004-04-21 devnull int
579 53db2d0f 2004-04-21 devnull atoix(char **p)
580 53db2d0f 2004-04-21 devnull {
581 53db2d0f 2004-04-21 devnull int n = 0, c;
582 53db2d0f 2004-04-21 devnull
583 53db2d0f 2004-04-21 devnull while(isdigit(c = *++*p))
584 53db2d0f 2004-04-21 devnull n = 10*n + c - '0';
585 53db2d0f 2004-04-21 devnull (*p)--;
586 53db2d0f 2004-04-21 devnull return n;
587 53db2d0f 2004-04-21 devnull }
588 53db2d0f 2004-04-21 devnull
589 53db2d0f 2004-04-21 devnull /*
590 53db2d0f 2004-04-21 devnull * Defer message about failure to open file to prevent messing up
591 53db2d0f 2004-04-21 devnull * alignment of page with tear perforations or form markers.
592 53db2d0f 2004-04-21 devnull * Treat empty file as special case and report as diagnostic.
593 53db2d0f 2004-04-21 devnull */
594 53db2d0f 2004-04-21 devnull Biobuf*
595 53db2d0f 2004-04-21 devnull mustopen(char *s, Fils *f)
596 53db2d0f 2004-04-21 devnull {
597 53db2d0f 2004-04-21 devnull char *tmp;
598 53db2d0f 2004-04-21 devnull
599 53db2d0f 2004-04-21 devnull if(*s == '\0') {
600 53db2d0f 2004-04-21 devnull f->f_name = STDINNAME();
601 53db2d0f 2004-04-21 devnull f->f_f = malloc(sizeof(Biobuf));
602 53db2d0f 2004-04-21 devnull if(f->f_f == 0)
603 53db2d0f 2004-04-21 devnull cerror("no memory");
604 53db2d0f 2004-04-21 devnull Binit(f->f_f, 0, OREAD);
605 53db2d0f 2004-04-21 devnull } else
606 53db2d0f 2004-04-21 devnull if((f->f_f = Bopen(f->f_name = s, OREAD)) == 0) {
607 53db2d0f 2004-04-21 devnull tmp = ffiler(f->f_name);
608 53db2d0f 2004-04-21 devnull s = strcpy((char*)getspace(strlen(tmp) + 1), tmp);
609 53db2d0f 2004-04-21 devnull free(tmp);
610 53db2d0f 2004-04-21 devnull }
611 53db2d0f 2004-04-21 devnull if(f->f_f != 0) {
612 53db2d0f 2004-04-21 devnull if((f->f_nextc = Bgetrune(f->f_f)) >= 0 || Multi == 'm')
613 53db2d0f 2004-04-21 devnull return f->f_f;
614 53db2d0f 2004-04-21 devnull sprint(s = (char*)getspace(strlen(f->f_name) + 1 + EMPTY),
615 53db2d0f 2004-04-21 devnull "%s -- empty file\n", f->f_name);
616 53db2d0f 2004-04-21 devnull Bterm(f->f_f);
617 53db2d0f 2004-04-21 devnull }
618 53db2d0f 2004-04-21 devnull error = 1;
619 53db2d0f 2004-04-21 devnull cerror(s);
620 53db2d0f 2004-04-21 devnull fprint(2, "\n");
621 53db2d0f 2004-04-21 devnull return 0;
622 53db2d0f 2004-04-21 devnull }
623 53db2d0f 2004-04-21 devnull
624 53db2d0f 2004-04-21 devnull void*
625 53db2d0f 2004-04-21 devnull getspace(ulong n)
626 53db2d0f 2004-04-21 devnull {
627 53db2d0f 2004-04-21 devnull void *t;
628 53db2d0f 2004-04-21 devnull
629 53db2d0f 2004-04-21 devnull if((t = malloc(n)) == 0)
630 53db2d0f 2004-04-21 devnull die("out of space");
631 53db2d0f 2004-04-21 devnull return t;
632 53db2d0f 2004-04-21 devnull }
633 53db2d0f 2004-04-21 devnull
634 53db2d0f 2004-04-21 devnull void
635 53db2d0f 2004-04-21 devnull die(char *s)
636 53db2d0f 2004-04-21 devnull {
637 53db2d0f 2004-04-21 devnull error++;
638 53db2d0f 2004-04-21 devnull errprint();
639 53db2d0f 2004-04-21 devnull cerror(s);
640 53db2d0f 2004-04-21 devnull Bputc(&bout, '\n');
641 53db2d0f 2004-04-21 devnull exits("error");
642 53db2d0f 2004-04-21 devnull }
643 53db2d0f 2004-04-21 devnull
644 53db2d0f 2004-04-21 devnull /*
645 53db2d0f 2004-04-21 devnull void
646 53db2d0f 2004-04-21 devnull onintr(void)
647 53db2d0f 2004-04-21 devnull {
648 53db2d0f 2004-04-21 devnull error++;
649 53db2d0f 2004-04-21 devnull errprint();
650 53db2d0f 2004-04-21 devnull exits("error");
651 53db2d0f 2004-04-21 devnull }
652 53db2d0f 2004-04-21 devnull /**/
653 53db2d0f 2004-04-21 devnull
654 53db2d0f 2004-04-21 devnull /*
655 53db2d0f 2004-04-21 devnull * print accumulated error reports
656 53db2d0f 2004-04-21 devnull */
657 53db2d0f 2004-04-21 devnull void
658 53db2d0f 2004-04-21 devnull errprint(void)
659 53db2d0f 2004-04-21 devnull {
660 53db2d0f 2004-04-21 devnull Bflush(&bout);
661 53db2d0f 2004-04-21 devnull for(; err != 0; err = err->e_nextp) {
662 53db2d0f 2004-04-21 devnull cerror(err->e_mess);
663 53db2d0f 2004-04-21 devnull fprint(2, "\n");
664 53db2d0f 2004-04-21 devnull }
665 53db2d0f 2004-04-21 devnull }