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