📄 builtin.c
字号:
#include <u.h>#include <libc.h>#include <bio.h>#include <ctype.h>#include <mach.h>#include <regexp.h>#define Extern extern#include "acid.h"#include "y.tab.h"void cvtatof(Node*, Node*);void cvtatoi(Node*, Node*);void cvtitoa(Node*, Node*);void bprint(Node*, Node*);void funcbound(Node*, Node*);void printto(Node*, Node*);void getfile(Node*, Node*);void fmt(Node*, Node*);void pcfile(Node*, Node*);void pcline(Node*, Node*);void setproc(Node*, Node*);void strace(Node*, Node*);void follow(Node*, Node*);void reason(Node*, Node*);void newproc(Node*, Node*);void startstop(Node*, Node*);void match(Node*, Node*);void status(Node*, Node*);void kill(Node*,Node*);void waitstop(Node*, Node*);void stop(Node*, Node*);void start(Node*, Node*);void filepc(Node*, Node*);void doerror(Node*, Node*);void rc(Node*, Node*);void doaccess(Node*, Node*);void map(Node*, Node*);void readfile(Node*, Node*);void interpret(Node*, Node*);void include(Node*, Node*);void regexp(Node*, Node*);void dosysr1(Node*, Node*);typedef struct Btab Btab;struct Btab{ char *name; void (*fn)(Node*, Node*);} tab[] ={ "atof", cvtatof, "atoi", cvtatoi, "error", doerror, "file", getfile, "readfile", readfile, "access", doaccess, "filepc", filepc, "fnbound", funcbound, "fmt", fmt, "follow", follow, "itoa", cvtitoa, "kill", kill, "match", match, "newproc", newproc, "pcfile", pcfile, "pcline", pcline, "print", bprint, "printto", printto, "rc", rc, "reason", reason, "setproc", setproc, "start", start, "startstop", startstop, "status", status, "stop", stop, "strace", strace, "sysr1", dosysr1, "waitstop", waitstop, "map", map, "interpret", interpret, "include", include, "regexp", regexp, 0};char vfmt[] = "aBbcCdDfFgGiIoOqQrRsSuUVWxXYZ";voidmkprint(Lsym *s){ prnt = malloc(sizeof(Node)); memset(prnt, 0, sizeof(Node)); prnt->op = OCALL; prnt->left = malloc(sizeof(Node)); memset(prnt->left, 0, sizeof(Node)); prnt->left->sym = s;}voidinstallbuiltin(void){ Btab *b; Lsym *s; b = tab; while(b->name) { s = look(b->name); if(s == 0) s = enter(b->name, Tid); s->builtin = b->fn; if(b->fn == bprint) mkprint(s); b++; }}voiddosysr1(Node *r, Node*){ extern int sysr1(void); r->op = OCONST; r->type = TINT; r->fmt = 'D'; r->ival = sysr1();}voidmatch(Node *r, Node *args){ int i; List *f; Node *av[Maxarg]; Node resi, resl; na = 0; flatten(av, args); if(na != 2) error("match(obj, list): arg count"); expr(av[1], &resl); if(resl.type != TLIST) error("match(obj, list): need list"); expr(av[0], &resi); r->op = OCONST; r->type = TINT; r->fmt = 'D'; r->ival = -1; i = 0; for(f = resl.l; f; f = f->next) { if(resi.type == f->type) { switch(resi.type) { case TINT: if(resi.ival == f->ival) { r->ival = i; return; } break; case TFLOAT: if(resi.fval == f->fval) { r->ival = i; return; } break; case TSTRING: if(scmp(resi.string, f->string)) { r->ival = i; return; } break; case TLIST: error("match(obj, list): not defined for list"); } } i++; }}voidnewproc(Node *r, Node *args){ int i; Node res; char *p, *e; char *argv[Maxarg], buf[Strsize]; i = 1; argv[0] = aout; if(args) { expr(args, &res); if(res.type != TSTRING) error("newproc(): arg not string"); if(res.string->len >= sizeof(buf)) error("newproc(): too many arguments"); memmove(buf, res.string->string, res.string->len); buf[res.string->len] = '\0'; p = buf; e = buf+res.string->len; for(;;) { while(p < e && (*p == '\t' || *p == ' ')) *p++ = '\0'; if(p >= e) break; argv[i++] = p; if(i >= Maxarg) error("newproc: too many arguments"); while(p < e && *p != '\t' && *p != ' ') p++; } } argv[i] = 0; r->op = OCONST; r->type = TINT; r->fmt = 'D'; r->ival = nproc(argv);}voidstartstop(Node *r, Node *args){ Node res; USED(r); if(args == 0) error("startstop(pid): no pid"); expr(args, &res); if(res.type != TINT) error("startstop(pid): arg type"); msg(res.ival, "startstop"); notes(res.ival); dostop(res.ival);}voidwaitstop(Node *r, Node *args){ Node res; USED(r); if(args == 0) error("waitstop(pid): no pid"); expr(args, &res); if(res.type != TINT) error("waitstop(pid): arg type"); Bflush(bout); msg(res.ival, "waitstop"); notes(res.ival); dostop(res.ival);}voidstart(Node *r, Node *args){ Node res; USED(r); if(args == 0) error("start(pid): no pid"); expr(args, &res); if(res.type != TINT) error("start(pid): arg type"); msg(res.ival, "start");}voidstop(Node *r, Node *args){ Node res; USED(r); if(args == 0) error("stop(pid): no pid"); expr(args, &res); if(res.type != TINT) error("stop(pid): arg type"); Bflush(bout); msg(res.ival, "stop"); notes(res.ival); dostop(res.ival);}voidkill(Node *r, Node *args){ Node res; USED(r); if(args == 0) error("kill(pid): no pid"); expr(args, &res); if(res.type != TINT) error("kill(pid): arg type"); msg(res.ival, "kill"); deinstall(res.ival);}voidstatus(Node *r, Node *args){ Node res; char *p; USED(r); if(args == 0) error("status(pid): no pid"); expr(args, &res); if(res.type != TINT) error("status(pid): arg type"); p = getstatus(res.ival); r->string = strnode(p); r->op = OCONST; r->fmt = 's'; r->type = TSTRING;}voidreason(Node *r, Node *args){ Node res; if(args == 0) error("reason(cause): no cause"); expr(args, &res); if(res.type != TINT) error("reason(cause): arg type"); r->op = OCONST; r->type = TSTRING; r->fmt = 's'; r->string = strnode((*machdata->excep)(cormap, rget));}voidfollow(Node *r, Node *args){ int n, i; Node res; uvlong f[10]; List **tail, *l; if(args == 0) error("follow(addr): no addr"); expr(args, &res); if(res.type != TINT) error("follow(addr): arg type"); n = (*machdata->foll)(cormap, res.ival, rget, f); if (n < 0) error("follow(addr): %r"); tail = &r->l; for(i = 0; i < n; i++) { l = al(TINT); l->ival = f[i]; l->fmt = 'X'; *tail = l; tail = &l->next; }}voidfuncbound(Node *r, Node *args){ int n; Node res; uvlong bounds[2]; List *l; if(args == 0) error("fnbound(addr): no addr"); expr(args, &res); if(res.type != TINT) error("fnbound(addr): arg type"); n = fnbound(res.ival, bounds); if (n != 0) { r->l = al(TINT); l = r->l; l->ival = bounds[0]; l->fmt = 'X'; l->next = al(TINT); l = l->next; l->ival = bounds[1]; l->fmt = 'X'; }}voidsetproc(Node *r, Node *args){ Node res; USED(r); if(args == 0) error("setproc(pid): no pid"); expr(args, &res); if(res.type != TINT) error("setproc(pid): arg type"); sproc(res.ival);}voidfilepc(Node *r, Node *args){ Node res; char *p, c; if(args == 0) error("filepc(filename:line): arg count"); expr(args, &res); if(res.type != TSTRING) error("filepc(filename:line): arg type"); p = strchr(res.string->string, ':'); if(p == 0) error("filepc(filename:line): bad arg format"); c = *p; *p++ = '\0'; r->ival = file2pc(res.string->string, strtol(p, 0, 0)); p[-1] = c; if(r->ival == ~0) error("filepc(filename:line): can't find address"); r->op = OCONST; r->type = TINT; r->fmt = 'V';}voidinterpret(Node *r, Node *args){ Node res; int isave; if(args == 0) error("interpret(string): arg count"); expr(args, &res); if(res.type != TSTRING) error("interpret(string): arg type"); pushstr(&res); isave = interactive; interactive = 0; r->ival = yyparse(); interactive = isave; popio(); r->op = OCONST; r->type = TINT; r->fmt = 'D';}voidinclude(Node *r, Node *args){ Node res; int isave; if(args == 0) error("include(string): arg count"); expr(args, &res); if(res.type != TSTRING) error("include(string): arg type"); pushfile(res.string->string); isave = interactive; interactive = 0; r->ival = yyparse(); interactive = isave; popio(); r->op = OCONST; r->type = TINT; r->fmt = 'D';}voidrc(Node *r, Node *args){ Node res; int pid; char *p, *q, *argv[4]; Waitmsg *w; USED(r); if(args == 0) error("error(string): arg count"); expr(args, &res); if(res.type != TSTRING) error("error(string): arg type"); argv[0] = "/bin/rc"; argv[1] = "-c"; argv[2] = res.string->string; argv[3] = 0; pid = fork(); switch(pid) { case -1: error("fork %r"); case 0: exec("/bin/rc", argv); exits(0); default: w = waitfor(pid); break; } p = w->msg; q = strrchr(p, ':'); if (q) p = q+1; r->op = OCONST; r->type = TSTRING; r->string = strnode(p); free(w); r->fmt = 's';}voiddoerror(Node *r, Node *args){ Node res; USED(r); if(args == 0) error("error(string): arg count"); expr(args, &res); if(res.type != TSTRING) error("error(string): arg type"); error(res.string->string);}voiddoaccess(Node *r, Node *args){ Node res; if(args == 0) error("access(filename): arg count"); expr(args, &res); if(res.type != TSTRING) error("access(filename): arg type"); r->op = OCONST; r->type = TINT; r->ival = 0; if(access(res.string->string, 4) == 0) r->ival = 1;}voidreadfile(Node *r, Node *args){ Node res; int n, fd; char *buf; Dir *db; if(args == 0) error("readfile(filename): arg count"); expr(args, &res); if(res.type != TSTRING) error("readfile(filename): arg type"); fd = open(res.string->string, OREAD); if(fd < 0) return; db = dirfstat(fd); if(db == nil || db->length == 0) n = 8192; else n = db->length; free(db); buf = malloc(n); n = read(fd, buf, n); if(n > 0) { r->op = OCONST; r->type = TSTRING; r->string = strnodlen(buf, n); r->fmt = 's'; } free(buf); close(fd);}voidgetfile(Node *r, Node *args){ int n; char *p; Node res; String *s; Biobuf *bp; List **l, *new; if(args == 0) error("file(filename): arg count"); expr(args, &res); if(res.type != TSTRING) error("file(filename): arg type"); r->op = OCONST; r->type = TLIST; r->l = 0; p = res.string->string; bp = Bopen(p, OREAD); if(bp == 0) return; l = &r->l; for(;;) { p = Brdline(bp, '\n'); n = Blinelen(bp); if(p == 0) { if(n == 0) break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -