Blame


1 564ca709 2004-04-19 devnull #include <u.h>
2 564ca709 2004-04-19 devnull #include <libc.h>
3 564ca709 2004-04-19 devnull #include <bio.h>
4 564ca709 2004-04-19 devnull #include <ctype.h>
5 564ca709 2004-04-19 devnull #include <mach.h>
6 564ca709 2004-04-19 devnull #include <regexp.h>
7 564ca709 2004-04-19 devnull #define Extern extern
8 564ca709 2004-04-19 devnull #include "acid.h"
9 564ca709 2004-04-19 devnull #include "y.tab.h"
10 564ca709 2004-04-19 devnull
11 564ca709 2004-04-19 devnull void cvtatof(Node*, Node*);
12 564ca709 2004-04-19 devnull void cvtatoi(Node*, Node*);
13 564ca709 2004-04-19 devnull void cvtitoa(Node*, Node*);
14 564ca709 2004-04-19 devnull void bprint(Node*, Node*);
15 564ca709 2004-04-19 devnull void funcbound(Node*, Node*);
16 564ca709 2004-04-19 devnull void printto(Node*, Node*);
17 564ca709 2004-04-19 devnull void getfile(Node*, Node*);
18 564ca709 2004-04-19 devnull void fmt(Node*, Node*);
19 564ca709 2004-04-19 devnull void pcfile(Node*, Node*);
20 564ca709 2004-04-19 devnull void pcline(Node*, Node*);
21 564ca709 2004-04-19 devnull void setproc(Node*, Node*);
22 564ca709 2004-04-19 devnull void strace(Node*, Node*);
23 564ca709 2004-04-19 devnull void follow(Node*, Node*);
24 564ca709 2004-04-19 devnull void reason(Node*, Node*);
25 564ca709 2004-04-19 devnull void newproc(Node*, Node*);
26 564ca709 2004-04-19 devnull void startstop(Node*, Node*);
27 564ca709 2004-04-19 devnull void match(Node*, Node*);
28 564ca709 2004-04-19 devnull void status(Node*, Node*);
29 564ca709 2004-04-19 devnull void xkill(Node*,Node*);
30 564ca709 2004-04-19 devnull void waitstop(Node*, Node*);
31 564ca709 2004-04-19 devnull void sysstop(Node*, Node*);
32 564ca709 2004-04-19 devnull void stop(Node*, Node*);
33 564ca709 2004-04-19 devnull void start(Node*, Node*);
34 564ca709 2004-04-19 devnull void filepc(Node*, Node*);
35 564ca709 2004-04-19 devnull void doerror(Node*, Node*);
36 564ca709 2004-04-19 devnull void rc(Node*, Node*);
37 564ca709 2004-04-19 devnull void doaccess(Node*, Node*);
38 564ca709 2004-04-19 devnull void map(Node*, Node*);
39 564ca709 2004-04-19 devnull void readfile(Node*, Node*);
40 564ca709 2004-04-19 devnull void interpret(Node*, Node*);
41 564ca709 2004-04-19 devnull void include(Node*, Node*);
42 564ca709 2004-04-19 devnull void includepipe(Node*, Node*);
43 564ca709 2004-04-19 devnull void regexp(Node*, Node*);
44 564ca709 2004-04-19 devnull void textfile(Node*, Node*);
45 564ca709 2004-04-19 devnull void deltextfile(Node*, Node*);
46 564ca709 2004-04-19 devnull
47 564ca709 2004-04-19 devnull typedef struct Btab Btab;
48 564ca709 2004-04-19 devnull struct Btab
49 564ca709 2004-04-19 devnull {
50 564ca709 2004-04-19 devnull char *name;
51 564ca709 2004-04-19 devnull void (*fn)(Node*, Node*);
52 564ca709 2004-04-19 devnull } tab[] =
53 564ca709 2004-04-19 devnull {
54 564ca709 2004-04-19 devnull "atof", cvtatof,
55 564ca709 2004-04-19 devnull "atoi", cvtatoi,
56 564ca709 2004-04-19 devnull "deltextfile", deltextfile,
57 564ca709 2004-04-19 devnull "error", doerror,
58 564ca709 2004-04-19 devnull "file", getfile,
59 564ca709 2004-04-19 devnull "readfile", readfile,
60 564ca709 2004-04-19 devnull "access", doaccess,
61 564ca709 2004-04-19 devnull "filepc", filepc,
62 564ca709 2004-04-19 devnull "fnbound", funcbound,
63 564ca709 2004-04-19 devnull "fmt", fmt,
64 564ca709 2004-04-19 devnull "follow", follow,
65 564ca709 2004-04-19 devnull "include", include,
66 564ca709 2004-04-19 devnull "includepipe", includepipe,
67 564ca709 2004-04-19 devnull "interpret", interpret,
68 564ca709 2004-04-19 devnull "itoa", cvtitoa,
69 564ca709 2004-04-19 devnull "kill", xkill,
70 564ca709 2004-04-19 devnull "map", map,
71 564ca709 2004-04-19 devnull "match", match,
72 564ca709 2004-04-19 devnull "newproc", newproc,
73 564ca709 2004-04-19 devnull "pcfile", pcfile,
74 564ca709 2004-04-19 devnull "pcline", pcline,
75 564ca709 2004-04-19 devnull "print", bprint,
76 564ca709 2004-04-19 devnull "printto", printto,
77 564ca709 2004-04-19 devnull "rc", rc,
78 564ca709 2004-04-19 devnull "reason", reason,
79 564ca709 2004-04-19 devnull "regexp", regexp,
80 564ca709 2004-04-19 devnull "setproc", setproc,
81 564ca709 2004-04-19 devnull "start", start,
82 564ca709 2004-04-19 devnull "startstop", startstop,
83 564ca709 2004-04-19 devnull "status", status,
84 564ca709 2004-04-19 devnull "stop", stop,
85 564ca709 2004-04-19 devnull "strace", strace,
86 564ca709 2004-04-19 devnull "sysstop", sysstop,
87 564ca709 2004-04-19 devnull "textfile", textfile,
88 564ca709 2004-04-19 devnull "waitstop", waitstop,
89 564ca709 2004-04-19 devnull 0
90 564ca709 2004-04-19 devnull };
91 564ca709 2004-04-19 devnull
92 564ca709 2004-04-19 devnull void
93 564ca709 2004-04-19 devnull mkprint(Lsym *s)
94 564ca709 2004-04-19 devnull {
95 564ca709 2004-04-19 devnull prnt = malloc(sizeof(Node));
96 564ca709 2004-04-19 devnull memset(prnt, 0, sizeof(Node));
97 564ca709 2004-04-19 devnull prnt->op = OCALL;
98 564ca709 2004-04-19 devnull prnt->left = malloc(sizeof(Node));
99 564ca709 2004-04-19 devnull memset(prnt->left, 0, sizeof(Node));
100 564ca709 2004-04-19 devnull prnt->left->sym = s;
101 564ca709 2004-04-19 devnull }
102 564ca709 2004-04-19 devnull
103 564ca709 2004-04-19 devnull void
104 564ca709 2004-04-19 devnull installbuiltin(void)
105 564ca709 2004-04-19 devnull {
106 564ca709 2004-04-19 devnull Btab *b;
107 564ca709 2004-04-19 devnull Lsym *s;
108 564ca709 2004-04-19 devnull
109 564ca709 2004-04-19 devnull b = tab;
110 564ca709 2004-04-19 devnull while(b->name) {
111 564ca709 2004-04-19 devnull s = look(b->name);
112 564ca709 2004-04-19 devnull if(s == 0)
113 564ca709 2004-04-19 devnull s = enter(b->name, Tid);
114 564ca709 2004-04-19 devnull
115 564ca709 2004-04-19 devnull s->builtin = b->fn;
116 564ca709 2004-04-19 devnull if(b->fn == bprint)
117 564ca709 2004-04-19 devnull mkprint(s);
118 564ca709 2004-04-19 devnull b++;
119 564ca709 2004-04-19 devnull }
120 564ca709 2004-04-19 devnull }
121 564ca709 2004-04-19 devnull
122 564ca709 2004-04-19 devnull void
123 564ca709 2004-04-19 devnull match(Node *r, Node *args)
124 564ca709 2004-04-19 devnull {
125 564ca709 2004-04-19 devnull int i;
126 564ca709 2004-04-19 devnull List *f;
127 564ca709 2004-04-19 devnull Node *av[Maxarg];
128 564ca709 2004-04-19 devnull Node resi, resl;
129 564ca709 2004-04-19 devnull
130 564ca709 2004-04-19 devnull na = 0;
131 564ca709 2004-04-19 devnull flatten(av, args);
132 564ca709 2004-04-19 devnull if(na != 2)
133 564ca709 2004-04-19 devnull error("match(obj, list): arg count");
134 564ca709 2004-04-19 devnull
135 564ca709 2004-04-19 devnull expr(av[1], &resl);
136 564ca709 2004-04-19 devnull if(resl.type != TLIST)
137 564ca709 2004-04-19 devnull error("match(obj, list): need list");
138 564ca709 2004-04-19 devnull expr(av[0], &resi);
139 564ca709 2004-04-19 devnull
140 564ca709 2004-04-19 devnull r->op = OCONST;
141 564ca709 2004-04-19 devnull r->type = TINT;
142 564ca709 2004-04-19 devnull r->store.fmt = 'D';
143 564ca709 2004-04-19 devnull r->store.u.ival = -1;
144 564ca709 2004-04-19 devnull
145 564ca709 2004-04-19 devnull i = 0;
146 564ca709 2004-04-19 devnull for(f = resl.store.u.l; f; f = f->next) {
147 564ca709 2004-04-19 devnull if(resi.type == f->type) {
148 564ca709 2004-04-19 devnull switch(resi.type) {
149 564ca709 2004-04-19 devnull case TINT:
150 564ca709 2004-04-19 devnull if(resi.store.u.ival == f->store.u.ival) {
151 564ca709 2004-04-19 devnull r->store.u.ival = i;
152 564ca709 2004-04-19 devnull return;
153 564ca709 2004-04-19 devnull }
154 564ca709 2004-04-19 devnull break;
155 564ca709 2004-04-19 devnull case TFLOAT:
156 564ca709 2004-04-19 devnull if(resi.store.u.fval == f->store.u.fval) {
157 564ca709 2004-04-19 devnull r->store.u.ival = i;
158 564ca709 2004-04-19 devnull return;
159 564ca709 2004-04-19 devnull }
160 564ca709 2004-04-19 devnull break;
161 564ca709 2004-04-19 devnull case TSTRING:
162 564ca709 2004-04-19 devnull if(scmp(resi.store.u.string, f->store.u.string)) {
163 564ca709 2004-04-19 devnull r->store.u.ival = i;
164 564ca709 2004-04-19 devnull return;
165 564ca709 2004-04-19 devnull }
166 564ca709 2004-04-19 devnull break;
167 564ca709 2004-04-19 devnull case TLIST:
168 564ca709 2004-04-19 devnull error("match(obj, list): not defined for list");
169 564ca709 2004-04-19 devnull }
170 564ca709 2004-04-19 devnull }
171 564ca709 2004-04-19 devnull i++;
172 564ca709 2004-04-19 devnull }
173 564ca709 2004-04-19 devnull }
174 564ca709 2004-04-19 devnull
175 564ca709 2004-04-19 devnull void
176 564ca709 2004-04-19 devnull newproc(Node *r, Node *args)
177 564ca709 2004-04-19 devnull {
178 564ca709 2004-04-19 devnull int i;
179 564ca709 2004-04-19 devnull Node res;
180 564ca709 2004-04-19 devnull char *p, *e;
181 564ca709 2004-04-19 devnull char *argv[Maxarg], buf[Strsize];
182 564ca709 2004-04-19 devnull
183 564ca709 2004-04-19 devnull i = 1;
184 564ca709 2004-04-19 devnull argv[0] = symfil;
185 564ca709 2004-04-19 devnull
186 564ca709 2004-04-19 devnull if(args) {
187 564ca709 2004-04-19 devnull expr(args, &res);
188 564ca709 2004-04-19 devnull if(res.type != TSTRING)
189 564ca709 2004-04-19 devnull error("newproc(): arg not string");
190 564ca709 2004-04-19 devnull if(res.store.u.string->len >= sizeof(buf))
191 564ca709 2004-04-19 devnull error("newproc(): too many arguments");
192 564ca709 2004-04-19 devnull memmove(buf, res.store.u.string->string, res.store.u.string->len);
193 564ca709 2004-04-19 devnull buf[res.store.u.string->len] = '\0';
194 564ca709 2004-04-19 devnull p = buf;
195 564ca709 2004-04-19 devnull e = buf+res.store.u.string->len;
196 564ca709 2004-04-19 devnull for(;;) {
197 564ca709 2004-04-19 devnull while(p < e && (*p == '\t' || *p == ' '))
198 564ca709 2004-04-19 devnull *p++ = '\0';
199 564ca709 2004-04-19 devnull if(p >= e)
200 564ca709 2004-04-19 devnull break;
201 564ca709 2004-04-19 devnull argv[i++] = p;
202 564ca709 2004-04-19 devnull if(i >= Maxarg)
203 564ca709 2004-04-19 devnull error("newproc: too many arguments");
204 564ca709 2004-04-19 devnull while(p < e && *p != '\t' && *p != ' ')
205 564ca709 2004-04-19 devnull p++;
206 564ca709 2004-04-19 devnull }
207 564ca709 2004-04-19 devnull }
208 564ca709 2004-04-19 devnull argv[i] = 0;
209 564ca709 2004-04-19 devnull r->op = OCONST;
210 564ca709 2004-04-19 devnull r->type = TINT;
211 564ca709 2004-04-19 devnull r->store.fmt = 'D';
212 564ca709 2004-04-19 devnull r->store.u.ival = nproc(argv);
213 564ca709 2004-04-19 devnull }
214 564ca709 2004-04-19 devnull
215 564ca709 2004-04-19 devnull void
216 564ca709 2004-04-19 devnull startstop(Node *r, Node *args)
217 564ca709 2004-04-19 devnull {
218 564ca709 2004-04-19 devnull Node res;
219 564ca709 2004-04-19 devnull
220 564ca709 2004-04-19 devnull USED(r);
221 564ca709 2004-04-19 devnull if(args == 0)
222 564ca709 2004-04-19 devnull error("startstop(pid): no pid");
223 564ca709 2004-04-19 devnull expr(args, &res);
224 564ca709 2004-04-19 devnull if(res.type != TINT)
225 564ca709 2004-04-19 devnull error("startstop(pid): arg type");
226 564ca709 2004-04-19 devnull
227 564ca709 2004-04-19 devnull msg(res.store.u.ival, "startstop");
228 564ca709 2004-04-19 devnull notes(res.store.u.ival);
229 564ca709 2004-04-19 devnull dostop(res.store.u.ival);
230 564ca709 2004-04-19 devnull }
231 564ca709 2004-04-19 devnull
232 564ca709 2004-04-19 devnull void
233 564ca709 2004-04-19 devnull waitstop(Node *r, Node *args)
234 564ca709 2004-04-19 devnull {
235 564ca709 2004-04-19 devnull Node res;
236 564ca709 2004-04-19 devnull
237 564ca709 2004-04-19 devnull USED(r);
238 564ca709 2004-04-19 devnull if(args == 0)
239 564ca709 2004-04-19 devnull error("waitstop(pid): no pid");
240 564ca709 2004-04-19 devnull expr(args, &res);
241 564ca709 2004-04-19 devnull if(res.type != TINT)
242 564ca709 2004-04-19 devnull error("waitstop(pid): arg type");
243 564ca709 2004-04-19 devnull
244 564ca709 2004-04-19 devnull Bflush(bout);
245 564ca709 2004-04-19 devnull msg(res.store.u.ival, "waitstop");
246 564ca709 2004-04-19 devnull notes(res.store.u.ival);
247 564ca709 2004-04-19 devnull dostop(res.store.u.ival);
248 564ca709 2004-04-19 devnull }
249 564ca709 2004-04-19 devnull
250 564ca709 2004-04-19 devnull void
251 564ca709 2004-04-19 devnull sysstop(Node *r, Node *args)
252 564ca709 2004-04-19 devnull {
253 564ca709 2004-04-19 devnull Node res;
254 564ca709 2004-04-19 devnull
255 564ca709 2004-04-19 devnull USED(r);
256 564ca709 2004-04-19 devnull if(args == 0)
257 564ca709 2004-04-19 devnull error("waitstop(pid): no pid");
258 564ca709 2004-04-19 devnull expr(args, &res);
259 564ca709 2004-04-19 devnull if(res.type != TINT)
260 564ca709 2004-04-19 devnull error("waitstop(pid): arg type");
261 564ca709 2004-04-19 devnull
262 564ca709 2004-04-19 devnull Bflush(bout);
263 564ca709 2004-04-19 devnull msg(res.store.u.ival, "sysstop");
264 564ca709 2004-04-19 devnull notes(res.store.u.ival);
265 564ca709 2004-04-19 devnull dostop(res.store.u.ival);
266 564ca709 2004-04-19 devnull }
267 564ca709 2004-04-19 devnull
268 564ca709 2004-04-19 devnull void
269 564ca709 2004-04-19 devnull start(Node *r, Node *args)
270 564ca709 2004-04-19 devnull {
271 564ca709 2004-04-19 devnull Node res;
272 564ca709 2004-04-19 devnull
273 564ca709 2004-04-19 devnull USED(r);
274 564ca709 2004-04-19 devnull if(args == 0)
275 564ca709 2004-04-19 devnull error("start(pid): no pid");
276 564ca709 2004-04-19 devnull expr(args, &res);
277 564ca709 2004-04-19 devnull if(res.type != TINT)
278 564ca709 2004-04-19 devnull error("start(pid): arg type");
279 564ca709 2004-04-19 devnull
280 564ca709 2004-04-19 devnull msg(res.store.u.ival, "start");
281 564ca709 2004-04-19 devnull }
282 564ca709 2004-04-19 devnull
283 564ca709 2004-04-19 devnull void
284 564ca709 2004-04-19 devnull stop(Node *r, Node *args)
285 564ca709 2004-04-19 devnull {
286 564ca709 2004-04-19 devnull Node res;
287 564ca709 2004-04-19 devnull
288 564ca709 2004-04-19 devnull USED(r);
289 564ca709 2004-04-19 devnull if(args == 0)
290 564ca709 2004-04-19 devnull error("stop(pid): no pid");
291 564ca709 2004-04-19 devnull expr(args, &res);
292 564ca709 2004-04-19 devnull if(res.type != TINT)
293 564ca709 2004-04-19 devnull error("stop(pid): arg type");
294 564ca709 2004-04-19 devnull
295 564ca709 2004-04-19 devnull Bflush(bout);
296 564ca709 2004-04-19 devnull msg(res.store.u.ival, "stop");
297 564ca709 2004-04-19 devnull notes(res.store.u.ival);
298 564ca709 2004-04-19 devnull dostop(res.store.u.ival);
299 564ca709 2004-04-19 devnull }
300 564ca709 2004-04-19 devnull
301 564ca709 2004-04-19 devnull void
302 564ca709 2004-04-19 devnull xkill(Node *r, Node *args)
303 564ca709 2004-04-19 devnull {
304 564ca709 2004-04-19 devnull Node res;
305 564ca709 2004-04-19 devnull
306 564ca709 2004-04-19 devnull USED(r);
307 564ca709 2004-04-19 devnull if(args == 0)
308 564ca709 2004-04-19 devnull error("kill(pid): no pid");
309 564ca709 2004-04-19 devnull expr(args, &res);
310 564ca709 2004-04-19 devnull if(res.type != TINT)
311 564ca709 2004-04-19 devnull error("kill(pid): arg type");
312 564ca709 2004-04-19 devnull
313 564ca709 2004-04-19 devnull msg(res.store.u.ival, "kill");
314 564ca709 2004-04-19 devnull deinstall(res.store.u.ival);
315 564ca709 2004-04-19 devnull }
316 564ca709 2004-04-19 devnull
317 564ca709 2004-04-19 devnull void
318 564ca709 2004-04-19 devnull status(Node *r, Node *args)
319 564ca709 2004-04-19 devnull {
320 564ca709 2004-04-19 devnull Node res;
321 564ca709 2004-04-19 devnull char *p;
322 564ca709 2004-04-19 devnull
323 564ca709 2004-04-19 devnull USED(r);
324 564ca709 2004-04-19 devnull if(args == 0)
325 564ca709 2004-04-19 devnull error("status(pid): no pid");
326 564ca709 2004-04-19 devnull expr(args, &res);
327 564ca709 2004-04-19 devnull if(res.type != TINT)
328 564ca709 2004-04-19 devnull error("status(pid): arg type");
329 564ca709 2004-04-19 devnull
330 564ca709 2004-04-19 devnull p = getstatus(res.store.u.ival);
331 564ca709 2004-04-19 devnull r->store.u.string = strnode(p);
332 564ca709 2004-04-19 devnull r->op = OCONST;
333 564ca709 2004-04-19 devnull r->store.fmt = 's';
334 564ca709 2004-04-19 devnull r->type = TSTRING;
335 564ca709 2004-04-19 devnull }
336 564ca709 2004-04-19 devnull
337 564ca709 2004-04-19 devnull void
338 564ca709 2004-04-19 devnull reason(Node *r, Node *args)
339 564ca709 2004-04-19 devnull {
340 564ca709 2004-04-19 devnull Node res;
341 564ca709 2004-04-19 devnull
342 564ca709 2004-04-19 devnull if(args == 0)
343 564ca709 2004-04-19 devnull error("reason(cause): no cause");
344 564ca709 2004-04-19 devnull expr(args, &res);
345 564ca709 2004-04-19 devnull if(res.type != TINT)
346 564ca709 2004-04-19 devnull error("reason(cause): arg type");
347 564ca709 2004-04-19 devnull
348 564ca709 2004-04-19 devnull r->op = OCONST;
349 564ca709 2004-04-19 devnull r->type = TSTRING;
350 564ca709 2004-04-19 devnull r->store.fmt = 's';
351 564ca709 2004-04-19 devnull r->store.u.string = strnode((*mach->exc)(cormap, correg));
352 564ca709 2004-04-19 devnull }
353 564ca709 2004-04-19 devnull
354 564ca709 2004-04-19 devnull void
355 564ca709 2004-04-19 devnull follow(Node *r, Node *args)
356 564ca709 2004-04-19 devnull {
357 564ca709 2004-04-19 devnull int n, i;
358 564ca709 2004-04-19 devnull Node res;
359 564ca709 2004-04-19 devnull ulong f[10];
360 564ca709 2004-04-19 devnull List **tail, *l;
361 564ca709 2004-04-19 devnull
362 564ca709 2004-04-19 devnull if(args == 0)
363 564ca709 2004-04-19 devnull error("follow(addr): no addr");
364 564ca709 2004-04-19 devnull expr(args, &res);
365 564ca709 2004-04-19 devnull if(res.type != TINT)
366 564ca709 2004-04-19 devnull error("follow(addr): arg type");
367 564ca709 2004-04-19 devnull
368 564ca709 2004-04-19 devnull n = (*mach->foll)(cormap, correg, res.store.u.ival, f);
369 564ca709 2004-04-19 devnull if (n < 0)
370 564ca709 2004-04-19 devnull error("follow(addr): %r");
371 564ca709 2004-04-19 devnull tail = &r->store.u.l;
372 564ca709 2004-04-19 devnull for(i = 0; i < n; i++) {
373 564ca709 2004-04-19 devnull l = al(TINT);
374 564ca709 2004-04-19 devnull l->store.u.ival = f[i];
375 564ca709 2004-04-19 devnull l->store.fmt = 'X';
376 564ca709 2004-04-19 devnull *tail = l;
377 564ca709 2004-04-19 devnull tail = &l->next;
378 564ca709 2004-04-19 devnull }
379 564ca709 2004-04-19 devnull }
380 564ca709 2004-04-19 devnull
381 564ca709 2004-04-19 devnull void
382 564ca709 2004-04-19 devnull funcbound(Node *r, Node *args)
383 564ca709 2004-04-19 devnull {
384 564ca709 2004-04-19 devnull int n;
385 564ca709 2004-04-19 devnull Node res;
386 564ca709 2004-04-19 devnull ulong bounds[2];
387 564ca709 2004-04-19 devnull List *l;
388 564ca709 2004-04-19 devnull
389 564ca709 2004-04-19 devnull if(args == 0)
390 564ca709 2004-04-19 devnull error("fnbound(addr): no addr");
391 564ca709 2004-04-19 devnull expr(args, &res);
392 564ca709 2004-04-19 devnull if(res.type != TINT)
393 564ca709 2004-04-19 devnull error("fnbound(addr): arg type");
394 564ca709 2004-04-19 devnull
395 564ca709 2004-04-19 devnull n = fnbound(res.store.u.ival, bounds);
396 564ca709 2004-04-19 devnull if (n != 0) {
397 564ca709 2004-04-19 devnull r->store.u.l = al(TINT);
398 564ca709 2004-04-19 devnull l = r->store.u.l;
399 564ca709 2004-04-19 devnull l->store.u.ival = bounds[0];
400 564ca709 2004-04-19 devnull l->store.fmt = 'X';
401 564ca709 2004-04-19 devnull l->next = al(TINT);
402 564ca709 2004-04-19 devnull l = l->next;
403 564ca709 2004-04-19 devnull l->store.u.ival = bounds[1];
404 564ca709 2004-04-19 devnull l->store.fmt = 'X';
405 564ca709 2004-04-19 devnull }
406 564ca709 2004-04-19 devnull }
407 564ca709 2004-04-19 devnull
408 564ca709 2004-04-19 devnull void
409 564ca709 2004-04-19 devnull setproc(Node *r, Node *args)
410 564ca709 2004-04-19 devnull {
411 564ca709 2004-04-19 devnull Node res;
412 564ca709 2004-04-19 devnull
413 564ca709 2004-04-19 devnull USED(r);
414 564ca709 2004-04-19 devnull if(args == 0)
415 564ca709 2004-04-19 devnull error("setproc(pid): no pid");
416 564ca709 2004-04-19 devnull expr(args, &res);
417 564ca709 2004-04-19 devnull if(res.type != TINT)
418 564ca709 2004-04-19 devnull error("setproc(pid): arg type");
419 564ca709 2004-04-19 devnull
420 564ca709 2004-04-19 devnull sproc(res.store.u.ival);
421 564ca709 2004-04-19 devnull }
422 564ca709 2004-04-19 devnull
423 564ca709 2004-04-19 devnull void
424 564ca709 2004-04-19 devnull filepc(Node *r, Node *args)
425 564ca709 2004-04-19 devnull {
426 564ca709 2004-04-19 devnull int i;
427 564ca709 2004-04-19 devnull Node res;
428 564ca709 2004-04-19 devnull char *p, c;
429 564ca709 2004-04-19 devnull ulong v;
430 564ca709 2004-04-19 devnull
431 564ca709 2004-04-19 devnull if(args == 0)
432 564ca709 2004-04-19 devnull error("filepc(filename:line): arg count");
433 564ca709 2004-04-19 devnull expr(args, &res);
434 564ca709 2004-04-19 devnull if(res.type != TSTRING)
435 564ca709 2004-04-19 devnull error("filepc(filename:line): arg type");
436 564ca709 2004-04-19 devnull
437 564ca709 2004-04-19 devnull p = strchr(res.store.u.string->string, ':');
438 564ca709 2004-04-19 devnull if(p == 0)
439 564ca709 2004-04-19 devnull error("filepc(filename:line): bad arg format");
440 564ca709 2004-04-19 devnull
441 564ca709 2004-04-19 devnull c = *p;
442 564ca709 2004-04-19 devnull *p++ = '\0';
443 564ca709 2004-04-19 devnull i = file2pc(res.store.u.string->string, atoi(p), &v);
444 564ca709 2004-04-19 devnull p[-1] = c;
445 564ca709 2004-04-19 devnull if(i < 0)
446 564ca709 2004-04-19 devnull error("filepc(filename:line): can't find address");
447 564ca709 2004-04-19 devnull
448 564ca709 2004-04-19 devnull r->op = OCONST;
449 564ca709 2004-04-19 devnull r->type = TINT;
450 564ca709 2004-04-19 devnull r->store.fmt = 'D';
451 564ca709 2004-04-19 devnull r->store.u.ival = v;
452 564ca709 2004-04-19 devnull }
453 564ca709 2004-04-19 devnull
454 564ca709 2004-04-19 devnull void
455 564ca709 2004-04-19 devnull interpret(Node *r, Node *args)
456 564ca709 2004-04-19 devnull {
457 564ca709 2004-04-19 devnull Node res;
458 564ca709 2004-04-19 devnull int isave;
459 564ca709 2004-04-19 devnull
460 564ca709 2004-04-19 devnull if(args == 0)
461 564ca709 2004-04-19 devnull error("interpret(string): arg count");
462 564ca709 2004-04-19 devnull expr(args, &res);
463 564ca709 2004-04-19 devnull if(res.type != TSTRING)
464 564ca709 2004-04-19 devnull error("interpret(string): arg type");
465 564ca709 2004-04-19 devnull
466 564ca709 2004-04-19 devnull pushstr(&res);
467 564ca709 2004-04-19 devnull
468 564ca709 2004-04-19 devnull isave = interactive;
469 564ca709 2004-04-19 devnull interactive = 0;
470 564ca709 2004-04-19 devnull r->store.u.ival = yyparse();
471 564ca709 2004-04-19 devnull interactive = isave;
472 564ca709 2004-04-19 devnull popio();
473 564ca709 2004-04-19 devnull r->op = OCONST;
474 564ca709 2004-04-19 devnull r->type = TINT;
475 564ca709 2004-04-19 devnull r->store.fmt = 'D';
476 564ca709 2004-04-19 devnull }
477 564ca709 2004-04-19 devnull
478 564ca709 2004-04-19 devnull void
479 564ca709 2004-04-19 devnull include(Node *r, Node *args)
480 564ca709 2004-04-19 devnull {
481 a8c15b08 2004-04-21 devnull char *file, *libfile;
482 a8c15b08 2004-04-21 devnull static char buf[1024];
483 564ca709 2004-04-19 devnull Node res;
484 564ca709 2004-04-19 devnull int isave;
485 564ca709 2004-04-19 devnull
486 564ca709 2004-04-19 devnull if(args == 0)
487 564ca709 2004-04-19 devnull error("include(string): arg count");
488 564ca709 2004-04-19 devnull expr(args, &res);
489 564ca709 2004-04-19 devnull if(res.type != TSTRING)
490 564ca709 2004-04-19 devnull error("include(string): arg type");
491 564ca709 2004-04-19 devnull
492 564ca709 2004-04-19 devnull Bflush(bout);
493 a8c15b08 2004-04-21 devnull
494 a8c15b08 2004-04-21 devnull libfile = nil;
495 a8c15b08 2004-04-21 devnull file = res.store.u.string->string;
496 a8c15b08 2004-04-21 devnull if(access(file, AREAD) < 0 && file[0] != '/'){
497 a8c15b08 2004-04-21 devnull snprint(buf, sizeof buf, "#9/acid/%s", file);
498 a8c15b08 2004-04-21 devnull libfile = unsharp(buf);
499 a8c15b08 2004-04-21 devnull if(access(libfile, AREAD) >= 0){
500 a8c15b08 2004-04-21 devnull strecpy(buf, buf+sizeof buf, libfile);
501 a8c15b08 2004-04-21 devnull file = buf;
502 a8c15b08 2004-04-21 devnull }
503 a8c15b08 2004-04-21 devnull free(libfile);
504 a8c15b08 2004-04-21 devnull }
505 564ca709 2004-04-19 devnull
506 a9df759c 2004-04-21 devnull pushfile(file);
507 564ca709 2004-04-19 devnull isave = interactive;
508 564ca709 2004-04-19 devnull interactive = 0;
509 564ca709 2004-04-19 devnull r->store.u.ival = yyparse();
510 564ca709 2004-04-19 devnull interactive = isave;
511 564ca709 2004-04-19 devnull popio();
512 564ca709 2004-04-19 devnull r->op = OCONST;
513 564ca709 2004-04-19 devnull r->type = TINT;
514 564ca709 2004-04-19 devnull r->store.fmt = 'D';
515 564ca709 2004-04-19 devnull }
516 564ca709 2004-04-19 devnull
517 564ca709 2004-04-19 devnull void
518 564ca709 2004-04-19 devnull includepipe(Node *r, Node *args)
519 564ca709 2004-04-19 devnull {
520 564ca709 2004-04-19 devnull Node res;
521 564ca709 2004-04-19 devnull int i, isave, pid, pip[2];
522 564ca709 2004-04-19 devnull char *argv[4];
523 564ca709 2004-04-19 devnull Waitmsg *w;
524 564ca709 2004-04-19 devnull
525 564ca709 2004-04-19 devnull USED(r);
526 564ca709 2004-04-19 devnull if(args == 0)
527 564ca709 2004-04-19 devnull error("includepipe(string): arg count");
528 564ca709 2004-04-19 devnull expr(args, &res);
529 564ca709 2004-04-19 devnull if(res.type != TSTRING)
530 564ca709 2004-04-19 devnull error("includepipe(string): arg type");
531 564ca709 2004-04-19 devnull
532 564ca709 2004-04-19 devnull Bflush(bout);
533 564ca709 2004-04-19 devnull
534 564ca709 2004-04-19 devnull argv[0] = "rc";
535 564ca709 2004-04-19 devnull argv[1] = "-c";
536 564ca709 2004-04-19 devnull argv[2] = res.store.u.string->string;
537 564ca709 2004-04-19 devnull argv[3] = 0;
538 564ca709 2004-04-19 devnull
539 564ca709 2004-04-19 devnull if(pipe(pip) < 0)
540 564ca709 2004-04-19 devnull error("pipe: %r");
541 564ca709 2004-04-19 devnull
542 564ca709 2004-04-19 devnull pid = fork();
543 564ca709 2004-04-19 devnull switch(pid) {
544 564ca709 2004-04-19 devnull case -1:
545 564ca709 2004-04-19 devnull close(pip[0]);
546 564ca709 2004-04-19 devnull close(pip[1]);
547 564ca709 2004-04-19 devnull error("fork: %r");
548 564ca709 2004-04-19 devnull case 0:
549 564ca709 2004-04-19 devnull close(pip[0]);
550 564ca709 2004-04-19 devnull close(0);
551 564ca709 2004-04-19 devnull open("/dev/null", OREAD);
552 564ca709 2004-04-19 devnull dup(pip[1], 1);
553 564ca709 2004-04-19 devnull if(pip[1] > 1)
554 564ca709 2004-04-19 devnull close(pip[1]);
555 564ca709 2004-04-19 devnull for(i=3; i<100; i++)
556 564ca709 2004-04-19 devnull close(i);
557 564ca709 2004-04-19 devnull exec("rc", argv);
558 564ca709 2004-04-19 devnull sysfatal("exec rc: %r");
559 564ca709 2004-04-19 devnull }
560 564ca709 2004-04-19 devnull
561 564ca709 2004-04-19 devnull close(pip[1]);
562 564ca709 2004-04-19 devnull pushfd(pip[0]);
563 564ca709 2004-04-19 devnull
564 564ca709 2004-04-19 devnull isave = interactive;
565 564ca709 2004-04-19 devnull interactive = 0;
566 564ca709 2004-04-19 devnull r->store.u.ival = yyparse();
567 564ca709 2004-04-19 devnull interactive = isave;
568 564ca709 2004-04-19 devnull popio();
569 a9df759c 2004-04-21 devnull
570 564ca709 2004-04-19 devnull r->op = OCONST;
571 564ca709 2004-04-19 devnull r->type = TINT;
572 564ca709 2004-04-19 devnull r->store.fmt = 'D';
573 564ca709 2004-04-19 devnull
574 564ca709 2004-04-19 devnull w = waitfor(pid);
575 564ca709 2004-04-19 devnull if(w->msg && w->msg[0])
576 564ca709 2004-04-19 devnull error("includepipe(\"%s\"): %s", argv[2], w->msg); /* leaks w */
577 564ca709 2004-04-19 devnull free(w);
578 564ca709 2004-04-19 devnull }
579 564ca709 2004-04-19 devnull
580 564ca709 2004-04-19 devnull void
581 564ca709 2004-04-19 devnull rc(Node *r, Node *args)
582 564ca709 2004-04-19 devnull {
583 564ca709 2004-04-19 devnull Node res;
584 564ca709 2004-04-19 devnull int pid;
585 564ca709 2004-04-19 devnull char *p, *q, *argv[4];
586 564ca709 2004-04-19 devnull Waitmsg *w;
587 564ca709 2004-04-19 devnull
588 564ca709 2004-04-19 devnull USED(r);
589 564ca709 2004-04-19 devnull if(args == 0)
590 564ca709 2004-04-19 devnull error("rc(string): arg count");
591 564ca709 2004-04-19 devnull expr(args, &res);
592 564ca709 2004-04-19 devnull if(res.type != TSTRING)
593 564ca709 2004-04-19 devnull error("rc(string): arg type");
594 564ca709 2004-04-19 devnull
595 564ca709 2004-04-19 devnull argv[0] = "rc";
596 564ca709 2004-04-19 devnull argv[1] = "-c";
597 564ca709 2004-04-19 devnull argv[2] = res.store.u.string->string;
598 564ca709 2004-04-19 devnull argv[3] = 0;
599 564ca709 2004-04-19 devnull
600 564ca709 2004-04-19 devnull pid = fork();
601 564ca709 2004-04-19 devnull switch(pid) {
602 564ca709 2004-04-19 devnull case -1:
603 564ca709 2004-04-19 devnull error("fork %r");
604 564ca709 2004-04-19 devnull case 0:
605 564ca709 2004-04-19 devnull exec("rc", argv);
606 564ca709 2004-04-19 devnull exits(0);
607 564ca709 2004-04-19 devnull default:
608 564ca709 2004-04-19 devnull w = waitfor(pid);
609 564ca709 2004-04-19 devnull break;
610 564ca709 2004-04-19 devnull }
611 564ca709 2004-04-19 devnull p = w->msg;
612 564ca709 2004-04-19 devnull q = strrchr(p, ':');
613 564ca709 2004-04-19 devnull if (q)
614 564ca709 2004-04-19 devnull p = q+1;
615 564ca709 2004-04-19 devnull
616 564ca709 2004-04-19 devnull r->op = OCONST;
617 564ca709 2004-04-19 devnull r->type = TSTRING;
618 564ca709 2004-04-19 devnull r->store.u.string = strnode(p);
619 564ca709 2004-04-19 devnull free(w);
620 564ca709 2004-04-19 devnull r->store.fmt = 's';
621 564ca709 2004-04-19 devnull }
622 564ca709 2004-04-19 devnull
623 564ca709 2004-04-19 devnull void
624 564ca709 2004-04-19 devnull doerror(Node *r, Node *args)
625 564ca709 2004-04-19 devnull {
626 564ca709 2004-04-19 devnull Node res;
627 564ca709 2004-04-19 devnull
628 564ca709 2004-04-19 devnull USED(r);
629 564ca709 2004-04-19 devnull if(args == 0)
630 564ca709 2004-04-19 devnull error("error(string): arg count");
631 564ca709 2004-04-19 devnull expr(args, &res);
632 564ca709 2004-04-19 devnull if(res.type != TSTRING)
633 564ca709 2004-04-19 devnull error("error(string): arg type");
634 564ca709 2004-04-19 devnull
635 564ca709 2004-04-19 devnull error(res.store.u.string->string);
636 564ca709 2004-04-19 devnull }
637 564ca709 2004-04-19 devnull
638 564ca709 2004-04-19 devnull void
639 564ca709 2004-04-19 devnull doaccess(Node *r, Node *args)
640 564ca709 2004-04-19 devnull {
641 564ca709 2004-04-19 devnull Node res;
642 564ca709 2004-04-19 devnull
643 564ca709 2004-04-19 devnull if(args == 0)
644 564ca709 2004-04-19 devnull error("access(filename): arg count");
645 564ca709 2004-04-19 devnull expr(args, &res);
646 564ca709 2004-04-19 devnull if(res.type != TSTRING)
647 564ca709 2004-04-19 devnull error("access(filename): arg type");
648 564ca709 2004-04-19 devnull
649 564ca709 2004-04-19 devnull r->op = OCONST;
650 564ca709 2004-04-19 devnull r->type = TINT;
651 6c885647 2004-04-20 devnull r->store.fmt = 'D';
652 564ca709 2004-04-19 devnull r->store.u.ival = 0;
653 564ca709 2004-04-19 devnull if(access(res.store.u.string->string, 4) == 0)
654 564ca709 2004-04-19 devnull r->store.u.ival = 1;
655 564ca709 2004-04-19 devnull }
656 564ca709 2004-04-19 devnull
657 564ca709 2004-04-19 devnull void
658 564ca709 2004-04-19 devnull readfile(Node *r, Node *args)
659 564ca709 2004-04-19 devnull {
660 564ca709 2004-04-19 devnull Node res;
661 564ca709 2004-04-19 devnull int n, fd;
662 564ca709 2004-04-19 devnull char *buf;
663 564ca709 2004-04-19 devnull Dir *db;
664 564ca709 2004-04-19 devnull
665 564ca709 2004-04-19 devnull if(args == 0)
666 564ca709 2004-04-19 devnull error("readfile(filename): arg count");
667 564ca709 2004-04-19 devnull expr(args, &res);
668 564ca709 2004-04-19 devnull if(res.type != TSTRING)
669 564ca709 2004-04-19 devnull error("readfile(filename): arg type");
670 564ca709 2004-04-19 devnull
671 564ca709 2004-04-19 devnull fd = open(res.store.u.string->string, OREAD);
672 564ca709 2004-04-19 devnull if(fd < 0)
673 564ca709 2004-04-19 devnull return;
674 564ca709 2004-04-19 devnull
675 564ca709 2004-04-19 devnull db = dirfstat(fd);
676 564ca709 2004-04-19 devnull if(db == nil || db->length == 0)
677 564ca709 2004-04-19 devnull n = 8192;
678 564ca709 2004-04-19 devnull else
679 564ca709 2004-04-19 devnull n = db->length;
680 564ca709 2004-04-19 devnull free(db);
681 564ca709 2004-04-19 devnull
682 564ca709 2004-04-19 devnull buf = malloc(n);
683 564ca709 2004-04-19 devnull n = read(fd, buf, n);
684 564ca709 2004-04-19 devnull
685 564ca709 2004-04-19 devnull if(n > 0) {
686 564ca709 2004-04-19 devnull r->op = OCONST;
687 564ca709 2004-04-19 devnull r->type = TSTRING;
688 564ca709 2004-04-19 devnull r->store.u.string = strnodlen(buf, n);
689 564ca709 2004-04-19 devnull r->store.fmt = 's';
690 564ca709 2004-04-19 devnull }
691 564ca709 2004-04-19 devnull free(buf);
692 564ca709 2004-04-19 devnull close(fd);
693 564ca709 2004-04-19 devnull }
694 564ca709 2004-04-19 devnull
695 564ca709 2004-04-19 devnull void
696 564ca709 2004-04-19 devnull getfile(Node *r, Node *args)
697 564ca709 2004-04-19 devnull {
698 564ca709 2004-04-19 devnull int n;
699 564ca709 2004-04-19 devnull char *p;
700 564ca709 2004-04-19 devnull Node res;
701 564ca709 2004-04-19 devnull String *s;
702 564ca709 2004-04-19 devnull Biobuf *bp;
703 564ca709 2004-04-19 devnull List **l, *new;
704 564ca709 2004-04-19 devnull
705 564ca709 2004-04-19 devnull if(args == 0)
706 564ca709 2004-04-19 devnull error("file(filename): arg count");
707 564ca709 2004-04-19 devnull expr(args, &res);
708 564ca709 2004-04-19 devnull if(res.type != TSTRING)
709 564ca709 2004-04-19 devnull error("file(filename): arg type");
710 564ca709 2004-04-19 devnull
711 564ca709 2004-04-19 devnull r->op = OCONST;
712 564ca709 2004-04-19 devnull r->type = TLIST;
713 564ca709 2004-04-19 devnull r->store.u.l = 0;
714 564ca709 2004-04-19 devnull
715 564ca709 2004-04-19 devnull p = res.store.u.string->string;
716 564ca709 2004-04-19 devnull bp = Bopen(p, OREAD);
717 564ca709 2004-04-19 devnull if(bp == 0)
718 564ca709 2004-04-19 devnull return;
719 564ca709 2004-04-19 devnull
720 564ca709 2004-04-19 devnull l = &r->store.u.l;
721 564ca709 2004-04-19 devnull for(;;) {
722 564ca709 2004-04-19 devnull p = Brdline(bp, '\n');
723 564ca709 2004-04-19 devnull n = Blinelen(bp);
724 564ca709 2004-04-19 devnull if(p == 0) {
725 564ca709 2004-04-19 devnull if(n == 0)
726 564ca709 2004-04-19 devnull break;
727 564ca709 2004-04-19 devnull s = strnodlen(0, n);
728 564ca709 2004-04-19 devnull Bread(bp, s->string, n);
729 564ca709 2004-04-19 devnull }
730 564ca709 2004-04-19 devnull else
731 564ca709 2004-04-19 devnull s = strnodlen(p, n-1);
732 564ca709 2004-04-19 devnull
733 564ca709 2004-04-19 devnull new = al(TSTRING);
734 564ca709 2004-04-19 devnull new->store.u.string = s;
735 564ca709 2004-04-19 devnull new->store.fmt = 's';
736 564ca709 2004-04-19 devnull *l = new;
737 564ca709 2004-04-19 devnull l = &new->next;
738 564ca709 2004-04-19 devnull }
739 564ca709 2004-04-19 devnull Bterm(bp);
740 564ca709 2004-04-19 devnull }
741 564ca709 2004-04-19 devnull
742 564ca709 2004-04-19 devnull void
743 564ca709 2004-04-19 devnull cvtatof(Node *r, Node *args)
744 564ca709 2004-04-19 devnull {
745 564ca709 2004-04-19 devnull Node res;
746 564ca709 2004-04-19 devnull
747 564ca709 2004-04-19 devnull if(args == 0)
748 564ca709 2004-04-19 devnull error("atof(string): arg count");
749 564ca709 2004-04-19 devnull expr(args, &res);
750 564ca709 2004-04-19 devnull if(res.type != TSTRING)
751 564ca709 2004-04-19 devnull error("atof(string): arg type");
752 564ca709 2004-04-19 devnull
753 564ca709 2004-04-19 devnull r->op = OCONST;
754 564ca709 2004-04-19 devnull r->type = TFLOAT;
755 564ca709 2004-04-19 devnull r->store.u.fval = atof(res.store.u.string->string);
756 564ca709 2004-04-19 devnull r->store.fmt = 'f';
757 564ca709 2004-04-19 devnull }
758 564ca709 2004-04-19 devnull
759 564ca709 2004-04-19 devnull void
760 564ca709 2004-04-19 devnull cvtatoi(Node *r, Node *args)
761 564ca709 2004-04-19 devnull {
762 564ca709 2004-04-19 devnull Node res;
763 564ca709 2004-04-19 devnull
764 564ca709 2004-04-19 devnull if(args == 0)
765 564ca709 2004-04-19 devnull error("atoi(string): arg count");
766 564ca709 2004-04-19 devnull expr(args, &res);
767 564ca709 2004-04-19 devnull if(res.type != TSTRING)
768 564ca709 2004-04-19 devnull error("atoi(string): arg type");
769 564ca709 2004-04-19 devnull
770 564ca709 2004-04-19 devnull r->op = OCONST;
771 564ca709 2004-04-19 devnull r->type = TINT;
772 564ca709 2004-04-19 devnull r->store.u.ival = strtoul(res.store.u.string->string, 0, 0);
773 564ca709 2004-04-19 devnull r->store.fmt = 'D';
774 564ca709 2004-04-19 devnull }
775 564ca709 2004-04-19 devnull
776 564ca709 2004-04-19 devnull void
777 564ca709 2004-04-19 devnull cvtitoa(Node *r, Node *args)
778 564ca709 2004-04-19 devnull {
779 564ca709 2004-04-19 devnull Node res;
780 564ca709 2004-04-19 devnull Node *av[Maxarg];
781 564ca709 2004-04-19 devnull int ival;
782 564ca709 2004-04-19 devnull char buf[128], *fmt;
783 564ca709 2004-04-19 devnull
784 564ca709 2004-04-19 devnull if(args == 0)
785 564ca709 2004-04-19 devnull err:
786 564ca709 2004-04-19 devnull error("itoa(number [, printformat]): arg count");
787 564ca709 2004-04-19 devnull na = 0;
788 564ca709 2004-04-19 devnull flatten(av, args);
789 564ca709 2004-04-19 devnull if(na == 0 || na > 2)
790 564ca709 2004-04-19 devnull goto err;
791 564ca709 2004-04-19 devnull expr(av[0], &res);
792 564ca709 2004-04-19 devnull if(res.type != TINT)
793 564ca709 2004-04-19 devnull error("itoa(integer): arg type");
794 564ca709 2004-04-19 devnull ival = (int)res.store.u.ival;
795 564ca709 2004-04-19 devnull fmt = "%d";
796 564ca709 2004-04-19 devnull if(na == 2){
797 564ca709 2004-04-19 devnull expr(av[1], &res);
798 564ca709 2004-04-19 devnull if(res.type != TSTRING)
799 564ca709 2004-04-19 devnull error("itoa(integer, string): arg type");
800 564ca709 2004-04-19 devnull fmt = res.store.u.string->string;
801 564ca709 2004-04-19 devnull }
802 564ca709 2004-04-19 devnull
803 564ca709 2004-04-19 devnull sprint(buf, fmt, ival);
804 564ca709 2004-04-19 devnull r->op = OCONST;
805 564ca709 2004-04-19 devnull r->type = TSTRING;
806 564ca709 2004-04-19 devnull r->store.u.string = strnode(buf);
807 564ca709 2004-04-19 devnull r->store.fmt = 's';
808 564ca709 2004-04-19 devnull }
809 564ca709 2004-04-19 devnull
810 564ca709 2004-04-19 devnull List*
811 564ca709 2004-04-19 devnull mapent(Map *m)
812 564ca709 2004-04-19 devnull {
813 564ca709 2004-04-19 devnull int i;
814 564ca709 2004-04-19 devnull List *l, *n, **t, *h;
815 564ca709 2004-04-19 devnull
816 564ca709 2004-04-19 devnull h = 0;
817 564ca709 2004-04-19 devnull t = &h;
818 564ca709 2004-04-19 devnull for(i = 0; i < m->nseg; i++) {
819 564ca709 2004-04-19 devnull l = al(TSTRING);
820 564ca709 2004-04-19 devnull n = al(TLIST);
821 564ca709 2004-04-19 devnull n->store.u.l = l;
822 564ca709 2004-04-19 devnull *t = n;
823 564ca709 2004-04-19 devnull t = &n->next;
824 564ca709 2004-04-19 devnull l->store.u.string = strnode(m->seg[i].name);
825 564ca709 2004-04-19 devnull l->store.fmt = 's';
826 564ca709 2004-04-19 devnull l->next = al(TSTRING);
827 564ca709 2004-04-19 devnull l = l->next;
828 564ca709 2004-04-19 devnull l->store.u.string = strnode(m->seg[i].file ? m->seg[i].file : "");
829 564ca709 2004-04-19 devnull l->store.fmt = 's';
830 564ca709 2004-04-19 devnull l->next = al(TINT);
831 564ca709 2004-04-19 devnull l = l->next;
832 564ca709 2004-04-19 devnull l->store.u.ival = m->seg[i].base;
833 564ca709 2004-04-19 devnull l->store.fmt = 'X';
834 564ca709 2004-04-19 devnull l->next = al(TINT);
835 564ca709 2004-04-19 devnull l = l->next;
836 564ca709 2004-04-19 devnull l->store.u.ival = m->seg[i].base + m->seg[i].size;
837 564ca709 2004-04-19 devnull l->store.fmt = 'X';
838 564ca709 2004-04-19 devnull l->next = al(TINT);
839 564ca709 2004-04-19 devnull l = l->next;
840 564ca709 2004-04-19 devnull l->store.u.ival = m->seg[i].offset;
841 564ca709 2004-04-19 devnull l->store.fmt = 'X';
842 564ca709 2004-04-19 devnull }
843 564ca709 2004-04-19 devnull return h;
844 564ca709 2004-04-19 devnull }
845 564ca709 2004-04-19 devnull
846 564ca709 2004-04-19 devnull void
847 564ca709 2004-04-19 devnull map(Node *r, Node *args)
848 564ca709 2004-04-19 devnull {
849 564ca709 2004-04-19 devnull int i;
850 564ca709 2004-04-19 devnull Map *m;
851 564ca709 2004-04-19 devnull List *l;
852 564ca709 2004-04-19 devnull char *nam, *fil;
853 564ca709 2004-04-19 devnull Node *av[Maxarg], res;
854 564ca709 2004-04-19 devnull
855 564ca709 2004-04-19 devnull na = 0;
856 564ca709 2004-04-19 devnull flatten(av, args);
857 564ca709 2004-04-19 devnull
858 564ca709 2004-04-19 devnull if(na != 0) {
859 564ca709 2004-04-19 devnull expr(av[0], &res);
860 564ca709 2004-04-19 devnull if(res.type != TLIST)
861 564ca709 2004-04-19 devnull error("map(list): map needs a list");
862 564ca709 2004-04-19 devnull if(listlen(res.store.u.l) != 5)
863 564ca709 2004-04-19 devnull error("map(list): list must have 5 entries");
864 564ca709 2004-04-19 devnull
865 564ca709 2004-04-19 devnull l = res.store.u.l;
866 564ca709 2004-04-19 devnull if(l->type != TSTRING)
867 564ca709 2004-04-19 devnull error("map name must be a string");
868 564ca709 2004-04-19 devnull nam = l->store.u.string->string;
869 564ca709 2004-04-19 devnull l = l->next;
870 564ca709 2004-04-19 devnull if(l->type != TSTRING)
871 564ca709 2004-04-19 devnull error("map file must be a string");
872 564ca709 2004-04-19 devnull fil = l->store.u.string->string;
873 564ca709 2004-04-19 devnull m = symmap;
874 564ca709 2004-04-19 devnull i = findseg(m, nam, fil);
875 564ca709 2004-04-19 devnull if(i < 0) {
876 564ca709 2004-04-19 devnull m = cormap;
877 564ca709 2004-04-19 devnull i = findseg(m, nam, fil);
878 564ca709 2004-04-19 devnull }
879 564ca709 2004-04-19 devnull if(i < 0)
880 564ca709 2004-04-19 devnull error("%s %s is not a map entry", nam, fil);
881 564ca709 2004-04-19 devnull l = l->next;
882 564ca709 2004-04-19 devnull if(l->type != TINT)
883 564ca709 2004-04-19 devnull error("map entry not int");
884 564ca709 2004-04-19 devnull m->seg[i].base = l->store.u.ival;
885 564ca709 2004-04-19 devnull /*
886 564ca709 2004-04-19 devnull if (strcmp(ent, "text") == 0)
887 564ca709 2004-04-19 devnull textseg(l->store.u.ival, &fhdr);
888 564ca709 2004-04-19 devnull */
889 564ca709 2004-04-19 devnull l = l->next;
890 564ca709 2004-04-19 devnull if(l->type != TINT)
891 564ca709 2004-04-19 devnull error("map entry not int");
892 564ca709 2004-04-19 devnull m->seg[i].size = l->store.u.ival - m->seg[i].base;
893 564ca709 2004-04-19 devnull l = l->next;
894 564ca709 2004-04-19 devnull if(l->type != TINT)
895 564ca709 2004-04-19 devnull error("map entry not int");
896 564ca709 2004-04-19 devnull m->seg[i].offset = l->store.u.ival;
897 564ca709 2004-04-19 devnull }
898 564ca709 2004-04-19 devnull
899 564ca709 2004-04-19 devnull r->type = TLIST;
900 564ca709 2004-04-19 devnull r->store.u.l = 0;
901 564ca709 2004-04-19 devnull if(symmap)
902 564ca709 2004-04-19 devnull r->store.u.l = mapent(symmap);
903 564ca709 2004-04-19 devnull if(cormap) {
904 564ca709 2004-04-19 devnull if(r->store.u.l == 0)
905 564ca709 2004-04-19 devnull r->store.u.l = mapent(cormap);
906 564ca709 2004-04-19 devnull else {
907 564ca709 2004-04-19 devnull for(l = r->store.u.l; l->next; l = l->next)
908 564ca709 2004-04-19 devnull ;
909 564ca709 2004-04-19 devnull l->next = mapent(cormap);
910 564ca709 2004-04-19 devnull }
911 564ca709 2004-04-19 devnull }
912 564ca709 2004-04-19 devnull }
913 564ca709 2004-04-19 devnull
914 564ca709 2004-04-19 devnull void
915 564ca709 2004-04-19 devnull flatten(Node **av, Node *n)
916 564ca709 2004-04-19 devnull {
917 564ca709 2004-04-19 devnull if(n == 0)
918 564ca709 2004-04-19 devnull return;
919 564ca709 2004-04-19 devnull
920 564ca709 2004-04-19 devnull switch(n->op) {
921 564ca709 2004-04-19 devnull case OLIST:
922 564ca709 2004-04-19 devnull flatten(av, n->left);
923 564ca709 2004-04-19 devnull flatten(av, n->right);
924 564ca709 2004-04-19 devnull break;
925 564ca709 2004-04-19 devnull default:
926 564ca709 2004-04-19 devnull av[na++] = n;
927 564ca709 2004-04-19 devnull if(na >= Maxarg)
928 564ca709 2004-04-19 devnull error("too many function arguments");
929 564ca709 2004-04-19 devnull break;
930 564ca709 2004-04-19 devnull }
931 564ca709 2004-04-19 devnull }
932 564ca709 2004-04-19 devnull
933 564ca709 2004-04-19 devnull static struct
934 564ca709 2004-04-19 devnull {
935 564ca709 2004-04-19 devnull char *name;
936 564ca709 2004-04-19 devnull ulong val;
937 564ca709 2004-04-19 devnull } sregs[Maxarg/2];
938 564ca709 2004-04-19 devnull static int nsregs;
939 564ca709 2004-04-19 devnull
940 564ca709 2004-04-19 devnull static int
941 564ca709 2004-04-19 devnull straceregrw(Regs *regs, char *name, ulong *val, int isr)
942 564ca709 2004-04-19 devnull {
943 564ca709 2004-04-19 devnull int i;
944 564ca709 2004-04-19 devnull
945 564ca709 2004-04-19 devnull if(!isr){
946 564ca709 2004-04-19 devnull werrstr("saved registers cannot be written");
947 564ca709 2004-04-19 devnull return -1;
948 564ca709 2004-04-19 devnull }
949 564ca709 2004-04-19 devnull for(i=0; i<nsregs; i++)
950 564ca709 2004-04-19 devnull if(strcmp(sregs[i].name, name) == 0){
951 564ca709 2004-04-19 devnull *val = sregs[i].val;
952 564ca709 2004-04-19 devnull return 0;
953 564ca709 2004-04-19 devnull }
954 564ca709 2004-04-19 devnull return rget(correg, name, val);
955 564ca709 2004-04-19 devnull }
956 564ca709 2004-04-19 devnull
957 564ca709 2004-04-19 devnull void
958 564ca709 2004-04-19 devnull strace(Node *r, Node *args)
959 564ca709 2004-04-19 devnull {
960 564ca709 2004-04-19 devnull Node *av[Maxarg], res;
961 564ca709 2004-04-19 devnull List *l;
962 564ca709 2004-04-19 devnull Regs regs;
963 564ca709 2004-04-19 devnull
964 564ca709 2004-04-19 devnull na = 0;
965 564ca709 2004-04-19 devnull flatten(av, args);
966 564ca709 2004-04-19 devnull
967 564ca709 2004-04-19 devnull if(na != 1)
968 564ca709 2004-04-19 devnull error("strace(list): want one arg");
969 564ca709 2004-04-19 devnull
970 564ca709 2004-04-19 devnull expr(av[0], &res);
971 564ca709 2004-04-19 devnull if(res.type != TLIST)
972 564ca709 2004-04-19 devnull error("strace(list): strace needs a list");
973 564ca709 2004-04-19 devnull l = res.store.u.l;
974 564ca709 2004-04-19 devnull if(listlen(l)%2)
975 564ca709 2004-04-19 devnull error("strace(list): strace needs an even-length list");
976 564ca709 2004-04-19 devnull for(nsregs=0; l; nsregs++){
977 564ca709 2004-04-19 devnull if(l->type != TSTRING)
978 564ca709 2004-04-19 devnull error("strace({r,v,r,v,...}): non-string name");
979 564ca709 2004-04-19 devnull sregs[nsregs].name = l->store.u.string->string;
980 564ca709 2004-04-19 devnull if(regdesc(sregs[nsregs].name) == nil)
981 564ca709 2004-04-19 devnull error("strace: bad register '%s'", sregs[nsregs].name);
982 564ca709 2004-04-19 devnull l = l->next;
983 564ca709 2004-04-19 devnull
984 564ca709 2004-04-19 devnull if(l == nil)
985 564ca709 2004-04-19 devnull error("cannot happen in strace");
986 564ca709 2004-04-19 devnull if(l->type != TINT)
987 564ca709 2004-04-19 devnull error("strace: non-int value for %s", sregs[nsregs].name);
988 564ca709 2004-04-19 devnull sregs[nsregs].val = l->store.u.ival;
989 564ca709 2004-04-19 devnull l = l->next;
990 564ca709 2004-04-19 devnull }
991 564ca709 2004-04-19 devnull regs.rw = straceregrw;
992 564ca709 2004-04-19 devnull
993 564ca709 2004-04-19 devnull tracelist = 0;
994 564ca709 2004-04-19 devnull if(stacktrace(cormap, &regs, trlist) <= 0)
995 564ca709 2004-04-19 devnull error("no stack frame");
996 564ca709 2004-04-19 devnull r->type = TLIST;
997 564ca709 2004-04-19 devnull r->store.u.l = tracelist;
998 564ca709 2004-04-19 devnull }
999 564ca709 2004-04-19 devnull
1000 564ca709 2004-04-19 devnull void
1001 564ca709 2004-04-19 devnull regerror(char *msg)
1002 564ca709 2004-04-19 devnull {
1003 564ca709 2004-04-19 devnull error(msg);
1004 564ca709 2004-04-19 devnull }
1005 564ca709 2004-04-19 devnull
1006 564ca709 2004-04-19 devnull void
1007 564ca709 2004-04-19 devnull regexp(Node *r, Node *args)
1008 564ca709 2004-04-19 devnull {
1009 564ca709 2004-04-19 devnull Node res;
1010 564ca709 2004-04-19 devnull Reprog *rp;
1011 564ca709 2004-04-19 devnull Node *av[Maxarg];
1012 564ca709 2004-04-19 devnull
1013 564ca709 2004-04-19 devnull na = 0;
1014 564ca709 2004-04-19 devnull flatten(av, args);
1015 564ca709 2004-04-19 devnull if(na != 2)
1016 564ca709 2004-04-19 devnull error("regexp(pattern, string): arg count");
1017 564ca709 2004-04-19 devnull expr(av[0], &res);
1018 564ca709 2004-04-19 devnull if(res.type != TSTRING)
1019 564ca709 2004-04-19 devnull error("regexp(pattern, string): pattern must be string");
1020 564ca709 2004-04-19 devnull rp = regcomp(res.store.u.string->string);
1021 564ca709 2004-04-19 devnull if(rp == 0)
1022 564ca709 2004-04-19 devnull return;
1023 564ca709 2004-04-19 devnull
1024 564ca709 2004-04-19 devnull expr(av[1], &res);
1025 564ca709 2004-04-19 devnull if(res.type != TSTRING)
1026 564ca709 2004-04-19 devnull error("regexp(pattern, string): bad string");
1027 564ca709 2004-04-19 devnull
1028 564ca709 2004-04-19 devnull r->store.fmt = 'D';
1029 564ca709 2004-04-19 devnull r->type = TINT;
1030 564ca709 2004-04-19 devnull r->store.u.ival = regexec(rp, res.store.u.string->string, 0, 0);
1031 564ca709 2004-04-19 devnull free(rp);
1032 564ca709 2004-04-19 devnull }
1033 564ca709 2004-04-19 devnull
1034 564ca709 2004-04-19 devnull char vfmt[] = "aBbcCdDfFgGiIoOqQrRsSuUVxXYZ";
1035 564ca709 2004-04-19 devnull
1036 564ca709 2004-04-19 devnull void
1037 564ca709 2004-04-19 devnull fmt(Node *r, Node *args)
1038 564ca709 2004-04-19 devnull {
1039 564ca709 2004-04-19 devnull Node res;
1040 564ca709 2004-04-19 devnull Node *av[Maxarg];
1041 564ca709 2004-04-19 devnull
1042 564ca709 2004-04-19 devnull na = 0;
1043 564ca709 2004-04-19 devnull flatten(av, args);
1044 564ca709 2004-04-19 devnull if(na != 2)
1045 564ca709 2004-04-19 devnull error("fmt(obj, fmt): arg count");
1046 564ca709 2004-04-19 devnull expr(av[1], &res);
1047 564ca709 2004-04-19 devnull if(res.type != TINT || strchr(vfmt, res.store.u.ival) == 0)
1048 564ca709 2004-04-19 devnull error("fmt(obj, fmt): bad format '%c'", (char)res.store.u.ival);
1049 564ca709 2004-04-19 devnull expr(av[0], r);
1050 564ca709 2004-04-19 devnull r->store.fmt = res.store.u.ival;
1051 564ca709 2004-04-19 devnull }
1052 564ca709 2004-04-19 devnull
1053 564ca709 2004-04-19 devnull void
1054 564ca709 2004-04-19 devnull patom(char type, Store *res)
1055 564ca709 2004-04-19 devnull {
1056 564ca709 2004-04-19 devnull int i;
1057 564ca709 2004-04-19 devnull char buf[512];
1058 564ca709 2004-04-19 devnull extern char *typenames[];
1059 564ca709 2004-04-19 devnull
1060 564ca709 2004-04-19 devnull switch(res->fmt) {
1061 564ca709 2004-04-19 devnull case 'c':
1062 564ca709 2004-04-19 devnull Bprint(bout, "%c", (int)res->u.ival);
1063 564ca709 2004-04-19 devnull break;
1064 564ca709 2004-04-19 devnull case 'C':
1065 564ca709 2004-04-19 devnull if(res->u.ival < ' ' || res->u.ival >= 0x7f)
1066 564ca709 2004-04-19 devnull Bprint(bout, "%3d", (int)res->u.ival&0xff);
1067 564ca709 2004-04-19 devnull else
1068 564ca709 2004-04-19 devnull Bprint(bout, "%3c", (int)res->u.ival);
1069 564ca709 2004-04-19 devnull break;
1070 564ca709 2004-04-19 devnull case 'r':
1071 564ca709 2004-04-19 devnull Bprint(bout, "%C", (int)res->u.ival);
1072 564ca709 2004-04-19 devnull break;
1073 564ca709 2004-04-19 devnull case 'B':
1074 564ca709 2004-04-19 devnull memset(buf, '0', 34);
1075 564ca709 2004-04-19 devnull buf[1] = 'b';
1076 564ca709 2004-04-19 devnull for(i = 0; i < 32; i++) {
1077 564ca709 2004-04-19 devnull if(res->u.ival & (1<<i))
1078 564ca709 2004-04-19 devnull buf[33-i] = '1';
1079 564ca709 2004-04-19 devnull }
1080 564ca709 2004-04-19 devnull buf[35] = '\0';
1081 564ca709 2004-04-19 devnull Bprint(bout, "%s", buf);
1082 564ca709 2004-04-19 devnull break;
1083 564ca709 2004-04-19 devnull case 'b':
1084 564ca709 2004-04-19 devnull Bprint(bout, "%.2x", (int)res->u.ival&0xff);
1085 564ca709 2004-04-19 devnull break;
1086 564ca709 2004-04-19 devnull case 'X':
1087 564ca709 2004-04-19 devnull Bprint(bout, "%.8lux", (ulong)res->u.ival);
1088 564ca709 2004-04-19 devnull break;
1089 564ca709 2004-04-19 devnull case 'x':
1090 564ca709 2004-04-19 devnull Bprint(bout, "%.4lux", (ulong)res->u.ival&0xffff);
1091 564ca709 2004-04-19 devnull break;
1092 564ca709 2004-04-19 devnull case 'W':
1093 564ca709 2004-04-19 devnull Bprint(bout, "%.16llux", res->u.ival);
1094 564ca709 2004-04-19 devnull break;
1095 564ca709 2004-04-19 devnull case 'D':
1096 564ca709 2004-04-19 devnull Bprint(bout, "%d", (int)res->u.ival);
1097 564ca709 2004-04-19 devnull break;
1098 564ca709 2004-04-19 devnull case 'd':
1099 564ca709 2004-04-19 devnull Bprint(bout, "%d", (ushort)res->u.ival);
1100 564ca709 2004-04-19 devnull break;
1101 564ca709 2004-04-19 devnull case 'u':
1102 564ca709 2004-04-19 devnull Bprint(bout, "%d", (int)res->u.ival&0xffff);
1103 564ca709 2004-04-19 devnull break;
1104 564ca709 2004-04-19 devnull case 'U':
1105 564ca709 2004-04-19 devnull Bprint(bout, "%lud", (ulong)res->u.ival);
1106 564ca709 2004-04-19 devnull break;
1107 564ca709 2004-04-19 devnull case 'Z':
1108 564ca709 2004-04-19 devnull Bprint(bout, "%llud", res->u.ival);
1109 564ca709 2004-04-19 devnull break;
1110 564ca709 2004-04-19 devnull case 'V':
1111 564ca709 2004-04-19 devnull Bprint(bout, "%lld", res->u.ival);
1112 564ca709 2004-04-19 devnull break;
1113 564ca709 2004-04-19 devnull case 'Y':
1114 564ca709 2004-04-19 devnull Bprint(bout, "%.16llux", res->u.ival);
1115 564ca709 2004-04-19 devnull break;
1116 564ca709 2004-04-19 devnull case 'o':
1117 564ca709 2004-04-19 devnull Bprint(bout, "0%.11uo", (int)res->u.ival&0xffff);
1118 564ca709 2004-04-19 devnull break;
1119 564ca709 2004-04-19 devnull case 'O':
1120 564ca709 2004-04-19 devnull Bprint(bout, "0%.6uo", (int)res->u.ival);
1121 564ca709 2004-04-19 devnull break;
1122 564ca709 2004-04-19 devnull case 'q':
1123 564ca709 2004-04-19 devnull Bprint(bout, "0%.11o", (short)(res->u.ival&0xffff));
1124 564ca709 2004-04-19 devnull break;
1125 564ca709 2004-04-19 devnull case 'Q':
1126 564ca709 2004-04-19 devnull Bprint(bout, "0%.6o", (int)res->u.ival);
1127 564ca709 2004-04-19 devnull break;
1128 564ca709 2004-04-19 devnull case 'f':
1129 564ca709 2004-04-19 devnull case 'F':
1130 564ca709 2004-04-19 devnull if(type != TFLOAT)
1131 564ca709 2004-04-19 devnull Bprint(bout, "*%c<%s>*", res->fmt, typenames[(uchar)type]);
1132 564ca709 2004-04-19 devnull else
1133 564ca709 2004-04-19 devnull Bprint(bout, "%g", res->u.fval);
1134 564ca709 2004-04-19 devnull break;
1135 564ca709 2004-04-19 devnull case 's':
1136 564ca709 2004-04-19 devnull case 'g':
1137 564ca709 2004-04-19 devnull case 'G':
1138 564ca709 2004-04-19 devnull if(type != TSTRING)
1139 564ca709 2004-04-19 devnull Bprint(bout, "*%c<%s>*", res->fmt, typenames[(uchar)type]);
1140 564ca709 2004-04-19 devnull else
1141 564ca709 2004-04-19 devnull Bwrite(bout, res->u.string->string, res->u.string->len);
1142 564ca709 2004-04-19 devnull break;
1143 564ca709 2004-04-19 devnull case 'R':
1144 564ca709 2004-04-19 devnull if(type != TSTRING)
1145 564ca709 2004-04-19 devnull Bprint(bout, "*%c<%s>*", res->fmt, typenames[(uchar)type]);
1146 564ca709 2004-04-19 devnull else
1147 564ca709 2004-04-19 devnull Bprint(bout, "%S", (Rune*)res->u.string->string);
1148 564ca709 2004-04-19 devnull break;
1149 564ca709 2004-04-19 devnull case 'a':
1150 564ca709 2004-04-19 devnull case 'A':
1151 564ca709 2004-04-19 devnull symoff(buf, sizeof(buf), res->u.ival, CANY);
1152 564ca709 2004-04-19 devnull Bprint(bout, "%s", buf);
1153 564ca709 2004-04-19 devnull break;
1154 564ca709 2004-04-19 devnull case 'I':
1155 564ca709 2004-04-19 devnull case 'i':
1156 564ca709 2004-04-19 devnull if(type != TINT)
1157 564ca709 2004-04-19 devnull Bprint(bout, "*%c<%s>*", res->fmt, typenames[(uchar)type]);
1158 564ca709 2004-04-19 devnull else {
1159 564ca709 2004-04-19 devnull if (symmap == nil || (*mach->das)(symmap, res->u.ival, res->fmt, buf, sizeof(buf)) < 0)
1160 564ca709 2004-04-19 devnull Bprint(bout, "no instruction");
1161 564ca709 2004-04-19 devnull else
1162 564ca709 2004-04-19 devnull Bprint(bout, "%s", buf);
1163 564ca709 2004-04-19 devnull }
1164 564ca709 2004-04-19 devnull break;
1165 564ca709 2004-04-19 devnull }
1166 564ca709 2004-04-19 devnull }
1167 564ca709 2004-04-19 devnull
1168 564ca709 2004-04-19 devnull void
1169 564ca709 2004-04-19 devnull blprint(List *l)
1170 564ca709 2004-04-19 devnull {
1171 564ca709 2004-04-19 devnull Store *res;
1172 564ca709 2004-04-19 devnull
1173 564ca709 2004-04-19 devnull Bprint(bout, "{");
1174 564ca709 2004-04-19 devnull while(l) {
1175 564ca709 2004-04-19 devnull switch(l->type) {
1176 564ca709 2004-04-19 devnull case TINT:
1177 564ca709 2004-04-19 devnull res = &l->store;
1178 564ca709 2004-04-19 devnull if(res->fmt == 'c'){
1179 564ca709 2004-04-19 devnull Bprint(bout, "\'%c\'", (int)res->u.ival);
1180 564ca709 2004-04-19 devnull break;
1181 564ca709 2004-04-19 devnull }else if(res->fmt == 'r'){
1182 564ca709 2004-04-19 devnull Bprint(bout, "\'%C\'", (int)res->u.ival);
1183 564ca709 2004-04-19 devnull break;
1184 564ca709 2004-04-19 devnull }
1185 564ca709 2004-04-19 devnull /* fall through */
1186 564ca709 2004-04-19 devnull default:
1187 564ca709 2004-04-19 devnull patom(l->type, &l->store);
1188 564ca709 2004-04-19 devnull break;
1189 564ca709 2004-04-19 devnull case TSTRING:
1190 564ca709 2004-04-19 devnull Bputc(bout, '"');
1191 564ca709 2004-04-19 devnull patom(l->type, &l->store);
1192 564ca709 2004-04-19 devnull Bputc(bout, '"');
1193 564ca709 2004-04-19 devnull break;
1194 564ca709 2004-04-19 devnull case TLIST:
1195 564ca709 2004-04-19 devnull blprint(l->store.u.l);
1196 564ca709 2004-04-19 devnull break;
1197 564ca709 2004-04-19 devnull case TCODE:
1198 564ca709 2004-04-19 devnull pcode(l->store.u.cc, 0);
1199 564ca709 2004-04-19 devnull break;
1200 564ca709 2004-04-19 devnull }
1201 564ca709 2004-04-19 devnull l = l->next;
1202 564ca709 2004-04-19 devnull if(l)
1203 564ca709 2004-04-19 devnull Bprint(bout, ", ");
1204 564ca709 2004-04-19 devnull }
1205 564ca709 2004-04-19 devnull Bprint(bout, "}");
1206 564ca709 2004-04-19 devnull }
1207 564ca709 2004-04-19 devnull
1208 564ca709 2004-04-19 devnull int
1209 564ca709 2004-04-19 devnull comx(Node res)
1210 564ca709 2004-04-19 devnull {
1211 564ca709 2004-04-19 devnull Lsym *sl;
1212 564ca709 2004-04-19 devnull Node *n, xx;
1213 564ca709 2004-04-19 devnull
1214 564ca709 2004-04-19 devnull if(res.store.fmt != 'a' && res.store.fmt != 'A')
1215 564ca709 2004-04-19 devnull return 0;
1216 564ca709 2004-04-19 devnull
1217 564ca709 2004-04-19 devnull if(res.store.comt == 0 || res.store.comt->base == 0)
1218 564ca709 2004-04-19 devnull return 0;
1219 564ca709 2004-04-19 devnull
1220 564ca709 2004-04-19 devnull sl = res.store.comt->base;
1221 564ca709 2004-04-19 devnull if(sl->proc) {
1222 564ca709 2004-04-19 devnull res.left = ZN;
1223 564ca709 2004-04-19 devnull res.right = ZN;
1224 564ca709 2004-04-19 devnull n = an(ONAME, ZN, ZN);
1225 564ca709 2004-04-19 devnull n->sym = sl;
1226 564ca709 2004-04-19 devnull n = an(OCALL, n, &res);
1227 564ca709 2004-04-19 devnull n->left->sym = sl;
1228 564ca709 2004-04-19 devnull expr(n, &xx);
1229 564ca709 2004-04-19 devnull return 1;
1230 564ca709 2004-04-19 devnull }
1231 564ca709 2004-04-19 devnull print("(%s)", sl->name);
1232 564ca709 2004-04-19 devnull return 0;
1233 564ca709 2004-04-19 devnull }
1234 564ca709 2004-04-19 devnull
1235 564ca709 2004-04-19 devnull void
1236 564ca709 2004-04-19 devnull bprint(Node *r, Node *args)
1237 564ca709 2004-04-19 devnull {
1238 564ca709 2004-04-19 devnull int i, nas;
1239 564ca709 2004-04-19 devnull Node res, *av[Maxarg];
1240 564ca709 2004-04-19 devnull
1241 564ca709 2004-04-19 devnull USED(r);
1242 564ca709 2004-04-19 devnull na = 0;
1243 564ca709 2004-04-19 devnull flatten(av, args);
1244 564ca709 2004-04-19 devnull nas = na;
1245 564ca709 2004-04-19 devnull for(i = 0; i < nas; i++) {
1246 564ca709 2004-04-19 devnull expr(av[i], &res);
1247 564ca709 2004-04-19 devnull switch(res.type) {
1248 564ca709 2004-04-19 devnull default:
1249 564ca709 2004-04-19 devnull if(comx(res))
1250 564ca709 2004-04-19 devnull break;
1251 564ca709 2004-04-19 devnull patom(res.type, &res.store);
1252 564ca709 2004-04-19 devnull break;
1253 564ca709 2004-04-19 devnull case TCODE:
1254 564ca709 2004-04-19 devnull pcode(res.store.u.cc, 0);
1255 564ca709 2004-04-19 devnull break;
1256 564ca709 2004-04-19 devnull case TLIST:
1257 564ca709 2004-04-19 devnull blprint(res.store.u.l);
1258 564ca709 2004-04-19 devnull break;
1259 564ca709 2004-04-19 devnull }
1260 564ca709 2004-04-19 devnull }
1261 564ca709 2004-04-19 devnull if(ret == 0)
1262 564ca709 2004-04-19 devnull Bputc(bout, '\n');
1263 564ca709 2004-04-19 devnull }
1264 564ca709 2004-04-19 devnull
1265 564ca709 2004-04-19 devnull void
1266 564ca709 2004-04-19 devnull printto(Node *r, Node *args)
1267 564ca709 2004-04-19 devnull {
1268 564ca709 2004-04-19 devnull int fd;
1269 564ca709 2004-04-19 devnull Biobuf *b;
1270 564ca709 2004-04-19 devnull int i, nas;
1271 564ca709 2004-04-19 devnull Node res, *av[Maxarg];
1272 564ca709 2004-04-19 devnull
1273 564ca709 2004-04-19 devnull USED(r);
1274 564ca709 2004-04-19 devnull na = 0;
1275 564ca709 2004-04-19 devnull flatten(av, args);
1276 564ca709 2004-04-19 devnull nas = na;
1277 564ca709 2004-04-19 devnull
1278 564ca709 2004-04-19 devnull expr(av[0], &res);
1279 564ca709 2004-04-19 devnull if(res.type != TSTRING)
1280 564ca709 2004-04-19 devnull error("printto(string, ...): need string");
1281 564ca709 2004-04-19 devnull
1282 564ca709 2004-04-19 devnull fd = create(res.store.u.string->string, OWRITE, 0666);
1283 564ca709 2004-04-19 devnull if(fd < 0)
1284 564ca709 2004-04-19 devnull fd = open(res.store.u.string->string, OWRITE);
1285 564ca709 2004-04-19 devnull if(fd < 0)
1286 564ca709 2004-04-19 devnull error("printto: open %s: %r", res.store.u.string->string);
1287 564ca709 2004-04-19 devnull
1288 564ca709 2004-04-19 devnull b = gmalloc(sizeof(Biobuf));
1289 564ca709 2004-04-19 devnull Binit(b, fd, OWRITE);
1290 564ca709 2004-04-19 devnull
1291 564ca709 2004-04-19 devnull Bflush(bout);
1292 564ca709 2004-04-19 devnull io[iop++] = bout;
1293 564ca709 2004-04-19 devnull bout = b;
1294 564ca709 2004-04-19 devnull
1295 564ca709 2004-04-19 devnull for(i = 1; i < nas; i++) {
1296 564ca709 2004-04-19 devnull expr(av[i], &res);
1297 564ca709 2004-04-19 devnull switch(res.type) {
1298 564ca709 2004-04-19 devnull default:
1299 564ca709 2004-04-19 devnull if(comx(res))
1300 564ca709 2004-04-19 devnull break;
1301 564ca709 2004-04-19 devnull patom(res.type, &res.store);
1302 564ca709 2004-04-19 devnull break;
1303 564ca709 2004-04-19 devnull case TLIST:
1304 564ca709 2004-04-19 devnull blprint(res.store.u.l);
1305 564ca709 2004-04-19 devnull break;
1306 564ca709 2004-04-19 devnull }
1307 564ca709 2004-04-19 devnull }
1308 564ca709 2004-04-19 devnull if(ret == 0)
1309 564ca709 2004-04-19 devnull Bputc(bout, '\n');
1310 564ca709 2004-04-19 devnull
1311 564ca709 2004-04-19 devnull Bterm(b);
1312 564ca709 2004-04-19 devnull close(fd);
1313 564ca709 2004-04-19 devnull free(b);
1314 564ca709 2004-04-19 devnull bout = io[--iop];
1315 564ca709 2004-04-19 devnull }
1316 564ca709 2004-04-19 devnull
1317 564ca709 2004-04-19 devnull void
1318 564ca709 2004-04-19 devnull pcfile(Node *r, Node *args)
1319 564ca709 2004-04-19 devnull {
1320 564ca709 2004-04-19 devnull Node res;
1321 564ca709 2004-04-19 devnull char *p, buf[128];
1322 564ca709 2004-04-19 devnull
1323 564ca709 2004-04-19 devnull if(args == 0)
1324 564ca709 2004-04-19 devnull error("pcfile(addr): arg count");
1325 564ca709 2004-04-19 devnull expr(args, &res);
1326 564ca709 2004-04-19 devnull if(res.type != TINT)
1327 564ca709 2004-04-19 devnull error("pcfile(addr): arg type");
1328 564ca709 2004-04-19 devnull
1329 564ca709 2004-04-19 devnull r->type = TSTRING;
1330 564ca709 2004-04-19 devnull r->store.fmt = 's';
1331 564ca709 2004-04-19 devnull if(fileline(res.store.u.ival, buf, sizeof(buf)) < 0) {
1332 564ca709 2004-04-19 devnull r->store.u.string = strnode("?file?");
1333 564ca709 2004-04-19 devnull return;
1334 564ca709 2004-04-19 devnull }
1335 564ca709 2004-04-19 devnull p = strrchr(buf, ':');
1336 564ca709 2004-04-19 devnull if(p == 0)
1337 564ca709 2004-04-19 devnull error("pcfile(addr): funny file %s", buf);
1338 564ca709 2004-04-19 devnull *p = '\0';
1339 564ca709 2004-04-19 devnull r->store.u.string = strnode(buf);
1340 564ca709 2004-04-19 devnull }
1341 564ca709 2004-04-19 devnull
1342 564ca709 2004-04-19 devnull void
1343 564ca709 2004-04-19 devnull pcline(Node *r, Node *args)
1344 564ca709 2004-04-19 devnull {
1345 564ca709 2004-04-19 devnull Node res;
1346 564ca709 2004-04-19 devnull char *p, buf[128];
1347 564ca709 2004-04-19 devnull
1348 564ca709 2004-04-19 devnull if(args == 0)
1349 564ca709 2004-04-19 devnull error("pcline(addr): arg count");
1350 564ca709 2004-04-19 devnull expr(args, &res);
1351 564ca709 2004-04-19 devnull if(res.type != TINT)
1352 564ca709 2004-04-19 devnull error("pcline(addr): arg type");
1353 564ca709 2004-04-19 devnull
1354 564ca709 2004-04-19 devnull r->type = TINT;
1355 564ca709 2004-04-19 devnull r->store.fmt = 'D';
1356 564ca709 2004-04-19 devnull if(fileline(res.store.u.ival, buf, sizeof(buf)) < 0) {
1357 564ca709 2004-04-19 devnull r->store.u.ival = 0;
1358 564ca709 2004-04-19 devnull return;
1359 564ca709 2004-04-19 devnull }
1360 564ca709 2004-04-19 devnull
1361 564ca709 2004-04-19 devnull p = strrchr(buf, ':');
1362 564ca709 2004-04-19 devnull if(p == 0)
1363 564ca709 2004-04-19 devnull error("pcline(addr): funny file %s", buf);
1364 564ca709 2004-04-19 devnull r->store.u.ival = atoi(p+1);
1365 564ca709 2004-04-19 devnull }
1366 564ca709 2004-04-19 devnull
1367 564ca709 2004-04-19 devnull void
1368 564ca709 2004-04-19 devnull textfile(Node *r, Node *args)
1369 564ca709 2004-04-19 devnull {
1370 564ca709 2004-04-19 devnull char *file;
1371 564ca709 2004-04-19 devnull long base;
1372 564ca709 2004-04-19 devnull Fhdr *fp;
1373 564ca709 2004-04-19 devnull Node res, *av[Maxarg];
1374 564ca709 2004-04-19 devnull List *l, *l2, **tail, *list, *tl;
1375 564ca709 2004-04-19 devnull
1376 564ca709 2004-04-19 devnull na = 0;
1377 564ca709 2004-04-19 devnull flatten(av, args);
1378 564ca709 2004-04-19 devnull
1379 564ca709 2004-04-19 devnull if(na != 0) {
1380 564ca709 2004-04-19 devnull expr(av[0], &res);
1381 564ca709 2004-04-19 devnull if(res.type != TLIST)
1382 564ca709 2004-04-19 devnull error("textfile(list): textfile needs a list");
1383 564ca709 2004-04-19 devnull if(listlen(res.store.u.l) != 2)
1384 564ca709 2004-04-19 devnull error("textfile(list): list must have 2 entries");
1385 564ca709 2004-04-19 devnull
1386 564ca709 2004-04-19 devnull l = res.store.u.l;
1387 564ca709 2004-04-19 devnull if(l->type != TSTRING)
1388 564ca709 2004-04-19 devnull error("textfile name must be a string");
1389 564ca709 2004-04-19 devnull file = l->store.u.string->string;
1390 564ca709 2004-04-19 devnull
1391 564ca709 2004-04-19 devnull l = l->next;
1392 564ca709 2004-04-19 devnull if(l->type != TINT)
1393 564ca709 2004-04-19 devnull error("textfile base must be an int");
1394 564ca709 2004-04-19 devnull base = l->store.u.ival;
1395 564ca709 2004-04-19 devnull
1396 564ca709 2004-04-19 devnull if((fp = crackhdr(file, OREAD)) == nil)
1397 564ca709 2004-04-19 devnull error("crackhdr %s: %r", file);
1398 564ca709 2004-04-19 devnull Bflush(bout);
1399 564ca709 2004-04-19 devnull fp->base = base;
1400 564ca709 2004-04-19 devnull fprint(2, "%s: %s %s %s\n", file, fp->aname, fp->mname, fp->fname);
1401 564ca709 2004-04-19 devnull if(mapfile(fp, base, symmap, nil) < 0)
1402 564ca709 2004-04-19 devnull fprint(2, "mapping %s: %r\n", file);
1403 564ca709 2004-04-19 devnull if(corhdr){
1404 564ca709 2004-04-19 devnull unmapfile(corhdr, cormap);
1405 564ca709 2004-04-19 devnull mapfile(fp, base, cormap, nil);
1406 564ca709 2004-04-19 devnull free(correg);
1407 564ca709 2004-04-19 devnull mapfile(corhdr, 0, cormap, &correg);
1408 564ca709 2004-04-19 devnull }
1409 564ca709 2004-04-19 devnull if(syminit(fp) < 0)
1410 564ca709 2004-04-19 devnull fprint(2, "syminit %s: %r\n", file);
1411 564ca709 2004-04-19 devnull else
1412 564ca709 2004-04-19 devnull addvarsym(fp);
1413 564ca709 2004-04-19 devnull return;
1414 564ca709 2004-04-19 devnull }
1415 564ca709 2004-04-19 devnull
1416 564ca709 2004-04-19 devnull l2 = nil;
1417 564ca709 2004-04-19 devnull tail = &l2;
1418 564ca709 2004-04-19 devnull for(fp=fhdrlist; fp; fp=fp->next){
1419 564ca709 2004-04-19 devnull if(fp->ftype == FCORE)
1420 564ca709 2004-04-19 devnull continue;
1421 564ca709 2004-04-19 devnull tl = al(TLIST);
1422 564ca709 2004-04-19 devnull *tail = tl;
1423 564ca709 2004-04-19 devnull tail = &tl->next;
1424 564ca709 2004-04-19 devnull
1425 564ca709 2004-04-19 devnull list = al(TSTRING);
1426 564ca709 2004-04-19 devnull tl->store.u.l = list;
1427 564ca709 2004-04-19 devnull list->store.u.string = strnode(fp->filename);
1428 564ca709 2004-04-19 devnull list->store.fmt = 's';
1429 564ca709 2004-04-19 devnull list->next = al(TINT);
1430 564ca709 2004-04-19 devnull list = list->next;
1431 564ca709 2004-04-19 devnull list->store.fmt = 'X';
1432 564ca709 2004-04-19 devnull list->store.u.ival = fp->base;
1433 564ca709 2004-04-19 devnull }
1434 564ca709 2004-04-19 devnull
1435 564ca709 2004-04-19 devnull r->type = TLIST;
1436 564ca709 2004-04-19 devnull r->store.u.l = l2;
1437 564ca709 2004-04-19 devnull }
1438 564ca709 2004-04-19 devnull
1439 564ca709 2004-04-19 devnull void
1440 564ca709 2004-04-19 devnull deltextfile(Node *r, Node *args)
1441 564ca709 2004-04-19 devnull {
1442 564ca709 2004-04-19 devnull int did;
1443 564ca709 2004-04-19 devnull char *file;
1444 564ca709 2004-04-19 devnull Fhdr *fp, *fpnext;
1445 564ca709 2004-04-19 devnull Node res, *av[Maxarg];
1446 564ca709 2004-04-19 devnull
1447 564ca709 2004-04-19 devnull na = 0;
1448 564ca709 2004-04-19 devnull flatten(av, args);
1449 564ca709 2004-04-19 devnull
1450 564ca709 2004-04-19 devnull if(na != 1)
1451 564ca709 2004-04-19 devnull error("deltextfile(string): arg count");
1452 564ca709 2004-04-19 devnull
1453 564ca709 2004-04-19 devnull expr(av[0], &res);
1454 564ca709 2004-04-19 devnull if(res.type != TSTRING)
1455 564ca709 2004-04-19 devnull error("deltextfile(string): arg type");
1456 564ca709 2004-04-19 devnull file = res.store.u.string->string;
1457 564ca709 2004-04-19 devnull
1458 564ca709 2004-04-19 devnull did = 0;
1459 564ca709 2004-04-19 devnull for(fp=fhdrlist; fp; fp=fpnext){
1460 564ca709 2004-04-19 devnull fpnext = fp->next;
1461 564ca709 2004-04-19 devnull if(fp->ftype == FCORE)
1462 564ca709 2004-04-19 devnull continue;
1463 564ca709 2004-04-19 devnull if(strcmp(file, fp->filename) == 0){
1464 564ca709 2004-04-19 devnull did = 1;
1465 564ca709 2004-04-19 devnull if(fp == symhdr)
1466 564ca709 2004-04-19 devnull error("cannot remove symbols from main text file");
1467 564ca709 2004-04-19 devnull unmapfile(fp, symmap);
1468 564ca709 2004-04-19 devnull uncrackhdr(fp);
1469 564ca709 2004-04-19 devnull }
1470 564ca709 2004-04-19 devnull }
1471 564ca709 2004-04-19 devnull
1472 564ca709 2004-04-19 devnull delvarsym(file);
1473 564ca709 2004-04-19 devnull if(!did)
1474 564ca709 2004-04-19 devnull error("symbol file %s not open", file);
1475 564ca709 2004-04-19 devnull }
1476 564ca709 2004-04-19 devnull