Make a start on command-line options. Here I introduce --text,
[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];
18 char auxbuf[256];
19 char *sp, *sp2;
20 wchar_t *wsp;
21 filepos fpos, fpos2;
22 int flags;
23
24 switch(code) {
25 case err_nomemory: /* no arguments */
26 sprintf(error, "out of memory");
27 flags = PREFIX;
28 break;
29 case err_optnoarg:
30 sp = va_arg(ap, char *);
31 sprintf(error, "option `-%.200s' requires an argument", sp);
32 flags = PREFIX;
33 break;
34 case err_nosuchopt:
35 sp = va_arg(ap, char *);
36 sprintf(error, "unrecognised option `-%.200s'", sp);
37 flags = PREFIX;
38 break;
39 case err_noinput: /* no arguments */
40 sprintf(error, "no input files");
41 flags = PREFIX;
42 break;
43 case err_cantopen:
44 sp = va_arg(ap, char *);
45 sprintf(error, "unable to open input file `%.200s'", sp);
46 flags = PREFIX;
47 break;
48 case err_nodata: /* no arguments */
49 sprintf(error, "no data in input files");
50 flags = PREFIX;
51 break;
52 case err_brokencodepara:
53 fpos = *va_arg(ap, filepos *);
54 sprintf(error, "every line of a code paragraph should begin `\\c'");
55 flags = FILEPOS;
56 break;
57 case err_kwunclosed:
58 fpos = *va_arg(ap, filepos *);
59 sprintf(error, "expected `}' after paragraph keyword");
60 flags = FILEPOS;
61 break;
62 case err_kwexpected:
63 fpos = *va_arg(ap, filepos *);
64 sprintf(error, "expected a paragraph keyword");
65 flags = FILEPOS;
66 break;
67 case err_kwillegal:
68 fpos = *va_arg(ap, filepos *);
69 sprintf(error, "expected no paragraph keyword");
70 flags = FILEPOS;
71 break;
72 case err_kwtoomany:
73 fpos = *va_arg(ap, filepos *);
74 sprintf(error, "expected only one paragraph keyword");
75 flags = FILEPOS;
76 break;
77 case err_bodyillegal:
78 fpos = *va_arg(ap, filepos *);
79 sprintf(error, "expected no text after paragraph keyword");
80 flags = FILEPOS;
81 break;
82 case err_badparatype:
83 wsp = va_arg(ap, wchar_t *);
84 sp = ustrtoa(wsp, auxbuf, sizeof(auxbuf));
85 fpos = *va_arg(ap, filepos *);
86 sprintf(error, "command `%.200s' unrecognised at start of"
87 " paragraph", sp);
88 flags = FILEPOS;
89 break;
90 case err_badmidcmd:
91 wsp = va_arg(ap, wchar_t *);
92 sp = ustrtoa(wsp, auxbuf, sizeof(auxbuf));
93 fpos = *va_arg(ap, filepos *);
94 sprintf(error, "command `%.200s' unexpected in mid-paragraph", sp);
95 flags = FILEPOS;
96 break;
97 case err_unexbrace:
98 fpos = *va_arg(ap, filepos *);
99 sprintf(error, "brace character unexpected in mid-paragraph");
100 flags = FILEPOS;
101 break;
102 case err_explbr:
103 fpos = *va_arg(ap, filepos *);
104 sprintf(error, "expected `{' after command");
105 flags = FILEPOS;
106 break;
107 case err_commenteof:
108 fpos = *va_arg(ap, filepos *);
109 sprintf(error, "end of file unexpected inside `\\#{...}' comment");
110 flags = FILEPOS;
111 break;
112 case err_kwexprbr:
113 fpos = *va_arg(ap, filepos *);
114 sprintf(error, "expected `}' after cross-reference");
115 flags = FILEPOS;
116 break;
117 case err_missingrbrace:
118 fpos = *va_arg(ap, filepos *);
119 sprintf(error, "unclosed braces at end of paragraph");
120 flags = FILEPOS;
121 break;
7136a6c7 122 case err_missingrbrace2:
123 fpos = *va_arg(ap, filepos *);
124 sprintf(error, "unclosed braces at end of input file");
125 flags = FILEPOS;
126 break;
d7482997 127 case err_nestedstyles:
128 fpos = *va_arg(ap, filepos *);
129 sprintf(error, "unable to nest text styles");
130 flags = FILEPOS;
131 break;
132 case err_nestedindex:
133 fpos = *va_arg(ap, filepos *);
134 sprintf(error, "unable to nest index markings");
135 flags = FILEPOS;
136 break;
137 case err_nosuchkw:
138 fpos = *va_arg(ap, filepos *);
139 wsp = va_arg(ap, wchar_t *);
140 sp = ustrtoa(wsp, auxbuf, sizeof(auxbuf));
141 sprintf(error, "unable to resolve cross-reference to `%.200s'", sp);
142 flags = FILEPOS;
143 break;
144 case err_multiBR:
145 fpos = *va_arg(ap, filepos *);
146 wsp = va_arg(ap, wchar_t *);
147 sp = ustrtoa(wsp, auxbuf, sizeof(auxbuf));
148 sprintf(error, "multiple `\\BR' entries given for `%.200s'", sp);
149 flags = FILEPOS;
150 break;
151 case err_nosuchidxtag:
152 wsp = va_arg(ap, wchar_t *);
153 sp = ustrtoa(wsp, auxbuf, sizeof(auxbuf));
154 sprintf(error, "`\\IM' on unknown index tag `%.200s'", sp);
155 flags = 0;
156 /* FIXME: need to get a filepos to here somehow */
157 break;
158 case err_cantopenw:
159 sp = va_arg(ap, char *);
160 sprintf(error, "unable to open output file `%.200s'", sp);
161 flags = PREFIX;
162 break;
163 case err_macroexists:
164 fpos = *va_arg(ap, filepos *);
165 wsp = va_arg(ap, wchar_t *);
166 sp = ustrtoa(wsp, auxbuf, sizeof(auxbuf));
167 sprintf(error, "macro `%.200s' already defined", sp);
168 flags = FILEPOS;
169 break;
170 case err_sectjump:
171 fpos = *va_arg(ap, filepos *);
172 sprintf(error, "expected higher heading levels before this one");
173 flags = FILEPOS;
174 break;
175 case err_winhelp_ctxclash:
176 fpos = *va_arg(ap, filepos *);
177 sp = va_arg(ap, char *);
178 sp2 = va_arg(ap, char *);
179 sprintf(error, "Windows Help context id `%.200s' clashes with "
180 "previously defined `%.200s'", sp, sp2);
181 flags = FILEPOS;
182 break;
183 case err_multikw:
184 fpos = *va_arg(ap, filepos *);
185 fpos2 = *va_arg(ap, filepos *);
186 wsp = va_arg(ap, wchar_t *);
187 sp = ustrtoa(wsp, auxbuf, sizeof(auxbuf));
188 sprintf(error, "paragraph keyword `%.200s' already defined at ", sp);
189 sprintf(error + strlen(error), "%s:%d", fpos2.filename, fpos2.line);
190 flags = FILEPOS;
191 break;
7136a6c7 192 case err_misplacedlcont:
193 fpos = *va_arg(ap, filepos *);
194 sprintf(error, "\\lcont is only expected after a list item");
195 flags = FILEPOS;
196 break;
2614b01d 197 case err_sectmarkerinblock:
7136a6c7 198 fpos = *va_arg(ap, filepos *);
2614b01d 199 sp = va_arg(ap, char *);
200 sprintf(error, "section headings are not supported within \\%.100s",
201 sp);
7136a6c7 202 flags = FILEPOS;
203 break;
d7482997 204 case err_whatever:
205 sp = va_arg(ap, char *);
206 vsprintf(error, sp, ap);
207 flags = PREFIX;
208 break;
209 }
210
211 if (flags & PREFIX)
212 fputs("halibut: ", stderr);
213 if (flags & FILEPOS) {
214 fprintf(stderr, "%s:%d:", fpos.filename, fpos.line);
215 if (fpos.col > 0)
216 fprintf(stderr, "%d:", fpos.col);
217 fputc(' ', stderr);
218 }
219 fputs(error, stderr);
220 fputc('\n', stderr);
221}
222
223void fatal(int code, ...) {
224 va_list ap;
225 va_start(ap, code);
226 do_error(code, ap);
227 va_end(ap);
228 exit(EXIT_FAILURE);
229}
230
231void error(int code, ...) {
232 va_list ap;
233 va_start(ap, code);
234 do_error(code, ap);
235 va_end(ap);
236}