📄 builtin.c
字号:
s = strnodlen(0, n); Bread(bp, s->string, n); } else s = strnodlen(p, n-1); new = al(TSTRING); new->string = s; new->fmt = 's'; *l = new; l = &new->next; } Bterm(bp);}voidcvtatof(Node *r, Node *args){ Node res; if(args == 0) error("atof(string): arg count"); expr(args, &res); if(res.type != TSTRING) error("atof(string): arg type"); r->op = OCONST; r->type = TFLOAT; r->fval = atof(res.string->string); r->fmt = 'f';}voidcvtatoi(Node *r, Node *args){ Node res; if(args == 0) error("atoi(string): arg count"); expr(args, &res); if(res.type != TSTRING) error("atoi(string): arg type"); r->op = OCONST; r->type = TINT; r->ival = strtoull(res.string->string, 0, 0); r->fmt = 'V';}static char *fmtflags = "-0123456789. #,u";static char *fmtverbs = "bdox";static intacidfmt(char *fmt, char *buf, int blen){ char *r, *w, *e; w = buf; e = buf+blen; for(r=fmt; *r; r++){ if(w >= e) return -1; if(*r != '%'){ *w++ = *r; continue; } if(*r == '%'){ *w++ = *r++; if(*r == '%'){ if(w >= e) return -1; *w++ = *r; continue; } while(*r && strchr(fmtflags, *r)){ if(w >= e) return -1; *w++ = *r++; } if(*r == 0 || strchr(fmtverbs, *r) == nil) return -1; if(w+3 > e) return -1; *w++ = 'l'; *w++ = 'l'; *w++ = *r; } } if(w >= e) return -1; *w = 0; return 0;}voidcvtitoa(Node *r, Node *args){ Node res; Node *av[Maxarg]; vlong ival; char buf[128], fmt[32]; if(args == 0)err: error("itoa(number [, fmt]): arg count"); na = 0; flatten(av, args); if(na == 0 || na > 2) goto err; expr(av[0], &res); if(res.type != TINT) error("itoa(number [, fmt]): arg type"); ival = res.ival; strncpy(fmt, "%lld", sizeof(fmt)); if(na == 2){ expr(av[1], &res); if(res.type != TSTRING) error("itoa(number [, fmt]): fmt type"); if(acidfmt(res.string->string, fmt, sizeof(buf))) error("itoa(number [, fmt]): malformed fmt"); } snprint(buf, sizeof(buf), fmt, ival); r->op = OCONST; r->type = TSTRING; r->string = strnode(buf); r->fmt = 's';}List*mapent(Map *m){ int i; List *l, *n, **t, *h; h = 0; t = &h; for(i = 0; i < m->nsegs; i++) { if(m->seg[i].inuse == 0) continue; l = al(TSTRING); n = al(TLIST); n->l = l; *t = n; t = &n->next; l->string = strnode(m->seg[i].name); l->fmt = 's'; l->next = al(TINT); l = l->next; l->ival = m->seg[i].b; l->fmt = 'W'; l->next = al(TINT); l = l->next; l->ival = m->seg[i].e; l->fmt = 'W'; l->next = al(TINT); l = l->next; l->ival = m->seg[i].f; l->fmt = 'W'; } return h;}voidmap(Node *r, Node *args){ int i; Map *m; List *l; char *ent; Node *av[Maxarg], res; na = 0; flatten(av, args); if(na != 0) { expr(av[0], &res); if(res.type != TLIST) error("map(list): map needs a list"); if(listlen(res.l) != 4) error("map(list): list must have 4 entries"); l = res.l; if(l->type != TSTRING) error("map name must be a string"); ent = l->string->string; m = symmap; i = findseg(m, ent); if(i < 0) { m = cormap; i = findseg(m, ent); } if(i < 0) error("%s is not a map entry", ent); l = l->next; if(l->type != TINT) error("map entry not int"); m->seg[i].b = l->ival; if (strcmp(ent, "text") == 0) textseg(l->ival, &fhdr); l = l->next; if(l->type != TINT) error("map entry not int"); m->seg[i].e = l->ival; l = l->next; if(l->type != TINT) error("map entry not int"); m->seg[i].f = l->ival; } r->type = TLIST; r->l = 0; if(symmap) r->l = mapent(symmap); if(cormap) { if(r->l == 0) r->l = mapent(cormap); else { for(l = r->l; l->next; l = l->next) ; l->next = mapent(cormap); } }}void flatten(Node **av, Node *n){ if(n == 0) return; switch(n->op) { case OLIST: flatten(av, n->left); flatten(av, n->right); break; default: av[na++] = n; if(na >= Maxarg) error("too many function arguments"); break; }}voidstrace(Node *r, Node *args){ Node *av[Maxarg], *n, res; uvlong pc, sp; na = 0; flatten(av, args); if(na != 3) error("strace(pc, sp, link): arg count"); n = av[0]; expr(n, &res); if(res.type != TINT) error("strace(pc, sp, link): pc bad type"); pc = res.ival; n = av[1]; expr(n, &res); if(res.type != TINT) error("strace(pc, sp, link): sp bad type"); sp = res.ival; n = av[2]; expr(n, &res); if(res.type != TINT) error("strace(pc, sp, link): link bad type"); tracelist = 0; if ((*machdata->ctrace)(cormap, pc, sp, res.ival, trlist) <= 0) error("no stack frame: %r"); r->type = TLIST; r->l = tracelist;}voidregerror(char *msg){ error(msg);}voidregexp(Node *r, Node *args){ Node res; Reprog *rp; Node *av[Maxarg]; na = 0; flatten(av, args); if(na != 2) error("regexp(pattern, string): arg count"); expr(av[0], &res); if(res.type != TSTRING) error("regexp(pattern, string): pattern must be string"); rp = regcomp(res.string->string); if(rp == 0) return; expr(av[1], &res); if(res.type != TSTRING) error("regexp(pattern, string): bad string"); r->fmt = 'D'; r->type = TINT; r->ival = regexec(rp, res.string->string, 0, 0); free(rp);}voidfmt(Node *r, Node *args){ Node res; Node *av[Maxarg]; na = 0; flatten(av, args); if(na != 2) error("fmt(obj, fmt): arg count"); expr(av[1], &res); if(res.type != TINT || strchr(vfmt, res.ival) == 0) error("fmt(obj, fmt): bad format '%c'", (char)res.ival); expr(av[0], r); r->fmt = res.ival;}voidpatom(char type, Store *res){ int i; char buf[512]; extern char *typenames[]; switch(res->fmt) { case 'c': Bprint(bout, "%c", (int)res->ival); break; case 'C': if(res->ival < ' ' || res->ival >= 0x7f) Bprint(bout, "%3d", (int)res->ival&0xff); else Bprint(bout, "%3c", (int)res->ival); break; case 'r': Bprint(bout, "%C", (int)res->ival); break; case 'B': memset(buf, '0', 34); buf[1] = 'b'; for(i = 0; i < 32; i++) { if(res->ival & (1<<i)) buf[33-i] = '1'; } buf[35] = '\0'; Bprint(bout, "%s", buf); break; case 'b': Bprint(bout, "%.2x", (int)res->ival&0xff); break; case 'X': Bprint(bout, "%.8lux", (ulong)res->ival); break; case 'x': Bprint(bout, "%.4lux", (ulong)res->ival&0xffff); break; case 'D': Bprint(bout, "%d", (int)res->ival); break; case 'd': Bprint(bout, "%d", (ushort)res->ival); break; case 'u': Bprint(bout, "%d", (int)res->ival&0xffff); break; case 'U': Bprint(bout, "%lud", (ulong)res->ival); break; case 'Z': Bprint(bout, "%llud", res->ival); break; case 'V': Bprint(bout, "%lld", res->ival); break; case 'W': Bprint(bout, "%.8llux", res->ival); break; case 'Y': Bprint(bout, "%.16llux", res->ival); break; case 'o': Bprint(bout, "0%.11uo", (int)res->ival&0xffff); break; case 'O': Bprint(bout, "0%.6uo", (int)res->ival); break; case 'q': Bprint(bout, "0%.11o", (short)(res->ival&0xffff)); break; case 'Q': Bprint(bout, "0%.6o", (int)res->ival); break; case 'f': case 'F': if(type != TFLOAT) Bprint(bout, "*%c<%s>*", res->fmt, typenames[type]); else Bprint(bout, "%g", res->fval); break; case 's': case 'g': case 'G': if(type != TSTRING) Bprint(bout, "*%c<%s>*", res->fmt, typenames[type]); else Bwrite(bout, res->string->string, res->string->len); break; case 'R': if(type != TSTRING) Bprint(bout, "*%c<%s>*", res->fmt, typenames[type]); else Bprint(bout, "%S", (Rune*)res->string->string); break; case 'a': case 'A': symoff(buf, sizeof(buf), res->ival, CANY); Bprint(bout, "%s", buf); break; case 'I': case 'i': if(type != TINT) Bprint(bout, "*%c<%s>*", res->fmt, typenames[type]); else { if (symmap == nil || (*machdata->das)(symmap, res->ival, res->fmt, buf, sizeof(buf)) < 0) Bprint(bout, "no instruction"); else Bprint(bout, "%s", buf); } break; }}voidblprint(List *l){ Bprint(bout, "{"); while(l) { switch(l->type) { default: patom(l->type, &l->Store); break; case TSTRING: Bputc(bout, '"'); patom(l->type, &l->Store); Bputc(bout, '"'); break; case TLIST: blprint(l->l); break; case TCODE: pcode(l->cc, 0); break; } l = l->next; if(l) Bprint(bout, ", "); } Bprint(bout, "}");}intcomx(Node res){ Lsym *sl; Node *n, xx; if(res.fmt != 'a' && res.fmt != 'A') return 0; if(res.comt == 0 || res.comt->base == 0) return 0; sl = res.comt->base; if(sl->proc) { res.left = ZN; res.right = ZN; n = an(ONAME, ZN, ZN); n->sym = sl; n = an(OCALL, n, &res); n->left->sym = sl; expr(n, &xx); return 1; } print("(%s)", sl->name); return 0;}voidbprint(Node *r, Node *args){ int i, nas; Node res, *av[Maxarg]; USED(r); na = 0; flatten(av, args); nas = na; for(i = 0; i < nas; i++) { expr(av[i], &res); switch(res.type) { default: if(comx(res)) break; patom(res.type, &res.Store); break; case TCODE: pcode(res.cc, 0); break; case TLIST: blprint(res.l); break; } } if(ret == 0) Bputc(bout, '\n');}voidprintto(Node *r, Node *args){ int fd; Biobuf *b; int i, nas; Node res, *av[Maxarg]; USED(r); na = 0; flatten(av, args); nas = na; expr(av[0], &res); if(res.type != TSTRING) error("printto(string, ...): need string"); fd = create(res.string->string, OWRITE, 0666); if(fd < 0) fd = open(res.string->string, OWRITE); if(fd < 0) error("printto: open %s: %r", res.string->string); b = gmalloc(sizeof(Biobuf)); Binit(b, fd, OWRITE); Bflush(bout); io[iop++] = bout; bout = b; for(i = 1; i < nas; i++) { expr(av[i], &res); switch(res.type) { default: if(comx(res)) break; patom(res.type, &res.Store); break; case TLIST: blprint(res.l); break; } } if(ret == 0) Bputc(bout, '\n'); Bterm(b); close(fd); free(b); bout = io[--iop];}voidpcfile(Node *r, Node *args){ Node res; char *p, buf[128]; if(args == 0) error("pcfile(addr): arg count"); expr(args, &res); if(res.type != TINT) error("pcfile(addr): arg type"); r->type = TSTRING; r->fmt = 's'; if(fileline(buf, sizeof(buf), res.ival) == 0) { r->string = strnode("?file?"); return; } p = strrchr(buf, ':'); if(p == 0) error("pcfile(addr): funny file %s", buf); *p = '\0'; r->string = strnode(buf); }voidpcline(Node *r, Node *args){ Node res; char *p, buf[128]; if(args == 0) error("pcline(addr): arg count"); expr(args, &res); if(res.type != TINT) error("pcline(addr): arg type"); r->type = TINT; r->fmt = 'D'; if(fileline(buf, sizeof(buf), res.ival) == 0) { r->ival = 0; return; } p = strrchr(buf, ':'); if(p == 0) error("pcline(addr): funny file %s", buf); r->ival = strtol(p+1, 0, 0); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -