Blame


1 c42a1d3d 2006-02-21 devnull #include "a.h"
2 c42a1d3d 2006-02-21 devnull
3 c42a1d3d 2006-02-21 devnull enum
4 c42a1d3d 2006-02-21 devnull {
5 c42a1d3d 2006-02-21 devnull MAXREQ = 100,
6 c42a1d3d 2006-02-21 devnull MAXRAW = 40,
7 c42a1d3d 2006-02-21 devnull MAXESC = 60,
8 c42a1d3d 2006-02-21 devnull MAXLINE = 1024,
9 c42a1d3d 2006-02-21 devnull MAXIF = 20,
10 cbeb0b26 2006-04-01 devnull MAXARG = 10
11 c42a1d3d 2006-02-21 devnull };
12 c42a1d3d 2006-02-21 devnull
13 c42a1d3d 2006-02-21 devnull typedef struct Esc Esc;
14 c42a1d3d 2006-02-21 devnull typedef struct Req Req;
15 c42a1d3d 2006-02-21 devnull typedef struct Raw Raw;
16 c42a1d3d 2006-02-21 devnull
17 c42a1d3d 2006-02-21 devnull /* escape sequence handler, like for \c */
18 c42a1d3d 2006-02-21 devnull struct Esc
19 c42a1d3d 2006-02-21 devnull {
20 c42a1d3d 2006-02-21 devnull Rune r;
21 c42a1d3d 2006-02-21 devnull int (*f)(void);
22 c42a1d3d 2006-02-21 devnull int mode;
23 c42a1d3d 2006-02-21 devnull };
24 c42a1d3d 2006-02-21 devnull
25 c42a1d3d 2006-02-21 devnull /* raw request handler, like for .ie */
26 c42a1d3d 2006-02-21 devnull struct Raw
27 c42a1d3d 2006-02-21 devnull {
28 c42a1d3d 2006-02-21 devnull Rune *name;
29 c42a1d3d 2006-02-21 devnull void (*f)(Rune*);
30 c42a1d3d 2006-02-21 devnull };
31 c42a1d3d 2006-02-21 devnull
32 c42a1d3d 2006-02-21 devnull /* regular request handler, like for .ft */
33 c42a1d3d 2006-02-21 devnull struct Req
34 c42a1d3d 2006-02-21 devnull {
35 c42a1d3d 2006-02-21 devnull int argc;
36 c42a1d3d 2006-02-21 devnull Rune *name;
37 c42a1d3d 2006-02-21 devnull void (*f)(int, Rune**);
38 c42a1d3d 2006-02-21 devnull };
39 c42a1d3d 2006-02-21 devnull
40 c42a1d3d 2006-02-21 devnull int dot = '.';
41 c42a1d3d 2006-02-21 devnull int tick = '\'';
42 c42a1d3d 2006-02-21 devnull int backslash = '\\';
43 c42a1d3d 2006-02-21 devnull
44 c42a1d3d 2006-02-21 devnull int inputmode;
45 c42a1d3d 2006-02-21 devnull Req req[MAXREQ];
46 c42a1d3d 2006-02-21 devnull int nreq;
47 c42a1d3d 2006-02-21 devnull Raw raw[MAXRAW];
48 c42a1d3d 2006-02-21 devnull int nraw;
49 c42a1d3d 2006-02-21 devnull Esc esc[MAXESC];
50 c42a1d3d 2006-02-21 devnull int nesc;
51 c42a1d3d 2006-02-21 devnull int iftrue[MAXIF];
52 c42a1d3d 2006-02-21 devnull int niftrue;
53 c42a1d3d 2006-02-21 devnull
54 c42a1d3d 2006-02-21 devnull int isoutput;
55 c42a1d3d 2006-02-21 devnull int linepos;
56 c42a1d3d 2006-02-21 devnull
57 c42a1d3d 2006-02-21 devnull
58 c42a1d3d 2006-02-21 devnull void
59 c42a1d3d 2006-02-21 devnull addraw(Rune *name, void (*f)(Rune*))
60 c42a1d3d 2006-02-21 devnull {
61 c42a1d3d 2006-02-21 devnull Raw *r;
62 fa325e9b 2020-01-10 cross
63 c42a1d3d 2006-02-21 devnull if(nraw >= nelem(raw)){
64 c42a1d3d 2006-02-21 devnull fprint(2, "too many raw requets\n");
65 c42a1d3d 2006-02-21 devnull return;
66 c42a1d3d 2006-02-21 devnull }
67 c42a1d3d 2006-02-21 devnull r = &raw[nraw++];
68 c42a1d3d 2006-02-21 devnull r->name = erunestrdup(name);
69 c42a1d3d 2006-02-21 devnull r->f = f;
70 c42a1d3d 2006-02-21 devnull }
71 c42a1d3d 2006-02-21 devnull
72 c42a1d3d 2006-02-21 devnull void
73 c42a1d3d 2006-02-21 devnull delraw(Rune *name)
74 c42a1d3d 2006-02-21 devnull {
75 c42a1d3d 2006-02-21 devnull int i;
76 fa325e9b 2020-01-10 cross
77 c42a1d3d 2006-02-21 devnull for(i=0; i<nraw; i++){
78 c42a1d3d 2006-02-21 devnull if(runestrcmp(raw[i].name, name) == 0){
79 c42a1d3d 2006-02-21 devnull if(i != --nraw){
80 c42a1d3d 2006-02-21 devnull free(raw[i].name);
81 c42a1d3d 2006-02-21 devnull raw[i] = raw[nraw];
82 c42a1d3d 2006-02-21 devnull }
83 c42a1d3d 2006-02-21 devnull return;
84 c42a1d3d 2006-02-21 devnull }
85 c42a1d3d 2006-02-21 devnull }
86 c42a1d3d 2006-02-21 devnull }
87 c42a1d3d 2006-02-21 devnull
88 c42a1d3d 2006-02-21 devnull void
89 c42a1d3d 2006-02-21 devnull renraw(Rune *from, Rune *to)
90 c42a1d3d 2006-02-21 devnull {
91 c42a1d3d 2006-02-21 devnull int i;
92 fa325e9b 2020-01-10 cross
93 c42a1d3d 2006-02-21 devnull delraw(to);
94 c42a1d3d 2006-02-21 devnull for(i=0; i<nraw; i++)
95 c42a1d3d 2006-02-21 devnull if(runestrcmp(raw[i].name, from) == 0){
96 c42a1d3d 2006-02-21 devnull free(raw[i].name);
97 c42a1d3d 2006-02-21 devnull raw[i].name = erunestrdup(to);
98 c42a1d3d 2006-02-21 devnull return;
99 c42a1d3d 2006-02-21 devnull }
100 c42a1d3d 2006-02-21 devnull }
101 c42a1d3d 2006-02-21 devnull
102 c42a1d3d 2006-02-21 devnull
103 c42a1d3d 2006-02-21 devnull void
104 c42a1d3d 2006-02-21 devnull addreq(Rune *s, void (*f)(int, Rune**), int argc)
105 c42a1d3d 2006-02-21 devnull {
106 c42a1d3d 2006-02-21 devnull Req *r;
107 c42a1d3d 2006-02-21 devnull
108 c42a1d3d 2006-02-21 devnull if(nreq >= nelem(req)){
109 c42a1d3d 2006-02-21 devnull fprint(2, "too many requests\n");
110 c42a1d3d 2006-02-21 devnull return;
111 c42a1d3d 2006-02-21 devnull }
112 c42a1d3d 2006-02-21 devnull r = &req[nreq++];
113 c42a1d3d 2006-02-21 devnull r->name = erunestrdup(s);
114 c42a1d3d 2006-02-21 devnull r->f = f;
115 c42a1d3d 2006-02-21 devnull r->argc = argc;
116 c42a1d3d 2006-02-21 devnull }
117 c42a1d3d 2006-02-21 devnull
118 c42a1d3d 2006-02-21 devnull void
119 c42a1d3d 2006-02-21 devnull delreq(Rune *name)
120 c42a1d3d 2006-02-21 devnull {
121 c42a1d3d 2006-02-21 devnull int i;
122 c42a1d3d 2006-02-21 devnull
123 c42a1d3d 2006-02-21 devnull for(i=0; i<nreq; i++){
124 c42a1d3d 2006-02-21 devnull if(runestrcmp(req[i].name, name) == 0){
125 c42a1d3d 2006-02-21 devnull if(i != --nreq){
126 c42a1d3d 2006-02-21 devnull free(req[i].name);
127 c42a1d3d 2006-02-21 devnull req[i] = req[nreq];
128 c42a1d3d 2006-02-21 devnull }
129 c42a1d3d 2006-02-21 devnull return;
130 c42a1d3d 2006-02-21 devnull }
131 c42a1d3d 2006-02-21 devnull }
132 c42a1d3d 2006-02-21 devnull }
133 c42a1d3d 2006-02-21 devnull
134 c42a1d3d 2006-02-21 devnull void
135 c42a1d3d 2006-02-21 devnull renreq(Rune *from, Rune *to)
136 c42a1d3d 2006-02-21 devnull {
137 c42a1d3d 2006-02-21 devnull int i;
138 fa325e9b 2020-01-10 cross
139 c42a1d3d 2006-02-21 devnull delreq(to);
140 c42a1d3d 2006-02-21 devnull for(i=0; i<nreq; i++)
141 c42a1d3d 2006-02-21 devnull if(runestrcmp(req[i].name, from) == 0){
142 c42a1d3d 2006-02-21 devnull free(req[i].name);
143 c42a1d3d 2006-02-21 devnull req[i].name = erunestrdup(to);
144 c42a1d3d 2006-02-21 devnull return;
145 c42a1d3d 2006-02-21 devnull }
146 c42a1d3d 2006-02-21 devnull }
147 c42a1d3d 2006-02-21 devnull
148 c42a1d3d 2006-02-21 devnull void
149 c42a1d3d 2006-02-21 devnull addesc(Rune r, int (*f)(void), int mode)
150 c42a1d3d 2006-02-21 devnull {
151 c42a1d3d 2006-02-21 devnull Esc *e;
152 fa325e9b 2020-01-10 cross
153 c42a1d3d 2006-02-21 devnull if(nesc >= nelem(esc)){
154 c42a1d3d 2006-02-21 devnull fprint(2, "too many escapes\n");
155 c42a1d3d 2006-02-21 devnull return;
156 c42a1d3d 2006-02-21 devnull }
157 c42a1d3d 2006-02-21 devnull e = &esc[nesc++];
158 c42a1d3d 2006-02-21 devnull e->r = r;
159 c42a1d3d 2006-02-21 devnull e->f = f;
160 c42a1d3d 2006-02-21 devnull e->mode = mode;
161 c42a1d3d 2006-02-21 devnull }
162 c42a1d3d 2006-02-21 devnull
163 c42a1d3d 2006-02-21 devnull /*
164 c42a1d3d 2006-02-21 devnull * Get the next logical character in the input stream.
165 c42a1d3d 2006-02-21 devnull */
166 c42a1d3d 2006-02-21 devnull int
167 c42a1d3d 2006-02-21 devnull getnext(void)
168 c42a1d3d 2006-02-21 devnull {
169 c42a1d3d 2006-02-21 devnull int i, r;
170 c42a1d3d 2006-02-21 devnull
171 c42a1d3d 2006-02-21 devnull next:
172 c42a1d3d 2006-02-21 devnull r = getrune();
173 c42a1d3d 2006-02-21 devnull if(r < 0)
174 c42a1d3d 2006-02-21 devnull return -1;
175 c42a1d3d 2006-02-21 devnull if(r == Uformatted){
176 c42a1d3d 2006-02-21 devnull br();
177 c42a1d3d 2006-02-21 devnull assert(!isoutput);
178 c42a1d3d 2006-02-21 devnull while((r = getrune()) >= 0 && r != Uunformatted){
179 c42a1d3d 2006-02-21 devnull if(r == Uformatted)
180 c42a1d3d 2006-02-21 devnull continue;
181 c42a1d3d 2006-02-21 devnull outrune(r);
182 c42a1d3d 2006-02-21 devnull }
183 c42a1d3d 2006-02-21 devnull goto next;
184 c42a1d3d 2006-02-21 devnull }
185 c42a1d3d 2006-02-21 devnull if(r == Uunformatted)
186 c42a1d3d 2006-02-21 devnull goto next;
187 c42a1d3d 2006-02-21 devnull if(r == backslash){
188 c42a1d3d 2006-02-21 devnull r = getrune();
189 c42a1d3d 2006-02-21 devnull if(r < 0)
190 c42a1d3d 2006-02-21 devnull return -1;
191 c42a1d3d 2006-02-21 devnull for(i=0; i<nesc; i++){
192 c42a1d3d 2006-02-21 devnull if(r == esc[i].r && (inputmode&esc[i].mode)==inputmode){
193 c42a1d3d 2006-02-21 devnull if(esc[i].f == e_warn)
194 c42a1d3d 2006-02-21 devnull warn("ignoring %C%C", backslash, r);
195 c42a1d3d 2006-02-21 devnull r = esc[i].f();
196 c42a1d3d 2006-02-21 devnull if(r <= 0)
197 c42a1d3d 2006-02-21 devnull goto next;
198 c42a1d3d 2006-02-21 devnull return r;
199 c42a1d3d 2006-02-21 devnull }
200 c42a1d3d 2006-02-21 devnull }
201 c42a1d3d 2006-02-21 devnull if(inputmode&(ArgMode|CopyMode)){
202 c42a1d3d 2006-02-21 devnull ungetrune(r);
203 c42a1d3d 2006-02-21 devnull r = backslash;
204 c42a1d3d 2006-02-21 devnull }
205 c42a1d3d 2006-02-21 devnull }
206 c42a1d3d 2006-02-21 devnull return r;
207 c42a1d3d 2006-02-21 devnull }
208 c42a1d3d 2006-02-21 devnull
209 c42a1d3d 2006-02-21 devnull void
210 c42a1d3d 2006-02-21 devnull ungetnext(Rune r)
211 c42a1d3d 2006-02-21 devnull {
212 c42a1d3d 2006-02-21 devnull /*
213 c42a1d3d 2006-02-21 devnull * really we want to undo the getrunes that led us here,
214 c42a1d3d 2006-02-21 devnull * since the call after ungetnext might be getrune!
215 c42a1d3d 2006-02-21 devnull */
216 c42a1d3d 2006-02-21 devnull ungetrune(r);
217 c42a1d3d 2006-02-21 devnull }
218 c42a1d3d 2006-02-21 devnull
219 c42a1d3d 2006-02-21 devnull int
220 c42a1d3d 2006-02-21 devnull _readx(Rune *p, int n, int nmode, int line)
221 c42a1d3d 2006-02-21 devnull {
222 c42a1d3d 2006-02-21 devnull int c, omode;
223 c42a1d3d 2006-02-21 devnull Rune *e;
224 c42a1d3d 2006-02-21 devnull
225 c42a1d3d 2006-02-21 devnull while((c = getrune()) == ' ' || c == '\t')
226 c42a1d3d 2006-02-21 devnull ;
227 c42a1d3d 2006-02-21 devnull ungetrune(c);
228 c42a1d3d 2006-02-21 devnull omode = inputmode;
229 c42a1d3d 2006-02-21 devnull inputmode = nmode;
230 c42a1d3d 2006-02-21 devnull e = p+n-1;
231 c42a1d3d 2006-02-21 devnull for(c=getnext(); p<e; c=getnext()){
232 c42a1d3d 2006-02-21 devnull if(c < 0)
233 c42a1d3d 2006-02-21 devnull break;
234 c42a1d3d 2006-02-21 devnull if(!line && (c == ' ' || c == '\t'))
235 c42a1d3d 2006-02-21 devnull break;
236 c42a1d3d 2006-02-21 devnull if(c == '\n'){
237 c42a1d3d 2006-02-21 devnull if(!line)
238 c42a1d3d 2006-02-21 devnull ungetnext(c);
239 c42a1d3d 2006-02-21 devnull break;
240 c42a1d3d 2006-02-21 devnull }
241 c42a1d3d 2006-02-21 devnull *p++ = c;
242 c42a1d3d 2006-02-21 devnull }
243 c42a1d3d 2006-02-21 devnull inputmode = omode;
244 c42a1d3d 2006-02-21 devnull *p = 0;
245 c42a1d3d 2006-02-21 devnull if(c < 0)
246 c42a1d3d 2006-02-21 devnull return -1;
247 c42a1d3d 2006-02-21 devnull return 0;
248 c42a1d3d 2006-02-21 devnull }
249 c42a1d3d 2006-02-21 devnull
250 c42a1d3d 2006-02-21 devnull /*
251 c42a1d3d 2006-02-21 devnull * Get the next argument from the current line.
252 c42a1d3d 2006-02-21 devnull */
253 c42a1d3d 2006-02-21 devnull Rune*
254 c42a1d3d 2006-02-21 devnull copyarg(void)
255 c42a1d3d 2006-02-21 devnull {
256 c42a1d3d 2006-02-21 devnull static Rune buf[MaxLine];
257 c42a1d3d 2006-02-21 devnull int c;
258 c42a1d3d 2006-02-21 devnull Rune *r;
259 fa325e9b 2020-01-10 cross
260 0144f87d 2021-01-29 crossd if(_readx(buf, MaxLine, ArgMode, 0) < 0)
261 c42a1d3d 2006-02-21 devnull return nil;
262 c42a1d3d 2006-02-21 devnull r = runestrstr(buf, L("\\\""));
263 c42a1d3d 2006-02-21 devnull if(r){
264 c42a1d3d 2006-02-21 devnull *r = 0;
265 c42a1d3d 2006-02-21 devnull while((c = getrune()) >= 0 && c != '\n')
266 c42a1d3d 2006-02-21 devnull ;
267 c42a1d3d 2006-02-21 devnull ungetrune('\n');
268 c42a1d3d 2006-02-21 devnull }
269 fa325e9b 2020-01-10 cross r = erunestrdup(buf);
270 c42a1d3d 2006-02-21 devnull return r;
271 c42a1d3d 2006-02-21 devnull }
272 c42a1d3d 2006-02-21 devnull
273 c42a1d3d 2006-02-21 devnull /*
274 c42a1d3d 2006-02-21 devnull * Read the current line in given mode. Newline not kept.
275 c42a1d3d 2006-02-21 devnull * Uses different buffer from copyarg!
276 c42a1d3d 2006-02-21 devnull */
277 c42a1d3d 2006-02-21 devnull Rune*
278 c42a1d3d 2006-02-21 devnull readline(int m)
279 c42a1d3d 2006-02-21 devnull {
280 c42a1d3d 2006-02-21 devnull static Rune buf[MaxLine];
281 c42a1d3d 2006-02-21 devnull Rune *r;
282 c42a1d3d 2006-02-21 devnull
283 0144f87d 2021-01-29 crossd if(_readx(buf, MaxLine, m, 1) < 0)
284 c42a1d3d 2006-02-21 devnull return nil;
285 c42a1d3d 2006-02-21 devnull r = erunestrdup(buf);
286 c42a1d3d 2006-02-21 devnull return r;
287 c42a1d3d 2006-02-21 devnull }
288 c42a1d3d 2006-02-21 devnull
289 c42a1d3d 2006-02-21 devnull /*
290 c42a1d3d 2006-02-21 devnull * Given the argument line (already read in copy+arg mode),
291 c42a1d3d 2006-02-21 devnull * parse into arguments. Note that \" has been left in place
292 c42a1d3d 2006-02-21 devnull * during copy+arg mode parsing, so comments still need to be stripped.
293 c42a1d3d 2006-02-21 devnull */
294 c42a1d3d 2006-02-21 devnull int
295 c42a1d3d 2006-02-21 devnull parseargs(Rune *p, Rune **argv)
296 c42a1d3d 2006-02-21 devnull {
297 c42a1d3d 2006-02-21 devnull int argc;
298 c42a1d3d 2006-02-21 devnull Rune *w;
299 c42a1d3d 2006-02-21 devnull
300 c42a1d3d 2006-02-21 devnull for(argc=0; argc<MAXARG; argc++){
301 c42a1d3d 2006-02-21 devnull while(*p == ' ' || *p == '\t')
302 c42a1d3d 2006-02-21 devnull p++;
303 c42a1d3d 2006-02-21 devnull if(*p == 0)
304 c42a1d3d 2006-02-21 devnull break;
305 c42a1d3d 2006-02-21 devnull argv[argc] = p;
306 c42a1d3d 2006-02-21 devnull if(*p == '"'){
307 c42a1d3d 2006-02-21 devnull /* quoted argument */
308 c42a1d3d 2006-02-21 devnull if(*(p+1) == '"'){
309 c42a1d3d 2006-02-21 devnull /* empty argument */
310 c42a1d3d 2006-02-21 devnull *p = 0;
311 c42a1d3d 2006-02-21 devnull p += 2;
312 c42a1d3d 2006-02-21 devnull }else{
313 c42a1d3d 2006-02-21 devnull /* parse quoted string */
314 c42a1d3d 2006-02-21 devnull w = p++;
315 c42a1d3d 2006-02-21 devnull for(; *p; p++){
316 c42a1d3d 2006-02-21 devnull if(*p == '"' && *(p+1) == '"')
317 c42a1d3d 2006-02-21 devnull *w++ = '"';
318 c42a1d3d 2006-02-21 devnull else if(*p == '"'){
319 c42a1d3d 2006-02-21 devnull p++;
320 c42a1d3d 2006-02-21 devnull break;
321 c42a1d3d 2006-02-21 devnull }else
322 c42a1d3d 2006-02-21 devnull *w++ = *p;
323 c42a1d3d 2006-02-21 devnull }
324 c42a1d3d 2006-02-21 devnull *w = 0;
325 fa325e9b 2020-01-10 cross }
326 c42a1d3d 2006-02-21 devnull }else{
327 c42a1d3d 2006-02-21 devnull /* unquoted argument - need to watch out for \" comment */
328 c42a1d3d 2006-02-21 devnull for(; *p; p++){
329 c42a1d3d 2006-02-21 devnull if(*p == ' ' || *p == '\t'){
330 c42a1d3d 2006-02-21 devnull *p++ = 0;
331 c42a1d3d 2006-02-21 devnull break;
332 c42a1d3d 2006-02-21 devnull }
333 c42a1d3d 2006-02-21 devnull if(*p == '\\' && *(p+1) == '"'){
334 c42a1d3d 2006-02-21 devnull *p = 0;
335 c42a1d3d 2006-02-21 devnull if(p != argv[argc])
336 c42a1d3d 2006-02-21 devnull argc++;
337 c42a1d3d 2006-02-21 devnull return argc;
338 c42a1d3d 2006-02-21 devnull }
339 c42a1d3d 2006-02-21 devnull }
340 c42a1d3d 2006-02-21 devnull }
341 c42a1d3d 2006-02-21 devnull }
342 c42a1d3d 2006-02-21 devnull return argc;
343 c42a1d3d 2006-02-21 devnull }
344 c42a1d3d 2006-02-21 devnull
345 c42a1d3d 2006-02-21 devnull /*
346 c42a1d3d 2006-02-21 devnull * Process a dot line. The dot has been read.
347 c42a1d3d 2006-02-21 devnull */
348 c42a1d3d 2006-02-21 devnull void
349 c42a1d3d 2006-02-21 devnull dotline(int dot)
350 c42a1d3d 2006-02-21 devnull {
351 c42a1d3d 2006-02-21 devnull int argc, i;
352 c42a1d3d 2006-02-21 devnull Rune *a, *argv[1+MAXARG];
353 c42a1d3d 2006-02-21 devnull
354 c42a1d3d 2006-02-21 devnull /*
355 c42a1d3d 2006-02-21 devnull * Read request/macro name
356 c42a1d3d 2006-02-21 devnull */
357 c42a1d3d 2006-02-21 devnull a = copyarg();
358 c42a1d3d 2006-02-21 devnull if(a == nil || a[0] == 0){
359 c42a1d3d 2006-02-21 devnull free(a);
360 c42a1d3d 2006-02-21 devnull getrune(); /* \n */
361 c42a1d3d 2006-02-21 devnull return;
362 c42a1d3d 2006-02-21 devnull }
363 c42a1d3d 2006-02-21 devnull argv[0] = a;
364 c42a1d3d 2006-02-21 devnull /*
365 c42a1d3d 2006-02-21 devnull * Check for .if, .ie, and others with special parsing.
366 c42a1d3d 2006-02-21 devnull */
367 c42a1d3d 2006-02-21 devnull for(i=0; i<nraw; i++){
368 c42a1d3d 2006-02-21 devnull if(runestrcmp(raw[i].name, a) == 0){
369 c42a1d3d 2006-02-21 devnull raw[i].f(raw[i].name);
370 c42a1d3d 2006-02-21 devnull free(a);
371 c42a1d3d 2006-02-21 devnull return;
372 fa325e9b 2020-01-10 cross }
373 c42a1d3d 2006-02-21 devnull }
374 c42a1d3d 2006-02-21 devnull
375 c42a1d3d 2006-02-21 devnull /*
376 c42a1d3d 2006-02-21 devnull * Read rest of line in copy mode, invoke regular request.
377 c42a1d3d 2006-02-21 devnull */
378 c42a1d3d 2006-02-21 devnull a = readline(ArgMode);
379 c42a1d3d 2006-02-21 devnull if(a == nil){
380 c42a1d3d 2006-02-21 devnull free(argv[0]);
381 c42a1d3d 2006-02-21 devnull return;
382 c42a1d3d 2006-02-21 devnull }
383 c42a1d3d 2006-02-21 devnull argc = 1+parseargs(a, argv+1);
384 c42a1d3d 2006-02-21 devnull for(i=0; i<nreq; i++){
385 c42a1d3d 2006-02-21 devnull if(runestrcmp(req[i].name, argv[0]) == 0){
386 c42a1d3d 2006-02-21 devnull if(req[i].argc != -1){
387 c42a1d3d 2006-02-21 devnull if(argc < 1+req[i].argc){
388 c42a1d3d 2006-02-21 devnull warn("not enough arguments for %C%S", dot, req[i].name);
389 c42a1d3d 2006-02-21 devnull free(argv[0]);
390 c42a1d3d 2006-02-21 devnull free(a);
391 c42a1d3d 2006-02-21 devnull return;
392 c42a1d3d 2006-02-21 devnull }
393 c42a1d3d 2006-02-21 devnull if(argc > 1+req[i].argc)
394 c42a1d3d 2006-02-21 devnull warn("too many arguments for %C%S", dot, req[i].name);
395 c42a1d3d 2006-02-21 devnull }
396 c42a1d3d 2006-02-21 devnull req[i].f(argc, argv);
397 c42a1d3d 2006-02-21 devnull free(argv[0]);
398 c42a1d3d 2006-02-21 devnull free(a);
399 c42a1d3d 2006-02-21 devnull return;
400 c42a1d3d 2006-02-21 devnull }
401 c42a1d3d 2006-02-21 devnull }
402 c42a1d3d 2006-02-21 devnull
403 c42a1d3d 2006-02-21 devnull /*
404 c42a1d3d 2006-02-21 devnull * Invoke user-defined macros.
405 c42a1d3d 2006-02-21 devnull */
406 c42a1d3d 2006-02-21 devnull runmacro(dot, argc, argv);
407 c42a1d3d 2006-02-21 devnull free(argv[0]);
408 c42a1d3d 2006-02-21 devnull free(a);
409 c42a1d3d 2006-02-21 devnull }
410 c42a1d3d 2006-02-21 devnull
411 c42a1d3d 2006-02-21 devnull /*
412 c42a1d3d 2006-02-21 devnull * newlines are magical in various ways.
413 c42a1d3d 2006-02-21 devnull */
414 c42a1d3d 2006-02-21 devnull int bol;
415 c42a1d3d 2006-02-21 devnull void
416 c42a1d3d 2006-02-21 devnull newline(void)
417 c42a1d3d 2006-02-21 devnull {
418 c42a1d3d 2006-02-21 devnull int n;
419 c42a1d3d 2006-02-21 devnull
420 c42a1d3d 2006-02-21 devnull if(bol)
421 c42a1d3d 2006-02-21 devnull sp(eval(L("1v")));
422 c42a1d3d 2006-02-21 devnull bol = 1;
423 c42a1d3d 2006-02-21 devnull if((n=getnr(L(".ce"))) > 0){
424 c42a1d3d 2006-02-21 devnull nr(L(".ce"), n-1);
425 c42a1d3d 2006-02-21 devnull br();
426 c42a1d3d 2006-02-21 devnull }
427 c42a1d3d 2006-02-21 devnull if(getnr(L(".fi")) == 0)
428 c42a1d3d 2006-02-21 devnull br();
429 c42a1d3d 2006-02-21 devnull outrune('\n');
430 c42a1d3d 2006-02-21 devnull }
431 c42a1d3d 2006-02-21 devnull
432 c42a1d3d 2006-02-21 devnull void
433 c42a1d3d 2006-02-21 devnull startoutput(void)
434 c42a1d3d 2006-02-21 devnull {
435 c42a1d3d 2006-02-21 devnull char *align;
436 c42a1d3d 2006-02-21 devnull double ps, vs, lm, rm, ti;
437 c42a1d3d 2006-02-21 devnull Rune buf[200];
438 c42a1d3d 2006-02-21 devnull
439 c42a1d3d 2006-02-21 devnull if(isoutput)
440 c42a1d3d 2006-02-21 devnull return;
441 c42a1d3d 2006-02-21 devnull isoutput = 1;
442 c42a1d3d 2006-02-21 devnull
443 c42a1d3d 2006-02-21 devnull if(getnr(L(".paragraph")) == 0)
444 c42a1d3d 2006-02-21 devnull return;
445 c42a1d3d 2006-02-21 devnull
446 c42a1d3d 2006-02-21 devnull nr(L(".ns"), 0);
447 c42a1d3d 2006-02-21 devnull isoutput = 1;
448 c42a1d3d 2006-02-21 devnull ps = getnr(L(".s"));
449 c42a1d3d 2006-02-21 devnull if(ps <= 1)
450 c42a1d3d 2006-02-21 devnull ps = 10;
451 c42a1d3d 2006-02-21 devnull ps /= 72.0;
452 c42a1d3d 2006-02-21 devnull USED(ps);
453 c42a1d3d 2006-02-21 devnull
454 c42a1d3d 2006-02-21 devnull vs = getnr(L(".v"))*getnr(L(".ls")) * 1.0/UPI;
455 c42a1d3d 2006-02-21 devnull vs /= (10.0/72.0); /* ps */
456 c42a1d3d 2006-02-21 devnull if(vs == 0)
457 c42a1d3d 2006-02-21 devnull vs = 1.2;
458 c42a1d3d 2006-02-21 devnull
459 c42a1d3d 2006-02-21 devnull lm = (getnr(L(".o"))+getnr(L(".i"))) * 1.0/UPI;
460 c42a1d3d 2006-02-21 devnull ti = getnr(L(".ti")) * 1.0/UPI;
461 c42a1d3d 2006-02-21 devnull nr(L(".ti"), 0);
462 c42a1d3d 2006-02-21 devnull
463 c42a1d3d 2006-02-21 devnull rm = 8.0 - getnr(L(".l"))*1.0/UPI - getnr(L(".o"))*1.0/UPI;
464 c42a1d3d 2006-02-21 devnull if(rm < 0)
465 c42a1d3d 2006-02-21 devnull rm = 0;
466 c42a1d3d 2006-02-21 devnull switch(getnr(L(".j"))){
467 c42a1d3d 2006-02-21 devnull default:
468 c42a1d3d 2006-02-21 devnull case 0:
469 c42a1d3d 2006-02-21 devnull align = "left";
470 c42a1d3d 2006-02-21 devnull break;
471 c42a1d3d 2006-02-21 devnull case 1:
472 c42a1d3d 2006-02-21 devnull align = "justify";
473 c42a1d3d 2006-02-21 devnull break;
474 c42a1d3d 2006-02-21 devnull case 3:
475 c42a1d3d 2006-02-21 devnull align = "center";
476 c42a1d3d 2006-02-21 devnull break;
477 c42a1d3d 2006-02-21 devnull case 5:
478 c42a1d3d 2006-02-21 devnull align = "right";
479 c42a1d3d 2006-02-21 devnull break;
480 c42a1d3d 2006-02-21 devnull }
481 c42a1d3d 2006-02-21 devnull if(getnr(L(".ce")))
482 c42a1d3d 2006-02-21 devnull align = "center";
483 c42a1d3d 2006-02-21 devnull if(!getnr(L(".margin")))
484 c42a1d3d 2006-02-21 devnull runesnprint(buf, nelem(buf), "<p style=\"line-height: %.1fem; text-indent: %.2fin; margin-top: 0; margin-bottom: 0; text-align: %s;\">\n",
485 c42a1d3d 2006-02-21 devnull vs, ti, align);
486 c42a1d3d 2006-02-21 devnull else
487 c42a1d3d 2006-02-21 devnull runesnprint(buf, nelem(buf), "<p style=\"line-height: %.1fem; margin-left: %.2fin; text-indent: %.2fin; margin-right: %.2fin; margin-top: 0; margin-bottom: 0; text-align: %s;\">\n",
488 c42a1d3d 2006-02-21 devnull vs, lm, ti, rm, align);
489 c42a1d3d 2006-02-21 devnull outhtml(buf);
490 c42a1d3d 2006-02-21 devnull }
491 c42a1d3d 2006-02-21 devnull void
492 c42a1d3d 2006-02-21 devnull br(void)
493 c42a1d3d 2006-02-21 devnull {
494 c42a1d3d 2006-02-21 devnull if(!isoutput)
495 c42a1d3d 2006-02-21 devnull return;
496 c42a1d3d 2006-02-21 devnull isoutput = 0;
497 c42a1d3d 2006-02-21 devnull
498 c42a1d3d 2006-02-21 devnull nr(L(".dv"), 0);
499 c42a1d3d 2006-02-21 devnull dv(0);
500 c42a1d3d 2006-02-21 devnull hideihtml();
501 c42a1d3d 2006-02-21 devnull if(getnr(L(".paragraph")))
502 c42a1d3d 2006-02-21 devnull outhtml(L("</p>"));
503 c42a1d3d 2006-02-21 devnull }
504 c42a1d3d 2006-02-21 devnull
505 c42a1d3d 2006-02-21 devnull void
506 c42a1d3d 2006-02-21 devnull r_margin(int argc, Rune **argv)
507 c42a1d3d 2006-02-21 devnull {
508 c42a1d3d 2006-02-21 devnull USED(argc);
509 c42a1d3d 2006-02-21 devnull
510 c42a1d3d 2006-02-21 devnull nr(L(".margin"), eval(argv[1]));
511 c42a1d3d 2006-02-21 devnull }
512 c42a1d3d 2006-02-21 devnull
513 c42a1d3d 2006-02-21 devnull int inrequest;
514 c42a1d3d 2006-02-21 devnull void
515 c42a1d3d 2006-02-21 devnull runinput(void)
516 c42a1d3d 2006-02-21 devnull {
517 c42a1d3d 2006-02-21 devnull int c;
518 fa325e9b 2020-01-10 cross
519 c42a1d3d 2006-02-21 devnull bol = 1;
520 c42a1d3d 2006-02-21 devnull for(;;){
521 c42a1d3d 2006-02-21 devnull c = getnext();
522 c42a1d3d 2006-02-21 devnull if(c < 0)
523 c42a1d3d 2006-02-21 devnull break;
524 c42a1d3d 2006-02-21 devnull if((c == dot || c == tick) && bol){
525 c42a1d3d 2006-02-21 devnull inrequest = 1;
526 c42a1d3d 2006-02-21 devnull dotline(c);
527 c42a1d3d 2006-02-21 devnull bol = 1;
528 c42a1d3d 2006-02-21 devnull inrequest = 0;
529 c42a1d3d 2006-02-21 devnull }else if(c == '\n'){
530 c42a1d3d 2006-02-21 devnull newline();
531 c42a1d3d 2006-02-21 devnull itrap();
532 c42a1d3d 2006-02-21 devnull linepos = 0;
533 c42a1d3d 2006-02-21 devnull }else{
534 c42a1d3d 2006-02-21 devnull outtrap();
535 c42a1d3d 2006-02-21 devnull startoutput();
536 c42a1d3d 2006-02-21 devnull showihtml();
537 c42a1d3d 2006-02-21 devnull if(c == '\t'){
538 c42a1d3d 2006-02-21 devnull /* XXX do better */
539 c42a1d3d 2006-02-21 devnull outrune(' ');
540 c42a1d3d 2006-02-21 devnull while(++linepos%4)
541 c42a1d3d 2006-02-21 devnull outrune(' ');
542 c42a1d3d 2006-02-21 devnull }else{
543 c42a1d3d 2006-02-21 devnull outrune(c);
544 c42a1d3d 2006-02-21 devnull linepos++;
545 c42a1d3d 2006-02-21 devnull }
546 c42a1d3d 2006-02-21 devnull bol = 0;
547 c42a1d3d 2006-02-21 devnull }
548 c42a1d3d 2006-02-21 devnull }
549 c42a1d3d 2006-02-21 devnull }
550 c42a1d3d 2006-02-21 devnull
551 c42a1d3d 2006-02-21 devnull void
552 c42a1d3d 2006-02-21 devnull run(void)
553 c42a1d3d 2006-02-21 devnull {
554 c42a1d3d 2006-02-21 devnull t1init();
555 c42a1d3d 2006-02-21 devnull t2init();
556 c42a1d3d 2006-02-21 devnull t3init();
557 c42a1d3d 2006-02-21 devnull t4init();
558 c42a1d3d 2006-02-21 devnull t5init();
559 c42a1d3d 2006-02-21 devnull t6init();
560 c42a1d3d 2006-02-21 devnull t7init();
561 c42a1d3d 2006-02-21 devnull t8init();
562 c42a1d3d 2006-02-21 devnull /* t9init(); t9.c */
563 c42a1d3d 2006-02-21 devnull t10init();
564 c42a1d3d 2006-02-21 devnull t11init();
565 c42a1d3d 2006-02-21 devnull /* t12init(); t12.c */
566 c42a1d3d 2006-02-21 devnull t13init();
567 c42a1d3d 2006-02-21 devnull t14init();
568 c42a1d3d 2006-02-21 devnull t15init();
569 c42a1d3d 2006-02-21 devnull t16init();
570 c42a1d3d 2006-02-21 devnull t17init();
571 c42a1d3d 2006-02-21 devnull t18init();
572 c42a1d3d 2006-02-21 devnull t19init();
573 c42a1d3d 2006-02-21 devnull t20init();
574 c42a1d3d 2006-02-21 devnull htmlinit();
575 c42a1d3d 2006-02-21 devnull hideihtml();
576 fa325e9b 2020-01-10 cross
577 c42a1d3d 2006-02-21 devnull addreq(L("margin"), r_margin, 1);
578 c42a1d3d 2006-02-21 devnull nr(L(".margin"), 1);
579 c42a1d3d 2006-02-21 devnull nr(L(".paragraph"), 1);
580 c42a1d3d 2006-02-21 devnull
581 c42a1d3d 2006-02-21 devnull runinput();
582 c42a1d3d 2006-02-21 devnull while(popinput())
583 c42a1d3d 2006-02-21 devnull ;
584 c42a1d3d 2006-02-21 devnull dot = '.';
585 c42a1d3d 2006-02-21 devnull if(verbose)
586 c42a1d3d 2006-02-21 devnull fprint(2, "eof\n");
587 c42a1d3d 2006-02-21 devnull runmacro1(L("eof"));
588 c42a1d3d 2006-02-21 devnull closehtml();
589 c42a1d3d 2006-02-21 devnull }
590 c42a1d3d 2006-02-21 devnull
591 c42a1d3d 2006-02-21 devnull void
592 c42a1d3d 2006-02-21 devnull out(Rune *s)
593 c42a1d3d 2006-02-21 devnull {
594 c42a1d3d 2006-02-21 devnull if(s == nil)
595 c42a1d3d 2006-02-21 devnull return;
596 c42a1d3d 2006-02-21 devnull for(; *s; s++)
597 c42a1d3d 2006-02-21 devnull outrune(*s);
598 c42a1d3d 2006-02-21 devnull }
599 c42a1d3d 2006-02-21 devnull
600 c42a1d3d 2006-02-21 devnull void (*outcb)(Rune);
601 c42a1d3d 2006-02-21 devnull
602 c42a1d3d 2006-02-21 devnull void
603 c42a1d3d 2006-02-21 devnull inroman(Rune r)
604 c42a1d3d 2006-02-21 devnull {
605 c42a1d3d 2006-02-21 devnull int f;
606 fa325e9b 2020-01-10 cross
607 c42a1d3d 2006-02-21 devnull f = getnr(L(".f"));
608 c42a1d3d 2006-02-21 devnull nr(L(".f"), 1);
609 c42a1d3d 2006-02-21 devnull runmacro1(L("font"));
610 c42a1d3d 2006-02-21 devnull outrune(r);
611 c42a1d3d 2006-02-21 devnull nr(L(".f"), f);
612 c42a1d3d 2006-02-21 devnull runmacro1(L("font"));
613 c42a1d3d 2006-02-21 devnull }
614 c42a1d3d 2006-02-21 devnull
615 c42a1d3d 2006-02-21 devnull void
616 c42a1d3d 2006-02-21 devnull Brune(Rune r)
617 c42a1d3d 2006-02-21 devnull {
618 c42a1d3d 2006-02-21 devnull if(r == '&')
619 c42a1d3d 2006-02-21 devnull Bprint(&bout, "&amp;");
620 c42a1d3d 2006-02-21 devnull else if(r == '<')
621 c42a1d3d 2006-02-21 devnull Bprint(&bout, "&lt;");
622 c42a1d3d 2006-02-21 devnull else if(r == '>')
623 c42a1d3d 2006-02-21 devnull Bprint(&bout, "&gt;");
624 c42a1d3d 2006-02-21 devnull else if(r < Runeself || utf8)
625 c42a1d3d 2006-02-21 devnull Bprint(&bout, "%C", r);
626 c42a1d3d 2006-02-21 devnull else
627 c42a1d3d 2006-02-21 devnull Bprint(&bout, "%S", rune2html(r));
628 c42a1d3d 2006-02-21 devnull }
629 c42a1d3d 2006-02-21 devnull
630 c42a1d3d 2006-02-21 devnull void
631 c42a1d3d 2006-02-21 devnull outhtml(Rune *s)
632 c42a1d3d 2006-02-21 devnull {
633 c42a1d3d 2006-02-21 devnull Rune r;
634 fa325e9b 2020-01-10 cross
635 c42a1d3d 2006-02-21 devnull for(; *s; s++){
636 c42a1d3d 2006-02-21 devnull switch(r = *s){
637 c42a1d3d 2006-02-21 devnull case '<':
638 c42a1d3d 2006-02-21 devnull r = Ult;
639 c42a1d3d 2006-02-21 devnull break;
640 c42a1d3d 2006-02-21 devnull case '>':
641 c42a1d3d 2006-02-21 devnull r = Ugt;
642 c42a1d3d 2006-02-21 devnull break;
643 c42a1d3d 2006-02-21 devnull case '&':
644 c42a1d3d 2006-02-21 devnull r = Uamp;
645 c42a1d3d 2006-02-21 devnull break;
646 c42a1d3d 2006-02-21 devnull case ' ':
647 c42a1d3d 2006-02-21 devnull r = Uspace;
648 c42a1d3d 2006-02-21 devnull break;
649 c42a1d3d 2006-02-21 devnull }
650 c42a1d3d 2006-02-21 devnull outrune(r);
651 c42a1d3d 2006-02-21 devnull }
652 c42a1d3d 2006-02-21 devnull }
653 c42a1d3d 2006-02-21 devnull
654 c42a1d3d 2006-02-21 devnull void
655 c42a1d3d 2006-02-21 devnull outrune(Rune r)
656 c42a1d3d 2006-02-21 devnull {
657 c42a1d3d 2006-02-21 devnull switch(r){
658 c42a1d3d 2006-02-21 devnull case ' ':
659 c42a1d3d 2006-02-21 devnull if(getnr(L(".fi")) == 0)
660 c42a1d3d 2006-02-21 devnull r = Unbsp;
661 c42a1d3d 2006-02-21 devnull break;
662 c42a1d3d 2006-02-21 devnull case Uformatted:
663 c42a1d3d 2006-02-21 devnull case Uunformatted:
664 c42a1d3d 2006-02-21 devnull abort();
665 c42a1d3d 2006-02-21 devnull }
666 c42a1d3d 2006-02-21 devnull if(outcb){
667 c42a1d3d 2006-02-21 devnull if(r == ' ')
668 c42a1d3d 2006-02-21 devnull r = Uspace;
669 c42a1d3d 2006-02-21 devnull outcb(r);
670 c42a1d3d 2006-02-21 devnull return;
671 c42a1d3d 2006-02-21 devnull }
672 c42a1d3d 2006-02-21 devnull /* writing to bout */
673 c42a1d3d 2006-02-21 devnull switch(r){
674 c42a1d3d 2006-02-21 devnull case Uempty:
675 c42a1d3d 2006-02-21 devnull return;
676 c42a1d3d 2006-02-21 devnull case Upl:
677 c42a1d3d 2006-02-21 devnull inroman('+');
678 c42a1d3d 2006-02-21 devnull return;
679 c42a1d3d 2006-02-21 devnull case Ueq:
680 c42a1d3d 2006-02-21 devnull inroman('=');
681 c42a1d3d 2006-02-21 devnull return;
682 c42a1d3d 2006-02-21 devnull case Umi:
683 c42a1d3d 2006-02-21 devnull inroman(0x2212);
684 c42a1d3d 2006-02-21 devnull return;
685 c42a1d3d 2006-02-21 devnull case Utick:
686 c42a1d3d 2006-02-21 devnull r = '\'';
687 c42a1d3d 2006-02-21 devnull break;
688 c42a1d3d 2006-02-21 devnull case Ubtick:
689 c42a1d3d 2006-02-21 devnull r = '`';
690 c42a1d3d 2006-02-21 devnull break;
691 c42a1d3d 2006-02-21 devnull case Uminus:
692 c42a1d3d 2006-02-21 devnull r = '-';
693 c42a1d3d 2006-02-21 devnull break;
694 c42a1d3d 2006-02-21 devnull case '\'':
695 c42a1d3d 2006-02-21 devnull Bprint(&bout, "&rsquo;");
696 c42a1d3d 2006-02-21 devnull return;
697 c42a1d3d 2006-02-21 devnull case '`':
698 c42a1d3d 2006-02-21 devnull Bprint(&bout, "&lsquo;");
699 c42a1d3d 2006-02-21 devnull return;
700 c42a1d3d 2006-02-21 devnull case Uamp:
701 c42a1d3d 2006-02-21 devnull Bputrune(&bout, '&');
702 c42a1d3d 2006-02-21 devnull return;
703 c42a1d3d 2006-02-21 devnull case Ult:
704 c42a1d3d 2006-02-21 devnull Bputrune(&bout, '<');
705 c42a1d3d 2006-02-21 devnull return;
706 c42a1d3d 2006-02-21 devnull case Ugt:
707 c42a1d3d 2006-02-21 devnull Bputrune(&bout, '>');
708 c42a1d3d 2006-02-21 devnull return;
709 c42a1d3d 2006-02-21 devnull case Uspace:
710 c42a1d3d 2006-02-21 devnull Bputrune(&bout, ' ');
711 c42a1d3d 2006-02-21 devnull return;
712 c42a1d3d 2006-02-21 devnull case 0x2032:
713 c42a1d3d 2006-02-21 devnull /*
714 c42a1d3d 2006-02-21 devnull * In Firefox, at least, the prime is not
715 c42a1d3d 2006-02-21 devnull * a superscript by default.
716 c42a1d3d 2006-02-21 devnull */
717 c42a1d3d 2006-02-21 devnull Bprint(&bout, "<sup>");
718 c42a1d3d 2006-02-21 devnull Brune(r);
719 c42a1d3d 2006-02-21 devnull Bprint(&bout, "</sup>");
720 c42a1d3d 2006-02-21 devnull return;
721 c42a1d3d 2006-02-21 devnull }
722 c42a1d3d 2006-02-21 devnull Brune(r);
723 c42a1d3d 2006-02-21 devnull }
724 c42a1d3d 2006-02-21 devnull
725 c42a1d3d 2006-02-21 devnull void
726 c42a1d3d 2006-02-21 devnull r_nop(int argc, Rune **argv)
727 c42a1d3d 2006-02-21 devnull {
728 c42a1d3d 2006-02-21 devnull USED(argc);
729 c42a1d3d 2006-02-21 devnull USED(argv);
730 c42a1d3d 2006-02-21 devnull }
731 c42a1d3d 2006-02-21 devnull
732 c42a1d3d 2006-02-21 devnull void
733 c42a1d3d 2006-02-21 devnull r_warn(int argc, Rune **argv)
734 c42a1d3d 2006-02-21 devnull {
735 c42a1d3d 2006-02-21 devnull USED(argc);
736 c42a1d3d 2006-02-21 devnull warn("ignoring %C%S", dot, argv[0]);
737 c42a1d3d 2006-02-21 devnull }
738 c42a1d3d 2006-02-21 devnull
739 c42a1d3d 2006-02-21 devnull int
740 c42a1d3d 2006-02-21 devnull e_warn(void)
741 c42a1d3d 2006-02-21 devnull {
742 c42a1d3d 2006-02-21 devnull /* dispatch loop prints a warning for us */
743 c42a1d3d 2006-02-21 devnull return 0;
744 c42a1d3d 2006-02-21 devnull }
745 c42a1d3d 2006-02-21 devnull
746 c42a1d3d 2006-02-21 devnull int
747 c42a1d3d 2006-02-21 devnull e_nop(void)
748 c42a1d3d 2006-02-21 devnull {
749 c42a1d3d 2006-02-21 devnull return 0;
750 c42a1d3d 2006-02-21 devnull }