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