#include #include #include #include #include "stdio-util.h" /* * fwrap_tee */ typedef struct tee_priv TEE_PRIV; struct tee_priv { FILE **fv; int nf; } ; static int tee_w(void *pv, const char *data, int len) { TEE_PRIV *p; int i; p = pv; for (i=p->nf-1;i>=0;i--) fwrite(data,1,len,p->fv[i]); return(len); } static int tee_c(void *pv) { TEE_PRIV *p; p = pv; free(p->fv); free(p); return(0); } FILE *fwrap_tee(FILE *arg0, ...) { va_list ap; FILE *rv; TEE_PRIV *p; int nsub; FILE *arg; int i; p = malloc(sizeof(TEE_PRIV)); if (! p) return(0); nsub = 0; va_start(ap,arg0); arg = arg0; while (arg) { nsub ++; arg = va_arg(ap,FILE *); } va_end(ap); p->fv = malloc(nsub*sizeof(FILE *)); if (! p->fv) { free(p); return(0); } rv = funopen(p,0,&tee_w,0,&tee_c); if (! rv) { free(p->fv); free(p); return(0); } i = 0; va_start(ap,arg0); arg = arg0; while (arg) { p->fv[i++] = arg; arg = va_arg(ap,FILE *); } va_end(ap); p->nf = nsub; return(rv); } /* * fwrap_lno */ typedef struct lno_priv LNO_PRIV; struct lno_priv { FILE *inner; int atbol; unsigned long long int lno; int closeinner; } ; static int lno_w(void *pv, const char *data, int len) { LNO_PRIV *p; void *nl; int o; p = pv; o = 0; while (o < len) { if (p->atbol) { fprintf(p->inner,"%llu: ",p->lno++); p->atbol = 0; } nl = memchr(data+o,'\n',len-o); if (nl) { fwrite(data+o,1,1+((const char *)nl)-(data+o),p->inner); o = (((char *)nl)+1) - data; p->atbol = 1; } else { fwrite(data+o,1,len-o,p->inner); p->atbol = 0; break; } } return(len); } static int lno_c(void *pv) { LNO_PRIV *p; p = pv; if (p->closeinner) fclose(p->inner); free(pv); return(0); } FILE *fwrap_lno(FILE *inner, unsigned long long int flno, unsigned int flags) { FILE *rv; LNO_PRIV *p; p = malloc(sizeof(LNO_PRIV)); if (! p) return(0); rv = funopen(p,0,&lno_w,0,&lno_c); if (! rv) { free(p); return(0); } p->inner = inner; p->atbol = 1; p->lno = flno; p->closeinner = (flags & FWLF_CLOSE) ? 1 : 0; return(rv); } /* * fwrap_prefix */ typedef struct pfx_priv PFX_PRIV; struct pfx_priv { FILE *inner; int atbol; const char *pref; int preflen; int closeinner; } ; static int pfx_w(void *pv, const char *data, int len) { PFX_PRIV *p; void *nl; int o; p = pv; o = 0; while (o < len) { if (p->atbol) { fwrite(p->pref,1,p->preflen,p->inner); p->atbol = 0; } nl = memchr(data+o,'\n',len-o); if (nl) { fwrite(data+o,1,1+((const char *)nl)-(data+o),p->inner); o = (((char *)nl)+1) - data; p->atbol = 1; } else { fwrite(data+o,1,len-o,p->inner); p->atbol = 0; break; } } return(len); } static int pfx_c(void *pv) { PFX_PRIV *p; p = pv; if (p->closeinner) fclose(p->inner); free(p); return(0); } FILE *fwrap_prefix(FILE *inner, const char *pfx, unsigned int flags) { FILE *rv; PFX_PRIV *p; p = malloc(sizeof(PFX_PRIV)); if (! p) return(0); rv = funopen(p,0,&pfx_w,0,&pfx_c); if (! rv) { free(p); return(0); } p->inner = inner; p->atbol = 1; p->pref = pfx; p->preflen = strlen(pfx); p->closeinner = (flags & FWPF_CLOSE) ? 1 : 0; return(rv); }