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