#define PREFIX 0x0001 /* give `halibut:' prefix */
#define FILEPOS 0x0002 /* give file position prefix */
-static void do_error(int code, va_list ap) {
- char error[1024];
- char c;
- int i, j;
- char *sp, *sp2;
- wchar_t *wsp, *wsp2;
- filepos fpos, fpos2;
- int flags;
-
- switch(code) {
- case err_nomemory: /* no arguments */
- sprintf(error, "out of memory");
- flags = PREFIX;
- break;
- case err_optnoarg:
- sp = va_arg(ap, char *);
- sprintf(error, "option `-%.200s' requires an argument", sp);
- flags = PREFIX;
- break;
- case err_nosuchopt:
- sp = va_arg(ap, char *);
- sprintf(error, "unrecognised option `-%.200s'", sp);
- flags = PREFIX;
- break;
- case err_noinput: /* no arguments */
- sprintf(error, "no input files");
- flags = PREFIX;
- break;
- case err_cantopen:
- sp = va_arg(ap, char *);
- sprintf(error, "unable to open input file `%.200s'", sp);
- flags = PREFIX;
- break;
- case err_nodata: /* no arguments */
- sprintf(error, "no data in input files");
- flags = PREFIX;
- break;
- case err_brokencodepara:
- fpos = *va_arg(ap, filepos *);
- sprintf(error, "every line of a code paragraph should begin `\\c'");
- flags = FILEPOS;
- break;
- case err_kwunclosed:
- fpos = *va_arg(ap, filepos *);
- sprintf(error, "expected `}' after paragraph keyword");
- flags = FILEPOS;
- break;
- case err_kwexpected:
- fpos = *va_arg(ap, filepos *);
- sprintf(error, "expected a paragraph keyword");
- flags = FILEPOS;
- break;
- case err_kwillegal:
- fpos = *va_arg(ap, filepos *);
- sprintf(error, "expected no paragraph keyword");
- flags = FILEPOS;
- break;
- case err_kwtoomany:
- fpos = *va_arg(ap, filepos *);
- sprintf(error, "expected only one paragraph keyword");
- flags = FILEPOS;
- break;
- case err_bodyillegal:
- fpos = *va_arg(ap, filepos *);
- sprintf(error, "expected no text after paragraph keyword");
- flags = FILEPOS;
- break;
- case err_badparatype:
- wsp = va_arg(ap, wchar_t *);
- sp = utoa_locale_dup(wsp);
- fpos = *va_arg(ap, filepos *);
- sprintf(error, "command `%.200s' unrecognised at start of"
- " paragraph", sp);
- flags = FILEPOS;
- sfree(sp);
- break;
- case err_badmidcmd:
- wsp = va_arg(ap, wchar_t *);
- sp = utoa_locale_dup(wsp);
- fpos = *va_arg(ap, filepos *);
- sprintf(error, "command `%.200s' unexpected in mid-paragraph", sp);
- flags = FILEPOS;
- sfree(sp);
- break;
- case err_unexbrace:
- fpos = *va_arg(ap, filepos *);
- sprintf(error, "brace character unexpected in mid-paragraph");
- flags = FILEPOS;
- break;
- case err_explbr:
- fpos = *va_arg(ap, filepos *);
- sprintf(error, "expected `{' after command");
- flags = FILEPOS;
- break;
- case err_commenteof:
- fpos = *va_arg(ap, filepos *);
- sprintf(error, "end of file unexpected inside `\\#{...}' comment");
- flags = FILEPOS;
- break;
- case err_kwexprbr:
- fpos = *va_arg(ap, filepos *);
- sprintf(error, "expected `}' after cross-reference");
- flags = FILEPOS;
- break;
- case err_codequote:
- fpos = *va_arg(ap, filepos *);
- sprintf(error, "unable to nest \\q{...} within \\c{...} or \\cw{...}");
- flags = FILEPOS;
- break;
- case err_missingrbrace:
- fpos = *va_arg(ap, filepos *);
- sprintf(error, "unclosed braces at end of paragraph");
- flags = FILEPOS;
- break;
- case err_missingrbrace2:
- fpos = *va_arg(ap, filepos *);
- sprintf(error, "unclosed braces at end of input file");
- flags = FILEPOS;
- break;
- case err_nestedstyles:
- fpos = *va_arg(ap, filepos *);
- sprintf(error, "unable to nest text styles");
- flags = FILEPOS;
- break;
- case err_nestedindex:
- fpos = *va_arg(ap, filepos *);
- sprintf(error, "unable to nest index markings");
- flags = FILEPOS;
- break;
- case err_indexcase:
- fpos = *va_arg(ap, filepos *);
- wsp = va_arg(ap, wchar_t *);
- sp = utoa_locale_dup(wsp);
- fpos2 = *va_arg(ap, filepos *);
- wsp2 = va_arg(ap, wchar_t *);
- sp2 = utoa_locale_dup(wsp2);
- sprintf(error, "warning: index tag `%.200s' used with ", sp);
- sprintf(error + strlen(error), "different case (`%.200s') at %s:%d",
- sp2, fpos2.filename, fpos2.line);
- flags = FILEPOS;
- sfree(sp);
- sfree(sp2);
- break;
- case err_nosuchkw:
- fpos = *va_arg(ap, filepos *);
- wsp = va_arg(ap, wchar_t *);
- sp = utoa_locale_dup(wsp);
- sprintf(error, "unable to resolve cross-reference to `%.200s'", sp);
- flags = FILEPOS;
- sfree(sp);
- break;
- case err_multiBR:
- fpos = *va_arg(ap, filepos *);
- wsp = va_arg(ap, wchar_t *);
- sp = utoa_locale_dup(wsp);
- sprintf(error, "multiple `\\BR' entries given for `%.200s'", sp);
- flags = FILEPOS;
- sfree(sp);
- break;
- case err_nosuchidxtag:
- fpos = *va_arg(ap, filepos *);
- wsp = va_arg(ap, wchar_t *);
- sp = utoa_locale_dup(wsp);
- sprintf(error, "`\\IM' on unknown index tag `%.200s'", sp);
- sfree(sp);
- flags = FILEPOS;
- break;
- case err_cantopenw:
- sp = va_arg(ap, char *);
- sprintf(error, "unable to open output file `%.200s'", sp);
- flags = PREFIX;
- break;
- case err_macroexists:
- fpos = *va_arg(ap, filepos *);
- wsp = va_arg(ap, wchar_t *);
- sp = utoa_locale_dup(wsp);
- sprintf(error, "macro `%.200s' already defined", sp);
- flags = FILEPOS;
- sfree(sp);
- break;
- case err_sectjump:
- fpos = *va_arg(ap, filepos *);
- sprintf(error, "expected higher heading levels before this one");
- flags = FILEPOS;
- break;
- case err_winhelp_ctxclash:
- fpos = *va_arg(ap, filepos *);
- sp = va_arg(ap, char *);
- sp2 = va_arg(ap, char *);
- sprintf(error, "Windows Help context id `%.200s' clashes with "
- "previously defined `%.200s'", sp, sp2);
- flags = FILEPOS;
- break;
- case err_multikw:
- fpos = *va_arg(ap, filepos *);
- fpos2 = *va_arg(ap, filepos *);
- wsp = va_arg(ap, wchar_t *);
- sp = utoa_locale_dup(wsp);
- sprintf(error, "paragraph keyword `%.200s' already defined at ", sp);
- sprintf(error + strlen(error), "%s:%d", fpos2.filename, fpos2.line);
- flags = FILEPOS;
- sfree(sp);
- break;
- case err_misplacedlcont:
- fpos = *va_arg(ap, filepos *);
- sprintf(error, "\\lcont is only expected after a list item");
- flags = FILEPOS;
- break;
- case err_sectmarkerinblock:
- fpos = *va_arg(ap, filepos *);
- sp = va_arg(ap, char *);
- sprintf(error, "section headings are not supported within \\%.100s",
- sp);
- flags = FILEPOS;
- break;
- case err_infodirentry:
- fpos = *va_arg(ap, filepos *);
- sprintf(error, "\\cfg{info-dir-entry} expects at least three"
- " parameters");
- flags = FILEPOS;
- break;
- case err_infonodechar:
- fpos = *va_arg(ap, filepos *);
- c = (char)va_arg(ap, int);
- sprintf(error, "info output format does not support '%c' in"
- " node names; removing", c);
- flags = FILEPOS;
- break;
- case err_text_codeline:
- fpos = *va_arg(ap, filepos *);
- i = va_arg(ap, int);
- j = va_arg(ap, int);
- sprintf(error, "warning: code paragraph line is %d chars wide, wider"
- " than body width %d", i, j);
- flags = FILEPOS;
- break;
- case err_htmlver:
- fpos = *va_arg(ap, filepos *);
- wsp = va_arg(ap, wchar_t *);
- sp = utoa_locale_dup(wsp);
- sprintf(error, "unrecognised HTML version keyword `%.200s'", sp);
- sfree(sp);
- flags = FILEPOS;
- break;
- case err_charset:
- fpos = *va_arg(ap, filepos *);
- wsp = va_arg(ap, wchar_t *);
- sp = utoa_locale_dup(wsp);
- sprintf(error, "character set `%.200s' not recognised", sp);
- flags = FILEPOS;
- sfree(sp);
- break;
- case err_whatever:
- sp = va_arg(ap, char *);
- vsprintf(error, sp, ap);
- flags = PREFIX;
- break;
- }
+static void do_error(const filepos *fpos, const char *fmt, ...)
+{
+ va_list ap;
- if (flags & PREFIX)
- fputs("halibut: ", stderr);
- if (flags & FILEPOS) {
- fprintf(stderr, "%s:", fpos.filename);
- if (fpos.line > 0)
- fprintf(stderr, "%d:", fpos.line);
- if (fpos.col > 0)
- fprintf(stderr, "%d:", fpos.col);
+ if (fpos) {
+ fprintf(stderr, "%s:",
+ fpos->filename ? fpos->filename : "<standard input>");
+ if (fpos->line > 0)
+ fprintf(stderr, "%d:", fpos->line);
+ if (fpos->col > 0)
+ fprintf(stderr, "%d:", fpos->col);
fputc(' ', stderr);
+ } else {
+ fputs("halibut: ", stderr);
}
- fputs(error, stderr);
+
+ va_start(ap, fmt);
+ vfprintf(stderr, fmt, ap);
+ va_end(ap);
+
fputc('\n', stderr);
}
-void fatal(int code, ...) {
- va_list ap;
- va_start(ap, code);
- do_error(code, ap);
- va_end(ap);
+void fatalerr_nomemory(void)
+{
+ do_error(NULL, "out of memory");
exit(EXIT_FAILURE);
}
-void error(int code, ...) {
- va_list ap;
- va_start(ap, code);
- do_error(code, ap);
- va_end(ap);
+void err_optnoarg(const char *sp)
+{
+ do_error(NULL, "option `-%s' requires an argument", sp);
+}
+
+void err_nosuchopt(const char *sp)
+{
+ do_error(NULL, "unrecognised option `-%s'", sp);
+}
+
+void err_cmdcharset(const char *sp)
+{
+ do_error(NULL, "character set `%s' not recognised", sp);
+}
+
+void err_futileopt(const char *sp, const char *sp2)
+{
+ do_error(NULL, "warning: option `-%s' has no effect%s", sp, sp2);
+}
+
+void err_noinput(void)
+{
+ do_error(NULL, "no input files");
+}
+
+void err_cantopen(const char *sp)
+{
+ do_error(NULL, "unable to open input file `%s'", sp);
+}
+
+void err_nodata(void)
+{
+ do_error(NULL, "no data in input files");
+}
+
+void err_brokencodepara(const filepos *fpos)
+{
+ do_error(fpos, "every line of a code paragraph should begin `\\c'");
+}
+
+void err_kwunclosed(const filepos *fpos)
+{
+ do_error(fpos, "expected `}' after paragraph keyword");
+}
+
+void err_kwexpected(const filepos *fpos)
+{
+ do_error(fpos, "expected a paragraph keyword");
+}
+
+void err_kwillegal(const filepos *fpos)
+{
+ do_error(fpos, "expected no paragraph keyword");
+}
+
+void err_kwtoomany(const filepos *fpos)
+{
+ do_error(fpos, "expected only one paragraph keyword");
+}
+
+void err_bodyillegal(const filepos *fpos)
+{
+ do_error(fpos, "expected no text after paragraph keyword");
+}
+
+void err_badparatype(const wchar_t *wsp, const filepos *fpos)
+{
+ char *sp = utoa_locale_dup(wsp);
+ do_error(fpos, "command `%s' unrecognised at start of paragraph", sp);
+ sfree(sp);
+}
+
+void err_badmidcmd(const wchar_t *wsp, const filepos *fpos)
+{
+ char *sp = utoa_locale_dup(wsp);
+ do_error(fpos, "command `%s' unexpected in mid-paragraph", sp);
+ sfree(sp);
+}
+
+void err_unexbrace(const filepos *fpos)
+{
+ do_error(fpos, "brace character unexpected in mid-paragraph");
+}
+
+void err_explbr(const filepos *fpos)
+{
+ do_error(fpos, "expected `{' after command");
+}
+
+void err_commenteof(const filepos *fpos)
+{
+ do_error(fpos, "end of file unexpected inside `\\#{...}' comment");
+}
+
+void err_kwexprbr(const filepos *fpos)
+{
+ do_error(fpos, "expected `}' after cross-reference");
+}
+
+void err_codequote(const filepos *fpos)
+{
+ do_error(fpos, "unable to nest \\q{...} within \\c{...} or \\cw{...}");
+}
+
+void err_missingrbrace(const filepos *fpos)
+{
+ do_error(fpos, "unclosed braces at end of paragraph");
+}
+
+void err_missingrbrace2(const filepos *fpos)
+{
+ do_error(fpos, "unclosed braces at end of input file");
+}
+
+void err_nestedstyles(const filepos *fpos)
+{
+ do_error(fpos, "unable to nest text styles");
+}
+
+void err_nestedindex(const filepos *fpos)
+{
+ do_error(fpos, "unable to nest index markings");
+}
+
+void err_indexcase(const filepos *fpos, const wchar_t *wsp,
+ const filepos *fpos2, const wchar_t *wsp2)
+{
+ char *sp = utoa_locale_dup(wsp), *sp2 = utoa_locale_dup(wsp2);
+ do_error(fpos, "warning: index tag `%s' used with different "
+ "case (`%s') at %s:%d",
+ sp, sp2, fpos2->filename, fpos2->line);
+ sfree(sp);
+ sfree(sp2);
+}
+
+void err_nosuchkw(const filepos *fpos, const wchar_t *wsp)
+{
+ char *sp = utoa_locale_dup(wsp);
+ do_error(fpos, "unable to resolve cross-reference to `%s'", sp);
+ sfree(sp);
+}
+
+void err_multiBR(const filepos *fpos, const wchar_t *wsp)
+{
+ char *sp = utoa_locale_dup(wsp);
+ do_error(fpos, "multiple `\\BR' entries given for `%s'", sp);
+ sfree(sp);
+}
+
+void err_nosuchidxtag(const filepos *fpos, const wchar_t *wsp)
+{
+ char *sp = utoa_locale_dup(wsp);
+ do_error(fpos, "`\\IM' on unknown index tag `%s'", sp);
+ sfree(sp);
+}
+
+void err_cantopenw(const char *sp)
+{
+ do_error(NULL, "unable to open output file `%s'", sp);
+}
+
+void err_macroexists(const filepos *fpos, const wchar_t *wsp)
+{
+ char *sp = utoa_locale_dup(wsp);
+ do_error(fpos, "macro `%s' already defined", sp);
+ sfree(sp);
+}
+
+void err_sectjump(const filepos *fpos)
+{
+ do_error(fpos, "expected higher heading levels before this one");
+}
+
+void err_winhelp_ctxclash(const filepos *fpos, const char *sp, const char *sp2)
+{
+ do_error(fpos, "Windows Help context id `%s' clashes with "
+ "previously defined `%s'", sp, sp2);
+}
+
+void err_multikw(const filepos *fpos, const filepos *fpos2, const wchar_t *wsp)
+{
+ char *sp = utoa_locale_dup(wsp);
+ do_error(fpos, "paragraph keyword `%s' already defined at %s:%d",
+ sp, fpos2->filename, fpos2->line);
+ sfree(sp);
+}
+
+void err_misplacedlcont(const filepos *fpos)
+{
+ do_error(fpos, "\\lcont is only expected after a list item");
+}
+
+void err_sectmarkerinblock(const filepos *fpos, const char *sp)
+{
+ do_error(fpos, "section headings are not supported within \\%s", sp);
+}
+
+void err_cfginsufarg(const filepos *fpos, const char *sp, int i)
+{
+ do_error(fpos, "\\cfg{%s} expects at least %d parameter%s",
+ sp, i, (i==1)?"":"s");
+}
+
+void err_infonodechar(const filepos *fpos, char c) /* fpos might be NULL */
+{
+ do_error(fpos, "info output format does not support '%c' in"
+ " node names; removing", c);
+}
+
+void err_text_codeline(const filepos *fpos, int i, int j)
+{
+ do_error(fpos, "warning: code paragraph line is %d chars wide, wider"
+ " than body width %d", i, j);
+}
+
+void err_htmlver(const filepos *fpos, const wchar_t *wsp)
+{
+ char *sp = utoa_locale_dup(wsp);
+ do_error(fpos, "unrecognised HTML version keyword `%s'", sp);
+ sfree(sp);
+}
+
+void err_charset(const filepos *fpos, const wchar_t *wsp)
+{
+ char *sp = utoa_locale_dup(wsp);
+ do_error(fpos, "character set `%s' not recognised", sp);
+ sfree(sp);
+}
+
+void err_nofont(const filepos *fpos, const wchar_t *wsp)
+{
+ char *sp = utoa_locale_dup(wsp);
+ do_error(fpos, "font `%s' not recognised", sp);
+ sfree(sp);
+}
+
+void err_afmeof(const filepos *fpos)
+{
+ do_error(fpos, "AFM file ended unexpectedly");
+}
+
+void err_afmkey(const filepos *fpos, const char *sp)
+{
+ do_error(fpos, "required AFM key '%s' missing", sp);
+}
+
+void err_afmvers(const filepos *fpos)
+{
+ do_error(fpos, "unsupported AFM version");
+}
+
+void err_afmval(const filepos *fpos, const char *sp, int i)
+{
+ if (i == 1)
+ do_error(fpos, "AFM key '%s' requires a value", sp);
+ else
+ do_error(fpos, "AFM key '%s' requires %d values", sp, i);
+}
+
+void err_pfeof(const filepos *fpos)
+{
+ do_error(fpos, "Type 1 font file ended unexpectedly");
+}
+
+void err_pfhead(const filepos *fpos)
+{
+ do_error(fpos, "Type 1 font file header line invalid");
+}
+
+void err_pfbad(const filepos *fpos)
+{
+ do_error(fpos, "Type 1 font file invalid");
+}
+
+void err_pfnoafm(const filepos *fpos, const char *sp)
+{
+ do_error(fpos, "no metrics available for Type 1 font '%s'", sp);
+}
+
+void err_chmnames(void)
+{
+ do_error(NULL, "only one of html-mshtmlhelp-chm and "
+ "html-mshtmlhelp-hhp found");
+}
+
+void err_sfntnotable(const filepos *fpos, const char *sp)
+{
+ do_error(fpos, "font has no '%s' table", sp);
+}
+
+void err_sfntnopsname(const filepos *fpos)
+{
+ do_error(fpos, "font has no PostScript name");
+}
+
+void err_sfntbadtable(const filepos *fpos, const char *sp)
+{
+ do_error(fpos, "font has an invalid '%s' table", sp);
+}
+
+void err_sfntnounicmap(const filepos *fpos)
+{
+ do_error(fpos, "font has no UCS-2 character map");
+}
+
+void err_sfnttablevers(const filepos *fpos, const char *sp)
+{
+ do_error(fpos, "font has an unsupported '%s' table version", sp);
+}
+
+void err_sfntbadhdr(const filepos *fpos)
+{
+ do_error(fpos, "font has an invalid header");
+}
+
+void err_sfntbadglyph(const filepos *fpos, unsigned wc)
+{
+ do_error(fpos,
+ "warning: character U+%04X references a non-existent glyph",
+ wc);
}