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