11 void cvtatof(Node*, Node*);
12 void cvtatoi(Node*, Node*);
13 void cvtitoa(Node*, Node*);
14 void bprint(Node*, Node*);
15 void funcbound(Node*, Node*);
16 void printto(Node*, Node*);
17 void getfile(Node*, Node*);
18 void fmt(Node*, Node*);
19 void pcfile(Node*, Node*);
20 void pcline(Node*, Node*);
21 void setproc(Node*, Node*);
22 void strace(Node*, Node*);
23 void follow(Node*, Node*);
24 void reason(Node*, Node*);
25 void newproc(Node*, Node*);
26 void startstop(Node*, Node*);
27 void match(Node*, Node*);
28 void status(Node*, Node*);
29 void kill(Node*,Node*);
30 void waitstop(Node*, Node*);
31 void stop(Node*, Node*);
32 void start(Node*, Node*);
33 void filepc(Node*, Node*);
34 void doerror(Node*, Node*);
35 void rc(Node*, Node*);
36 void doaccess(Node*, Node*);
37 void map(Node*, Node*);
38 void readfile(Node*, Node*);
39 void interpret(Node*, Node*);
40 void include(Node*, Node*);
41 void regexp(Node*, Node*);
42 void dosysr1(Node*, Node*);
43 void fmtof(Node*, Node*) ;
44 void dofmtsize(Node*, Node*) ;
45 void dogetfields(Node*, Node*);
47 typedef struct Btab Btab;
51 void (*fn)(Node*, Node*);
64 "getfields", dogetfields,
77 "startstop", startstop,
84 "interpret", interpret,
92 char vfmt[] = "aABbcCdDfFgGiIoOqQrRsSuUVWxXYZ38";
97 prnt = malloc(sizeof(Node));
98 memset(prnt, 0, sizeof(Node));
100 prnt->left = malloc(sizeof(Node));
101 memset(prnt->left, 0, sizeof(Node));
115 s = enter(b->name, Tid);
125 dosysr1(Node *r, Node*)
127 /* dummy argument for RARG spill */
128 extern int sysr1(void*);
137 match(Node *r, Node *args)
147 error("match(obj, list): arg count");
150 if(resl.type != TLIST)
151 error("match(obj, list): need list");
160 for(f = resl.l; f; f = f->next) {
161 if(resi.type == f->type) {
164 if(resi.ival == f->ival) {
170 if(resi.fval == f->fval) {
176 if(scmp(resi.string, f->string)) {
182 error("match(obj, list): not defined for list");
190 newproc(Node *r, Node *args)
195 char *argv[Maxarg], buf[Strsize];
202 if(res.type != TSTRING)
203 error("newproc(): arg not string");
204 if(res.string->len >= sizeof(buf))
205 error("newproc(): too many arguments");
206 memmove(buf, res.string->string, res.string->len);
207 buf[res.string->len] = '\0';
209 e = buf+res.string->len;
211 while(p < e && (*p == '\t' || *p == ' '))
217 error("newproc: too many arguments");
218 while(p < e && *p != '\t' && *p != ' ')
226 r->ival = nproc(argv);
230 startstop(Node *r, Node *args)
236 error("startstop(pid): no pid");
239 error("startstop(pid): arg type");
241 msg(res.ival, "startstop");
247 waitstop(Node *r, Node *args)
253 error("waitstop(pid): no pid");
256 error("waitstop(pid): arg type");
259 msg(res.ival, "waitstop");
265 start(Node *r, Node *args)
271 error("start(pid): no pid");
274 error("start(pid): arg type");
276 msg(res.ival, "start");
280 stop(Node *r, Node *args)
286 error("stop(pid): no pid");
289 error("stop(pid): arg type");
292 msg(res.ival, "stop");
298 kill(Node *r, Node *args)
304 error("kill(pid): no pid");
307 error("kill(pid): arg type");
309 msg(res.ival, "kill");
314 status(Node *r, Node *args)
321 error("status(pid): no pid");
324 error("status(pid): arg type");
326 p = getstatus(res.ival);
327 r->string = strnode(p);
334 reason(Node *r, Node *args)
339 error("reason(cause): no cause");
342 error("reason(cause): arg type");
347 r->string = strnode((*machdata->excep)(cormap, rget));
351 follow(Node *r, Node *args)
359 error("follow(addr): no addr");
362 error("follow(addr): arg type");
364 n = (*machdata->foll)(cormap, res.ival, rget, f);
366 error("follow(addr): %r");
368 for(i = 0; i < n; i++) {
378 funcbound(Node *r, Node *args)
386 error("fnbound(addr): no addr");
389 error("fnbound(addr): arg type");
391 n = fnbound(res.ival, bounds);
405 setproc(Node *r, Node *args)
411 error("setproc(pid): no pid");
414 error("setproc(pid): arg type");
420 filepc(Node *r, Node *args)
426 error("filepc(filename:line): arg count");
428 if(res.type != TSTRING)
429 error("filepc(filename:line): arg type");
431 p = strchr(res.string->string, ':');
433 error("filepc(filename:line): bad arg format");
437 r->ival = file2pc(res.string->string, strtol(p, 0, 0));
440 error("filepc(filename:line): can't find address");
448 interpret(Node *r, Node *args)
454 error("interpret(string): arg count");
456 if(res.type != TSTRING)
457 error("interpret(string): arg type");
472 include(Node *r, Node *args)
478 error("include(string): arg count");
480 if(res.type != TSTRING)
481 error("include(string): arg type");
483 pushfile(res.string->string);
496 rc(Node *r, Node *args)
500 char *p, *q, *argv[4];
505 error("error(string): arg count");
507 if(res.type != TSTRING)
508 error("error(string): arg type");
512 argv[2] = res.string->string;
520 exec("/bin/rc", argv);
533 r->string = strnode(p);
539 doerror(Node *r, Node *args)
545 error("error(string): arg count");
547 if(res.type != TSTRING)
548 error("error(string): arg type");
550 error(res.string->string);
554 doaccess(Node *r, Node *args)
559 error("access(filename): arg count");
561 if(res.type != TSTRING)
562 error("access(filename): arg type");
567 if(access(res.string->string, 4) == 0)
572 readfile(Node *r, Node *args)
580 error("readfile(filename): arg count");
582 if(res.type != TSTRING)
583 error("readfile(filename): arg type");
585 fd = open(res.string->string, OREAD);
590 if(db == nil || db->length == 0)
597 n = read(fd, buf, n);
602 r->string = strnodlen(buf, n);
610 getfile(Node *r, Node *args)
620 error("file(filename): arg count");
622 if(res.type != TSTRING)
623 error("file(filename): arg type");
629 p = res.string->string;
630 bp = Bopen(p, OREAD);
636 p = Brdline(bp, '\n');
642 Bread(bp, s->string, n);
645 s = strnodlen(p, n-1);
657 cvtatof(Node *r, Node *args)
662 error("atof(string): arg count");
664 if(res.type != TSTRING)
665 error("atof(string): arg type");
669 r->fval = atof(res.string->string);
674 cvtatoi(Node *r, Node *args)
679 error("atoi(string): arg count");
681 if(res.type != TSTRING)
682 error("atoi(string): arg type");
686 r->ival = strtoull(res.string->string, 0, 0);
690 static char *fmtflags = "-0123456789. #,u";
691 static char *fmtverbs = "bdox";
694 acidfmt(char *fmt, char *buf, int blen)
715 while(*r && strchr(fmtflags, *r)){
720 if(*r == 0 || strchr(fmtverbs, *r) == nil)
737 cvtitoa(Node *r, Node *args)
742 char buf[128], fmt[32];
746 error("itoa(number [, fmt]): arg count");
749 if(na == 0 || na > 2)
753 error("itoa(number [, fmt]): arg type");
755 strncpy(fmt, "%lld", sizeof(fmt));
758 if(res.type != TSTRING)
759 error("itoa(number [, fmt]): fmt type");
760 if(acidfmt(res.string->string, fmt, sizeof(fmt)))
761 error("itoa(number [, fmt]): malformed fmt");
764 snprint(buf, sizeof(buf), fmt, ival);
767 r->string = strnode(buf);
775 List *l, *n, **t, *h;
779 for(i = 0; i < m->nsegs; i++) {
780 if(m->seg[i].inuse == 0)
787 l->string = strnode(m->seg[i].name);
791 l->ival = m->seg[i].b;
795 l->ival = m->seg[i].e;
799 l->ival = m->seg[i].f;
806 map(Node *r, Node *args)
812 Node *av[Maxarg], res;
819 if(res.type != TLIST)
820 error("map(list): map needs a list");
821 if(listlen(res.l) != 4)
822 error("map(list): list must have 4 entries");
825 if(l->type != TSTRING)
826 error("map name must be a string");
827 ent = l->string->string;
835 error("%s is not a map entry", ent);
838 error("map entry not int");
839 m->seg[i].b = l->ival;
840 if (strcmp(ent, "text") == 0)
841 textseg(l->ival, &fhdr);
844 error("map entry not int");
845 m->seg[i].e = l->ival;
848 error("map entry not int");
849 m->seg[i].f = l->ival;
855 r->l = mapent(symmap);
858 r->l = mapent(cormap);
860 for(l = r->l; l->next; l = l->next)
862 l->next = mapent(cormap);
868 flatten(Node **av, Node *n)
875 flatten(av, n->left);
876 flatten(av, n->right);
881 error("too many function arguments");
887 strace(Node *r, Node *args)
889 Node *av[Maxarg], *n, res;
895 error("strace(pc, sp, link): arg count");
900 error("strace(pc, sp, link): pc bad type");
906 error("strace(pc, sp, link): sp bad type");
912 error("strace(pc, sp, link): link bad type");
915 if ((*machdata->ctrace)(cormap, pc, sp, res.ival, trlist) <= 0)
916 error("no stack frame: %r");
928 regexp(Node *r, Node *args)
937 error("regexp(pattern, string): arg count");
939 if(res.type != TSTRING)
940 error("regexp(pattern, string): pattern must be string");
941 rp = regcomp(res.string->string);
946 if(res.type != TSTRING)
947 error("regexp(pattern, string): bad string");
951 r->ival = regexec(rp, res.string->string, 0, 0);
956 fmt(Node *r, Node *args)
964 error("fmt(obj, fmt): arg count");
966 if(res.type != TINT || strchr(vfmt, res.ival) == 0)
967 error("fmt(obj, fmt): bad format '%c'", (char)res.ival);
973 patom(char type, Store *res)
978 extern char *typenames[];
985 Bprint(bout, "%c", (int)res->ival);
988 if(res->ival < ' ' || res->ival >= 0x7f)
989 Bprint(bout, "%3d", (int)res->ival&0xff);
991 Bprint(bout, "%3c", (int)res->ival);
994 Bprint(bout, "%C", (int)res->ival);
997 memset(buf, '0', 34);
999 for(i = 0; i < 32; i++) {
1000 if(res->ival & (1<<i))
1004 Bprint(bout, "%s", buf);
1007 Bprint(bout, "%.2x", (int)res->ival&0xff);
1010 Bprint(bout, "%.8lux", (ulong)res->ival);
1013 Bprint(bout, "%.4lux", (ulong)res->ival&0xffff);
1016 Bprint(bout, "%d", (int)res->ival);
1019 Bprint(bout, "%hd", (short)res->ival);
1022 Bprint(bout, "%hud", (ushort)res->ival);
1025 Bprint(bout, "%lud", (ulong)res->ival);
1028 Bprint(bout, "%llud", res->ival);
1031 Bprint(bout, "%lld", res->ival);
1034 Bprint(bout, "%.8llux", res->ival);
1037 Bprint(bout, "%.16llux", res->ival);
1040 Bprint(bout, "0%.11uo", (int)res->ival&0xffff);
1043 Bprint(bout, "0%.6uo", (int)res->ival);
1046 Bprint(bout, "0%.11o", (short)(res->ival&0xffff));
1049 Bprint(bout, "0%.6o", (int)res->ival);
1056 Bprint(bout, "*%c<%s>*", res->fmt, typenames[type]);
1058 Bprint(bout, "%g", res->fval);
1064 Bprint(bout, "*%c<%s>*", res->fmt, typenames[type]);
1066 Bwrite(bout, res->string->string, res->string->len);
1070 Bprint(bout, "*%c<%s>*", res->fmt, typenames[type]);
1072 Bprint(bout, "%S", (Rune*)res->string->string);
1075 symoff(buf, sizeof(buf), res->ival, CANY);
1076 Bprint(bout, "%s", buf);
1081 Bprint(bout, "*%c<%s>*", res->fmt, typenames[type]);
1083 if (symmap == nil || (*machdata->das)(symmap, res->ival, res->fmt, buf, sizeof(buf)) < 0)
1084 Bprint(bout, "no instruction");
1086 Bprint(bout, "%s", buf);
1099 patom(l->type, &l->Store);
1103 patom(l->type, &l->Store);
1126 if(res.fmt != 'a' || res.comt == 0 || res.comt->base == 0)
1129 sl = res.comt->base;
1133 n = an(ONAME, ZN, ZN);
1135 n = an(OCALL, n, &res);
1140 print("(%s)", sl->name);
1145 bprint(Node *r, Node *args)
1148 Node res, *av[Maxarg];
1154 for(i = 0; i < nas; i++) {
1160 patom(res.type, &res.Store);
1175 printto(Node *r, Node *args)
1180 Node res, *av[Maxarg];
1188 if(res.type != TSTRING)
1189 error("printto(string, ...): need string");
1191 fd = create(res.string->string, OWRITE, 0666);
1193 fd = open(res.string->string, OWRITE);
1195 error("printto: open %s: %r", res.string->string);
1197 b = gmalloc(sizeof(Biobuf));
1198 Binit(b, fd, OWRITE);
1204 for(i = 1; i < nas; i++) {
1210 patom(res.type, &res.Store);
1227 pcfile(Node *r, Node *args)
1233 error("pcfile(addr): arg count");
1235 if(res.type != TINT)
1236 error("pcfile(addr): arg type");
1240 if(fileline(buf, sizeof(buf), res.ival) == 0) {
1241 r->string = strnode("?file?");
1244 p = strrchr(buf, ':');
1246 error("pcfile(addr): funny file %s", buf);
1248 r->string = strnode(buf);
1252 pcline(Node *r, Node *args)
1258 error("pcline(addr): arg count");
1260 if(res.type != TINT)
1261 error("pcline(addr): arg type");
1265 if(fileline(buf, sizeof(buf), res.ival) == 0) {
1270 p = strrchr(buf, ':');
1272 error("pcline(addr): funny file %s", buf);
1273 r->ival = strtol(p+1, 0, 0);
1276 void fmtof(Node *r, Node *args)
1284 error("fmtof(obj): no argument");
1286 error("fmtof(obj): too many arguments") ;
1295 void dofmtsize(Node *r, Node *args)
1305 error("fmtsize(obj): no argument");
1307 error("fmtsize(obj): too many arguments") ;
1316 r->ival = fmtsize(&v) ;
1321 dogetfields(Node *r, Node *args)
1323 Node *av[Maxarg], nstr, ndelim, nmultif;
1332 error("getfields(str, delims, multiflag): arg count");
1334 expr(av[1], &ndelim);
1335 expr(av[2], &nmultif);
1336 if(nstr.type != TSTRING || ndelim.type != TSTRING)
1337 error("getfields(str, delims, multiflag): arg type");
1338 buf = strdup(nstr.string->string);
1340 fatal("out of memory");
1341 rc = getfields(buf, f, nelem(f), bool(&nmultif), ndelim.string->string);
1343 for(i = 0; i < rc; i++){
1346 l->string = strnode(f[i]);