chiark / gitweb /
Compress the screenshots file on output
[ypp-sc-tools.web-live.git] / pctb / common.c
1 /*
2  * Utility functions
3  */
4 /*
5  *  This is part of ypp-sc-tools, a set of third-party tools for assisting
6  *  players of Yohoho Puzzle Pirates.
7  * 
8  *  Copyright (C) 2009 Ian Jackson <ijackson@chiark.greenend.org.uk>
9  * 
10  *  This program is free software: you can redistribute it and/or modify
11  *  it under the terms of the GNU General Public License as published by
12  *  the Free Software Foundation, either version 3 of the License, or
13  *  (at your option) any later version.
14  * 
15  *  This program is distributed in the hope that it will be useful,
16  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
17  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  *  GNU General Public License for more details.
19  * 
20  *  You should have received a copy of the GNU General Public License
21  *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
22  * 
23  *  Yohoho and Puzzle Pirates are probably trademarks of Three Rings and
24  *  are used without permission.  This program is not endorsed or
25  *  sponsored by Three Rings.
26  */
27
28 #include "common.h"
29
30 void *mmalloc(size_t sz) {
31   void *r;
32   if (!sz) return 0;
33   sysassert( r= malloc(sz) );
34   return r;
35 }
36 void *mrealloc(void *p, size_t sz) {
37   assert(sz);
38   void *r;
39   sysassert( r= realloc(p,sz) );
40   return r;
41 }
42
43
44 FILE *dbfile;
45 static const char *basepath; /* as passed in by caller */
46 static pid_t dbzcat;
47
48 int dbfile_gzopen(const char *basepath_spec) {
49   assert(!dbfile);
50
51   basepath= basepath_spec;
52   //uncomppath= masprintf("%s (uncompressed)", basepath);
53
54   char *zpath= masprintf("%s.gz", basepath);
55   int zfd= open(zpath, O_RDONLY);
56   free(zpath);
57
58   if (zfd<0) { sysassert(errno==ENOENT); return 0; }
59
60   int pipefds[2];
61   sysassert(! pipe(pipefds) );
62
63   sysassert( (dbzcat=fork()) != -1 );
64   if (!dbzcat) {
65     sysassert( dup2(zfd,0)==0 );
66     sysassert( dup2(pipefds[1],1)==1 );
67     sysassert(! close(zfd) );
68     sysassert(! close(pipefds[0]) );
69     sysassert(! close(pipefds[1]) );
70     execlp("zcat","zcat",(char*)0);
71     sysassert(!"execlp zcat");
72   }
73   sysassert(! close(zfd) );
74   sysassert(! close(pipefds[1]) );
75   sysassert( dbfile= fdopen(pipefds[0], "r") );
76
77   return 1;
78 }  
79
80 int dbfile_open(const char *tpath) {
81   assert(!dbfile);
82
83   basepath= tpath;
84
85   dbzcat= -1;
86   dbfile= fopen(tpath,"r");
87   if (!dbfile) { sysassert(errno==ENOENT); return 0; }
88   return 1;
89 }  
90
91 void dbfile_close(void) {
92   if (!dbfile) return;
93
94   sysassert(!ferror(dbfile));
95   sysassert(!fclose(dbfile));
96
97   if (dbzcat != -1) {
98     char *zcatstr= masprintf("zcat %s.gz", basepath);
99     waitpid_check_exitstatus(dbzcat,zcatstr,1);
100     free(zcatstr);
101     dbzcat= -1;
102   }
103
104   dbfile= 0;
105 }
106
107 #define dbassertgl(x) ((x) ? (void)0 : dbfile_assertfail(file,line,#x))
108
109 void dbfile_getsline(char *lbuf, size_t lbufsz, const char *file, int line) {
110   errno=0;
111   char *s= fgets(lbuf,lbufsz,dbfile);
112   sysassert(!ferror(dbfile));
113   dbassertgl(!feof(dbfile));
114   assert(s);
115   int l= strlen(lbuf);
116   dbassertgl(l>0);  dbassertgl(lbuf[--l]=='\n');
117   lbuf[l]= 0;
118 }
119
120 int dbfile_vscanf(const char *fmt, va_list al) {
121   int r= vfscanf(dbfile,fmt,al);
122   sysassert(!ferror(dbfile));
123   return r;
124 }
125
126 int dbfile_scanf(const char *fmt, ...) {
127   va_list al;
128   va_start(al,fmt);
129   int r= dbfile_vscanf(fmt,al);
130   va_end(al);
131   return r;
132 }
133
134 void dbfile_assertfail(const char *file, int line, const char *m) {
135   if (dbzcat)
136     fatal("Error in dictionary file %s.gz:\n"
137           " Requirement not met at %s:%d:\n"
138           " %s",
139           basepath, file,line, m);
140   else if (dbfile)
141     fatal("Error in dictionary file %s at byte %ld:\n"
142           " Requirement not met at %s:%d:\n"
143           " %s",
144           basepath,(long)ftell(dbfile), file,line, m);
145   else
146     fatal("Semantic error in dictionaries:\n"
147           " Requirement not met at %s:%d:\n"
148           " %s",
149           file,line, m);
150 }