#include #include #include #include #include "stdio-util.h" typedef struct apriv APRIV; struct apriv { char *s; int l; char **sp; int *lp; } ; static int accum_w(void *pv, const char *buf, int len) { APRIV *p; p = pv; if (p->sp) { p->s = realloc(p->s,p->l+len); bcopy(buf,p->s+p->l,len); } p->l += len; return(len); } static int accum_c(void *pv) { APRIV *p; p = pv; if (p->sp) *p->sp = p->s; if (p->lp) *p->lp = p->l; free(p); return(0); } FILE *open_accum(char **sp, int *lp) { APRIV *p; FILE *f; p = malloc(sizeof(APRIV)); if (! p) return(0); f = funopen(p,0,&accum_w,0,&accum_c); if (! f) { free(p); return(0); } p->s = 0; p->l = 0; p->sp = sp; p->lp = lp; return(f); } typedef struct srpriv SRPRIV; struct srpriv { int nbuf; const char **bufs; int *lens; int bn; int o; } ; const char open_strings_r_end; static int osr_r(void *pv, char *buf, int len0) { SRPRIV *p; int left; int n; int bn; int l; int o; p = pv; left = len0; bn = p->bn; o = p->o; while (1) { if (left < 1) break; if (bn >= p->nbuf) break; l = p->lens[bn]; n = l - o; if (n > left) n = left; bcopy(p->bufs[bn]+o,buf,n); left -= n; buf += n; o += n; if (o >= p->lens[bn]) { bn ++; o = 0; } } p->bn = bn; p->o = o; return(len0-left); } static int osr_c(void *pv) { SRPRIV *p; p = pv; free(p->bufs); free(p->lens); free(p); return(0); } FILE *open_strings_r(const char *buf0, ...) { va_list ap; const char *buf; int i; int l; SRPRIV *p; FILE *f; va_start(ap,buf0); i = 0; buf = buf0; while (1) { if (buf == OSR_END) break; if (va_arg(ap,int)) i ++; buf = va_arg(ap,const char *); } p = malloc(sizeof(SRPRIV)); if (! p) return(0); p->nbuf = i; p->bufs = malloc(i*sizeof(const char *)); if (! p->bufs) { free(p); return(0); } p->lens = malloc(i*sizeof(int)); if (! p->lens) { free(p->bufs); free(p); return(0); } f = funopen(p,&osr_r,0,0,&osr_c); if (! f) { free(p->lens); free(p->bufs); free(p); return(0); } buf = buf0; i = 0; while (1) { if (buf == OSR_END) break; p->bufs[i] = buf; l = va_arg(ap,int); if (l == OSR_STRLEN) l = strlen(buf); if (l) { p->lens[i] = l; i ++; } buf = va_arg(ap,const char *); } if (i > p->nbuf) abort(); p->nbuf = i; p->bn = 0; p->o = 0; return(f); }