#include #include #include #include extern const char *__progname; #include "istack.h" #include "directive.h" typedef struct istack ISTACK; struct istack { ISTACK *link; IRDR *rdr; void *priv; int flags; #define ISF_ENDED 0x00000001 } ; static ISTACK *istack; void istack_init(void) { istack = 0; } void istack_push(IRDR *r, ...) { ISTACK *i; VALIST v; i = malloc(sizeof(ISTACK)); i->link = istack; istack = i; i->rdr = r; i->flags = 0; va_start(v.ap,r); (*r->init)(&i->priv,&v); } static void istack_pop(void) { ISTACK *t; (*istack->rdr->close)(istack->priv); t = istack; istack = t->link; free(t); } void istack_read(void) { TOKEN dt; int d; while (istack) { if (istack->flags & ISF_ENDED) { istack_pop(); continue; } (*istack->rdr->token)(istack->priv,&dt); switch (dt.type) { default: abort(); break; case TT_EOF: istack_pop(); continue; break; case TT_SEP: break; case TT_STR: d = lookup_directive(dt.str); if (d == DIR_NONE) { (*istack->rdr->baddir)(istack->priv,dt.str); } else { dir_process(d,istack->rdr->token,istack->priv); } break; } } } void istack_end(void) { istack->flags |= ISF_ENDED; } void istack_err(const char *fmt, ...) { va_list ap; ISTACK *i; va_start(ap,fmt); fprintf(stderr,"%s: ",__progname); vfprintf(stderr,fmt,ap); fprintf(stderr,"\n"); va_end(ap); for (i=istack;i;i=i->link) (*i->rdr->err)(i->priv,stderr); } typedef struct ies IES; struct ies { char *buf; int len; } ; static int ies_w(void *iesv, const char *data, int len) { IES *i; i = iesv; i->buf = realloc(i->buf,i->len+len); bcopy(data,i->buf+i->len,len); i->len += len; return(len); } static int ies_c(void *iesv) { IES *ies; ISTACK *i; ies = iesv; fwrite(ies->buf,1,ies->len,stderr); fprintf(stderr,"\n"); free(ies->buf); free(ies); for (i=istack;i;i=i->link) (*i->rdr->err)(i->priv,stderr); return(0); } FILE *istack_err_open(void) { FILE *f; IES *ies; ies = malloc(sizeof(IES)); ies->buf = 0; ies->len = 0; f = funopen(ies,0,&ies_w,0,&ies_c); if (! f) free(ies); fprintf(f,"%s: ",__progname); return(f); }