chiark / gitweb /
bac41d90ef37b1e0229d4ad98644318f9c973fe4
[ypp-sc-tools.main.git] / pctb / convert.c
1 /*
2  * ypp-commodities main program: argument parsing etc.
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 "convert.h"
29
30 void debug_flush(void) {
31   sysassert(!ferror(debug));
32   sysassert(!fflush(debug));
33 }
34
35 const char *get_vardir(void) { return "."; }
36
37 static enum {
38   mf_findwindow=      0001,
39   mf_screenshot=      0010,
40   mf_readscreenshot=  0020,
41   mf_analyse=         0100,
42   
43   mode_findwindow=    0001,
44   mode_screenshot=    0011,
45   mode_analyse=       0120,
46
47   mode_all=           0111,
48 } o_mode= mode_all;
49
50 static char *o_screenshots_fn;
51 static int o_single_page, o_quiet;
52
53 FILE *screenshots_file;
54
55
56 static void badusage(const char *fmt, ...)
57      __attribute__((format(printf,1,2),noreturn));
58 static void badusage(const char *fmt, ...) {
59   va_list al;
60   va_start(al,fmt);
61   exit(12);
62 }
63
64 static void open_screenshots_file(const char *mode) {
65   screenshots_file= fopen(o_screenshots_fn, mode);
66   if (!screenshots_file)
67     fatal("could not open screenshots file `%s': %s",
68           o_screenshots_fn, strerror(errno));
69 }
70
71 int main(int argc, char **argv) {
72   const char *arg;
73   int r;
74
75 #define ARGVAL  ((*++argv) ? *argv : \
76                  badusage("missing value for option %s",arg),(char*)0)
77
78   while ((arg=*++argv)) {
79     if (!strcmp(arg,"--find-window-only"))
80       o_mode= mode_findwindow;
81     else if (!strcmp(arg,"--screenshot-only"))
82       o_mode= mode_screenshot;
83     else if (!strcmp(arg,"--analyse-only"))
84       o_mode= mode_analyse;
85     else if (!strcmp(arg,"--single-page"))
86       o_single_page= 1;
87     else if (!strcmp(arg,"--quiet"))
88       o_quiet= 1;
89     else if (!strcmp(arg,"--screenshots-file"))
90       o_screenshots_fn= ARGVAL;
91 #define DF(f)                                   \
92     else if (!strcmp(arg,"-D" #f))              \
93       debug_flags |= dbg_##f;
94     DEBUG_FLAG_LIST
95 #undef DF
96     else if (!strcmp(arg,"--window-id")) {
97       char *ep;
98       unsigned long windowid= strtoul(ARGVAL,&ep,0);
99       if (*ep) badusage("invalid window id");
100       set_yppclient_window(windowid);
101     } else
102       badusage("unknown option `%s'",arg);
103   }
104   
105   if (!o_screenshots_fn) {
106     r= asprintf(&o_screenshots_fn,"%s/#pages#.ppm",get_vardir());
107     sysassert(r>=0);
108   }
109
110   if (o_mode & mf_findwindow) {
111     screenshot_startup();
112     find_yppclient_window();
113   }
114   if (o_mode & mf_screenshot) {
115     open_screenshots_file("w");
116     if (o_single_page) take_one_screenshot();
117     else take_screenshots();
118   }
119   if (o_mode & mf_readscreenshot) {
120     open_screenshots_file("r");
121     if (o_single_page) read_one_screenshot();
122     else read_screenshots();
123   }
124   if (o_mode & mf_analyse) {
125     analyse();
126     //output_tsv();
127   }
128   return 0;
129 }
130
131
132
133
134 DEFINE_VWRAPPERF(, progress, )
135 DEFINE_VWRAPPERF(, progress_log, )
136 DEFINE_VWRAPPERF(, progress_spinner, )
137 DEFINE_VWRAPPERF(, warning, )
138 DEFINE_VWRAPPERF(, fatal, NORET)
139
140 static int last_progress_len;
141      
142 static void vprogress_core(int spinner, const char *fmt, va_list al) {
143   int r;
144   
145   if (o_quiet) return;
146   if (!isatty(2)) return;
147   
148   if (last_progress_len)
149     putc('\r',stderr);
150
151   r= vfprintf(stderr,fmt,al);
152
153   if (spinner) {
154     putc(spinner,stderr);
155     r++;
156   }
157
158   if (r < last_progress_len) {
159     fprintf(stderr,"%*s", last_progress_len - r, "");
160     if (!r) putc('\r', stderr);
161     else while (last_progress_len-- > r) putc('\b',stderr);
162   }
163   last_progress_len= r;
164
165   if (ferror(stderr) || fflush(stderr)) _exit(16);
166 }
167    
168 void vprogress(const char *fmt, va_list al) { vprogress_core(0,fmt,al); }
169 void vprogress_spinner(const char *fmt, va_list al) {
170   static const char spinchars[]="/-\\";
171   static int spinner;
172
173   vprogress_core(spinchars[spinner],fmt,al);
174   spinner++;
175   spinner %= (sizeof(spinchars)-1);
176 }
177
178 void vprogress_log(const char *fmt, va_list al) {
179   if (o_quiet) return;
180   
181   progress("");
182   vfprintf(stderr,fmt,al);
183   putc('\n',stderr);
184   fflush(stderr);
185 }
186
187 void vwarning(const char *fmt, va_list al) {
188   progress("");
189   fputs("Warning: ",stderr);
190   vfprintf(stderr,fmt,al);
191   fputs("\n",stderr);
192   fflush(stderr);
193 }
194
195 void vfatal(const char *fmt, va_list al) {
196   progress("");
197   fputs("\n\nFatal error: ",stderr);
198   vfprintf(stderr,fmt,al);
199   fflush(stderr);
200   fputs("\n\n",stderr);
201   _exit(4);
202 }
203
204 void sysassert_fail(const char *file, int line, const char *what) {
205   int e= errno;
206   progress("");
207   fprintf(stderr,
208           "\nfatal operational error:\n"
209           " unsuccessful execution of: %s\n"
210           " %s:%d: %s\n\n",
211           what, file,line, strerror(e));
212   _exit(16);
213 }
214
215 void *mmalloc(size_t sz) {
216   void *r;
217   if (!sz) return 0;
218   sysassert( r= malloc(sz) );
219   return r;
220 }
221 void *mrealloc(void *p, size_t sz) {
222   assert(sz);
223   void *r;
224   sysassert( r= realloc(p,sz) );
225   return r;
226 }