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