From c42a1d3d6168df56f966ea1f3ba3ef39ebbff4e4 Mon Sep 17 00:00:00 2001 From: rsc Date: Tue, 21 Feb 2006 18:37:05 +0000 Subject: add --- src/cmd/htmlroff/input.c | 241 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 241 insertions(+) create mode 100644 src/cmd/htmlroff/input.c (limited to 'src/cmd/htmlroff/input.c') diff --git a/src/cmd/htmlroff/input.c b/src/cmd/htmlroff/input.c new file mode 100644 index 00000000..99e0d56e --- /dev/null +++ b/src/cmd/htmlroff/input.c @@ -0,0 +1,241 @@ +/* + * Read input files. + */ +#include "a.h" + +typedef struct Istack Istack; +struct Istack +{ + Rune unget[3]; + int nunget; + Biobuf *b; + Rune *p; + Rune *ep; + Rune *s; + int lineno; + Rune *name; + Istack *next; + void (*fn)(void); +}; + +Istack *istack; +Istack *ibottom; + +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); +} + +static void +ipush(Istack *is) +{ + if(istack == nil) + ibottom = is; + else + is->next = istack; + istack = is; + setname(); +} + +static void +iqueue(Istack *is) +{ + if(ibottom == nil){ + istack = is; + setname(); + }else + ibottom->next = is; + ibottom = is; +} + +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; +} + +int +pushinputfile(Rune *s) +{ + return _inputfile(s, ipush); +} + +int +queueinputfile(Rune *s) +{ + return _inputfile(s, iqueue); +} + +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; +} + +int +pushstdin(void) +{ + return _inputstdin(ipush); +} + +int +queuestdin(void) +{ + return _inputstdin(iqueue); +} + +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 +pushinputstring(Rune *s) +{ + _inputstring(s, ipush); +} + + +void +inputnotify(void (*fn)(void)) +{ + if(istack) + istack->fn = fn; +} + +int +popinput(void) +{ + Istack *is; + + is = istack; + if(is == nil) + return 0; + + istack = istack->next; + if(is->b) + Bterm(is->b); + free(is->s); + free(is->name); + if(is->fn) + is->fn(); + free(is); + setname(); + return 1; +} + +int +getrune(void) +{ + Rune r; + int c; + +top: + if(istack == nil) + return -1; + if(istack->nunget) + return istack->unget[--istack->nunget]; + else if(istack->p){ + if(istack->p >= istack->ep){ + popinput(); + goto top; + } + r = *istack->p++; + }else if(istack->b){ + if((c = Bgetrune(istack->b)) < 0){ + popinput(); + goto top; + } + r = c; + }else{ + r = 0; + sysfatal("getrune - can't happen"); + } + if(r == '\n') + istack->lineno++; + return r; +} + +void +ungetrune(Rune r) +{ + if(istack == nil || istack->nunget >= nelem(istack->unget)) + pushinputstring(L("")); + istack->unget[istack->nunget++] = r; +} + +int +linefmt(Fmt *f) +{ + Istack *is; + + for(is=istack; is && !is->b; is=is->next) + ; + if(is) + return fmtprint(f, "%S:%d", is->name, is->lineno); + else + return fmtprint(f, ""); +} + +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; + } +} -- cgit v1.2.3