Bug in utoi(), which made it ignore a leading minus sign when
[sgt/halibut] / error.c
diff --git a/error.c b/error.c
index 5f5cbda..00d007d 100644 (file)
--- a/error.c
+++ b/error.c
 
 static void do_error(int code, va_list ap) {
     char error[1024];
-    char auxbuf[256];
     char c;
+    int i, j;
     char *sp, *sp2;
-    wchar_t *wsp;
-    filepos fpos, fpos2;
-    int flags;
+    wchar_t *wsp, *wsp2;
+    unsigned wc;
+    filepos fpos, fpos2, *fposp;
+    int flags = 0;
 
     switch(code) {
       case err_nomemory:              /* no arguments */
@@ -37,6 +38,17 @@ static void do_error(int code, va_list ap) {
        sprintf(error, "unrecognised option `-%.200s'", sp);
        flags = PREFIX;
        break;
+      case err_cmdcharset:
+       sp = va_arg(ap, char *);
+       sprintf(error, "character set `%.200s' not recognised", sp);
+       flags = PREFIX;
+       break;
+      case err_futileopt:
+       sp = va_arg(ap, char *);
+       sp2 = va_arg(ap, char *);
+       sprintf(error, "warning: option `-%s' has no effect%s", sp, sp2);
+       flags = PREFIX;
+       break;
       case err_noinput:                       /* no arguments */
        sprintf(error, "no input files");
        flags = PREFIX;
@@ -82,18 +94,20 @@ static void do_error(int code, va_list ap) {
        break;
       case err_badparatype:
        wsp = va_arg(ap, wchar_t *);
-       sp = ustrtoa(wsp, auxbuf, sizeof(auxbuf));
+       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 = ustrtoa(wsp, auxbuf, sizeof(auxbuf));
+       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 *);
@@ -115,6 +129,11 @@ static void do_error(int code, va_list ap) {
        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");
@@ -135,26 +154,43 @@ static void do_error(int code, va_list ap) {
        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 = ustrtoa(wsp, auxbuf, sizeof(auxbuf));
+       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 = ustrtoa(wsp, auxbuf, sizeof(auxbuf));
+       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 = ustrtoa(wsp, auxbuf, sizeof(auxbuf));
+       sp = utoa_locale_dup(wsp);
        sprintf(error, "`\\IM' on unknown index tag `%.200s'", sp);
-       flags = 0;
-       /* FIXME: need to get a filepos to here somehow */
+       sfree(sp);
+       flags = FILEPOS;
        break;
       case err_cantopenw:
        sp = va_arg(ap, char *);
@@ -164,9 +200,10 @@ static void do_error(int code, va_list ap) {
       case err_macroexists:
        fpos = *va_arg(ap, filepos *);
        wsp = va_arg(ap, wchar_t *);
-       sp = ustrtoa(wsp, auxbuf, sizeof(auxbuf));
+       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 *);
@@ -185,10 +222,11 @@ static void do_error(int code, va_list ap) {
        fpos = *va_arg(ap, filepos *);
        fpos2 = *va_arg(ap, filepos *);
        wsp = va_arg(ap, wchar_t *);
-       sp = ustrtoa(wsp, auxbuf, sizeof(auxbuf));
+       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 *);
@@ -202,17 +240,147 @@ static void do_error(int code, va_list ap) {
                sp);
        flags = FILEPOS;
        break;
-      case err_infodirentry:
+      case err_cfginsufarg:
        fpos = *va_arg(ap, filepos *);
-       sprintf(error, "\\cfg{info-dir-entry} expects at least three"
-               " parameters");
+       sp = va_arg(ap, char *);
+       i = va_arg(ap, int);
+       sprintf(error, "\\cfg{%s} expects at least %d parameter%s", sp,
+               i, (i==1)?"":"s");
        flags = FILEPOS;
        break;
       case err_infonodechar:
-       fpos = *va_arg(ap, filepos *);
+       fposp = va_arg(ap, filepos *);
        c = (char)va_arg(ap, int);
        sprintf(error, "info output format does not support '%c' in"
                " node names; removing", c);
+       if (fposp) {
+           flags = FILEPOS;
+           fpos = *fposp;
+       }
+       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_nofont:
+       fpos = *va_arg(ap, filepos *);
+       wsp = va_arg(ap, wchar_t *);
+       sp = utoa_locale_dup(wsp);
+       sprintf(error, "font `%.200s' not recognised", sp);
+       flags = FILEPOS;
+       sfree(sp);
+       break;
+      case err_afmeof:
+       fpos = *va_arg(ap, filepos *);
+       sprintf(error, "AFM file ended unexpectedly");
+       flags = FILEPOS;
+       break;
+      case err_afmkey:
+       fpos = *va_arg(ap, filepos *);
+       sp = va_arg(ap, char *);
+       sprintf(error, "required AFM key '%.200s' missing", sp);
+       flags = FILEPOS;
+       break;
+      case err_afmvers:
+       fpos = *va_arg(ap, filepos *);
+       sprintf(error, "unsupported AFM version");
+       flags = FILEPOS;
+       break;
+      case err_afmval:
+       fpos = *va_arg(ap, filepos *);
+       sp = va_arg(ap, char *);
+       i = va_arg(ap, int);
+       if (i == 1)
+           sprintf(error, "AFM key '%.200s' requires a value", sp);
+       else
+           sprintf(error, "AFM key '%.200s' requires %d values", sp, i);
+       flags = FILEPOS;
+       break;  
+      case err_pfeof:
+       fpos = *va_arg(ap, filepos *);
+       sprintf(error, "Type 1 font file ended unexpectedly");
+       flags = FILEPOS;
+       break;
+      case err_pfhead:
+       fpos = *va_arg(ap, filepos *);
+       sprintf(error, "Type 1 font file header line invalid");
+       flags = FILEPOS;
+       break;
+      case err_pfbad:
+       fpos = *va_arg(ap, filepos *);
+       sprintf(error, "Type 1 font file invalid");
+       flags = FILEPOS;
+       break;
+      case err_pfnoafm:
+       fpos = *va_arg(ap, filepos *);
+       sp = va_arg(ap, char *);
+       sprintf(error, "no metrics available for Type 1 font '%.200s'", sp);
+       flags = FILEPOS;
+       break;
+      case err_chmnames:
+       sprintf(error, "only one of html-mshtmlhelp-chm and "
+               "html-mshtmlhelp-hhp found");
+       flags = PREFIX;
+       break;
+      case err_sfntnotable:
+       fpos = *va_arg(ap, filepos *);
+       sp = va_arg(ap, char *);
+       sprintf(error, "font has no '%.4s' table", sp);
+       flags = FILEPOS;
+       break;
+      case err_sfntnopsname:
+       fpos = *va_arg(ap, filepos *);
+       sprintf(error, "font has no PostScript name");
+       flags = FILEPOS;
+       break;
+      case err_sfntbadtable:
+       fpos = *va_arg(ap, filepos *);
+       sp = va_arg(ap, char *);
+       sprintf(error, "font has an invalid '%.4s' table", sp);
+       flags = FILEPOS;
+       break;
+      case err_sfntnounicmap:
+       fpos = *va_arg(ap, filepos *);
+       sprintf(error, "font has no UCS-2 character map");
+       flags = FILEPOS;
+       break;  
+      case err_sfnttablevers:
+       fpos = *va_arg(ap, filepos *);
+       sp = va_arg(ap, char *);
+       sprintf(error, "font has an unsupported '%.4s' table version", sp);
+       flags = FILEPOS;
+       break;
+      case err_sfntbadhdr:
+       fpos = *va_arg(ap, filepos *);
+       sprintf(error, "font has an invalid header");
+       flags = FILEPOS;
+       break;  
+      case err_sfntbadglyph:
+       fpos = *va_arg(ap, filepos *);
+       wc = va_arg(ap, unsigned);
+       sprintf(error,
+               "warning: character U+%04X references an non-existent glyph",
+               wc);
        flags = FILEPOS;
        break;
       case err_whatever:
@@ -225,7 +393,7 @@ static void do_error(int code, va_list ap) {
     if (flags & PREFIX)
        fputs("halibut: ", stderr);
     if (flags & FILEPOS) {
-       fprintf(stderr, "%s:", fpos.filename);
+       fprintf(stderr, "%s:", fpos.filename ? fpos.filename : "<standard input>");
        if (fpos.line > 0)
            fprintf(stderr, "%d:", fpos.line);
        if (fpos.col > 0)