Implemented an index. Good _grief_, that was hard work to get all
[sgt/halibut] / main.c
diff --git a/main.c b/main.c
index a528453..9af17b3 100644 (file)
--- a/main.c
+++ b/main.c
@@ -11,18 +11,29 @@ static void dbg_prtsource(paragraph *sourceform);
 static void dbg_prtwordlist(int level, word *w);
 static void dbg_prtkws(keywordlist *kws);
 
+static const struct pre_backend {
+    void *(*func)(paragraph *, keywordlist *, indexdata *);
+    int bitfield;
+} pre_backends[] = {
+    {paper_pre_backend, 0x0001}
+};
+
 static const struct backend {
     char *name;
-    void (*func)(paragraph *, keywordlist *, indexdata *);
-    int bitfield;
+    void (*func)(paragraph *, keywordlist *, indexdata *, void *);
+    paragraph *(*filename)(char *filename);
+    int bitfield, prebackend_bitfield;
 } backends[] = {
-    {"text", text_backend, 0x0001},
-    {"xhtml", xhtml_backend, 0x0002},
-    {"html", xhtml_backend, 0x0002},
-    {"hlp", whlp_backend, 0x0004},
-    {"whlp", whlp_backend, 0x0004},
-    {"winhelp", whlp_backend, 0x0004},
-    {"man", man_backend, 0x0008},
+    {"text", text_backend, text_config_filename, 0x0001, 0},
+    {"xhtml", xhtml_backend, xhtml_config_filename, 0x0002, 0},
+    {"html", xhtml_backend, xhtml_config_filename, 0x0002, 0},
+    {"hlp", whlp_backend, whlp_config_filename, 0x0004, 0},
+    {"whlp", whlp_backend, whlp_config_filename, 0x0004, 0},
+    {"winhelp", whlp_backend, whlp_config_filename, 0x0004, 0},
+    {"man", man_backend, man_config_filename, 0x0008, 0},
+    {"info", info_backend, info_config_filename, 0x0010, 0},
+    {"ps", ps_backend, ps_config_filename, 0x0020, 0x0001},
+    {"pdf", pdf_backend, pdf_config_filename, 0x0040, 0x0001},
 };
 
 int main(int argc, char **argv) {
@@ -32,8 +43,10 @@ int main(int argc, char **argv) {
     int errs;
     int reportcols;
     int debug;
-    int backendbits;
+    int backendbits, prebackbits;
     int k, b;
+    paragraph *cfg, *cfg_tail;
+    void *pre_backend_data[16];
 
     /*
      * Set up initial (default) parameters.
@@ -44,6 +57,7 @@ int main(int argc, char **argv) {
     reportcols = 0;
     debug = 0;
     backendbits = 0;
+    cfg = cfg_tail = NULL;
 
     if (argc == 1) {
        usage();
@@ -81,6 +95,17 @@ int main(int argc, char **argv) {
                        for (k = 0; k < (int)lenof(backends); k++)
                            if (!strcmp(opt+1, backends[k].name)) {
                                backendbits |= backends[k].bitfield;
+                               if (val) {
+                                   paragraph *p = backends[k].filename(val);
+                                   assert(p);
+                                   if (cfg_tail)
+                                       cfg_tail->next = p;
+                                   else
+                                       cfg = p;
+                                   while (p->next)
+                                       p = p->next;
+                                   cfg_tail = p;
+                               }
                                break;
                            }
                        if (k < (int)lenof(backends)) {
@@ -132,8 +157,7 @@ int main(int argc, char **argv) {
                        break;
                    }
                    break;
-#if 0
-                 case 'o':
+                 case 'C':
                    /*
                     * Option requiring parameter.
                     */
@@ -150,13 +174,54 @@ int main(int argc, char **argv) {
                     * Now c is the option and p is the parameter.
                     */
                    switch (c) {
-                     case 'o':
-                       outfile = p;
+                     case 'C':
+                       /*
+                        * -C means we split our argument up into
+                        * colon-separated chunks and assemble them
+                        * into a config paragraph.
+                        */
+                       {
+                           wchar_t *keywords;
+                           char *q;
+                           wchar_t *u;
+                           paragraph *para;
+
+                           keywords = mknewa(wchar_t, 2+strlen(p));
+
+                           u = keywords;
+                           q = p;
+
+                           while (*q) {
+                               if (*q == ':') {
+                                   *u++ = L'\0';
+                               } else {
+                                   if (*q == '\\' && q[1])
+                                       q++;
+                                   /* FIXME: lacks charset flexibility */
+                                   *u++ = *q;
+                               }
+                               q++;
+                           }
+                           *u = L'\0';
+
+                           para = mknew(paragraph);
+                           memset(para, 0, sizeof(*para));
+                           para->type = para_Config;
+                           para->keyword = keywords;
+                           para->next = NULL;
+                           para->fpos.filename = "<command line>";
+                           para->fpos.line = para->fpos.col = -1;
+
+                           if (cfg_tail)
+                               cfg_tail->next = para;
+                           else
+                               cfg = para;
+                           cfg_tail = para;
+                       }
                        break;
                    }
                    p = NULL;          /* prevent continued processing */
                    break;
-#endif
                  default:
                    /*
                     * Unrecognised option.
@@ -212,6 +277,21 @@ int main(int argc, char **argv) {
        if (!sourceform)
            exit(EXIT_FAILURE);
 
+       /*
+        * Append the config directives acquired from the command
+        * line.
+        */
+       {
+           paragraph *end;
+
+           end = sourceform;
+           while (end && end->next)
+               end = end->next;
+           assert(end);
+
+           end->next = cfg;
+       }
+
        sfree(in.pushback);
 
        mark_attr_ends(sourceform);
@@ -226,7 +306,7 @@ int main(int argc, char **argv) {
 
        for (p = sourceform; p; p = p->next)
            if (p->type == para_IM)
-               index_merge(idx, TRUE, p->keyword, p->words);
+               index_merge(idx, TRUE, p->keyword, p->words, &p->fpos);
 
        build_index(idx);
 
@@ -237,13 +317,39 @@ int main(int argc, char **argv) {
        }
 
        /*
+        * Select and run the pre-backends.
+        */
+       prebackbits = 0;
+       for (k = 0; k < (int)lenof(backends); k++)
+           if (backendbits == 0 || (backendbits & backends[k].bitfield))
+               prebackbits |= backends[k].prebackend_bitfield;
+       for (k = 0; k < (int)lenof(pre_backends); k++)
+           if (prebackbits & pre_backends[k].bitfield) {
+               assert(k < (int)lenof(pre_backend_data));
+               pre_backend_data[k] =
+                   pre_backends[k].func(sourceform, keywords, idx);
+           }
+
+       /*
         * Run the selected set of backends.
         */
        for (k = b = 0; k < (int)lenof(backends); k++)
            if (b != backends[k].bitfield) {
                b = backends[k].bitfield;
-               if (backendbits == 0 || (backendbits & b))
-                   backends[k].func(sourceform, keywords, idx);
+               if (backendbits == 0 || (backendbits & b)) {
+                   void *pbd = NULL;
+                   int pbb = backends[k].prebackend_bitfield;
+                   int m;
+
+                   for (m = 0; m < (int)lenof(pre_backends); m++)
+                       if (pbb & pre_backends[m].bitfield) {
+                           assert(m < (int)lenof(pre_backend_data));
+                           pbd = pre_backend_data[m];
+                           break;
+                       }
+                           
+                   backends[k].func(sourceform, keywords, idx, pbd);
+               }
            }
 
        free_para_list(sourceform);