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[] = "aABbcCdDfFgGiIoOqQrRsSuUVWxXYZ38";
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 /* dummy argument for RARG spill */
126 extern int sysr1(void*);
135 match(Node *r, Node *args)
145 error("match(obj, list): arg count");
148 if(resl.type != TLIST)
149 error("match(obj, list): need list");
158 for(f = resl.l; f; f = f->next) {
159 if(resi.type == f->type) {
162 if(resi.ival == f->ival) {
168 if(resi.fval == f->fval) {
174 if(scmp(resi.string, f->string)) {
180 error("match(obj, list): not defined for list");
188 newproc(Node *r, Node *args)
193 char *argv[Maxarg], buf[Strsize];
200 if(res.type != TSTRING)
201 error("newproc(): arg not string");
202 if(res.string->len >= sizeof(buf))
203 error("newproc(): too many arguments");
204 memmove(buf, res.string->string, res.string->len);
205 buf[res.string->len] = '\0';
207 e = buf+res.string->len;
209 while(p < e && (*p == '\t' || *p == ' '))
215 error("newproc: too many arguments");
216 while(p < e && *p != '\t' && *p != ' ')
224 r->ival = nproc(argv);
228 startstop(Node *r, Node *args)
234 error("startstop(pid): no pid");
237 error("startstop(pid): arg type");
239 msg(res.ival, "startstop");
245 waitstop(Node *r, Node *args)
251 error("waitstop(pid): no pid");
254 error("waitstop(pid): arg type");
257 msg(res.ival, "waitstop");
263 start(Node *r, Node *args)
269 error("start(pid): no pid");
272 error("start(pid): arg type");
274 msg(res.ival, "start");
278 stop(Node *r, Node *args)
284 error("stop(pid): no pid");
287 error("stop(pid): arg type");
290 msg(res.ival, "stop");
296 kill(Node *r, Node *args)
302 error("kill(pid): no pid");
305 error("kill(pid): arg type");
307 msg(res.ival, "kill");
312 status(Node *r, Node *args)
319 error("status(pid): no pid");
322 error("status(pid): arg type");
324 p = getstatus(res.ival);
325 r->string = strnode(p);
332 reason(Node *r, Node *args)
337 error("reason(cause): no cause");
340 error("reason(cause): arg type");
345 r->string = strnode((*machdata->excep)(cormap, rget));
349 follow(Node *r, Node *args)
357 error("follow(addr): no addr");
360 error("follow(addr): arg type");
362 n = (*machdata->foll)(cormap, res.ival, rget, f);
364 error("follow(addr): %r");
366 for(i = 0; i < n; i++) {
376 funcbound(Node *r, Node *args)
384 error("fnbound(addr): no addr");
387 error("fnbound(addr): arg type");
389 n = fnbound(res.ival, bounds);
403 setproc(Node *r, Node *args)
409 error("setproc(pid): no pid");
412 error("setproc(pid): arg type");
418 filepc(Node *r, Node *args)
424 error("filepc(filename:line): arg count");
426 if(res.type != TSTRING)
427 error("filepc(filename:line): arg type");
429 p = strchr(res.string->string, ':');
431 error("filepc(filename:line): bad arg format");
435 r->ival = file2pc(res.string->string, strtol(p, 0, 0));
438 error("filepc(filename:line): can't find address");
446 interpret(Node *r, Node *args)
452 error("interpret(string): arg count");
454 if(res.type != TSTRING)
455 error("interpret(string): arg type");
470 include(Node *r, Node *args)
476 error("include(string): arg count");
478 if(res.type != TSTRING)
479 error("include(string): arg type");
481 pushfile(res.string->string);
494 rc(Node *r, Node *args)
498 char *p, *q, *argv[4];
503 error("error(string): arg count");
505 if(res.type != TSTRING)
506 error("error(string): arg type");
510 argv[2] = res.string->string;
518 exec("/bin/rc", argv);
531 r->string = strnode(p);
537 doerror(Node *r, Node *args)
543 error("error(string): arg count");
545 if(res.type != TSTRING)
546 error("error(string): arg type");
548 error(res.string->string);
552 doaccess(Node *r, Node *args)
557 error("access(filename): arg count");
559 if(res.type != TSTRING)
560 error("access(filename): arg type");
565 if(access(res.string->string, 4) == 0)
570 readfile(Node *r, Node *args)
578 error("readfile(filename): arg count");
580 if(res.type != TSTRING)
581 error("readfile(filename): arg type");
583 fd = open(res.string->string, OREAD);
588 if(db == nil || db->length == 0)
595 n = read(fd, buf, n);
600 r->string = strnodlen(buf, n);
608 getfile(Node *r, Node *args)
618 error("file(filename): arg count");
620 if(res.type != TSTRING)
621 error("file(filename): arg type");
627 p = res.string->string;
628 bp = Bopen(p, OREAD);
634 p = Brdline(bp, '\n');
640 Bread(bp, s->string, n);
643 s = strnodlen(p, n-1);
655 cvtatof(Node *r, Node *args)
660 error("atof(string): arg count");
662 if(res.type != TSTRING)
663 error("atof(string): arg type");
667 r->fval = atof(res.string->string);
672 cvtatoi(Node *r, Node *args)
677 error("atoi(string): arg count");
679 if(res.type != TSTRING)
680 error("atoi(string): arg type");
684 r->ival = strtoull(res.string->string, 0, 0);
688 static char *fmtflags = "-0123456789. #,u";
689 static char *fmtverbs = "bdox";
692 acidfmt(char *fmt, char *buf, int blen)
713 while(*r && strchr(fmtflags, *r)){
718 if(*r == 0 || strchr(fmtverbs, *r) == nil)
735 cvtitoa(Node *r, Node *args)
740 char buf[128], fmt[32];
744 error("itoa(number [, fmt]): arg count");
747 if(na == 0 || na > 2)
751 error("itoa(number [, fmt]): arg type");
753 strncpy(fmt, "%lld", sizeof(fmt));
756 if(res.type != TSTRING)
757 error("itoa(number [, fmt]): fmt type");
758 if(acidfmt(res.string->string, fmt, sizeof(fmt)))
759 error("itoa(number [, fmt]): malformed fmt");
762 snprint(buf, sizeof(buf), fmt, ival);
765 r->string = strnode(buf);
773 List *l, *n, **t, *h;
777 for(i = 0; i < m->nsegs; i++) {
778 if(m->seg[i].inuse == 0)
785 l->string = strnode(m->seg[i].name);
789 l->ival = m->seg[i].b;
793 l->ival = m->seg[i].e;
797 l->ival = m->seg[i].f;
804 map(Node *r, Node *args)
810 Node *av[Maxarg], res;
817 if(res.type != TLIST)
818 error("map(list): map needs a list");
819 if(listlen(res.l) != 4)
820 error("map(list): list must have 4 entries");
823 if(l->type != TSTRING)
824 error("map name must be a string");
825 ent = l->string->string;
833 error("%s is not a map entry", ent);
836 error("map entry not int");
837 m->seg[i].b = l->ival;
838 if (strcmp(ent, "text") == 0)
839 textseg(l->ival, &fhdr);
842 error("map entry not int");
843 m->seg[i].e = l->ival;
846 error("map entry not int");
847 m->seg[i].f = l->ival;
853 r->l = mapent(symmap);
856 r->l = mapent(cormap);
858 for(l = r->l; l->next; l = l->next)
860 l->next = mapent(cormap);
866 flatten(Node **av, Node *n)
873 flatten(av, n->left);
874 flatten(av, n->right);
879 error("too many function arguments");
885 strace(Node *r, Node *args)
887 Node *av[Maxarg], *n, res;
893 error("strace(pc, sp, link): arg count");
898 error("strace(pc, sp, link): pc bad type");
904 error("strace(pc, sp, link): sp bad type");
910 error("strace(pc, sp, link): link bad type");
913 if ((*machdata->ctrace)(cormap, pc, sp, res.ival, trlist) <= 0)
914 error("no stack frame: %r");
926 regexp(Node *r, Node *args)
935 error("regexp(pattern, string): arg count");
937 if(res.type != TSTRING)
938 error("regexp(pattern, string): pattern must be string");
939 rp = regcomp(res.string->string);
944 if(res.type != TSTRING)
945 error("regexp(pattern, string): bad string");
949 r->ival = regexec(rp, res.string->string, 0, 0);
954 fmt(Node *r, Node *args)
962 error("fmt(obj, fmt): arg count");
964 if(res.type != TINT || strchr(vfmt, res.ival) == 0)
965 error("fmt(obj, fmt): bad format '%c'", (char)res.ival);
971 patom(char type, Store *res)
976 extern char *typenames[];
983 Bprint(bout, "%c", (int)res->ival);
986 if(res->ival < ' ' || res->ival >= 0x7f)
987 Bprint(bout, "%3d", (int)res->ival&0xff);
989 Bprint(bout, "%3c", (int)res->ival);
992 Bprint(bout, "%C", (int)res->ival);
995 memset(buf, '0', 34);
997 for(i = 0; i < 32; i++) {
998 if(res->ival & (1<<i))
1002 Bprint(bout, "%s", buf);
1005 Bprint(bout, "%.2x", (int)res->ival&0xff);
1008 Bprint(bout, "%.8lux", (ulong)res->ival);
1011 Bprint(bout, "%.4lux", (ulong)res->ival&0xffff);
1014 Bprint(bout, "%d", (int)res->ival);
1017 Bprint(bout, "%hd", (short)res->ival);
1020 Bprint(bout, "%hud", (ushort)res->ival);
1023 Bprint(bout, "%lud", (ulong)res->ival);
1026 Bprint(bout, "%llud", res->ival);
1029 Bprint(bout, "%lld", res->ival);
1032 Bprint(bout, "%.8llux", res->ival);
1035 Bprint(bout, "%.16llux", res->ival);
1038 Bprint(bout, "0%.11uo", (int)res->ival&0xffff);
1041 Bprint(bout, "0%.6uo", (int)res->ival);
1044 Bprint(bout, "0%.11o", (short)(res->ival&0xffff));
1047 Bprint(bout, "0%.6o", (int)res->ival);
1054 Bprint(bout, "*%c<%s>*", res->fmt, typenames[type]);
1056 Bprint(bout, "%g", res->fval);
1062 Bprint(bout, "*%c<%s>*", res->fmt, typenames[type]);
1064 Bwrite(bout, res->string->string, res->string->len);
1068 Bprint(bout, "*%c<%s>*", res->fmt, typenames[type]);
1070 Bprint(bout, "%S", (Rune*)res->string->string);
1073 symoff(buf, sizeof(buf), res->ival, CANY);
1074 Bprint(bout, "%s", buf);
1079 Bprint(bout, "*%c<%s>*", res->fmt, typenames[type]);
1081 if (symmap == nil || (*machdata->das)(symmap, res->ival, res->fmt, buf, sizeof(buf)) < 0)
1082 Bprint(bout, "no instruction");
1084 Bprint(bout, "%s", buf);
1097 patom(l->type, &l->Store);
1101 patom(l->type, &l->Store);
1124 if(res.fmt != 'a' || res.comt == 0 || res.comt->base == 0)
1127 sl = res.comt->base;
1131 n = an(ONAME, ZN, ZN);
1133 n = an(OCALL, n, &res);
1138 print("(%s)", sl->name);
1143 bprint(Node *r, Node *args)
1146 Node res, *av[Maxarg];
1152 for(i = 0; i < nas; i++) {
1158 patom(res.type, &res.Store);
1173 printto(Node *r, Node *args)
1178 Node res, *av[Maxarg];
1186 if(res.type != TSTRING)
1187 error("printto(string, ...): need string");
1189 fd = create(res.string->string, OWRITE, 0666);
1191 fd = open(res.string->string, OWRITE);
1193 error("printto: open %s: %r", res.string->string);
1195 b = gmalloc(sizeof(Biobuf));
1196 Binit(b, fd, OWRITE);
1202 for(i = 1; i < nas; i++) {
1208 patom(res.type, &res.Store);
1225 pcfile(Node *r, Node *args)
1231 error("pcfile(addr): arg count");
1233 if(res.type != TINT)
1234 error("pcfile(addr): arg type");
1238 if(fileline(buf, sizeof(buf), res.ival) == 0) {
1239 r->string = strnode("?file?");
1242 p = strrchr(buf, ':');
1244 error("pcfile(addr): funny file %s", buf);
1246 r->string = strnode(buf);
1250 pcline(Node *r, Node *args)
1256 error("pcline(addr): arg count");
1258 if(res.type != TINT)
1259 error("pcline(addr): arg type");
1263 if(fileline(buf, sizeof(buf), res.ival) == 0) {
1268 p = strrchr(buf, ':');
1270 error("pcline(addr): funny file %s", buf);
1271 r->ival = strtol(p+1, 0, 0);
1274 void fmtof(Node *r, Node *args)
1282 error("fmtof(obj): no argument");
1284 error("fmtof(obj): too many arguments") ;
1293 void dofmtsize(Node *r, Node *args)
1303 error("fmtsize(obj): no argument");
1305 error("fmtsize(obj): too many arguments") ;
1314 r->ival = fmtsize(&v) ;