int runmacro(int dot, int argc, Rune **argv) { Rune *p; int i; Mac *m; if(verbose && isupperrune(argv[0][0])) fprint(2, "run: %S\n", argv[0]); p = getds(argv[0]); if(p == nil){ if(verbose) warn("ignoring unknown request %C%S", dot, argv[0]); if(verbose > 1){ for(i=0; i<argc; i++) fprint(2, " %S", argv[i]); fprint(2, "\n"); } return -1; } if(nmstack >= nelem(mstack)){ fprint(2, "%L: macro stack overflow:"); for(i=0; i<nmstack; i++) fprint(2, " %S", mstack[i].argv[0]); fprint(2, "\n"); return -1; } m = &mstack[nmstack++]; m->argc = argc; for(i=0; i<argc; i++) m->argv[i] = erunestrdup(argv[i]); pushinputstring(p); nr(L(".$"), argc-1); inputnotify(popmacro); return 0; }
/* .wh - install trap */ void r_wh(int argc, Rune **argv) { int i; if(argc < 2) return; i = eval(argv[1]); if(argc == 2){ if(i == 0){ free(trap0); trap0 = nil; }else if(verbose) warn("not removing trap at %d", i); } if(argc > 2){ if(i == 0){ free(trap0); trap0 = erunestrdup(argv[2]); }else if(verbose) warn("not installing %S trap at %d", argv[2], i); } }
/* * Read the current line in given mode. Newline not kept. * Uses different buffer from copyarg! */ Rune* readline(int m) { static Rune buf[MaxLine]; Rune *r; if(_readx(buf, sizeof buf, m, 1) < 0) return nil; r = erunestrdup(buf); return r; }
void _inputstring(Rune *s, void (*push)(Istack*)) { Istack *is; is = emalloc(sizeof *is); is->s = erunestrdup(s); is->p = is->s; is->ep = is->p+runestrlen(is->p); push(is); }
void r_it(int argc, Rune **argv) { if(argc < 3){ itrapcount = 0; return; } itrapcount = eval(argv[1]); free(itrapname); itrapname = erunestrdup(argv[2]); }
void renraw(Rune *from, Rune *to) { int i; delraw(to); for(i=0; i<nraw; i++) if(runestrcmp(raw[i].name, from) == 0){ free(raw[i].name); raw[i].name = erunestrdup(to); return; } }
void addraw(Rune *name, void (*f)(Rune*)) { Raw *r; if(nraw >= nelem(raw)){ fprint(2, "too many raw requets\n"); return; } r = &raw[nraw++]; r->name = erunestrdup(name); r->f = f; }
/* this is a HACK */ Rune* urlcombine(Rune *b, Rune *u) { Rune *p, *q, *sep, *s; Rune endrune[] = { L'?', L'#' }; int i, restore; if(u == nil) error("urlcombine: u == nil"); if(validurl(u)) return erunestrdup(u); if(b==nil || !validurl(b)) error("urlcombine: b==nil || !validurl(b)"); if(runestrncmp(u, L"//", 2) == 0){ q = runestrchr(b, L':'); return runesmprint("%.*S:%S", (int)(q-b), b, u); } p = runestrstr(b, L"://"); if(p != nil) p += 3; sep = L""; q = nil; if(*u ==L'/') q = runestrchr(p, L'/'); else if(*u==L'#' || *u==L'?'){ for(i=0; i<nelem(endrune); i++) if(q = runestrchr(p, endrune[i])) break; }else if(p != nil){ sep = L"/"; restore = 0; s = runestrchr(p, L'?'); if(s != nil){ *s = '\0'; restore = 1; } q = runestrrchr(p, L'/'); if(restore) *s = L'?'; }else sep = L"/"; if(q == nil) p = runesmprint("%S%S%S", b, sep, u); else p = runesmprint("%.*S%S%S", (int)(q-b), b, sep, u); urlcanon(p); return p; }
void addreq(Rune *s, void (*f)(int, Rune**), int argc) { Req *r; if(nreq >= nelem(req)){ fprint(2, "too many requests\n"); return; } r = &req[nreq++]; r->name = erunestrdup(s); r->f = f; r->argc = argc; }
static void setname(void) { Rune *r, *p; if(istack == nil || istack->name == nil) return; _nr(L(".F"), istack->name); r = erunestrdup(istack->name); p = runestrchr(r, '.'); if(p) *p = 0; _nr(L(".B"), r); free(r); }
void setlinenumber(Rune *s, int n) { Istack *is; for(is=istack; is && !is->name; is=is->next) ; if(is){ if(s){ free(is->name); is->name = erunestrdup(s); } is->lineno = n; } }
int _inputstdin(void (*push)(Istack*)) { Biobuf *b; Istack *is; if((b = Bopen("/dev/null", OREAD)) == nil){ fprint(2, "%s: open /dev/null: %r\n", argv0); return -1; } dup(0, b->fid); is = emalloc(sizeof *is); is->b = b; is->name = erunestrdup(L("stdin")); is->lineno = 1; push(is); return 0; }
/* * Get the next argument from the current line. */ Rune* copyarg(void) { static Rune buf[MaxLine]; int c; Rune *r; if(_readx(buf, sizeof buf, ArgMode, 0) < 0) return nil; r = runestrstr(buf, L("\\\"")); if(r){ *r = 0; while((c = getrune()) >= 0 && c != '\n') ; ungetrune('\n'); } r = erunestrdup(buf); return r; }
int _inputfile(Rune *s, void (*push)(Istack*)) { Istack *is; Biobuf *b; char *t; t = esmprint("%S", s); if((b = Bopen(t, OREAD)) == nil){ free(t); fprint(2, "%s: open %S: %r\n", argv0, s); return -1; } free(t); is = emalloc(sizeof *is); is->b = b; is->name = erunestrdup(s); is->lineno = 1; push(is); return 0; }
void r_ch(int argc, Rune **argv) { int i; if(argc == 2){ if(trap0 && runestrcmp(argv[1], trap0) == 0){ free(trap0); trap0 = nil; }else if(verbose) warn("not removing %S trap", argv[1]); return; } if(argc >= 3){ i = eval(argv[2]); if(i == 0){ free(trap0); trap0 = erunestrdup(argv[1]); }else if(verbose) warn("not moving %S trap to %d", argv[1], i); } }
static void pageloadproc(void *v) { Page *p; char buf[BUFSIZE], *s; int32_t n, l; int fd, i, ctype; threadsetname("pageloadproc"); rfork(RFFDG); p = v; addrefresh(p, "opening: %S...", p->url->src.r); fd = urlopen(p->url); if(fd < 0){ addrefresh(p, "%S: %r", p->url->src.r); Err: p->loading = FALSE; return; } if(runestrlen(p->url->ctype.r) == 0) /* assume .html when headers don't say anyting */ goto Html; snprint(buf, sizeof(buf), "%S", p->url->ctype.r); for(i=0; mimetab[i]!=nil; i++) if(cistrncmp(buf, mimetab[i], strlen(mimetab[i])) == 0) break; if(mimetab[i]){ Html: ctype = TextHtml; }else if(cistrncmp(buf, "text/", 5) == 0) ctype = TextPlain; else{ close(fd); addrefresh(p, "%S: unsupported mime type: '%S'", p->url->act.r, p->url->ctype.r); goto Err; } addrefresh(p, "loading: %S...", p->url->src.r); s = nil; l = 0; while((n=read(fd, buf, sizeof(buf))) > 0){ if(p->aborting){ if(s){ free(s); s = nil; } break; } s = erealloc(s, l+n+1); memmove(s+l, buf, n); l += n; s[l] = '\0'; } close(fd); n = l; if(s){ s = convert(p->url->ctype, s, &n); p->items = parsehtml((uint8_t *)s, n, p->url->act.r, ctype, UTF_8, &p->doc); free(s); fixtext(p); if(ctype==TextHtml && p->aborting==FALSE){ p->changed = TRUE; addrefresh(p, ""); if(p->doc->doctitle){ p->title.r = erunestrdup(p->doc->doctitle); p->title.nr = runestrlen(p->title.r); } p->loading = XXX; if(p->doc->kidinfo) loadchilds(p, p->doc->kidinfo); else if(p->doc->images) loadimages(p); } } p->changed = TRUE; p->loading = FALSE; addrefresh(p, ""); }