1bd389b36SDavid du Colombier #include <u.h>
2bd389b36SDavid du Colombier #include <libc.h>
3bd389b36SDavid du Colombier #include <bio.h>
4bd389b36SDavid du Colombier #include <ctype.h>
5bd389b36SDavid du Colombier #include <mach.h>
6219b2ee8SDavid du Colombier #include <regexp.h>
7bd389b36SDavid du Colombier #define Extern extern
8bd389b36SDavid du Colombier #include "acid.h"
9bd389b36SDavid du Colombier #include "y.tab.h"
10bd389b36SDavid du Colombier
11bd389b36SDavid du Colombier void cvtatof(Node*, Node*);
12bd389b36SDavid du Colombier void cvtatoi(Node*, Node*);
13bd389b36SDavid du Colombier void cvtitoa(Node*, Node*);
14bd389b36SDavid du Colombier void bprint(Node*, Node*);
15219b2ee8SDavid du Colombier void funcbound(Node*, Node*);
16219b2ee8SDavid du Colombier void printto(Node*, Node*);
17bd389b36SDavid du Colombier void getfile(Node*, Node*);
18bd389b36SDavid du Colombier void fmt(Node*, Node*);
19bd389b36SDavid du Colombier void pcfile(Node*, Node*);
20bd389b36SDavid du Colombier void pcline(Node*, Node*);
21bd389b36SDavid du Colombier void setproc(Node*, Node*);
22bd389b36SDavid du Colombier void strace(Node*, Node*);
23bd389b36SDavid du Colombier void follow(Node*, Node*);
24bd389b36SDavid du Colombier void reason(Node*, Node*);
25bd389b36SDavid du Colombier void newproc(Node*, Node*);
26bd389b36SDavid du Colombier void startstop(Node*, Node*);
27bd389b36SDavid du Colombier void match(Node*, Node*);
28bd389b36SDavid du Colombier void status(Node*, Node*);
29bd389b36SDavid du Colombier void kill(Node*,Node*);
30bd389b36SDavid du Colombier void waitstop(Node*, Node*);
31bd389b36SDavid du Colombier void stop(Node*, Node*);
32bd389b36SDavid du Colombier void start(Node*, Node*);
33bd389b36SDavid du Colombier void filepc(Node*, Node*);
34bd389b36SDavid du Colombier void doerror(Node*, Node*);
35bd389b36SDavid du Colombier void rc(Node*, Node*);
36bd389b36SDavid du Colombier void doaccess(Node*, Node*);
37219b2ee8SDavid du Colombier void map(Node*, Node*);
38219b2ee8SDavid du Colombier void readfile(Node*, Node*);
39219b2ee8SDavid du Colombier void interpret(Node*, Node*);
40219b2ee8SDavid du Colombier void include(Node*, Node*);
41219b2ee8SDavid du Colombier void regexp(Node*, Node*);
429027b8f7SDavid du Colombier void dosysr1(Node*, Node*);
43*7c70c028SDavid du Colombier void fmtof(Node*, Node*) ;
44*7c70c028SDavid du Colombier void dofmtsize(Node*, Node*) ;
45bd389b36SDavid du Colombier
46bd389b36SDavid du Colombier typedef struct Btab Btab;
47bd389b36SDavid du Colombier struct Btab
48bd389b36SDavid du Colombier {
49bd389b36SDavid du Colombier char *name;
50bd389b36SDavid du Colombier void (*fn)(Node*, Node*);
51bd389b36SDavid du Colombier } tab[] =
52bd389b36SDavid du Colombier {
53bd389b36SDavid du Colombier "atof", cvtatof,
54bd389b36SDavid du Colombier "atoi", cvtatoi,
55bd389b36SDavid du Colombier "error", doerror,
56bd389b36SDavid du Colombier "file", getfile,
57219b2ee8SDavid du Colombier "readfile", readfile,
58bd389b36SDavid du Colombier "access", doaccess,
59bd389b36SDavid du Colombier "filepc", filepc,
60219b2ee8SDavid du Colombier "fnbound", funcbound,
61bd389b36SDavid du Colombier "fmt", fmt,
62bd389b36SDavid du Colombier "follow", follow,
63bd389b36SDavid du Colombier "itoa", cvtitoa,
64bd389b36SDavid du Colombier "kill", kill,
65bd389b36SDavid du Colombier "match", match,
66bd389b36SDavid du Colombier "newproc", newproc,
67bd389b36SDavid du Colombier "pcfile", pcfile,
68bd389b36SDavid du Colombier "pcline", pcline,
69bd389b36SDavid du Colombier "print", bprint,
70219b2ee8SDavid du Colombier "printto", printto,
71bd389b36SDavid du Colombier "rc", rc,
72bd389b36SDavid du Colombier "reason", reason,
73bd389b36SDavid du Colombier "setproc", setproc,
74bd389b36SDavid du Colombier "start", start,
75bd389b36SDavid du Colombier "startstop", startstop,
76bd389b36SDavid du Colombier "status", status,
77bd389b36SDavid du Colombier "stop", stop,
78bd389b36SDavid du Colombier "strace", strace,
799027b8f7SDavid du Colombier "sysr1", dosysr1,
80bd389b36SDavid du Colombier "waitstop", waitstop,
81219b2ee8SDavid du Colombier "map", map,
82219b2ee8SDavid du Colombier "interpret", interpret,
83219b2ee8SDavid du Colombier "include", include,
84219b2ee8SDavid du Colombier "regexp", regexp,
85*7c70c028SDavid du Colombier "fmtof", fmtof,
86*7c70c028SDavid du Colombier "fmtsize", dofmtsize,
87bd389b36SDavid du Colombier 0
88bd389b36SDavid du Colombier };
89bd389b36SDavid du Colombier
9037e88e97SDavid du Colombier char vfmt[] = "aBbcCdDfFgGiIoOqQrRsSuUVWxXYZ38";
917fb4e6f1SDavid du Colombier
92bd389b36SDavid du Colombier void
mkprint(Lsym * s)93219b2ee8SDavid du Colombier mkprint(Lsym *s)
94219b2ee8SDavid du Colombier {
95219b2ee8SDavid du Colombier prnt = malloc(sizeof(Node));
967dd7cddfSDavid du Colombier memset(prnt, 0, sizeof(Node));
97219b2ee8SDavid du Colombier prnt->op = OCALL;
98219b2ee8SDavid du Colombier prnt->left = malloc(sizeof(Node));
997dd7cddfSDavid du Colombier memset(prnt->left, 0, sizeof(Node));
100219b2ee8SDavid du Colombier prnt->left->sym = s;
101219b2ee8SDavid du Colombier }
102219b2ee8SDavid du Colombier
103219b2ee8SDavid du Colombier void
installbuiltin(void)104bd389b36SDavid du Colombier installbuiltin(void)
105bd389b36SDavid du Colombier {
106bd389b36SDavid du Colombier Btab *b;
107bd389b36SDavid du Colombier Lsym *s;
108bd389b36SDavid du Colombier
109bd389b36SDavid du Colombier b = tab;
110bd389b36SDavid du Colombier while(b->name) {
111bd389b36SDavid du Colombier s = look(b->name);
112bd389b36SDavid du Colombier if(s == 0)
113bd389b36SDavid du Colombier s = enter(b->name, Tid);
114bd389b36SDavid du Colombier
115bd389b36SDavid du Colombier s->builtin = b->fn;
116219b2ee8SDavid du Colombier if(b->fn == bprint)
117219b2ee8SDavid du Colombier mkprint(s);
118bd389b36SDavid du Colombier b++;
119bd389b36SDavid du Colombier }
120bd389b36SDavid du Colombier }
121bd389b36SDavid du Colombier
122bd389b36SDavid du Colombier void
dosysr1(Node * r,Node *)1239027b8f7SDavid du Colombier dosysr1(Node *r, Node*)
1249027b8f7SDavid du Colombier {
1259027b8f7SDavid du Colombier extern int sysr1(void);
1269027b8f7SDavid du Colombier
1279027b8f7SDavid du Colombier r->op = OCONST;
1289027b8f7SDavid du Colombier r->type = TINT;
1299027b8f7SDavid du Colombier r->fmt = 'D';
1309027b8f7SDavid du Colombier r->ival = sysr1();
1319027b8f7SDavid du Colombier }
1329027b8f7SDavid du Colombier
1339027b8f7SDavid du Colombier void
match(Node * r,Node * args)134bd389b36SDavid du Colombier match(Node *r, Node *args)
135bd389b36SDavid du Colombier {
136bd389b36SDavid du Colombier int i;
137bd389b36SDavid du Colombier List *f;
138bd389b36SDavid du Colombier Node *av[Maxarg];
139bd389b36SDavid du Colombier Node resi, resl;
140bd389b36SDavid du Colombier
141bd389b36SDavid du Colombier na = 0;
142bd389b36SDavid du Colombier flatten(av, args);
143bd389b36SDavid du Colombier if(na != 2)
144bd389b36SDavid du Colombier error("match(obj, list): arg count");
145bd389b36SDavid du Colombier
146bd389b36SDavid du Colombier expr(av[1], &resl);
147bd389b36SDavid du Colombier if(resl.type != TLIST)
148bd389b36SDavid du Colombier error("match(obj, list): need list");
149bd389b36SDavid du Colombier expr(av[0], &resi);
150bd389b36SDavid du Colombier
151bd389b36SDavid du Colombier r->op = OCONST;
152bd389b36SDavid du Colombier r->type = TINT;
153bd389b36SDavid du Colombier r->fmt = 'D';
154bd389b36SDavid du Colombier r->ival = -1;
155bd389b36SDavid du Colombier
156bd389b36SDavid du Colombier i = 0;
157bd389b36SDavid du Colombier for(f = resl.l; f; f = f->next) {
158bd389b36SDavid du Colombier if(resi.type == f->type) {
159bd389b36SDavid du Colombier switch(resi.type) {
160bd389b36SDavid du Colombier case TINT:
161bd389b36SDavid du Colombier if(resi.ival == f->ival) {
162bd389b36SDavid du Colombier r->ival = i;
163bd389b36SDavid du Colombier return;
164bd389b36SDavid du Colombier }
165bd389b36SDavid du Colombier break;
166bd389b36SDavid du Colombier case TFLOAT:
167bd389b36SDavid du Colombier if(resi.fval == f->fval) {
168bd389b36SDavid du Colombier r->ival = i;
169bd389b36SDavid du Colombier return;
170bd389b36SDavid du Colombier }
171bd389b36SDavid du Colombier break;
172bd389b36SDavid du Colombier case TSTRING:
173bd389b36SDavid du Colombier if(scmp(resi.string, f->string)) {
174bd389b36SDavid du Colombier r->ival = i;
175bd389b36SDavid du Colombier return;
176bd389b36SDavid du Colombier }
177bd389b36SDavid du Colombier break;
178bd389b36SDavid du Colombier case TLIST:
179bd389b36SDavid du Colombier error("match(obj, list): not defined for list");
180bd389b36SDavid du Colombier }
181bd389b36SDavid du Colombier }
182bd389b36SDavid du Colombier i++;
183bd389b36SDavid du Colombier }
184bd389b36SDavid du Colombier }
185bd389b36SDavid du Colombier
186bd389b36SDavid du Colombier void
newproc(Node * r,Node * args)187bd389b36SDavid du Colombier newproc(Node *r, Node *args)
188bd389b36SDavid du Colombier {
189bd389b36SDavid du Colombier int i;
190bd389b36SDavid du Colombier Node res;
191bd389b36SDavid du Colombier char *p, *e;
192219b2ee8SDavid du Colombier char *argv[Maxarg], buf[Strsize];
193bd389b36SDavid du Colombier
194bd389b36SDavid du Colombier i = 1;
195bd389b36SDavid du Colombier argv[0] = aout;
196bd389b36SDavid du Colombier
197bd389b36SDavid du Colombier if(args) {
198bd389b36SDavid du Colombier expr(args, &res);
199bd389b36SDavid du Colombier if(res.type != TSTRING)
200219b2ee8SDavid du Colombier error("newproc(): arg not string");
201bd389b36SDavid du Colombier if(res.string->len >= sizeof(buf))
202219b2ee8SDavid du Colombier error("newproc(): too many arguments");
203bd389b36SDavid du Colombier memmove(buf, res.string->string, res.string->len);
204219b2ee8SDavid du Colombier buf[res.string->len] = '\0';
205bd389b36SDavid du Colombier p = buf;
206bd389b36SDavid du Colombier e = buf+res.string->len;
207bd389b36SDavid du Colombier for(;;) {
208bd389b36SDavid du Colombier while(p < e && (*p == '\t' || *p == ' '))
209bd389b36SDavid du Colombier *p++ = '\0';
210bd389b36SDavid du Colombier if(p >= e)
211bd389b36SDavid du Colombier break;
212bd389b36SDavid du Colombier argv[i++] = p;
213219b2ee8SDavid du Colombier if(i >= Maxarg)
214219b2ee8SDavid du Colombier error("newproc: too many arguments");
215bd389b36SDavid du Colombier while(p < e && *p != '\t' && *p != ' ')
216bd389b36SDavid du Colombier p++;
217bd389b36SDavid du Colombier }
218bd389b36SDavid du Colombier }
219bd389b36SDavid du Colombier argv[i] = 0;
220bd389b36SDavid du Colombier r->op = OCONST;
221bd389b36SDavid du Colombier r->type = TINT;
222bd389b36SDavid du Colombier r->fmt = 'D';
223bd389b36SDavid du Colombier r->ival = nproc(argv);
224bd389b36SDavid du Colombier }
225bd389b36SDavid du Colombier
226bd389b36SDavid du Colombier void
startstop(Node * r,Node * args)227bd389b36SDavid du Colombier startstop(Node *r, Node *args)
228bd389b36SDavid du Colombier {
229bd389b36SDavid du Colombier Node res;
230bd389b36SDavid du Colombier
231bd389b36SDavid du Colombier USED(r);
232bd389b36SDavid du Colombier if(args == 0)
233bd389b36SDavid du Colombier error("startstop(pid): no pid");
234bd389b36SDavid du Colombier expr(args, &res);
235bd389b36SDavid du Colombier if(res.type != TINT)
236bd389b36SDavid du Colombier error("startstop(pid): arg type");
237bd389b36SDavid du Colombier
238bd389b36SDavid du Colombier msg(res.ival, "startstop");
239bd389b36SDavid du Colombier notes(res.ival);
240bd389b36SDavid du Colombier dostop(res.ival);
241bd389b36SDavid du Colombier }
242bd389b36SDavid du Colombier
243bd389b36SDavid du Colombier void
waitstop(Node * r,Node * args)244bd389b36SDavid du Colombier waitstop(Node *r, Node *args)
245bd389b36SDavid du Colombier {
246bd389b36SDavid du Colombier Node res;
247bd389b36SDavid du Colombier
248bd389b36SDavid du Colombier USED(r);
249bd389b36SDavid du Colombier if(args == 0)
250bd389b36SDavid du Colombier error("waitstop(pid): no pid");
251bd389b36SDavid du Colombier expr(args, &res);
252bd389b36SDavid du Colombier if(res.type != TINT)
253bd389b36SDavid du Colombier error("waitstop(pid): arg type");
254bd389b36SDavid du Colombier
255219b2ee8SDavid du Colombier Bflush(bout);
256bd389b36SDavid du Colombier msg(res.ival, "waitstop");
257bd389b36SDavid du Colombier notes(res.ival);
258bd389b36SDavid du Colombier dostop(res.ival);
259bd389b36SDavid du Colombier }
260bd389b36SDavid du Colombier
261bd389b36SDavid du Colombier void
start(Node * r,Node * args)262bd389b36SDavid du Colombier start(Node *r, Node *args)
263bd389b36SDavid du Colombier {
264bd389b36SDavid du Colombier Node res;
265bd389b36SDavid du Colombier
266bd389b36SDavid du Colombier USED(r);
267bd389b36SDavid du Colombier if(args == 0)
268bd389b36SDavid du Colombier error("start(pid): no pid");
269bd389b36SDavid du Colombier expr(args, &res);
270bd389b36SDavid du Colombier if(res.type != TINT)
271bd389b36SDavid du Colombier error("start(pid): arg type");
272bd389b36SDavid du Colombier
273bd389b36SDavid du Colombier msg(res.ival, "start");
274bd389b36SDavid du Colombier }
275bd389b36SDavid du Colombier
276bd389b36SDavid du Colombier void
stop(Node * r,Node * args)277bd389b36SDavid du Colombier stop(Node *r, Node *args)
278bd389b36SDavid du Colombier {
279bd389b36SDavid du Colombier Node res;
280bd389b36SDavid du Colombier
281bd389b36SDavid du Colombier USED(r);
282bd389b36SDavid du Colombier if(args == 0)
283bd389b36SDavid du Colombier error("stop(pid): no pid");
284bd389b36SDavid du Colombier expr(args, &res);
285bd389b36SDavid du Colombier if(res.type != TINT)
286bd389b36SDavid du Colombier error("stop(pid): arg type");
287bd389b36SDavid du Colombier
288219b2ee8SDavid du Colombier Bflush(bout);
289bd389b36SDavid du Colombier msg(res.ival, "stop");
290bd389b36SDavid du Colombier notes(res.ival);
291bd389b36SDavid du Colombier dostop(res.ival);
292bd389b36SDavid du Colombier }
293bd389b36SDavid du Colombier
294bd389b36SDavid du Colombier void
kill(Node * r,Node * args)295bd389b36SDavid du Colombier kill(Node *r, Node *args)
296bd389b36SDavid du Colombier {
297bd389b36SDavid du Colombier Node res;
298bd389b36SDavid du Colombier
299bd389b36SDavid du Colombier USED(r);
300bd389b36SDavid du Colombier if(args == 0)
301bd389b36SDavid du Colombier error("kill(pid): no pid");
302bd389b36SDavid du Colombier expr(args, &res);
303bd389b36SDavid du Colombier if(res.type != TINT)
304bd389b36SDavid du Colombier error("kill(pid): arg type");
305bd389b36SDavid du Colombier
306bd389b36SDavid du Colombier msg(res.ival, "kill");
307bd389b36SDavid du Colombier deinstall(res.ival);
308bd389b36SDavid du Colombier }
309bd389b36SDavid du Colombier
310bd389b36SDavid du Colombier void
status(Node * r,Node * args)311bd389b36SDavid du Colombier status(Node *r, Node *args)
312bd389b36SDavid du Colombier {
313bd389b36SDavid du Colombier Node res;
314219b2ee8SDavid du Colombier char *p;
315bd389b36SDavid du Colombier
316bd389b36SDavid du Colombier USED(r);
317bd389b36SDavid du Colombier if(args == 0)
318bd389b36SDavid du Colombier error("status(pid): no pid");
319bd389b36SDavid du Colombier expr(args, &res);
320bd389b36SDavid du Colombier if(res.type != TINT)
321bd389b36SDavid du Colombier error("status(pid): arg type");
322bd389b36SDavid du Colombier
323219b2ee8SDavid du Colombier p = getstatus(res.ival);
324219b2ee8SDavid du Colombier r->string = strnode(p);
325bd389b36SDavid du Colombier r->op = OCONST;
326bd389b36SDavid du Colombier r->fmt = 's';
327bd389b36SDavid du Colombier r->type = TSTRING;
328bd389b36SDavid du Colombier }
329bd389b36SDavid du Colombier
330bd389b36SDavid du Colombier void
reason(Node * r,Node * args)331bd389b36SDavid du Colombier reason(Node *r, Node *args)
332bd389b36SDavid du Colombier {
333bd389b36SDavid du Colombier Node res;
334bd389b36SDavid du Colombier
335bd389b36SDavid du Colombier if(args == 0)
336bd389b36SDavid du Colombier error("reason(cause): no cause");
337bd389b36SDavid du Colombier expr(args, &res);
338bd389b36SDavid du Colombier if(res.type != TINT)
339bd389b36SDavid du Colombier error("reason(cause): arg type");
340bd389b36SDavid du Colombier
341bd389b36SDavid du Colombier r->op = OCONST;
342bd389b36SDavid du Colombier r->type = TSTRING;
343bd389b36SDavid du Colombier r->fmt = 's';
344219b2ee8SDavid du Colombier r->string = strnode((*machdata->excep)(cormap, rget));
345bd389b36SDavid du Colombier }
346bd389b36SDavid du Colombier
347bd389b36SDavid du Colombier void
follow(Node * r,Node * args)348bd389b36SDavid du Colombier follow(Node *r, Node *args)
349bd389b36SDavid du Colombier {
350bd389b36SDavid du Colombier int n, i;
351bd389b36SDavid du Colombier Node res;
3524de34a7eSDavid du Colombier uvlong f[10];
353bd389b36SDavid du Colombier List **tail, *l;
354bd389b36SDavid du Colombier
355bd389b36SDavid du Colombier if(args == 0)
356bd389b36SDavid du Colombier error("follow(addr): no addr");
357bd389b36SDavid du Colombier expr(args, &res);
358bd389b36SDavid du Colombier if(res.type != TINT)
359bd389b36SDavid du Colombier error("follow(addr): arg type");
360bd389b36SDavid du Colombier
361219b2ee8SDavid du Colombier n = (*machdata->foll)(cormap, res.ival, rget, f);
362219b2ee8SDavid du Colombier if (n < 0)
363219b2ee8SDavid du Colombier error("follow(addr): %r");
364bd389b36SDavid du Colombier tail = &r->l;
365bd389b36SDavid du Colombier for(i = 0; i < n; i++) {
366bd389b36SDavid du Colombier l = al(TINT);
367bd389b36SDavid du Colombier l->ival = f[i];
368bd389b36SDavid du Colombier l->fmt = 'X';
369bd389b36SDavid du Colombier *tail = l;
370bd389b36SDavid du Colombier tail = &l->next;
371bd389b36SDavid du Colombier }
372bd389b36SDavid du Colombier }
373bd389b36SDavid du Colombier
374bd389b36SDavid du Colombier void
funcbound(Node * r,Node * args)375219b2ee8SDavid du Colombier funcbound(Node *r, Node *args)
376219b2ee8SDavid du Colombier {
377219b2ee8SDavid du Colombier int n;
378219b2ee8SDavid du Colombier Node res;
3794de34a7eSDavid du Colombier uvlong bounds[2];
380219b2ee8SDavid du Colombier List *l;
381219b2ee8SDavid du Colombier
382219b2ee8SDavid du Colombier if(args == 0)
383219b2ee8SDavid du Colombier error("fnbound(addr): no addr");
384219b2ee8SDavid du Colombier expr(args, &res);
385219b2ee8SDavid du Colombier if(res.type != TINT)
386219b2ee8SDavid du Colombier error("fnbound(addr): arg type");
387219b2ee8SDavid du Colombier
388219b2ee8SDavid du Colombier n = fnbound(res.ival, bounds);
389219b2ee8SDavid du Colombier if (n != 0) {
390219b2ee8SDavid du Colombier r->l = al(TINT);
391219b2ee8SDavid du Colombier l = r->l;
392219b2ee8SDavid du Colombier l->ival = bounds[0];
393219b2ee8SDavid du Colombier l->fmt = 'X';
394219b2ee8SDavid du Colombier l->next = al(TINT);
395219b2ee8SDavid du Colombier l = l->next;
396219b2ee8SDavid du Colombier l->ival = bounds[1];
397219b2ee8SDavid du Colombier l->fmt = 'X';
398219b2ee8SDavid du Colombier }
399219b2ee8SDavid du Colombier }
400219b2ee8SDavid du Colombier
401219b2ee8SDavid du Colombier void
setproc(Node * r,Node * args)402bd389b36SDavid du Colombier setproc(Node *r, Node *args)
403bd389b36SDavid du Colombier {
404bd389b36SDavid du Colombier Node res;
405bd389b36SDavid du Colombier
406bd389b36SDavid du Colombier USED(r);
407bd389b36SDavid du Colombier if(args == 0)
408bd389b36SDavid du Colombier error("setproc(pid): no pid");
409bd389b36SDavid du Colombier expr(args, &res);
410bd389b36SDavid du Colombier if(res.type != TINT)
411bd389b36SDavid du Colombier error("setproc(pid): arg type");
412bd389b36SDavid du Colombier
413bd389b36SDavid du Colombier sproc(res.ival);
414bd389b36SDavid du Colombier }
415bd389b36SDavid du Colombier
416bd389b36SDavid du Colombier void
filepc(Node * r,Node * args)417bd389b36SDavid du Colombier filepc(Node *r, Node *args)
418bd389b36SDavid du Colombier {
419bd389b36SDavid du Colombier Node res;
420219b2ee8SDavid du Colombier char *p, c;
421bd389b36SDavid du Colombier
422bd389b36SDavid du Colombier if(args == 0)
423bd389b36SDavid du Colombier error("filepc(filename:line): arg count");
424bd389b36SDavid du Colombier expr(args, &res);
425bd389b36SDavid du Colombier if(res.type != TSTRING)
426bd389b36SDavid du Colombier error("filepc(filename:line): arg type");
427bd389b36SDavid du Colombier
428bd389b36SDavid du Colombier p = strchr(res.string->string, ':');
429bd389b36SDavid du Colombier if(p == 0)
430bd389b36SDavid du Colombier error("filepc(filename:line): bad arg format");
431bd389b36SDavid du Colombier
432219b2ee8SDavid du Colombier c = *p;
433bd389b36SDavid du Colombier *p++ = '\0';
4344de34a7eSDavid du Colombier r->ival = file2pc(res.string->string, strtol(p, 0, 0));
435219b2ee8SDavid du Colombier p[-1] = c;
4364de34a7eSDavid du Colombier if(r->ival == ~0)
437bd389b36SDavid du Colombier error("filepc(filename:line): can't find address");
438bd389b36SDavid du Colombier
439bd389b36SDavid du Colombier r->op = OCONST;
440bd389b36SDavid du Colombier r->type = TINT;
4414de34a7eSDavid du Colombier r->fmt = 'V';
442219b2ee8SDavid du Colombier }
443219b2ee8SDavid du Colombier
444219b2ee8SDavid du Colombier void
interpret(Node * r,Node * args)445219b2ee8SDavid du Colombier interpret(Node *r, Node *args)
446219b2ee8SDavid du Colombier {
447219b2ee8SDavid du Colombier Node res;
448219b2ee8SDavid du Colombier int isave;
449219b2ee8SDavid du Colombier
450219b2ee8SDavid du Colombier if(args == 0)
451219b2ee8SDavid du Colombier error("interpret(string): arg count");
452219b2ee8SDavid du Colombier expr(args, &res);
453219b2ee8SDavid du Colombier if(res.type != TSTRING)
454219b2ee8SDavid du Colombier error("interpret(string): arg type");
455219b2ee8SDavid du Colombier
456219b2ee8SDavid du Colombier pushstr(&res);
457219b2ee8SDavid du Colombier
458219b2ee8SDavid du Colombier isave = interactive;
459219b2ee8SDavid du Colombier interactive = 0;
460219b2ee8SDavid du Colombier r->ival = yyparse();
461219b2ee8SDavid du Colombier interactive = isave;
462219b2ee8SDavid du Colombier popio();
463219b2ee8SDavid du Colombier r->op = OCONST;
464219b2ee8SDavid du Colombier r->type = TINT;
465219b2ee8SDavid du Colombier r->fmt = 'D';
466219b2ee8SDavid du Colombier }
467219b2ee8SDavid du Colombier
468219b2ee8SDavid du Colombier void
include(Node * r,Node * args)469219b2ee8SDavid du Colombier include(Node *r, Node *args)
470219b2ee8SDavid du Colombier {
471219b2ee8SDavid du Colombier Node res;
472219b2ee8SDavid du Colombier int isave;
473219b2ee8SDavid du Colombier
474219b2ee8SDavid du Colombier if(args == 0)
475219b2ee8SDavid du Colombier error("include(string): arg count");
476219b2ee8SDavid du Colombier expr(args, &res);
477219b2ee8SDavid du Colombier if(res.type != TSTRING)
478219b2ee8SDavid du Colombier error("include(string): arg type");
479219b2ee8SDavid du Colombier
480219b2ee8SDavid du Colombier pushfile(res.string->string);
481219b2ee8SDavid du Colombier
482219b2ee8SDavid du Colombier isave = interactive;
483219b2ee8SDavid du Colombier interactive = 0;
484219b2ee8SDavid du Colombier r->ival = yyparse();
485219b2ee8SDavid du Colombier interactive = isave;
486219b2ee8SDavid du Colombier popio();
487219b2ee8SDavid du Colombier r->op = OCONST;
488219b2ee8SDavid du Colombier r->type = TINT;
489bd389b36SDavid du Colombier r->fmt = 'D';
490bd389b36SDavid du Colombier }
491bd389b36SDavid du Colombier
492bd389b36SDavid du Colombier void
rc(Node * r,Node * args)493bd389b36SDavid du Colombier rc(Node *r, Node *args)
494bd389b36SDavid du Colombier {
495bd389b36SDavid du Colombier Node res;
496219b2ee8SDavid du Colombier int pid;
497219b2ee8SDavid du Colombier char *p, *q, *argv[4];
4989a747e4fSDavid du Colombier Waitmsg *w;
499bd389b36SDavid du Colombier
500bd389b36SDavid du Colombier USED(r);
501bd389b36SDavid du Colombier if(args == 0)
502bd389b36SDavid du Colombier error("error(string): arg count");
503bd389b36SDavid du Colombier expr(args, &res);
504bd389b36SDavid du Colombier if(res.type != TSTRING)
505bd389b36SDavid du Colombier error("error(string): arg type");
506bd389b36SDavid du Colombier
507bd389b36SDavid du Colombier argv[0] = "/bin/rc";
508bd389b36SDavid du Colombier argv[1] = "-c";
509bd389b36SDavid du Colombier argv[2] = res.string->string;
510bd389b36SDavid du Colombier argv[3] = 0;
511bd389b36SDavid du Colombier
512bd389b36SDavid du Colombier pid = fork();
513bd389b36SDavid du Colombier switch(pid) {
514bd389b36SDavid du Colombier case -1:
515bd389b36SDavid du Colombier error("fork %r");
516bd389b36SDavid du Colombier case 0:
517bd389b36SDavid du Colombier exec("/bin/rc", argv);
518bd389b36SDavid du Colombier exits(0);
519bd389b36SDavid du Colombier default:
5209a747e4fSDavid du Colombier w = waitfor(pid);
521bd389b36SDavid du Colombier break;
522bd389b36SDavid du Colombier }
5239a747e4fSDavid du Colombier p = w->msg;
524219b2ee8SDavid du Colombier q = strrchr(p, ':');
525219b2ee8SDavid du Colombier if (q)
526219b2ee8SDavid du Colombier p = q+1;
527219b2ee8SDavid du Colombier
528219b2ee8SDavid du Colombier r->op = OCONST;
529219b2ee8SDavid du Colombier r->type = TSTRING;
530219b2ee8SDavid du Colombier r->string = strnode(p);
5319a747e4fSDavid du Colombier free(w);
532219b2ee8SDavid du Colombier r->fmt = 's';
533bd389b36SDavid du Colombier }
534bd389b36SDavid du Colombier
535bd389b36SDavid du Colombier void
doerror(Node * r,Node * args)536bd389b36SDavid du Colombier doerror(Node *r, Node *args)
537bd389b36SDavid du Colombier {
538bd389b36SDavid du Colombier Node res;
539bd389b36SDavid du Colombier
540bd389b36SDavid du Colombier USED(r);
541bd389b36SDavid du Colombier if(args == 0)
542bd389b36SDavid du Colombier error("error(string): arg count");
543bd389b36SDavid du Colombier expr(args, &res);
544bd389b36SDavid du Colombier if(res.type != TSTRING)
545bd389b36SDavid du Colombier error("error(string): arg type");
546bd389b36SDavid du Colombier
547bd389b36SDavid du Colombier error(res.string->string);
548bd389b36SDavid du Colombier }
549bd389b36SDavid du Colombier
550bd389b36SDavid du Colombier void
doaccess(Node * r,Node * args)551bd389b36SDavid du Colombier doaccess(Node *r, Node *args)
552bd389b36SDavid du Colombier {
553bd389b36SDavid du Colombier Node res;
554bd389b36SDavid du Colombier
555bd389b36SDavid du Colombier if(args == 0)
556bd389b36SDavid du Colombier error("access(filename): arg count");
557bd389b36SDavid du Colombier expr(args, &res);
558bd389b36SDavid du Colombier if(res.type != TSTRING)
559bd389b36SDavid du Colombier error("access(filename): arg type");
560bd389b36SDavid du Colombier
561bd389b36SDavid du Colombier r->op = OCONST;
562bd389b36SDavid du Colombier r->type = TINT;
563bd389b36SDavid du Colombier r->ival = 0;
5647dd7cddfSDavid du Colombier if(access(res.string->string, 4) == 0)
565bd389b36SDavid du Colombier r->ival = 1;
566bd389b36SDavid du Colombier }
567bd389b36SDavid du Colombier
568bd389b36SDavid du Colombier void
readfile(Node * r,Node * args)569219b2ee8SDavid du Colombier readfile(Node *r, Node *args)
570219b2ee8SDavid du Colombier {
571219b2ee8SDavid du Colombier Node res;
572219b2ee8SDavid du Colombier int n, fd;
573219b2ee8SDavid du Colombier char *buf;
5749a747e4fSDavid du Colombier Dir *db;
575219b2ee8SDavid du Colombier
576219b2ee8SDavid du Colombier if(args == 0)
577219b2ee8SDavid du Colombier error("readfile(filename): arg count");
578219b2ee8SDavid du Colombier expr(args, &res);
579219b2ee8SDavid du Colombier if(res.type != TSTRING)
580219b2ee8SDavid du Colombier error("readfile(filename): arg type");
581219b2ee8SDavid du Colombier
582219b2ee8SDavid du Colombier fd = open(res.string->string, OREAD);
583219b2ee8SDavid du Colombier if(fd < 0)
584219b2ee8SDavid du Colombier return;
585219b2ee8SDavid du Colombier
5869a747e4fSDavid du Colombier db = dirfstat(fd);
5879a747e4fSDavid du Colombier if(db == nil || db->length == 0)
588219b2ee8SDavid du Colombier n = 8192;
589219b2ee8SDavid du Colombier else
5909a747e4fSDavid du Colombier n = db->length;
5919a747e4fSDavid du Colombier free(db);
592219b2ee8SDavid du Colombier
593219b2ee8SDavid du Colombier buf = malloc(n);
594219b2ee8SDavid du Colombier n = read(fd, buf, n);
595219b2ee8SDavid du Colombier
596219b2ee8SDavid du Colombier if(n > 0) {
597219b2ee8SDavid du Colombier r->op = OCONST;
598219b2ee8SDavid du Colombier r->type = TSTRING;
599219b2ee8SDavid du Colombier r->string = strnodlen(buf, n);
600219b2ee8SDavid du Colombier r->fmt = 's';
601219b2ee8SDavid du Colombier }
602219b2ee8SDavid du Colombier free(buf);
603219b2ee8SDavid du Colombier close(fd);
604219b2ee8SDavid du Colombier }
605219b2ee8SDavid du Colombier
606219b2ee8SDavid du Colombier void
getfile(Node * r,Node * args)607bd389b36SDavid du Colombier getfile(Node *r, Node *args)
608bd389b36SDavid du Colombier {
609219b2ee8SDavid du Colombier int n;
610bd389b36SDavid du Colombier char *p;
611bd389b36SDavid du Colombier Node res;
612219b2ee8SDavid du Colombier String *s;
613bd389b36SDavid du Colombier Biobuf *bp;
614bd389b36SDavid du Colombier List **l, *new;
615bd389b36SDavid du Colombier
616bd389b36SDavid du Colombier if(args == 0)
617bd389b36SDavid du Colombier error("file(filename): arg count");
618bd389b36SDavid du Colombier expr(args, &res);
619bd389b36SDavid du Colombier if(res.type != TSTRING)
620bd389b36SDavid du Colombier error("file(filename): arg type");
621bd389b36SDavid du Colombier
622bd389b36SDavid du Colombier r->op = OCONST;
623bd389b36SDavid du Colombier r->type = TLIST;
624bd389b36SDavid du Colombier r->l = 0;
625bd389b36SDavid du Colombier
626bd389b36SDavid du Colombier p = res.string->string;
627bd389b36SDavid du Colombier bp = Bopen(p, OREAD);
628bd389b36SDavid du Colombier if(bp == 0)
629bd389b36SDavid du Colombier return;
630bd389b36SDavid du Colombier
631bd389b36SDavid du Colombier l = &r->l;
632bd389b36SDavid du Colombier for(;;) {
633bd389b36SDavid du Colombier p = Brdline(bp, '\n');
6347dd7cddfSDavid du Colombier n = Blinelen(bp);
635219b2ee8SDavid du Colombier if(p == 0) {
636219b2ee8SDavid du Colombier if(n == 0)
637bd389b36SDavid du Colombier break;
638219b2ee8SDavid du Colombier s = strnodlen(0, n);
639219b2ee8SDavid du Colombier Bread(bp, s->string, n);
640219b2ee8SDavid du Colombier }
641219b2ee8SDavid du Colombier else
642219b2ee8SDavid du Colombier s = strnodlen(p, n-1);
643219b2ee8SDavid du Colombier
644bd389b36SDavid du Colombier new = al(TSTRING);
645219b2ee8SDavid du Colombier new->string = s;
646bd389b36SDavid du Colombier new->fmt = 's';
647bd389b36SDavid du Colombier *l = new;
648bd389b36SDavid du Colombier l = &new->next;
649bd389b36SDavid du Colombier }
650219b2ee8SDavid du Colombier Bterm(bp);
651bd389b36SDavid du Colombier }
652bd389b36SDavid du Colombier
653bd389b36SDavid du Colombier void
cvtatof(Node * r,Node * args)654bd389b36SDavid du Colombier cvtatof(Node *r, Node *args)
655bd389b36SDavid du Colombier {
656bd389b36SDavid du Colombier Node res;
657bd389b36SDavid du Colombier
658bd389b36SDavid du Colombier if(args == 0)
659bd389b36SDavid du Colombier error("atof(string): arg count");
660bd389b36SDavid du Colombier expr(args, &res);
661bd389b36SDavid du Colombier if(res.type != TSTRING)
662bd389b36SDavid du Colombier error("atof(string): arg type");
663bd389b36SDavid du Colombier
664bd389b36SDavid du Colombier r->op = OCONST;
665bd389b36SDavid du Colombier r->type = TFLOAT;
666bd389b36SDavid du Colombier r->fval = atof(res.string->string);
667219b2ee8SDavid du Colombier r->fmt = 'f';
668bd389b36SDavid du Colombier }
669bd389b36SDavid du Colombier
670bd389b36SDavid du Colombier void
cvtatoi(Node * r,Node * args)671bd389b36SDavid du Colombier cvtatoi(Node *r, Node *args)
672bd389b36SDavid du Colombier {
673bd389b36SDavid du Colombier Node res;
674bd389b36SDavid du Colombier
675bd389b36SDavid du Colombier if(args == 0)
676bd389b36SDavid du Colombier error("atoi(string): arg count");
677bd389b36SDavid du Colombier expr(args, &res);
678bd389b36SDavid du Colombier if(res.type != TSTRING)
679bd389b36SDavid du Colombier error("atoi(string): arg type");
680bd389b36SDavid du Colombier
681bd389b36SDavid du Colombier r->op = OCONST;
682bd389b36SDavid du Colombier r->type = TINT;
6834de34a7eSDavid du Colombier r->ival = strtoull(res.string->string, 0, 0);
6844de34a7eSDavid du Colombier r->fmt = 'V';
685bd389b36SDavid du Colombier }
686bd389b36SDavid du Colombier
6877fb4e6f1SDavid du Colombier static char *fmtflags = "-0123456789. #,u";
6887fb4e6f1SDavid du Colombier static char *fmtverbs = "bdox";
6897fb4e6f1SDavid du Colombier
6907fb4e6f1SDavid du Colombier static int
acidfmt(char * fmt,char * buf,int blen)6917fb4e6f1SDavid du Colombier acidfmt(char *fmt, char *buf, int blen)
6927fb4e6f1SDavid du Colombier {
6937fb4e6f1SDavid du Colombier char *r, *w, *e;
6947fb4e6f1SDavid du Colombier
6957fb4e6f1SDavid du Colombier w = buf;
6967fb4e6f1SDavid du Colombier e = buf+blen;
6977fb4e6f1SDavid du Colombier for(r=fmt; *r; r++){
6987fb4e6f1SDavid du Colombier if(w >= e)
6997fb4e6f1SDavid du Colombier return -1;
7007fb4e6f1SDavid du Colombier if(*r != '%'){
7017fb4e6f1SDavid du Colombier *w++ = *r;
7027fb4e6f1SDavid du Colombier continue;
7037fb4e6f1SDavid du Colombier }
7047fb4e6f1SDavid du Colombier if(*r == '%'){
7057fb4e6f1SDavid du Colombier *w++ = *r++;
7067fb4e6f1SDavid du Colombier if(*r == '%'){
7077fb4e6f1SDavid du Colombier if(w >= e)
7087fb4e6f1SDavid du Colombier return -1;
7097fb4e6f1SDavid du Colombier *w++ = *r;
7107fb4e6f1SDavid du Colombier continue;
7117fb4e6f1SDavid du Colombier }
7127fb4e6f1SDavid du Colombier while(*r && strchr(fmtflags, *r)){
7137fb4e6f1SDavid du Colombier if(w >= e)
7147fb4e6f1SDavid du Colombier return -1;
7157fb4e6f1SDavid du Colombier *w++ = *r++;
7167fb4e6f1SDavid du Colombier }
7177fb4e6f1SDavid du Colombier if(*r == 0 || strchr(fmtverbs, *r) == nil)
7187fb4e6f1SDavid du Colombier return -1;
7197fb4e6f1SDavid du Colombier if(w+3 > e)
7207fb4e6f1SDavid du Colombier return -1;
7217fb4e6f1SDavid du Colombier *w++ = 'l';
7227fb4e6f1SDavid du Colombier *w++ = 'l';
7237fb4e6f1SDavid du Colombier *w++ = *r;
7247fb4e6f1SDavid du Colombier }
7257fb4e6f1SDavid du Colombier }
7267fb4e6f1SDavid du Colombier if(w >= e)
7277fb4e6f1SDavid du Colombier return -1;
7287fb4e6f1SDavid du Colombier *w = 0;
7297fb4e6f1SDavid du Colombier
7307fb4e6f1SDavid du Colombier return 0;
7317fb4e6f1SDavid du Colombier }
7327fb4e6f1SDavid du Colombier
733bd389b36SDavid du Colombier void
cvtitoa(Node * r,Node * args)734bd389b36SDavid du Colombier cvtitoa(Node *r, Node *args)
735bd389b36SDavid du Colombier {
736bd389b36SDavid du Colombier Node res;
7379a747e4fSDavid du Colombier Node *av[Maxarg];
7384de34a7eSDavid du Colombier vlong ival;
7397fb4e6f1SDavid du Colombier char buf[128], fmt[32];
740bd389b36SDavid du Colombier
741bd389b36SDavid du Colombier if(args == 0)
7429a747e4fSDavid du Colombier err:
7437fb4e6f1SDavid du Colombier error("itoa(number [, fmt]): arg count");
7449a747e4fSDavid du Colombier na = 0;
7459a747e4fSDavid du Colombier flatten(av, args);
7469a747e4fSDavid du Colombier if(na == 0 || na > 2)
7479a747e4fSDavid du Colombier goto err;
7489a747e4fSDavid du Colombier expr(av[0], &res);
749bd389b36SDavid du Colombier if(res.type != TINT)
7507fb4e6f1SDavid du Colombier error("itoa(number [, fmt]): arg type");
7514de34a7eSDavid du Colombier ival = res.ival;
7527fb4e6f1SDavid du Colombier strncpy(fmt, "%lld", sizeof(fmt));
7539a747e4fSDavid du Colombier if(na == 2){
7549a747e4fSDavid du Colombier expr(av[1], &res);
7559a747e4fSDavid du Colombier if(res.type != TSTRING)
7567fb4e6f1SDavid du Colombier error("itoa(number [, fmt]): fmt type");
7577fb4e6f1SDavid du Colombier if(acidfmt(res.string->string, fmt, sizeof(buf)))
7587fb4e6f1SDavid du Colombier error("itoa(number [, fmt]): malformed fmt");
7599a747e4fSDavid du Colombier }
760bd389b36SDavid du Colombier
7614de34a7eSDavid du Colombier snprint(buf, sizeof(buf), fmt, ival);
762bd389b36SDavid du Colombier r->op = OCONST;
763bd389b36SDavid du Colombier r->type = TSTRING;
764bd389b36SDavid du Colombier r->string = strnode(buf);
765219b2ee8SDavid du Colombier r->fmt = 's';
766219b2ee8SDavid du Colombier }
767219b2ee8SDavid du Colombier
768219b2ee8SDavid du Colombier List*
mapent(Map * m)769219b2ee8SDavid du Colombier mapent(Map *m)
770219b2ee8SDavid du Colombier {
771219b2ee8SDavid du Colombier int i;
772219b2ee8SDavid du Colombier List *l, *n, **t, *h;
773219b2ee8SDavid du Colombier
774219b2ee8SDavid du Colombier h = 0;
775219b2ee8SDavid du Colombier t = &h;
776219b2ee8SDavid du Colombier for(i = 0; i < m->nsegs; i++) {
777219b2ee8SDavid du Colombier if(m->seg[i].inuse == 0)
778219b2ee8SDavid du Colombier continue;
779219b2ee8SDavid du Colombier l = al(TSTRING);
780219b2ee8SDavid du Colombier n = al(TLIST);
781219b2ee8SDavid du Colombier n->l = l;
782219b2ee8SDavid du Colombier *t = n;
783219b2ee8SDavid du Colombier t = &n->next;
784219b2ee8SDavid du Colombier l->string = strnode(m->seg[i].name);
785219b2ee8SDavid du Colombier l->fmt = 's';
786219b2ee8SDavid du Colombier l->next = al(TINT);
787219b2ee8SDavid du Colombier l = l->next;
788219b2ee8SDavid du Colombier l->ival = m->seg[i].b;
7894de34a7eSDavid du Colombier l->fmt = 'W';
790219b2ee8SDavid du Colombier l->next = al(TINT);
791219b2ee8SDavid du Colombier l = l->next;
792219b2ee8SDavid du Colombier l->ival = m->seg[i].e;
7934de34a7eSDavid du Colombier l->fmt = 'W';
794219b2ee8SDavid du Colombier l->next = al(TINT);
795219b2ee8SDavid du Colombier l = l->next;
796219b2ee8SDavid du Colombier l->ival = m->seg[i].f;
7974de34a7eSDavid du Colombier l->fmt = 'W';
798219b2ee8SDavid du Colombier }
799219b2ee8SDavid du Colombier return h;
800219b2ee8SDavid du Colombier }
801219b2ee8SDavid du Colombier
802219b2ee8SDavid du Colombier void
map(Node * r,Node * args)803219b2ee8SDavid du Colombier map(Node *r, Node *args)
804219b2ee8SDavid du Colombier {
805219b2ee8SDavid du Colombier int i;
806219b2ee8SDavid du Colombier Map *m;
807219b2ee8SDavid du Colombier List *l;
808219b2ee8SDavid du Colombier char *ent;
809219b2ee8SDavid du Colombier Node *av[Maxarg], res;
810219b2ee8SDavid du Colombier
811219b2ee8SDavid du Colombier na = 0;
812219b2ee8SDavid du Colombier flatten(av, args);
813219b2ee8SDavid du Colombier
814219b2ee8SDavid du Colombier if(na != 0) {
815219b2ee8SDavid du Colombier expr(av[0], &res);
816219b2ee8SDavid du Colombier if(res.type != TLIST)
817219b2ee8SDavid du Colombier error("map(list): map needs a list");
818219b2ee8SDavid du Colombier if(listlen(res.l) != 4)
819219b2ee8SDavid du Colombier error("map(list): list must have 4 entries");
820219b2ee8SDavid du Colombier
821219b2ee8SDavid du Colombier l = res.l;
822219b2ee8SDavid du Colombier if(l->type != TSTRING)
823219b2ee8SDavid du Colombier error("map name must be a string");
824219b2ee8SDavid du Colombier ent = l->string->string;
825219b2ee8SDavid du Colombier m = symmap;
826219b2ee8SDavid du Colombier i = findseg(m, ent);
827219b2ee8SDavid du Colombier if(i < 0) {
828219b2ee8SDavid du Colombier m = cormap;
829219b2ee8SDavid du Colombier i = findseg(m, ent);
830219b2ee8SDavid du Colombier }
831219b2ee8SDavid du Colombier if(i < 0)
832219b2ee8SDavid du Colombier error("%s is not a map entry", ent);
833219b2ee8SDavid du Colombier l = l->next;
834219b2ee8SDavid du Colombier if(l->type != TINT)
835219b2ee8SDavid du Colombier error("map entry not int");
836219b2ee8SDavid du Colombier m->seg[i].b = l->ival;
837219b2ee8SDavid du Colombier if (strcmp(ent, "text") == 0)
838219b2ee8SDavid du Colombier textseg(l->ival, &fhdr);
839219b2ee8SDavid du Colombier l = l->next;
840219b2ee8SDavid du Colombier if(l->type != TINT)
841219b2ee8SDavid du Colombier error("map entry not int");
842219b2ee8SDavid du Colombier m->seg[i].e = l->ival;
843219b2ee8SDavid du Colombier l = l->next;
844219b2ee8SDavid du Colombier if(l->type != TINT)
845219b2ee8SDavid du Colombier error("map entry not int");
846219b2ee8SDavid du Colombier m->seg[i].f = l->ival;
847219b2ee8SDavid du Colombier }
848219b2ee8SDavid du Colombier
849219b2ee8SDavid du Colombier r->type = TLIST;
850219b2ee8SDavid du Colombier r->l = 0;
851219b2ee8SDavid du Colombier if(symmap)
852219b2ee8SDavid du Colombier r->l = mapent(symmap);
853219b2ee8SDavid du Colombier if(cormap) {
854219b2ee8SDavid du Colombier if(r->l == 0)
855219b2ee8SDavid du Colombier r->l = mapent(cormap);
856219b2ee8SDavid du Colombier else {
857219b2ee8SDavid du Colombier for(l = r->l; l->next; l = l->next)
858219b2ee8SDavid du Colombier ;
859219b2ee8SDavid du Colombier l->next = mapent(cormap);
860219b2ee8SDavid du Colombier }
861219b2ee8SDavid du Colombier }
862bd389b36SDavid du Colombier }
863bd389b36SDavid du Colombier
864bd389b36SDavid du Colombier void
flatten(Node ** av,Node * n)865bd389b36SDavid du Colombier flatten(Node **av, Node *n)
866bd389b36SDavid du Colombier {
867bd389b36SDavid du Colombier if(n == 0)
868bd389b36SDavid du Colombier return;
869bd389b36SDavid du Colombier
870bd389b36SDavid du Colombier switch(n->op) {
871bd389b36SDavid du Colombier case OLIST:
872bd389b36SDavid du Colombier flatten(av, n->left);
873bd389b36SDavid du Colombier flatten(av, n->right);
874bd389b36SDavid du Colombier break;
875bd389b36SDavid du Colombier default:
876bd389b36SDavid du Colombier av[na++] = n;
877bd389b36SDavid du Colombier if(na >= Maxarg)
878bd389b36SDavid du Colombier error("too many function arguments");
879bd389b36SDavid du Colombier break;
880bd389b36SDavid du Colombier }
881bd389b36SDavid du Colombier }
882bd389b36SDavid du Colombier
883bd389b36SDavid du Colombier void
strace(Node * r,Node * args)884bd389b36SDavid du Colombier strace(Node *r, Node *args)
885bd389b36SDavid du Colombier {
886bd389b36SDavid du Colombier Node *av[Maxarg], *n, res;
8874de34a7eSDavid du Colombier uvlong pc, sp;
888bd389b36SDavid du Colombier
889bd389b36SDavid du Colombier na = 0;
890bd389b36SDavid du Colombier flatten(av, args);
891219b2ee8SDavid du Colombier if(na != 3)
892219b2ee8SDavid du Colombier error("strace(pc, sp, link): arg count");
893bd389b36SDavid du Colombier
894bd389b36SDavid du Colombier n = av[0];
895bd389b36SDavid du Colombier expr(n, &res);
896bd389b36SDavid du Colombier if(res.type != TINT)
897219b2ee8SDavid du Colombier error("strace(pc, sp, link): pc bad type");
898219b2ee8SDavid du Colombier pc = res.ival;
899219b2ee8SDavid du Colombier
900bd389b36SDavid du Colombier n = av[1];
901bd389b36SDavid du Colombier expr(n, &res);
902bd389b36SDavid du Colombier if(res.type != TINT)
903219b2ee8SDavid du Colombier error("strace(pc, sp, link): sp bad type");
904219b2ee8SDavid du Colombier sp = res.ival;
905219b2ee8SDavid du Colombier
906219b2ee8SDavid du Colombier n = av[2];
907219b2ee8SDavid du Colombier expr(n, &res);
908219b2ee8SDavid du Colombier if(res.type != TINT)
909219b2ee8SDavid du Colombier error("strace(pc, sp, link): link bad type");
910219b2ee8SDavid du Colombier
911219b2ee8SDavid du Colombier tracelist = 0;
912219b2ee8SDavid du Colombier if ((*machdata->ctrace)(cormap, pc, sp, res.ival, trlist) <= 0)
9134de34a7eSDavid du Colombier error("no stack frame: %r");
914bd389b36SDavid du Colombier r->type = TLIST;
915219b2ee8SDavid du Colombier r->l = tracelist;
916bd389b36SDavid du Colombier }
917bd389b36SDavid du Colombier
918219b2ee8SDavid du Colombier void
regerror(char * msg)919219b2ee8SDavid du Colombier regerror(char *msg)
920219b2ee8SDavid du Colombier {
921219b2ee8SDavid du Colombier error(msg);
922219b2ee8SDavid du Colombier }
923219b2ee8SDavid du Colombier
924219b2ee8SDavid du Colombier void
regexp(Node * r,Node * args)925219b2ee8SDavid du Colombier regexp(Node *r, Node *args)
926219b2ee8SDavid du Colombier {
927219b2ee8SDavid du Colombier Node res;
928219b2ee8SDavid du Colombier Reprog *rp;
929219b2ee8SDavid du Colombier Node *av[Maxarg];
930219b2ee8SDavid du Colombier
931219b2ee8SDavid du Colombier na = 0;
932219b2ee8SDavid du Colombier flatten(av, args);
933219b2ee8SDavid du Colombier if(na != 2)
934219b2ee8SDavid du Colombier error("regexp(pattern, string): arg count");
935219b2ee8SDavid du Colombier expr(av[0], &res);
936219b2ee8SDavid du Colombier if(res.type != TSTRING)
937219b2ee8SDavid du Colombier error("regexp(pattern, string): pattern must be string");
938219b2ee8SDavid du Colombier rp = regcomp(res.string->string);
939219b2ee8SDavid du Colombier if(rp == 0)
940219b2ee8SDavid du Colombier return;
941219b2ee8SDavid du Colombier
942219b2ee8SDavid du Colombier expr(av[1], &res);
943219b2ee8SDavid du Colombier if(res.type != TSTRING)
944219b2ee8SDavid du Colombier error("regexp(pattern, string): bad string");
945219b2ee8SDavid du Colombier
946219b2ee8SDavid du Colombier r->fmt = 'D';
947219b2ee8SDavid du Colombier r->type = TINT;
948219b2ee8SDavid du Colombier r->ival = regexec(rp, res.string->string, 0, 0);
949219b2ee8SDavid du Colombier free(rp);
950219b2ee8SDavid du Colombier }
951219b2ee8SDavid du Colombier
952bd389b36SDavid du Colombier void
fmt(Node * r,Node * args)953bd389b36SDavid du Colombier fmt(Node *r, Node *args)
954bd389b36SDavid du Colombier {
955bd389b36SDavid du Colombier Node res;
956bd389b36SDavid du Colombier Node *av[Maxarg];
957bd389b36SDavid du Colombier
958bd389b36SDavid du Colombier na = 0;
959bd389b36SDavid du Colombier flatten(av, args);
960bd389b36SDavid du Colombier if(na != 2)
961bd389b36SDavid du Colombier error("fmt(obj, fmt): arg count");
962bd389b36SDavid du Colombier expr(av[1], &res);
963bd389b36SDavid du Colombier if(res.type != TINT || strchr(vfmt, res.ival) == 0)
9647dd7cddfSDavid du Colombier error("fmt(obj, fmt): bad format '%c'", (char)res.ival);
965bd389b36SDavid du Colombier expr(av[0], r);
966bd389b36SDavid du Colombier r->fmt = res.ival;
967bd389b36SDavid du Colombier }
968bd389b36SDavid du Colombier
969bd389b36SDavid du Colombier void
patom(char type,Store * res)970bd389b36SDavid du Colombier patom(char type, Store *res)
971bd389b36SDavid du Colombier {
972219b2ee8SDavid du Colombier int i;
973219b2ee8SDavid du Colombier char buf[512];
97480ee5cbfSDavid du Colombier extern char *typenames[];
975bd389b36SDavid du Colombier
976bd389b36SDavid du Colombier switch(res->fmt) {
977bd389b36SDavid du Colombier case 'c':
9787dd7cddfSDavid du Colombier Bprint(bout, "%c", (int)res->ival);
979bd389b36SDavid du Colombier break;
980bd389b36SDavid du Colombier case 'C':
981bd389b36SDavid du Colombier if(res->ival < ' ' || res->ival >= 0x7f)
9827dd7cddfSDavid du Colombier Bprint(bout, "%3d", (int)res->ival&0xff);
983bd389b36SDavid du Colombier else
9847dd7cddfSDavid du Colombier Bprint(bout, "%3c", (int)res->ival);
985bd389b36SDavid du Colombier break;
986bd389b36SDavid du Colombier case 'r':
9877dd7cddfSDavid du Colombier Bprint(bout, "%C", (int)res->ival);
988bd389b36SDavid du Colombier break;
989219b2ee8SDavid du Colombier case 'B':
990219b2ee8SDavid du Colombier memset(buf, '0', 34);
991219b2ee8SDavid du Colombier buf[1] = 'b';
992219b2ee8SDavid du Colombier for(i = 0; i < 32; i++) {
993219b2ee8SDavid du Colombier if(res->ival & (1<<i))
994219b2ee8SDavid du Colombier buf[33-i] = '1';
995219b2ee8SDavid du Colombier }
996219b2ee8SDavid du Colombier buf[35] = '\0';
997219b2ee8SDavid du Colombier Bprint(bout, "%s", buf);
998219b2ee8SDavid du Colombier break;
9997dd7cddfSDavid du Colombier case 'b':
100059c21d95SDavid du Colombier Bprint(bout, "%.2x", (int)res->ival&0xff);
10017dd7cddfSDavid du Colombier break;
1002bd389b36SDavid du Colombier case 'X':
10037dd7cddfSDavid du Colombier Bprint(bout, "%.8lux", (ulong)res->ival);
1004bd389b36SDavid du Colombier break;
1005bd389b36SDavid du Colombier case 'x':
10067dd7cddfSDavid du Colombier Bprint(bout, "%.4lux", (ulong)res->ival&0xffff);
10077dd7cddfSDavid du Colombier break;
1008bd389b36SDavid du Colombier case 'D':
10097dd7cddfSDavid du Colombier Bprint(bout, "%d", (int)res->ival);
1010bd389b36SDavid du Colombier break;
1011bd389b36SDavid du Colombier case 'd':
1012bd389b36SDavid du Colombier Bprint(bout, "%d", (ushort)res->ival);
1013bd389b36SDavid du Colombier break;
1014bd389b36SDavid du Colombier case 'u':
10157dd7cddfSDavid du Colombier Bprint(bout, "%d", (int)res->ival&0xffff);
1016bd389b36SDavid du Colombier break;
1017bd389b36SDavid du Colombier case 'U':
10187dd7cddfSDavid du Colombier Bprint(bout, "%lud", (ulong)res->ival);
10197dd7cddfSDavid du Colombier break;
10207dd7cddfSDavid du Colombier case 'Z':
10217dd7cddfSDavid du Colombier Bprint(bout, "%llud", res->ival);
10227dd7cddfSDavid du Colombier break;
10237dd7cddfSDavid du Colombier case 'V':
10247dd7cddfSDavid du Colombier Bprint(bout, "%lld", res->ival);
10257dd7cddfSDavid du Colombier break;
10264de34a7eSDavid du Colombier case 'W':
10274de34a7eSDavid du Colombier Bprint(bout, "%.8llux", res->ival);
10284de34a7eSDavid du Colombier break;
10297dd7cddfSDavid du Colombier case 'Y':
10307dd7cddfSDavid du Colombier Bprint(bout, "%.16llux", res->ival);
1031bd389b36SDavid du Colombier break;
1032bd389b36SDavid du Colombier case 'o':
10337dd7cddfSDavid du Colombier Bprint(bout, "0%.11uo", (int)res->ival&0xffff);
1034bd389b36SDavid du Colombier break;
1035bd389b36SDavid du Colombier case 'O':
10367dd7cddfSDavid du Colombier Bprint(bout, "0%.6uo", (int)res->ival);
1037bd389b36SDavid du Colombier break;
1038bd389b36SDavid du Colombier case 'q':
1039bd389b36SDavid du Colombier Bprint(bout, "0%.11o", (short)(res->ival&0xffff));
1040bd389b36SDavid du Colombier break;
1041bd389b36SDavid du Colombier case 'Q':
10427dd7cddfSDavid du Colombier Bprint(bout, "0%.6o", (int)res->ival);
1043bd389b36SDavid du Colombier break;
1044bd389b36SDavid du Colombier case 'f':
1045bd389b36SDavid du Colombier case 'F':
104637e88e97SDavid du Colombier case '3':
104737e88e97SDavid du Colombier case '8':
1048219b2ee8SDavid du Colombier if(type != TFLOAT)
104980ee5cbfSDavid du Colombier Bprint(bout, "*%c<%s>*", res->fmt, typenames[type]);
1050219b2ee8SDavid du Colombier else
1051219b2ee8SDavid du Colombier Bprint(bout, "%g", res->fval);
1052bd389b36SDavid du Colombier break;
1053bd389b36SDavid du Colombier case 's':
1054219b2ee8SDavid du Colombier case 'g':
1055219b2ee8SDavid du Colombier case 'G':
1056bd389b36SDavid du Colombier if(type != TSTRING)
105780ee5cbfSDavid du Colombier Bprint(bout, "*%c<%s>*", res->fmt, typenames[type]);
1058219b2ee8SDavid du Colombier else
1059219b2ee8SDavid du Colombier Bwrite(bout, res->string->string, res->string->len);
1060bd389b36SDavid du Colombier break;
1061bd389b36SDavid du Colombier case 'R':
1062bd389b36SDavid du Colombier if(type != TSTRING)
106380ee5cbfSDavid du Colombier Bprint(bout, "*%c<%s>*", res->fmt, typenames[type]);
1064219b2ee8SDavid du Colombier else
10657dd7cddfSDavid du Colombier Bprint(bout, "%S", (Rune*)res->string->string);
1066bd389b36SDavid du Colombier break;
1067bd389b36SDavid du Colombier case 'a':
1068219b2ee8SDavid du Colombier case 'A':
1069219b2ee8SDavid du Colombier symoff(buf, sizeof(buf), res->ival, CANY);
1070219b2ee8SDavid du Colombier Bprint(bout, "%s", buf);
1071bd389b36SDavid du Colombier break;
1072bd389b36SDavid du Colombier case 'I':
1073bd389b36SDavid du Colombier case 'i':
1074bd389b36SDavid du Colombier if(type != TINT)
107580ee5cbfSDavid du Colombier Bprint(bout, "*%c<%s>*", res->fmt, typenames[type]);
1076219b2ee8SDavid du Colombier else {
10779a747e4fSDavid du Colombier if (symmap == nil || (*machdata->das)(symmap, res->ival, res->fmt, buf, sizeof(buf)) < 0)
10789a747e4fSDavid du Colombier Bprint(bout, "no instruction");
1079219b2ee8SDavid du Colombier else
1080219b2ee8SDavid du Colombier Bprint(bout, "%s", buf);
1081219b2ee8SDavid du Colombier }
1082bd389b36SDavid du Colombier break;
1083bd389b36SDavid du Colombier }
1084bd389b36SDavid du Colombier }
1085bd389b36SDavid du Colombier
1086bd389b36SDavid du Colombier void
blprint(List * l)1087bd389b36SDavid du Colombier blprint(List *l)
1088bd389b36SDavid du Colombier {
1089bd389b36SDavid du Colombier Bprint(bout, "{");
1090bd389b36SDavid du Colombier while(l) {
1091219b2ee8SDavid du Colombier switch(l->type) {
1092219b2ee8SDavid du Colombier default:
1093bd389b36SDavid du Colombier patom(l->type, &l->Store);
1094219b2ee8SDavid du Colombier break;
1095219b2ee8SDavid du Colombier case TSTRING:
1096219b2ee8SDavid du Colombier Bputc(bout, '"');
1097219b2ee8SDavid du Colombier patom(l->type, &l->Store);
1098219b2ee8SDavid du Colombier Bputc(bout, '"');
1099219b2ee8SDavid du Colombier break;
1100219b2ee8SDavid du Colombier case TLIST:
1101bd389b36SDavid du Colombier blprint(l->l);
1102219b2ee8SDavid du Colombier break;
1103219b2ee8SDavid du Colombier case TCODE:
1104219b2ee8SDavid du Colombier pcode(l->cc, 0);
1105219b2ee8SDavid du Colombier break;
1106219b2ee8SDavid du Colombier }
1107bd389b36SDavid du Colombier l = l->next;
1108bd389b36SDavid du Colombier if(l)
1109bd389b36SDavid du Colombier Bprint(bout, ", ");
1110bd389b36SDavid du Colombier }
1111bd389b36SDavid du Colombier Bprint(bout, "}");
1112bd389b36SDavid du Colombier }
1113bd389b36SDavid du Colombier
1114219b2ee8SDavid du Colombier int
comx(Node res)1115219b2ee8SDavid du Colombier comx(Node res)
1116219b2ee8SDavid du Colombier {
1117219b2ee8SDavid du Colombier Lsym *sl;
1118219b2ee8SDavid du Colombier Node *n, xx;
1119219b2ee8SDavid du Colombier
1120219b2ee8SDavid du Colombier if(res.fmt != 'a' && res.fmt != 'A')
1121219b2ee8SDavid du Colombier return 0;
1122219b2ee8SDavid du Colombier
1123219b2ee8SDavid du Colombier if(res.comt == 0 || res.comt->base == 0)
1124219b2ee8SDavid du Colombier return 0;
1125219b2ee8SDavid du Colombier
1126219b2ee8SDavid du Colombier sl = res.comt->base;
1127219b2ee8SDavid du Colombier if(sl->proc) {
1128219b2ee8SDavid du Colombier res.left = ZN;
1129219b2ee8SDavid du Colombier res.right = ZN;
1130219b2ee8SDavid du Colombier n = an(ONAME, ZN, ZN);
1131219b2ee8SDavid du Colombier n->sym = sl;
1132219b2ee8SDavid du Colombier n = an(OCALL, n, &res);
1133219b2ee8SDavid du Colombier n->left->sym = sl;
1134219b2ee8SDavid du Colombier expr(n, &xx);
1135219b2ee8SDavid du Colombier return 1;
1136219b2ee8SDavid du Colombier }
1137219b2ee8SDavid du Colombier print("(%s)", sl->name);
1138219b2ee8SDavid du Colombier return 0;
1139219b2ee8SDavid du Colombier }
1140219b2ee8SDavid du Colombier
1141bd389b36SDavid du Colombier void
bprint(Node * r,Node * args)1142bd389b36SDavid du Colombier bprint(Node *r, Node *args)
1143bd389b36SDavid du Colombier {
1144bd389b36SDavid du Colombier int i, nas;
1145bd389b36SDavid du Colombier Node res, *av[Maxarg];
1146bd389b36SDavid du Colombier
1147bd389b36SDavid du Colombier USED(r);
1148bd389b36SDavid du Colombier na = 0;
1149bd389b36SDavid du Colombier flatten(av, args);
1150bd389b36SDavid du Colombier nas = na;
1151bd389b36SDavid du Colombier for(i = 0; i < nas; i++) {
1152bd389b36SDavid du Colombier expr(av[i], &res);
1153bd389b36SDavid du Colombier switch(res.type) {
1154bd389b36SDavid du Colombier default:
1155219b2ee8SDavid du Colombier if(comx(res))
1156219b2ee8SDavid du Colombier break;
1157219b2ee8SDavid du Colombier patom(res.type, &res.Store);
1158219b2ee8SDavid du Colombier break;
1159219b2ee8SDavid du Colombier case TCODE:
1160219b2ee8SDavid du Colombier pcode(res.cc, 0);
1161219b2ee8SDavid du Colombier break;
1162219b2ee8SDavid du Colombier case TLIST:
1163219b2ee8SDavid du Colombier blprint(res.l);
1164219b2ee8SDavid du Colombier break;
1165219b2ee8SDavid du Colombier }
1166219b2ee8SDavid du Colombier }
1167219b2ee8SDavid du Colombier if(ret == 0)
1168219b2ee8SDavid du Colombier Bputc(bout, '\n');
1169219b2ee8SDavid du Colombier }
1170219b2ee8SDavid du Colombier
1171219b2ee8SDavid du Colombier void
printto(Node * r,Node * args)1172219b2ee8SDavid du Colombier printto(Node *r, Node *args)
1173219b2ee8SDavid du Colombier {
1174219b2ee8SDavid du Colombier int fd;
1175219b2ee8SDavid du Colombier Biobuf *b;
1176219b2ee8SDavid du Colombier int i, nas;
1177219b2ee8SDavid du Colombier Node res, *av[Maxarg];
1178219b2ee8SDavid du Colombier
1179219b2ee8SDavid du Colombier USED(r);
1180219b2ee8SDavid du Colombier na = 0;
1181219b2ee8SDavid du Colombier flatten(av, args);
1182219b2ee8SDavid du Colombier nas = na;
1183219b2ee8SDavid du Colombier
1184219b2ee8SDavid du Colombier expr(av[0], &res);
1185219b2ee8SDavid du Colombier if(res.type != TSTRING)
1186219b2ee8SDavid du Colombier error("printto(string, ...): need string");
1187219b2ee8SDavid du Colombier
1188219b2ee8SDavid du Colombier fd = create(res.string->string, OWRITE, 0666);
1189219b2ee8SDavid du Colombier if(fd < 0)
1190219b2ee8SDavid du Colombier fd = open(res.string->string, OWRITE);
1191219b2ee8SDavid du Colombier if(fd < 0)
1192219b2ee8SDavid du Colombier error("printto: open %s: %r", res.string->string);
1193219b2ee8SDavid du Colombier
1194219b2ee8SDavid du Colombier b = gmalloc(sizeof(Biobuf));
1195219b2ee8SDavid du Colombier Binit(b, fd, OWRITE);
1196219b2ee8SDavid du Colombier
1197219b2ee8SDavid du Colombier Bflush(bout);
1198219b2ee8SDavid du Colombier io[iop++] = bout;
1199219b2ee8SDavid du Colombier bout = b;
1200219b2ee8SDavid du Colombier
1201219b2ee8SDavid du Colombier for(i = 1; i < nas; i++) {
1202219b2ee8SDavid du Colombier expr(av[i], &res);
1203219b2ee8SDavid du Colombier switch(res.type) {
1204219b2ee8SDavid du Colombier default:
1205219b2ee8SDavid du Colombier if(comx(res))
1206219b2ee8SDavid du Colombier break;
1207bd389b36SDavid du Colombier patom(res.type, &res.Store);
1208bd389b36SDavid du Colombier break;
1209bd389b36SDavid du Colombier case TLIST:
1210bd389b36SDavid du Colombier blprint(res.l);
1211bd389b36SDavid du Colombier break;
1212bd389b36SDavid du Colombier }
1213bd389b36SDavid du Colombier }
1214bd389b36SDavid du Colombier if(ret == 0)
1215bd389b36SDavid du Colombier Bputc(bout, '\n');
1216219b2ee8SDavid du Colombier
1217219b2ee8SDavid du Colombier Bterm(b);
1218219b2ee8SDavid du Colombier close(fd);
1219219b2ee8SDavid du Colombier free(b);
1220219b2ee8SDavid du Colombier bout = io[--iop];
1221bd389b36SDavid du Colombier }
1222bd389b36SDavid du Colombier
1223bd389b36SDavid du Colombier void
pcfile(Node * r,Node * args)1224bd389b36SDavid du Colombier pcfile(Node *r, Node *args)
1225bd389b36SDavid du Colombier {
1226bd389b36SDavid du Colombier Node res;
1227bd389b36SDavid du Colombier char *p, buf[128];
1228bd389b36SDavid du Colombier
1229bd389b36SDavid du Colombier if(args == 0)
1230bd389b36SDavid du Colombier error("pcfile(addr): arg count");
1231bd389b36SDavid du Colombier expr(args, &res);
1232bd389b36SDavid du Colombier if(res.type != TINT)
1233bd389b36SDavid du Colombier error("pcfile(addr): arg type");
1234bd389b36SDavid du Colombier
1235bd389b36SDavid du Colombier r->type = TSTRING;
1236bd389b36SDavid du Colombier r->fmt = 's';
1237bd389b36SDavid du Colombier if(fileline(buf, sizeof(buf), res.ival) == 0) {
1238bd389b36SDavid du Colombier r->string = strnode("?file?");
1239bd389b36SDavid du Colombier return;
1240bd389b36SDavid du Colombier }
1241bd389b36SDavid du Colombier p = strrchr(buf, ':');
1242bd389b36SDavid du Colombier if(p == 0)
1243bd389b36SDavid du Colombier error("pcfile(addr): funny file %s", buf);
1244bd389b36SDavid du Colombier *p = '\0';
1245bd389b36SDavid du Colombier r->string = strnode(buf);
1246bd389b36SDavid du Colombier }
1247bd389b36SDavid du Colombier
1248bd389b36SDavid du Colombier void
pcline(Node * r,Node * args)1249bd389b36SDavid du Colombier pcline(Node *r, Node *args)
1250bd389b36SDavid du Colombier {
1251bd389b36SDavid du Colombier Node res;
1252bd389b36SDavid du Colombier char *p, buf[128];
1253bd389b36SDavid du Colombier
1254bd389b36SDavid du Colombier if(args == 0)
1255bd389b36SDavid du Colombier error("pcline(addr): arg count");
1256bd389b36SDavid du Colombier expr(args, &res);
1257bd389b36SDavid du Colombier if(res.type != TINT)
1258bd389b36SDavid du Colombier error("pcline(addr): arg type");
1259bd389b36SDavid du Colombier
1260bd389b36SDavid du Colombier r->type = TINT;
1261bd389b36SDavid du Colombier r->fmt = 'D';
1262bd389b36SDavid du Colombier if(fileline(buf, sizeof(buf), res.ival) == 0) {
1263bd389b36SDavid du Colombier r->ival = 0;
1264bd389b36SDavid du Colombier return;
1265bd389b36SDavid du Colombier }
1266bd389b36SDavid du Colombier
1267bd389b36SDavid du Colombier p = strrchr(buf, ':');
1268bd389b36SDavid du Colombier if(p == 0)
1269bd389b36SDavid du Colombier error("pcline(addr): funny file %s", buf);
12704de34a7eSDavid du Colombier r->ival = strtol(p+1, 0, 0);
1271bd389b36SDavid du Colombier }
1272*7c70c028SDavid du Colombier
fmtof(Node * r,Node * args)1273*7c70c028SDavid du Colombier void fmtof(Node *r, Node *args)
1274*7c70c028SDavid du Colombier {
1275*7c70c028SDavid du Colombier Node *av[Maxarg];
1276*7c70c028SDavid du Colombier Node res;
1277*7c70c028SDavid du Colombier
1278*7c70c028SDavid du Colombier na = 0;
1279*7c70c028SDavid du Colombier flatten(av, args);
1280*7c70c028SDavid du Colombier if(na < 1)
1281*7c70c028SDavid du Colombier error("fmtof(obj): no argument");
1282*7c70c028SDavid du Colombier if(na > 1)
1283*7c70c028SDavid du Colombier error("fmtof(obj): too many arguments") ;
1284*7c70c028SDavid du Colombier expr(av[0], &res);
1285*7c70c028SDavid du Colombier
1286*7c70c028SDavid du Colombier r->op = OCONST;
1287*7c70c028SDavid du Colombier r->type = TINT ;
1288*7c70c028SDavid du Colombier r->ival = res.fmt ;
1289*7c70c028SDavid du Colombier r->fmt = 'c';
1290*7c70c028SDavid du Colombier }
1291*7c70c028SDavid du Colombier
dofmtsize(Node * r,Node * args)1292*7c70c028SDavid du Colombier void dofmtsize(Node *r, Node *args)
1293*7c70c028SDavid du Colombier {
1294*7c70c028SDavid du Colombier Node *av[Maxarg];
1295*7c70c028SDavid du Colombier Node res;
1296*7c70c028SDavid du Colombier Store * s ;
1297*7c70c028SDavid du Colombier Value v ;
1298*7c70c028SDavid du Colombier
1299*7c70c028SDavid du Colombier na = 0;
1300*7c70c028SDavid du Colombier flatten(av, args);
1301*7c70c028SDavid du Colombier if(na < 1)
1302*7c70c028SDavid du Colombier error("fmtsize(obj): no argument");
1303*7c70c028SDavid du Colombier if(na > 1)
1304*7c70c028SDavid du Colombier error("fmtsize(obj): too many arguments") ;
1305*7c70c028SDavid du Colombier expr(av[0], &res);
1306*7c70c028SDavid du Colombier
1307*7c70c028SDavid du Colombier v.type = res.type ;
1308*7c70c028SDavid du Colombier s = &v.Store ;
1309*7c70c028SDavid du Colombier *s = res ;
1310*7c70c028SDavid du Colombier
1311*7c70c028SDavid du Colombier r->op = OCONST;
1312*7c70c028SDavid du Colombier r->type = TINT ;
1313*7c70c028SDavid du Colombier r->ival = fmtsize(&v) ;
1314*7c70c028SDavid du Colombier r->fmt = 'D';
1315*7c70c028SDavid du Colombier }
1316