Rename Buttress to Halibut. I _think_ I've caught everything in this pass.
[sgt/halibut] / main.c
CommitLineData
d7482997 1/*
2 * main.c: command line parsing and top level
3 */
4
5#include <stdio.h>
6#include <stdlib.h>
7#include "halibut.h"
8
9static void dbg_prtsource(paragraph *sourceform);
10static void dbg_prtwordlist(int level, word *w);
11static void dbg_prtkws(keywordlist *kws);
12
13int main(int argc, char **argv) {
14 char **infiles;
15 char *outfile;
16 int nfiles;
17 int nogo;
18 int errs;
19 int reportcols;
20 int debug;
21
22 /*
23 * Set up initial (default) parameters.
24 */
25 infiles = mknewa(char *, argc);
26 outfile = NULL;
27 nfiles = 0;
28 nogo = errs = FALSE;
29 reportcols = 0;
30 debug = 0;
31
32 if (argc == 1) {
33 usage();
34 exit(EXIT_SUCCESS);
35 }
36
37 /*
38 * Parse command line arguments.
39 */
40 while (--argc) {
41 char *p = *++argv;
42 if (*p == '-') {
43 /*
44 * An option.
45 */
46 while (p && *++p) {
47 char c = *p;
48 switch (c) {
49 case '-':
50 /*
51 * Long option.
52 */
53 {
54 char *opt, *val;
55 opt = p++; /* opt will have _one_ leading - */
56 while (*p && *p != '=')
57 p++; /* find end of option */
58 if (*p == '=') {
59 *p++ = '\0';
60 val = p;
61 } else
62 val = NULL;
63 if (!strcmp(opt, "-help")) {
64 help();
65 nogo = TRUE;
66 } else if (!strcmp(opt, "-version")) {
67 showversion();
68 nogo = TRUE;
69 } else if (!strcmp(opt, "-licence") ||
70 !strcmp(opt, "-license")) {
71 licence();
72 nogo = TRUE;
73 } else if (!strcmp(opt, "-output")) {
74 if (!val)
75 errs = TRUE, error(err_optnoarg, opt);
76 else
77 outfile = val;
78 } else if (!strcmp(opt, "-precise")) {
79 reportcols = 1;
80 } else {
81 errs = TRUE, error(err_nosuchopt, opt);
82 }
83 }
84 p = NULL;
85 break;
86 case 'h':
87 case 'V':
88 case 'L':
89 case 'P':
90 case 'd':
91 /*
92 * Option requiring no parameter.
93 */
94 switch (c) {
95 case 'h':
96 help();
97 nogo = TRUE;
98 break;
99 case 'V':
100 showversion();
101 nogo = TRUE;
102 break;
103 case 'L':
104 licence();
105 nogo = TRUE;
106 break;
107 case 'P':
108 reportcols = 1;
109 break;
110 case 'd':
111 debug = TRUE;
112 break;
113 }
114 break;
115 case 'o':
116 /*
117 * Option requiring parameter.
118 */
119 p++;
120 if (!*p && argc > 1)
121 --argc, p = *++argv;
122 else if (!*p) {
123 char opt[2];
124 opt[0] = c;
125 opt[1] = '\0';
126 errs = TRUE, error(err_optnoarg, opt);
127 }
128 /*
129 * Now c is the option and p is the parameter.
130 */
131 switch (c) {
132 case 'o':
133 outfile = p;
134 break;
135 }
136 p = NULL; /* prevent continued processing */
137 break;
138 default:
139 /*
140 * Unrecognised option.
141 */
142 {
143 char opt[2];
144 opt[0] = c;
145 opt[1] = '\0';
146 errs = TRUE, error(err_nosuchopt, opt);
147 }
148 }
149 }
150 } else {
151 /*
152 * A non-option argument.
153 */
154 infiles[nfiles++] = p;
155 }
156 }
157
158 if (errs)
159 exit(EXIT_FAILURE);
160 if (nogo)
161 exit(EXIT_SUCCESS);
162
163 /*
164 * Do the work.
165 */
166 if (nfiles == 0) {
167 error(err_noinput);
168 usage();
169 exit(EXIT_FAILURE);
170 }
171
172 {
173 input in;
174 paragraph *sourceform, *p;
175 indexdata *idx;
176 keywordlist *keywords;
177
178 in.filenames = infiles;
179 in.nfiles = nfiles;
180 in.currfp = NULL;
181 in.currindex = 0;
182 in.npushback = in.pushbacksize = 0;
183 in.pushback = NULL;
184 in.reportcols = reportcols;
185 in.stack = NULL;
186
187 idx = make_index();
188
189 sourceform = read_input(&in, idx);
190 if (!sourceform)
191 exit(EXIT_FAILURE);
192
193 sfree(in.pushback);
194
195 mark_attr_ends(sourceform);
196
197 sfree(infiles);
198
199 keywords = get_keywords(sourceform);
200 if (!keywords)
201 exit(EXIT_FAILURE);
202 gen_citations(sourceform, keywords);
203 subst_keywords(sourceform, keywords);
204
205 for (p = sourceform; p; p = p->next)
206 if (p->type == para_IM)
207 index_merge(idx, TRUE, p->keyword, p->words);
208
209 build_index(idx);
210
211 if (debug) {
212 index_debug(idx);
213 dbg_prtkws(keywords);
214 dbg_prtsource(sourceform);
215 }
216
217 text_backend(sourceform, keywords, idx);
218 xhtml_backend(sourceform, keywords, idx);
219 whlp_backend(sourceform, keywords, idx);
220
221 free_para_list(sourceform);
222 free_keywords(keywords);
223 cleanup_index(idx);
224 }
225
226 return 0;
227}
228
229static void dbg_prtsource(paragraph *sourceform) {
230 /*
231 * Output source form in debugging format.
232 */
233
234 paragraph *p;
235 for (p = sourceform; p; p = p->next) {
236 wchar_t *wp;
237 printf("para %d ", p->type);
238 if (p->keyword) {
239 wp = p->keyword;
240 while (*wp) {
241 putchar('\"');
242 for (; *wp; wp++)
243 putchar(*wp);
244 putchar('\"');
245 if (*++wp)
246 printf(", ");
247 }
248 } else
249 printf("(no keyword)");
250 printf(" {\n");
251 dbg_prtwordlist(1, p->words);
252 printf("}\n");
253 }
254}
255
256static void dbg_prtkws(keywordlist *kws) {
257 /*
258 * Output keywords in debugging format.
259 */
260
261 int i;
262 keyword *kw;
263
264 for (i = 0; (kw = index234(kws->keys, i)) != NULL; i++) {
265 wchar_t *wp;
266 printf("keyword ");
267 wp = kw->key;
268 while (*wp) {
269 putchar('\"');
270 for (; *wp; wp++)
271 putchar(*wp);
272 putchar('\"');
273 if (*++wp)
274 printf(", ");
275 }
276 printf(" {\n");
277 dbg_prtwordlist(1, kw->text);
278 printf("}\n");
279 }
280}
281
282static void dbg_prtwordlist(int level, word *w) {
283 for (; w; w = w->next) {
284 wchar_t *wp;
285 printf("%*sword %d ", level*4, "", w->type);
286 if (w->text) {
287 printf("\"");
288 for (wp = w->text; *wp; wp++)
289 putchar(*wp);
290 printf("\"");
291 } else
292 printf("(no text)");
293 if (w->alt) {
294 printf(" alt = {\n");
295 dbg_prtwordlist(level+1, w->alt);
296 printf("%*s}", level*4, "");
297 }
298 printf("\n");
299 }
300}