Switch the memory allocation macros from the Halibut ones
[sgt/halibut] / error.c
CommitLineData
d7482997 1/*
2 * error.c: Halibut error handling
3 */
4
5#include <stdio.h>
6#include <stdlib.h>
7#include <stdarg.h>
8#include "halibut.h"
9
10/*
11 * Error flags
12 */
13#define PREFIX 0x0001 /* give `halibut:' prefix */
14#define FILEPOS 0x0002 /* give file position prefix */
15
16static void do_error(int code, va_list ap) {
17 char error[1024];
f4551933 18 char c;
db662ca1 19 int i, j;
d7482997 20 char *sp, *sp2;
21 wchar_t *wsp;
22 filepos fpos, fpos2;
23 int flags;
24
25 switch(code) {
26 case err_nomemory: /* no arguments */
27 sprintf(error, "out of memory");
28 flags = PREFIX;
29 break;
30 case err_optnoarg:
31 sp = va_arg(ap, char *);
32 sprintf(error, "option `-%.200s' requires an argument", sp);
33 flags = PREFIX;
34 break;
35 case err_nosuchopt:
36 sp = va_arg(ap, char *);
37 sprintf(error, "unrecognised option `-%.200s'", sp);
38 flags = PREFIX;
39 break;
40 case err_noinput: /* no arguments */
41 sprintf(error, "no input files");
42 flags = PREFIX;
43 break;
44 case err_cantopen:
45 sp = va_arg(ap, char *);
46 sprintf(error, "unable to open input file `%.200s'", sp);
47 flags = PREFIX;
48 break;
49 case err_nodata: /* no arguments */
50 sprintf(error, "no data in input files");
51 flags = PREFIX;
52 break;
53 case err_brokencodepara:
54 fpos = *va_arg(ap, filepos *);
55 sprintf(error, "every line of a code paragraph should begin `\\c'");
56 flags = FILEPOS;
57 break;
58 case err_kwunclosed:
59 fpos = *va_arg(ap, filepos *);
60 sprintf(error, "expected `}' after paragraph keyword");
61 flags = FILEPOS;
62 break;
63 case err_kwexpected:
64 fpos = *va_arg(ap, filepos *);
65 sprintf(error, "expected a paragraph keyword");
66 flags = FILEPOS;
67 break;
68 case err_kwillegal:
69 fpos = *va_arg(ap, filepos *);
70 sprintf(error, "expected no paragraph keyword");
71 flags = FILEPOS;
72 break;
73 case err_kwtoomany:
74 fpos = *va_arg(ap, filepos *);
75 sprintf(error, "expected only one paragraph keyword");
76 flags = FILEPOS;
77 break;
78 case err_bodyillegal:
79 fpos = *va_arg(ap, filepos *);
80 sprintf(error, "expected no text after paragraph keyword");
81 flags = FILEPOS;
82 break;
83 case err_badparatype:
84 wsp = va_arg(ap, wchar_t *);
7e976207 85 sp = utoa_locale_dup(wsp);
d7482997 86 fpos = *va_arg(ap, filepos *);
87 sprintf(error, "command `%.200s' unrecognised at start of"
88 " paragraph", sp);
89 flags = FILEPOS;
7e976207 90 sfree(sp);
d7482997 91 break;
92 case err_badmidcmd:
93 wsp = va_arg(ap, wchar_t *);
7e976207 94 sp = utoa_locale_dup(wsp);
d7482997 95 fpos = *va_arg(ap, filepos *);
96 sprintf(error, "command `%.200s' unexpected in mid-paragraph", sp);
97 flags = FILEPOS;
7e976207 98 sfree(sp);
d7482997 99 break;
100 case err_unexbrace:
101 fpos = *va_arg(ap, filepos *);
102 sprintf(error, "brace character unexpected in mid-paragraph");
103 flags = FILEPOS;
104 break;
105 case err_explbr:
106 fpos = *va_arg(ap, filepos *);
107 sprintf(error, "expected `{' after command");
108 flags = FILEPOS;
109 break;
110 case err_commenteof:
111 fpos = *va_arg(ap, filepos *);
112 sprintf(error, "end of file unexpected inside `\\#{...}' comment");
113 flags = FILEPOS;
114 break;
115 case err_kwexprbr:
116 fpos = *va_arg(ap, filepos *);
117 sprintf(error, "expected `}' after cross-reference");
118 flags = FILEPOS;
119 break;
120 case err_missingrbrace:
121 fpos = *va_arg(ap, filepos *);
122 sprintf(error, "unclosed braces at end of paragraph");
123 flags = FILEPOS;
124 break;
7136a6c7 125 case err_missingrbrace2:
126 fpos = *va_arg(ap, filepos *);
127 sprintf(error, "unclosed braces at end of input file");
128 flags = FILEPOS;
129 break;
d7482997 130 case err_nestedstyles:
131 fpos = *va_arg(ap, filepos *);
132 sprintf(error, "unable to nest text styles");
133 flags = FILEPOS;
134 break;
135 case err_nestedindex:
136 fpos = *va_arg(ap, filepos *);
137 sprintf(error, "unable to nest index markings");
138 flags = FILEPOS;
139 break;
140 case err_nosuchkw:
141 fpos = *va_arg(ap, filepos *);
142 wsp = va_arg(ap, wchar_t *);
7e976207 143 sp = utoa_locale_dup(wsp);
d7482997 144 sprintf(error, "unable to resolve cross-reference to `%.200s'", sp);
145 flags = FILEPOS;
7e976207 146 sfree(sp);
d7482997 147 break;
148 case err_multiBR:
149 fpos = *va_arg(ap, filepos *);
150 wsp = va_arg(ap, wchar_t *);
7e976207 151 sp = utoa_locale_dup(wsp);
d7482997 152 sprintf(error, "multiple `\\BR' entries given for `%.200s'", sp);
153 flags = FILEPOS;
7e976207 154 sfree(sp);
d7482997 155 break;
156 case err_nosuchidxtag:
7e976207 157 fpos = *va_arg(ap, filepos *);
d7482997 158 wsp = va_arg(ap, wchar_t *);
7e976207 159 sp = utoa_locale_dup(wsp);
d7482997 160 sprintf(error, "`\\IM' on unknown index tag `%.200s'", sp);
7e976207 161 sfree(sp);
162 flags = FILEPOS;
d7482997 163 break;
164 case err_cantopenw:
165 sp = va_arg(ap, char *);
166 sprintf(error, "unable to open output file `%.200s'", sp);
167 flags = PREFIX;
168 break;
169 case err_macroexists:
170 fpos = *va_arg(ap, filepos *);
171 wsp = va_arg(ap, wchar_t *);
7e976207 172 sp = utoa_locale_dup(wsp);
d7482997 173 sprintf(error, "macro `%.200s' already defined", sp);
174 flags = FILEPOS;
7e976207 175 sfree(sp);
d7482997 176 break;
177 case err_sectjump:
178 fpos = *va_arg(ap, filepos *);
179 sprintf(error, "expected higher heading levels before this one");
180 flags = FILEPOS;
181 break;
182 case err_winhelp_ctxclash:
183 fpos = *va_arg(ap, filepos *);
184 sp = va_arg(ap, char *);
185 sp2 = va_arg(ap, char *);
186 sprintf(error, "Windows Help context id `%.200s' clashes with "
187 "previously defined `%.200s'", sp, sp2);
188 flags = FILEPOS;
189 break;
190 case err_multikw:
191 fpos = *va_arg(ap, filepos *);
192 fpos2 = *va_arg(ap, filepos *);
193 wsp = va_arg(ap, wchar_t *);
7e976207 194 sp = utoa_locale_dup(wsp);
d7482997 195 sprintf(error, "paragraph keyword `%.200s' already defined at ", sp);
196 sprintf(error + strlen(error), "%s:%d", fpos2.filename, fpos2.line);
197 flags = FILEPOS;
7e976207 198 sfree(sp);
d7482997 199 break;
7136a6c7 200 case err_misplacedlcont:
201 fpos = *va_arg(ap, filepos *);
202 sprintf(error, "\\lcont is only expected after a list item");
203 flags = FILEPOS;
204 break;
2614b01d 205 case err_sectmarkerinblock:
7136a6c7 206 fpos = *va_arg(ap, filepos *);
2614b01d 207 sp = va_arg(ap, char *);
208 sprintf(error, "section headings are not supported within \\%.100s",
209 sp);
7136a6c7 210 flags = FILEPOS;
d4c7e130 211 break;
212 case err_infodirentry:
213 fpos = *va_arg(ap, filepos *);
214 sprintf(error, "\\cfg{info-dir-entry} expects at least three"
215 " parameters");
216 flags = FILEPOS;
217 break;
f4551933 218 case err_infonodechar:
219 fpos = *va_arg(ap, filepos *);
220 c = (char)va_arg(ap, int);
221 sprintf(error, "info output format does not support '%c' in"
222 " node names; removing", c);
223 flags = FILEPOS;
224 break;
db662ca1 225 case err_text_codeline:
226 fpos = *va_arg(ap, filepos *);
227 i = va_arg(ap, int);
228 j = va_arg(ap, int);
229 sprintf(error, "warning: code paragraph line is %d chars wide, wider"
230 " than body width %d", i, j);
231 flags = FILEPOS;
232 break;
d7482997 233 case err_whatever:
234 sp = va_arg(ap, char *);
235 vsprintf(error, sp, ap);
236 flags = PREFIX;
237 break;
238 }
239
240 if (flags & PREFIX)
241 fputs("halibut: ", stderr);
242 if (flags & FILEPOS) {
6a0b9d08 243 fprintf(stderr, "%s:", fpos.filename);
244 if (fpos.line > 0)
245 fprintf(stderr, "%d:", fpos.line);
d7482997 246 if (fpos.col > 0)
247 fprintf(stderr, "%d:", fpos.col);
248 fputc(' ', stderr);
249 }
250 fputs(error, stderr);
251 fputc('\n', stderr);
252}
253
254void fatal(int code, ...) {
255 va_list ap;
256 va_start(ap, code);
257 do_error(code, ap);
258 va_end(ap);
259 exit(EXIT_FAILURE);
260}
261
262void error(int code, ...) {
263 va_list ap;
264 va_start(ap, code);
265 do_error(code, ap);
266 va_end(ap);
267}