X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~yarrgweb/git?a=blobdiff_plain;ds=sidebyside;f=pctb%2Fcommon.c;h=2c2a085a30e9fdaa7ded64ffa7b10c82f31208ac;hb=60cd4954d1d3c11c46251f68e2d56f24661a6d67;hp=bc1cb8df749cb63ec2ef392300551c37262c6e16;hpb=e2487a42fd29e7a15b92ce1a5855706dba1198dc;p=ypp-sc-tools.web-live.git diff --git a/pctb/common.c b/pctb/common.c index bc1cb8d..2c2a085 100644 --- a/pctb/common.c +++ b/pctb/common.c @@ -42,17 +42,68 @@ void *mrealloc(void *p, size_t sz) { FILE *dbfile; -static const char *path; +static const char *basepath; /* as passed in by caller */ +static pid_t dbzcat; + +int dbfile_gzopen(const char *basepath_spec) { + assert(!dbfile); + + basepath= basepath_spec; + //uncomppath= masprintf("%s (uncompressed)", basepath); + + char *zpath= masprintf("%s.gz", basepath); + int zfd= open(zpath, O_RDONLY); + free(zpath); + + if (zfd<0) { sysassert(errno==ENOENT); return 0; } + + int pipefds[2]; + sysassert(! pipe(pipefds) ); + + sysassert( (dbzcat=fork()) != -1 ); + if (!dbzcat) { + sysassert( dup2(zfd,0)==0 ); + sysassert( dup2(pipefds[1],1)==1 ); + sysassert(! close(zfd) ); + sysassert(! close(pipefds[0]) ); + sysassert(! close(pipefds[1]) ); + execlp("zcat","zcat",(char*)0); + sysassert(!"execlp zcat"); + } + sysassert(! close(zfd) ); + sysassert(! close(pipefds[1]) ); + sysassert( dbfile= fdopen(pipefds[0], "r") ); + + return 1; +} int dbfile_open(const char *tpath) { assert(!dbfile); - path= tpath; - dbfile= fopen(path,"r"); - if (dbfile) return 1; - sysassert(errno==ENOENT); - return 0; + + basepath= tpath; + + dbzcat= -1; + dbfile= fopen(tpath,"r"); + if (!dbfile) { sysassert(errno==ENOENT); return 0; } + return 1; } +void dbfile_close(void) { + if (!dbfile) return; + + sysassert(!ferror(dbfile)); + sysassert(!fclose(dbfile)); + + if (dbzcat != -1) { + char *zcatstr= masprintf("zcat %s.gz", basepath); + waitpid_check_exitstatus(dbzcat,zcatstr,1); + free(zcatstr); + dbzcat= -1; + } + + dbfile= 0; +} + #define dbassertgl(x) ((x) ? (void)0 : dbfile_assertfail(file,line,#x)) void dbfile_getsline(char *lbuf, size_t lbufsz, const char *file, int line) { @@ -66,13 +117,6 @@ void dbfile_getsline(char *lbuf, size_t lbufsz, const char *file, int line) { lbuf[l]= 0; } -void dbfile_close(void) { - if (!dbfile) return; - sysassert(!ferror(dbfile)); - sysassert(!fclose(dbfile)); - dbfile= 0; -} - int dbfile_vscanf(const char *fmt, va_list al) { int r= vfscanf(dbfile,fmt,al); sysassert(!ferror(dbfile)); @@ -88,11 +132,16 @@ int dbfile_scanf(const char *fmt, ...) { } void dbfile_assertfail(const char *file, int line, const char *m) { - if (dbfile) + if (dbzcat) + fatal("Error in dictionary file %s.gz:\n" + " Requirement not met at %s:%d:\n" + " %s", + basepath, file,line, m); + else if (dbfile) fatal("Error in dictionary file %s at byte %ld:\n" " Requirement not met at %s:%d:\n" " %s", - path,(long)ftell(dbfile), file,line, m); + basepath,(long)ftell(dbfile), file,line, m); else fatal("Semantic error in dictionaries:\n" " Requirement not met at %s:%d:\n"