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*) ;
46 typedef struct Btab Btab;
50 void (*fn)(Node*, Node*);
75 "startstop", startstop,
82 "interpret", interpret,
90 char vfmt[] = "aBbcCdDfFgGiIoOqQrRsSuUVWxXYZ38";
95 prnt = malloc(sizeof(Node));
96 memset(prnt, 0, sizeof(Node));
98 prnt->left = malloc(sizeof(Node));
99 memset(prnt->left, 0, sizeof(Node));
113 s = enter(b->name, Tid);
123 dosysr1(Node *r, Node*)
125 extern int sysr1(void);
134 match(Node *r, Node *args)
144 error("match(obj, list): arg count");
147 if(resl.type != TLIST)
148 error("match(obj, list): need list");
157 for(f = resl.l; f; f = f->next) {
158 if(resi.type == f->type) {
161 if(resi.ival == f->ival) {
167 if(resi.fval == f->fval) {
173 if(scmp(resi.string, f->string)) {
179 error("match(obj, list): not defined for list");
187 newproc(Node *r, Node *args)
192 char *argv[Maxarg], buf[Strsize];
199 if(res.type != TSTRING)
200 error("newproc(): arg not string");
201 if(res.string->len >= sizeof(buf))
202 error("newproc(): too many arguments");
203 memmove(buf, res.string->string, res.string->len);
204 buf[res.string->len] = '\0';
206 e = buf+res.string->len;
208 while(p < e && (*p == '\t' || *p == ' '))
214 error("newproc: too many arguments");
215 while(p < e && *p != '\t' && *p != ' ')
223 r->ival = nproc(argv);
227 startstop(Node *r, Node *args)
233 error("startstop(pid): no pid");
236 error("startstop(pid): arg type");
238 msg(res.ival, "startstop");
244 waitstop(Node *r, Node *args)
250 error("waitstop(pid): no pid");
253 error("waitstop(pid): arg type");
256 msg(res.ival, "waitstop");
262 start(Node *r, Node *args)
268 error("start(pid): no pid");
271 error("start(pid): arg type");
273 msg(res.ival, "start");
277 stop(Node *r, Node *args)
283 error("stop(pid): no pid");
286 error("stop(pid): arg type");
289 msg(res.ival, "stop");
295 kill(Node *r, Node *args)
301 error("kill(pid): no pid");
304 error("kill(pid): arg type");
306 msg(res.ival, "kill");
311 status(Node *r, Node *args)
318 error("status(pid): no pid");
321 error("status(pid): arg type");
323 p = getstatus(res.ival);
324 r->string = strnode(p);
331 reason(Node *r, Node *args)
336 error("reason(cause): no cause");
339 error("reason(cause): arg type");
344 r->string = strnode((*machdata->excep)(cormap, rget));
348 follow(Node *r, Node *args)
356 error("follow(addr): no addr");
359 error("follow(addr): arg type");
361 n = (*machdata->foll)(cormap, res.ival, rget, f);
363 error("follow(addr): %r");
365 for(i = 0; i < n; i++) {
375 funcbound(Node *r, Node *args)
383 error("fnbound(addr): no addr");
386 error("fnbound(addr): arg type");
388 n = fnbound(res.ival, bounds);
402 setproc(Node *r, Node *args)
408 error("setproc(pid): no pid");
411 error("setproc(pid): arg type");
417 filepc(Node *r, Node *args)
423 error("filepc(filename:line): arg count");
425 if(res.type != TSTRING)
426 error("filepc(filename:line): arg type");
428 p = strchr(res.string->string, ':');
430 error("filepc(filename:line): bad arg format");
434 r->ival = file2pc(res.string->string, strtol(p, 0, 0));
437 error("filepc(filename:line): can't find address");
445 interpret(Node *r, Node *args)
451 error("interpret(string): arg count");
453 if(res.type != TSTRING)
454 error("interpret(string): arg type");
469 include(Node *r, Node *args)
475 error("include(string): arg count");
477 if(res.type != TSTRING)
478 error("include(string): arg type");
480 pushfile(res.string->string);
493 rc(Node *r, Node *args)
497 char *p, *q, *argv[4];
502 error("error(string): arg count");
504 if(res.type != TSTRING)
505 error("error(string): arg type");
509 argv[2] = res.string->string;
517 exec("/bin/rc", argv);
530 r->string = strnode(p);
536 doerror(Node *r, Node *args)
542 error("error(string): arg count");
544 if(res.type != TSTRING)
545 error("error(string): arg type");
547 error(res.string->string);
551 doaccess(Node *r, Node *args)
556 error("access(filename): arg count");
558 if(res.type != TSTRING)
559 error("access(filename): arg type");
564 if(access(res.string->string, 4) == 0)
569 readfile(Node *r, Node *args)
577 error("readfile(filename): arg count");
579 if(res.type != TSTRING)
580 error("readfile(filename): arg type");
582 fd = open(res.string->string, OREAD);
587 if(db == nil || db->length == 0)
594 n = read(fd, buf, n);
599 r->string = strnodlen(buf, n);
607 getfile(Node *r, Node *args)
617 error("file(filename): arg count");
619 if(res.type != TSTRING)
620 error("file(filename): arg type");
626 p = res.string->string;
627 bp = Bopen(p, OREAD);
633 p = Brdline(bp, '\n');
639 Bread(bp, s->string, n);
642 s = strnodlen(p, n-1);
654 cvtatof(Node *r, Node *args)
659 error("atof(string): arg count");
661 if(res.type != TSTRING)
662 error("atof(string): arg type");
666 r->fval = atof(res.string->string);
671 cvtatoi(Node *r, Node *args)
676 error("atoi(string): arg count");
678 if(res.type != TSTRING)
679 error("atoi(string): arg type");
683 r->ival = strtoull(res.string->string, 0, 0);
687 static char *fmtflags = "-0123456789. #,u";
688 static char *fmtverbs = "bdox";
691 acidfmt(char *fmt, char *buf, int blen)
712 while(*r && strchr(fmtflags, *r)){
717 if(*r == 0 || strchr(fmtverbs, *r) == nil)
734 cvtitoa(Node *r, Node *args)
739 char buf[128], fmt[32];
743 error("itoa(number [, fmt]): arg count");
746 if(na == 0 || na > 2)
750 error("itoa(number [, fmt]): arg type");
752 strncpy(fmt, "%lld", sizeof(fmt));
755 if(res.type != TSTRING)
756 error("itoa(number [, fmt]): fmt type");
757 if(acidfmt(res.string->string, fmt, sizeof(buf)))
758 error("itoa(number [, fmt]): malformed fmt");
761 snprint(buf, sizeof(buf), fmt, ival);
764 r->string = strnode(buf);
772 List *l, *n, **t, *h;
776 for(i = 0; i < m->nsegs; i++) {
777 if(m->seg[i].inuse == 0)
784 l->string = strnode(m->seg[i].name);
788 l->ival = m->seg[i].b;
792 l->ival = m->seg[i].e;
796 l->ival = m->seg[i].f;
803 map(Node *r, Node *args)
809 Node *av[Maxarg], res;
816 if(res.type != TLIST)
817 error("map(list): map needs a list");
818 if(listlen(res.l) != 4)
819 error("map(list): list must have 4 entries");
822 if(l->type != TSTRING)
823 error("map name must be a string");
824 ent = l->string->string;
832 error("%s is not a map entry", ent);
835 error("map entry not int");
836 m->seg[i].b = l->ival;
837 if (strcmp(ent, "text") == 0)
838 textseg(l->ival, &fhdr);
841 error("map entry not int");
842 m->seg[i].e = l->ival;
845 error("map entry not int");
846 m->seg[i].f = l->ival;
852 r->l = mapent(symmap);
855 r->l = mapent(cormap);
857 for(l = r->l; l->next; l = l->next)
859 l->next = mapent(cormap);
865 flatten(Node **av, Node *n)
872 flatten(av, n->left);
873 flatten(av, n->right);
878 error("too many function arguments");
884 strace(Node *r, Node *args)
886 Node *av[Maxarg], *n, res;
892 error("strace(pc, sp, link): arg count");
897 error("strace(pc, sp, link): pc bad type");
903 error("strace(pc, sp, link): sp bad type");
909 error("strace(pc, sp, link): link bad type");
912 if ((*machdata->ctrace)(cormap, pc, sp, res.ival, trlist) <= 0)
913 error("no stack frame: %r");
925 regexp(Node *r, Node *args)
934 error("regexp(pattern, string): arg count");
936 if(res.type != TSTRING)
937 error("regexp(pattern, string): pattern must be string");
938 rp = regcomp(res.string->string);
943 if(res.type != TSTRING)
944 error("regexp(pattern, string): bad string");
948 r->ival = regexec(rp, res.string->string, 0, 0);
953 fmt(Node *r, Node *args)
961 error("fmt(obj, fmt): arg count");
963 if(res.type != TINT || strchr(vfmt, res.ival) == 0)
964 error("fmt(obj, fmt): bad format '%c'", (char)res.ival);
970 patom(char type, Store *res)
974 extern char *typenames[];
978 Bprint(bout, "%c", (int)res->ival);
981 if(res->ival < ' ' || res->ival >= 0x7f)
982 Bprint(bout, "%3d", (int)res->ival&0xff);
984 Bprint(bout, "%3c", (int)res->ival);
987 Bprint(bout, "%C", (int)res->ival);
990 memset(buf, '0', 34);
992 for(i = 0; i < 32; i++) {
993 if(res->ival & (1<<i))
997 Bprint(bout, "%s", buf);
1000 Bprint(bout, "%.2x", (int)res->ival&0xff);
1003 Bprint(bout, "%.8lux", (ulong)res->ival);
1006 Bprint(bout, "%.4lux", (ulong)res->ival&0xffff);
1009 Bprint(bout, "%d", (int)res->ival);
1012 Bprint(bout, "%d", (ushort)res->ival);
1015 Bprint(bout, "%d", (int)res->ival&0xffff);
1018 Bprint(bout, "%lud", (ulong)res->ival);
1021 Bprint(bout, "%llud", res->ival);
1024 Bprint(bout, "%lld", res->ival);
1027 Bprint(bout, "%.8llux", res->ival);
1030 Bprint(bout, "%.16llux", res->ival);
1033 Bprint(bout, "0%.11uo", (int)res->ival&0xffff);
1036 Bprint(bout, "0%.6uo", (int)res->ival);
1039 Bprint(bout, "0%.11o", (short)(res->ival&0xffff));
1042 Bprint(bout, "0%.6o", (int)res->ival);
1049 Bprint(bout, "*%c<%s>*", res->fmt, typenames[type]);
1051 Bprint(bout, "%g", res->fval);
1057 Bprint(bout, "*%c<%s>*", res->fmt, typenames[type]);
1059 Bwrite(bout, res->string->string, res->string->len);
1063 Bprint(bout, "*%c<%s>*", res->fmt, typenames[type]);
1065 Bprint(bout, "%S", (Rune*)res->string->string);
1069 symoff(buf, sizeof(buf), res->ival, CANY);
1070 Bprint(bout, "%s", buf);
1075 Bprint(bout, "*%c<%s>*", res->fmt, typenames[type]);
1077 if (symmap == nil || (*machdata->das)(symmap, res->ival, res->fmt, buf, sizeof(buf)) < 0)
1078 Bprint(bout, "no instruction");
1080 Bprint(bout, "%s", buf);
1093 patom(l->type, &l->Store);
1097 patom(l->type, &l->Store);
1120 if(res.fmt != 'a' && res.fmt != 'A')
1123 if(res.comt == 0 || res.comt->base == 0)
1126 sl = res.comt->base;
1130 n = an(ONAME, ZN, ZN);
1132 n = an(OCALL, n, &res);
1137 print("(%s)", sl->name);
1142 bprint(Node *r, Node *args)
1145 Node res, *av[Maxarg];
1151 for(i = 0; i < nas; i++) {
1157 patom(res.type, &res.Store);
1172 printto(Node *r, Node *args)
1177 Node res, *av[Maxarg];
1185 if(res.type != TSTRING)
1186 error("printto(string, ...): need string");
1188 fd = create(res.string->string, OWRITE, 0666);
1190 fd = open(res.string->string, OWRITE);
1192 error("printto: open %s: %r", res.string->string);
1194 b = gmalloc(sizeof(Biobuf));
1195 Binit(b, fd, OWRITE);
1201 for(i = 1; i < nas; i++) {
1207 patom(res.type, &res.Store);
1224 pcfile(Node *r, Node *args)
1230 error("pcfile(addr): arg count");
1232 if(res.type != TINT)
1233 error("pcfile(addr): arg type");
1237 if(fileline(buf, sizeof(buf), res.ival) == 0) {
1238 r->string = strnode("?file?");
1241 p = strrchr(buf, ':');
1243 error("pcfile(addr): funny file %s", buf);
1245 r->string = strnode(buf);
1249 pcline(Node *r, Node *args)
1255 error("pcline(addr): arg count");
1257 if(res.type != TINT)
1258 error("pcline(addr): arg type");
1262 if(fileline(buf, sizeof(buf), res.ival) == 0) {
1267 p = strrchr(buf, ':');
1269 error("pcline(addr): funny file %s", buf);
1270 r->ival = strtol(p+1, 0, 0);
1273 void fmtof(Node *r, Node *args)
1281 error("fmtof(obj): no argument");
1283 error("fmtof(obj): too many arguments") ;
1292 void dofmtsize(Node *r, Node *args)
1302 error("fmtsize(obj): no argument");
1304 error("fmtsize(obj): too many arguments") ;
1313 r->ival = fmtsize(&v) ;