2 * main.c: command line parsing and top level
11 static void dbg_prtsource(paragraph
*sourceform
);
12 static void dbg_prtwordlist(int level
, word
*w
);
13 static void dbg_prtkws(keywordlist
*kws
);
15 static const struct pre_backend
{
16 void *(*func
)(paragraph
*, keywordlist
*, indexdata
*);
19 {paper_pre_backend
, 0x0001}
22 static const struct backend
{
24 void (*func
)(paragraph
*, keywordlist
*, indexdata
*, void *);
25 paragraph
*(*filename
)(char *filename
);
26 int bitfield
, prebackend_bitfield
;
28 {"text", text_backend
, text_config_filename
, 0x0001, 0},
29 {"xhtml", html_backend
, html_config_filename
, 0x0002, 0},
30 {"html", html_backend
, html_config_filename
, 0x0002, 0},
31 {"hlp", whlp_backend
, whlp_config_filename
, 0x0004, 0},
32 {"whlp", whlp_backend
, whlp_config_filename
, 0x0004, 0},
33 {"winhelp", whlp_backend
, whlp_config_filename
, 0x0004, 0},
34 {"man", man_backend
, man_config_filename
, 0x0008, 0},
35 {"info", info_backend
, info_config_filename
, 0x0010, 0},
36 {"ps", ps_backend
, ps_config_filename
, 0x0020, 0x0001},
37 {"pdf", pdf_backend
, pdf_config_filename
, 0x0040, 0x0001},
40 int main(int argc
, char **argv
) {
49 int backendbits
, prebackbits
;
51 paragraph
*cfg
, *cfg_tail
;
52 void *pre_backend_data
[16];
55 * Use the specified locale everywhere. It'll be used for
56 * output of error messages, and as the default character set
57 * for input files if one is not explicitly specified.
59 * However, we need to use standard numeric formatting for
60 * output of things like PDF.
62 setlocale(LC_ALL
, "");
63 setlocale(LC_NUMERIC
, "C");
66 * Set up initial (default) parameters.
68 infiles
= snewn(argc
, char *);
73 input_charset
= CS_ASCII
;
76 cfg
= cfg_tail
= NULL
;
84 * Parse command line arguments.
88 if (*p
== '-' && p
[1]) {
101 opt
= p
++; /* opt will have _one_ leading - */
102 while (*p
&& *p
!= '=')
103 p
++; /* find end of option */
110 assert(opt
[0] == '-');
111 for (k
= 0; k
< (int)lenof(backends
); k
++)
112 if (!strcmp(opt
+1, backends
[k
].name
)) {
113 backendbits
|= backends
[k
].bitfield
;
115 paragraph
*p
= backends
[k
].filename(val
);
127 if (k
< (int)lenof(backends
)) {
129 } else if (!strcmp(opt
, "-input-charset")) {
131 errs
= TRUE
, error(err_optnoarg
, opt
);
133 int charset
= charset_from_localenc(val
);
134 if (charset
== CS_NONE
) {
135 errs
= TRUE
, error(err_cmdcharset
, val
);
137 input_charset
= charset
;
140 } else if (!strcmp(opt
, "-help")) {
143 } else if (!strcmp(opt
, "-version")) {
146 } else if (!strcmp(opt
, "-licence") ||
147 !strcmp(opt
, "-license")) {
150 } else if (!strcmp(opt
, "-list-charsets")) {
153 } else if (!strcmp(opt
, "-list-fonts")) {
155 } else if (!strcmp(opt
, "-precise")) {
158 errs
= TRUE
, error(err_nosuchopt
, opt
);
169 * Option requiring no parameter.
194 * Option requiring parameter.
203 errs
= TRUE
, error(err_optnoarg
, opt
);
206 * Now c is the option and p is the parameter.
211 * -C means we split our argument up into
212 * colon-separated chunks and assemble them
213 * into a config paragraph.
216 char *s
= dupstr(p
), *q
, *r
;
219 para
= cmdline_cfg_new();
225 /* XXX ad-hoc diagnostic */
226 if (!strcmp(s
, "input-charset"))
227 error(err_futileopt
, "Cinput-charset",
228 "; use --input-charset");
229 cmdline_cfg_add(para
, s
);
232 if (*q
== '\\' && q
[1])
239 cmdline_cfg_add(para
, s
);
242 cfg_tail
->next
= para
;
249 p
= NULL
; /* prevent continued processing */
253 * Unrecognised option.
259 errs
= TRUE
, error(err_nosuchopt
, opt
);
265 * A non-option argument.
268 infiles
[nfiles
++] = NULL
; /* special case: read stdin */
270 infiles
[nfiles
++] = p
;
282 if (nfiles
== 0 && !list_fonts
) {
290 paragraph
*sourceform
, *p
;
292 keywordlist
*keywords
;
294 in
.filenames
= infiles
;
298 in
.npushback
= in
.pushbacksize
= 0;
300 in
.reportcols
= reportcols
;
302 in
.defcharset
= input_charset
;
306 sourceform
= read_input(&in
, idx
);
315 * Append the config directives acquired from the command
322 while (end
&& end
->next
)
333 keywords
= get_keywords(sourceform
);
336 gen_citations(sourceform
, keywords
);
337 subst_keywords(sourceform
, keywords
);
339 for (p
= sourceform
; p
; p
= p
->next
)
340 if (p
->type
== para_IM
)
341 index_merge(idx
, TRUE
, p
->keyword
, p
->words
, &p
->fpos
);
346 * Set up attr_First / attr_Last / attr_Always, in the main
347 * document and in the index entries.
349 for (p
= sourceform
; p
; p
= p
->next
)
350 mark_attr_ends(p
->words
);
355 for (i
= 0; (entry
= index234(idx
->entries
, i
)) != NULL
; i
++)
356 mark_attr_ends(entry
->text
);
361 dbg_prtkws(keywords
);
362 dbg_prtsource(sourceform
);
366 * Select and run the pre-backends.
369 for (k
= 0; k
< (int)lenof(backends
); k
++)
370 if (backendbits
== 0 || (backendbits
& backends
[k
].bitfield
))
371 prebackbits
|= backends
[k
].prebackend_bitfield
;
372 for (k
= 0; k
< (int)lenof(pre_backends
); k
++)
373 if (prebackbits
& pre_backends
[k
].bitfield
) {
374 assert(k
< (int)lenof(pre_backend_data
));
375 pre_backend_data
[k
] =
376 pre_backends
[k
].func(sourceform
, keywords
, idx
);
380 * Run the selected set of backends.
382 for (k
= b
= 0; k
< (int)lenof(backends
); k
++)
383 if (b
!= backends
[k
].bitfield
) {
384 b
= backends
[k
].bitfield
;
385 if (backendbits
== 0 || (backendbits
& b
)) {
387 int pbb
= backends
[k
].prebackend_bitfield
;
390 for (m
= 0; m
< (int)lenof(pre_backends
); m
++)
391 if (pbb
& pre_backends
[m
].bitfield
) {
392 assert(m
< (int)lenof(pre_backend_data
));
393 pbd
= pre_backend_data
[m
];
397 backends
[k
].func(sourceform
, keywords
, idx
, pbd
);
401 free_para_list(sourceform
);
402 free_keywords(keywords
);
409 static void dbg_prtsource(paragraph
*sourceform
) {
411 * Output source form in debugging format.
415 for (p
= sourceform
; p
; p
= p
->next
) {
417 printf("para %d ", p
->type
);
429 printf("(no keyword)");
431 dbg_prtwordlist(1, p
->words
);
436 static void dbg_prtkws(keywordlist
*kws
) {
438 * Output keywords in debugging format.
444 for (i
= 0; (kw
= index234(kws
->keys
, i
)) != NULL
; i
++) {
457 dbg_prtwordlist(1, kw
->text
);
462 static void dbg_prtwordlist(int level
, word
*w
) {
463 for (; w
; w
= w
->next
) {
465 printf("%*sword %d ", level
*4, "", w
->type
);
468 for (wp
= w
->text
; *wp
; wp
++)
476 printf(" alt = {\n");
477 dbg_prtwordlist(level
+1, w
->alt
);
478 printf("%*s}", level
*4, "");