Add an error check for correct formatting in Deflate uncompressed
[sgt/halibut] / bk_whlp.c
index 08f2532..d15d029 100644 (file)
--- a/bk_whlp.c
+++ b/bk_whlp.c
@@ -24,6 +24,7 @@ struct bk_whlp_state {
 typedef struct {
     int charset;
     wchar_t *bullet, *lquote, *rquote, *titlepage, *sectsuffix, *listsuffix;
+    wchar_t *contents_text;
     char *filename;
 } whlpconf;
 
@@ -73,6 +74,7 @@ static whlpconf whlp_configure(paragraph *source) {
     ret.rquote = uadv(ret.lquote);
     ret.filename = dupstr("output.hlp");
     ret.titlepage = L"Title page";
+    ret.contents_text = L"Contents";
     ret.sectsuffix = L": ";
     ret.listsuffix = L".";
 
@@ -122,6 +124,8 @@ static whlpconf whlp_configure(paragraph *source) {
                    ret.lquote = uadv(p->keyword);
                    ret.rquote = uadv(ret.lquote);
                }
+           } else if (!ustricmp(p->keyword, L"contents")) {
+               ret.contents_text = uadv(p->keyword);
            }
        }
     }
@@ -201,17 +205,21 @@ void whlp_backend(paragraph *sourceform, keywordlist *keywords,
            tolower(conf.filename[len-2] != 'l') ||
            tolower(conf.filename[len-1] != 'p')) {
            char *newf;
-           newf = mknewa(char, len + 5);
+           newf = snewn(len + 5, char);
            sprintf(newf, "%s.hlp", conf.filename);
            sfree(conf.filename);
            conf.filename = newf;
            len = strlen(newf);
        }
-       cntname = mknewa(char, len+1);
+       cntname = snewn(len+1, char);
        sprintf(cntname, "%.*s.cnt", len-4, conf.filename);
     }
 
     state.cntfp = fopen(cntname, "wb");
+    if (!state.cntfp) {
+       error(err_cantopenw, cntname);
+       return;
+    }
     state.cnt_last_level = -1; state.cnt_workaround = 0;
 
     /*
@@ -246,10 +254,63 @@ void whlp_backend(paragraph *sourceform, keywordlist *keywords,
      * Loop over the index entries, preparing final text forms for
      * each one.
      */
-    for (i = 0; (ie = index234(idx->entries, i)) != NULL; i++) {
-       rdstringc rs = {0, 0, NULL};
-       whlp_rdaddwc(&rs, ie->text, &conf, NULL);
-       ie->backend_data = rs.text;
+    {
+       indexentry *ie_prev = NULL;
+       int nspaces = 1;
+
+       for (i = 0; (ie = index234(idx->entries, i)) != NULL; i++) {
+           rdstringc rs = {0, 0, NULL};
+           charset_state state = CHARSET_INIT_STATE;
+           whlp_rdaddwc(&rs, ie->text, &conf, &state);
+
+           if (ie_prev) {
+               /*
+                * It appears that Windows Help's index mechanism
+                * is inherently case-insensitive. Therefore, if two
+                * adjacent index terms compare equal apart from
+                * case, I'm going to append nonbreaking spaces to
+                * the end of the second one so that Windows will
+                * treat them as distinct.
+                * 
+                * This is nasty because we're depending on our
+                * case-insensitive comparison having the same
+                * semantics as the Windows one :-/ but I see no
+                * alternative.
+                */
+               wchar_t *a, *b;
+
+               a = ufroma_dup((char *)ie_prev->backend_data, conf.charset);
+               b = ufroma_dup(rs.text, conf.charset);
+               if (!ustricmp(a, b)) {
+                   int j;
+                   for (j = 0; j < nspaces; j++)
+                       whlp_rdadds(&rs, L"\xA0", &conf, &state);
+                   /*
+                    * Add one to nspaces, so that if another term
+                    * appears which is equivalent to the previous
+                    * two it'll acquire one more space.
+                    */
+                   nspaces++;
+               } else
+                   nspaces = 1;
+               sfree(a);
+               sfree(b);
+           }
+
+           whlp_rdadds(&rs, NULL, &conf, &state);
+
+           ie->backend_data = rs.text;
+
+           /*
+            * Only move ie_prev on if nspaces==1 (since when we
+            * have three or more adjacent terms differing only in
+            * case, we will want to compare with the _first_ of
+            * them because that won't have had any extra spaces
+            * added on which will foul up the comparison).
+            */
+           if (nspaces == 1)
+               ie_prev = ie;
+       }
     }
 
     whlp_prepare(h);
@@ -257,8 +318,13 @@ void whlp_backend(paragraph *sourceform, keywordlist *keywords,
     /* ------------------------------------------------------------------
      * Begin the contents page.
      */
-
-    whlp_begin_topic(h, contents_topic, "Contents", "DB(\"btn_up\")", NULL);
+    {
+       rdstringc rs = {0, 0, NULL};
+       whlp_rdadds(&rs, conf.contents_text, &conf, NULL);
+       whlp_begin_topic(h, contents_topic, rs.text, "DB(\"btn_up\")", NULL);
+       state.curr_topic = contents_topic;
+       sfree(rs.text);
+    }
 
     /*
      * The manual title goes in the non-scroll region, and also
@@ -359,8 +425,6 @@ void whlp_backend(paragraph *sourceform, keywordlist *keywords,
                    whlp_navmenu(&state, p, &conf);
            }
 
-           state.curr_topic = contents_topic;
-
            done_contents_topic = TRUE;
        }
 
@@ -552,7 +616,7 @@ void whlp_backend(paragraph *sourceform, keywordlist *keywords,
                        whlp_set_font(h, FONT_BOLD_CODE);
                    else
                        whlp_set_font(h, FONT_CODE);
-                   tmp = mknewa(wchar_t, n+1);
+                   tmp = snewn(n+1, wchar_t);
                    ustrncpy(tmp, t, n);
                    tmp[n] = L'\0';
                    whlp_wtext(&state, tmp);