blob: 3e461dcb9d06370a9c4b112894fc0aee858afde0 [file] [log] [blame]
Lev Walkin12984672004-09-24 21:00:15 +00001/*-
Lev Walkin46499872006-03-06 13:05:34 +00002 * Copyright (c) 2003, 2004, 2005, 2006
Lev Walkinc0d04912005-02-25 12:52:27 +00003 * Lev Walkin <vlm@lionet.info>. All rights reserved.
Lev Walkin12984672004-09-24 21:00:15 +00004 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 *
26 * $Id$
27 */
Lev Walkinf15320b2004-06-03 03:38:44 +000028/*
29 * This is the program that connects the libasn1* libraries together.
30 * It uses them in turn to parse, fix and then compile or print the ASN.1 tree.
31 */
Lev Walkinc0d04912005-02-25 12:52:27 +000032#include "sys-common.h"
Lev Walkinf15320b2004-06-03 03:38:44 +000033
Lev Walkinfb872bd2006-03-18 06:53:11 +000034#undef COPYRIGHT
35#define COPYRIGHT \
36 "Copyright (c) 2003, 2004, 2005, 2006 Lev Walkin <vlm@lionet.info>\n"
37
Lev Walkinf15320b2004-06-03 03:38:44 +000038#include <asn1parser.h> /* Parse the ASN.1 file and build a tree */
39#include <asn1fix.h> /* Fix the ASN.1 tree */
40#include <asn1print.h> /* Print the ASN.1 tree */
41#include <asn1compiler.h> /* Compile the ASN.1 tree */
42
Lev Walkin79f54952004-08-13 16:58:19 +000043#include <asn1c_compat.h> /* Portable basename(3) and dirname(3) */
44
Lev Walkin46499872006-03-06 13:05:34 +000045#ifdef WIN32
46#include <io.h>
47#include <direct.h>
48#else
49#include <dirent.h>
50#endif
51
Lev Walkinc0d04912005-02-25 12:52:27 +000052static void usage(const char *av0); /* Print the Usage screen and exit */
Lev Walkin46499872006-03-06 13:05:34 +000053static int importStandardModules(asn1p_t *asn, const char *skeletons_dir);
Lev Walkincbf218f2004-08-20 13:24:38 +000054
Lev Walkinf15320b2004-06-03 03:38:44 +000055int
56main(int ac, char **av) {
Lev Walkin7415bff2004-08-16 11:38:13 +000057 enum asn1p_flags asn1_parser_flags = A1P_NOFLAGS;
58 enum asn1f_flags asn1_fixer_flags = A1F_NOFLAGS;
Lev Walkincbf218f2004-08-20 13:24:38 +000059 enum asn1c_flags asn1_compiler_flags= A1C_NO_C99;
Lev Walkinab4bb292004-08-18 04:52:48 +000060 enum asn1print_flags asn1_printer_flags = APF_NOFLAGS;
Lev Walkinf15320b2004-06-03 03:38:44 +000061 int print_arg__print_out = 0; /* Don't compile, just print parsed */
62 int print_arg__fix_n_print = 0; /* Fix and print */
Lev Walkinf15320b2004-06-03 03:38:44 +000063 int warnings_as_errors = 0; /* Treat warnings as errors */
64 char *skeletons_dir = NULL; /* Directory with supplementary stuff */
65 asn1p_t *asn = 0; /* An ASN.1 parsed tree */
66 int ret; /* Return value from misc functions */
67 int ch; /* Command line character */
68 int i; /* Index in some loops */
69
70 /*
71 * Process command-line options.
72 */
Lev Walkin59b176e2005-11-26 11:25:14 +000073 while((ch = getopt(ac, av, "EFf:g:hLPp:RS:vW:X")) != -1)
Lev Walkinf15320b2004-06-03 03:38:44 +000074 switch(ch) {
75 case 'E':
76 print_arg__print_out = 1;
77 break;
78 case 'F':
79 print_arg__fix_n_print = 1;
80 break;
81 case 'f':
Lev Walkindd32b592004-09-06 08:07:29 +000082 if(strcmp(optarg, "all-defs-global") == 0) {
83 asn1_compiler_flags |= A1C_ALL_DEFS_GLOBAL;
84 } else if(strcmp(optarg, "bless-SIZE") == 0) {
85 asn1_fixer_flags |= A1F_EXTENDED_SizeConstraint;
Lev Walkin21d00002005-03-04 08:48:53 +000086 } else if(strcmp(optarg, "compound-names") == 0) {
87 asn1_compiler_flags |= A1C_COMPOUND_NAMES;
Lev Walkin72a0f5a2005-07-24 08:28:39 +000088 } else if(strcmp(optarg, "indirect-choice") == 0) {
89 asn1_compiler_flags |= A1C_INDIRECT_CHOICE;
Lev Walkin5555d532004-06-28 21:21:45 +000090 } else if(strncmp(optarg, "known-extern-type=", 18) == 0) {
91 char *known_type = optarg + 18;
92 ret = asn1f_make_known_external_type(known_type);
93 assert(ret == 0 || errno == EEXIST);
Lev Walkin46499872006-03-06 13:05:34 +000094 } else if(strcmp(optarg, "native-types") == 0) {
Lev Walkin99301892004-09-14 12:48:17 +000095 asn1_compiler_flags |= A1C_USE_NATIVE_TYPES;
Lev Walkin4e940a02004-09-26 13:13:13 +000096 } else if(strcmp(optarg, "no-constraints") == 0) {
97 asn1_compiler_flags |= A1C_NO_CONSTRAINTS;
Lev Walkinb9b8b952005-03-05 00:33:27 +000098 } else if(strcmp(optarg, "no-include-deps") == 0) {
99 asn1_compiler_flags |= A1C_NO_INCLUDE_DEPS;
Lev Walkindd32b592004-09-06 08:07:29 +0000100 } else if(strcmp(optarg, "unnamed-unions") == 0) {
101 asn1_compiler_flags |= A1C_UNNAMED_UNIONS;
Lev Walkina895afb2005-10-06 10:09:34 +0000102 } else if(strcmp(optarg, "skeletons-copy") == 0) {
103 asn1_compiler_flags |= A1C_SKELETONS_COPY;
Lev Walkinf15320b2004-06-03 03:38:44 +0000104 } else {
105 fprintf(stderr, "-f%s: Invalid argument\n", optarg);
106 exit(EX_USAGE);
107 }
108 break;
Lev Walkin59b176e2005-11-26 11:25:14 +0000109 case 'g':
110 if(strcmp(optarg, "en-PER") == 0) {
111 asn1_compiler_flags |= A1C_GEN_PER;
112 } else {
113 fprintf(stderr, "-g%s: Invalid argument\n", optarg);
114 exit(EX_USAGE);
115 }
116 break;
Lev Walkincbf218f2004-08-20 13:24:38 +0000117 case 'h':
118 usage(av[0]);
Lev Walkinf15320b2004-06-03 03:38:44 +0000119 case 'P':
120 asn1_compiler_flags |= A1C_PRINT_COMPILED;
Lev Walkincbf218f2004-08-20 13:24:38 +0000121 asn1_compiler_flags &= ~A1C_NO_C99;
Lev Walkinf15320b2004-06-03 03:38:44 +0000122 break;
Lev Walkinab4bb292004-08-18 04:52:48 +0000123 case 'p':
Lev Walkin59b176e2005-11-26 11:25:14 +0000124 if(strncmp(optarg, "du=", 3) == 0) {
125 char *pduname = optarg + 3;
126 if(strcmp(pduname, "auto")) {
127 fprintf(stderr, "-pdu=%s: expected -pdu=auto\n",
128 pduname);
129 exit(EX_USAGE);
130 }
131 asn1_compiler_flags |= A1C_PDU_AUTO;
Lev Walkind370e9f2006-03-16 10:03:35 +0000132 } else if(strcmp(optarg, "rint-class-matrix") == 0) {
133 asn1_printer_flags |= APF_PRINT_CLASS_MATRIX;
Lev Walkin59b176e2005-11-26 11:25:14 +0000134 } else if(strcmp(optarg, "rint-constraints") == 0) {
Lev Walkind370e9f2006-03-16 10:03:35 +0000135 asn1_printer_flags |= APF_PRINT_CONSTRAINTS;
Lev Walkincbf218f2004-08-20 13:24:38 +0000136 } else if(strcmp(optarg, "rint-lines") == 0) {
137 asn1_printer_flags |= APF_LINE_COMMENTS;
Lev Walkinab4bb292004-08-18 04:52:48 +0000138 } else {
139 fprintf(stderr, "-p%s: Invalid argument\n", optarg);
140 exit(EX_USAGE);
141 }
142 break;
Lev Walkinf15320b2004-06-03 03:38:44 +0000143 case 'R':
144 asn1_compiler_flags |= A1C_OMIT_SUPPORT_CODE;
145 break;
146 case 'S':
147 skeletons_dir = optarg;
148 break;
Lev Walkincbf218f2004-08-20 13:24:38 +0000149 case 'v':
150 fprintf(stderr, "ASN.1 Compiler, v" VERSION "\n" COPYRIGHT);
151 exit(0);
152 break;
Lev Walkinf15320b2004-06-03 03:38:44 +0000153 case 'W':
154 if(strcmp(optarg, "error") == 0) {
155 warnings_as_errors = 1;
156 break;
157 } else if(strcmp(optarg, "debug-lexer") == 0) {
158 asn1_parser_flags |= A1P_LEXER_DEBUG;
159 break;
160 } else if(strcmp(optarg, "debug-fixer") == 0) {
161 asn1_fixer_flags |= A1F_DEBUG;
162 break;
163 } else if(strcmp(optarg, "debug-compiler") == 0) {
164 asn1_compiler_flags |= A1C_DEBUG;
165 break;
166 } else {
167 fprintf(stderr, "-W%s: Invalid argument\n", optarg);
168 exit(EX_USAGE);
169 }
170 break;
Lev Walkinf7484512004-10-13 09:13:56 +0000171 case 'X':
172 print_arg__print_out = 1; /* Implicit -E */
173 print_arg__fix_n_print = 1; /* Implicit -F */
174 asn1_printer_flags |= APF_PRINT_XML_DTD;
175 break;
Lev Walkinf15320b2004-06-03 03:38:44 +0000176 default:
177 usage(av[0]);
178 }
179
180 /*
181 * Validate the options combination.
182 */
183 if(!print_arg__print_out) {
184 if(print_arg__fix_n_print) {
185 fprintf(stderr, "Error: -F requires -E\n");
186 exit(EX_USAGE);
187 }
Lev Walkinab4bb292004-08-18 04:52:48 +0000188 if(asn1_printer_flags) {
189 fprintf(stderr, "Error: "
Lev Walkincbf218f2004-08-20 13:24:38 +0000190 "-print-... arguments require -E\n");
Lev Walkinab4bb292004-08-18 04:52:48 +0000191 exit(EX_USAGE);
192 }
Lev Walkinf15320b2004-06-03 03:38:44 +0000193 }
194
195 /*
196 * Ensure that there are some input files present.
197 */
198 if(ac > optind) {
199 ac -= optind;
200 av += optind;
201 } else {
Lev Walkinbf430382005-11-05 12:28:16 +0000202 char *bin_name = a1c_basename(av[0]);
203 fprintf(stderr, "%s: No input files specified. "
204 "Try '%s -h' for more information\n",
205 bin_name, bin_name);
Lev Walkinf15320b2004-06-03 03:38:44 +0000206 exit(1);
207 }
208
209 /*
Lev Walkin46499872006-03-06 13:05:34 +0000210 * Make sure the skeleton directory is out there.
211 */
212 if(skeletons_dir == NULL) {
213 struct stat sb;
214 skeletons_dir = DATADIR;
215 if((av[-optind][0] == '.' || av[-optind][1] == '/')
216 && stat(skeletons_dir, &sb)) {
217 /*
218 * The default skeletons directory does not exist,
219 * compute it from my file name:
220 * ./asn1c/asn1c -> ./skeletons
221 */
222 char *p;
223 size_t len;
224
225 p = a1c_dirname(av[-optind]);
226
227 len = strlen(p) + sizeof("/../skeletons");
228 skeletons_dir = malloc(len);
229 assert(skeletons_dir);
230 snprintf(skeletons_dir, len, "%s/../skeletons", p);
231 if(stat(skeletons_dir, &sb)) {
232 fprintf(stderr,
233 "WARNING: skeletons are neither in "
234 "\"%s\" nor in \"%s\"!\n",
235 DATADIR, skeletons_dir);
236 if(warnings_as_errors)
237 exit(EX_OSFILE);
238 }
239 }
240 }
241
242 /*
Lev Walkinf15320b2004-06-03 03:38:44 +0000243 * Iterate over input files and parse each.
244 * All syntax trees from all files will be bundled together.
245 */
246 for(i = 0; i < ac; i++) {
247 asn1p_t *new_asn;
248
249 new_asn = asn1p_parse_file(av[i], asn1_parser_flags);
250 if(new_asn == NULL) {
251 fprintf(stderr, "Cannot parse \"%s\"\n", av[i]);
252 exit(EX_DATAERR);
253 }
254
255 /*
256 * Bundle the parsed tree with existing one.
257 */
258 if(asn) {
259 asn1p_module_t *mod;
260 while((mod = TQ_REMOVE(&(new_asn->modules), mod_next)))
261 TQ_ADD(&(asn->modules), mod, mod_next);
262 asn1p_free(new_asn);
263 } else {
264 asn = new_asn;
265 }
Lev Walkinf15320b2004-06-03 03:38:44 +0000266 }
267
Lev Walkin46499872006-03-06 13:05:34 +0000268 /* These are mostly notes for the human readers */
269 assert(asn);
270 assert(skeletons_dir);
271
Lev Walkinf15320b2004-06-03 03:38:44 +0000272 /*
Lev Walkin7415bff2004-08-16 11:38:13 +0000273 * Dump the parsed ASN.1 tree if -E specified and -F is NOT given.
Lev Walkinf15320b2004-06-03 03:38:44 +0000274 */
275 if(print_arg__print_out && !print_arg__fix_n_print) {
Lev Walkinab4bb292004-08-18 04:52:48 +0000276 if(asn1print(asn, asn1_printer_flags))
Lev Walkinf15320b2004-06-03 03:38:44 +0000277 exit(EX_SOFTWARE);
278 return 0;
279 }
280
Lev Walkin46499872006-03-06 13:05:34 +0000281 /*
282 * Read in the files from skeletons/standard-modules
283 */
284 if(importStandardModules(asn, skeletons_dir)) {
285 if(warnings_as_errors)
286 exit(EX_DATAERR);
287 }
Lev Walkinf15320b2004-06-03 03:38:44 +0000288
289 /*
290 * Process the ASN.1 specification: perform semantic checks,
291 * expand references, etc, etc.
292 * This function will emit necessary warnings and error messages.
293 */
294 ret = asn1f_process(asn, asn1_fixer_flags,
295 NULL /* default fprintf(stderr) */);
296 switch(ret) {
297 case 1:
298 if(!warnings_as_errors)
299 /* Fall through */
300 case 0:
301 break; /* All clear */
302 case -1:
303 exit(EX_DATAERR); /* Fatal failure */
304 }
305
306 /*
307 * Dump the parsed ASN.1 tree if -E specified and -F is given.
308 */
309 if(print_arg__print_out && print_arg__fix_n_print) {
Lev Walkinab4bb292004-08-18 04:52:48 +0000310 if(asn1print(asn, asn1_printer_flags))
Lev Walkinf15320b2004-06-03 03:38:44 +0000311 exit(EX_SOFTWARE);
312 return 0;
313 }
314
315 /*
Lev Walkinf15320b2004-06-03 03:38:44 +0000316 * Compile the ASN.1 tree into a set of source files
317 * of another language.
318 */
Lev Walkin866cff12005-03-05 00:50:53 +0000319 if(asn1_compile(asn, skeletons_dir, asn1_compiler_flags,
Lev Walkin8253ea92006-03-17 01:47:57 +0000320 ac + optind, optind - 1, av - optind)) {
Lev Walkinf15320b2004-06-03 03:38:44 +0000321 exit(EX_SOFTWARE);
322 }
323
Lev Walkincbad2512005-03-24 16:27:02 +0000324 return 0;
Lev Walkinf15320b2004-06-03 03:38:44 +0000325}
326
327/*
Lev Walkin46499872006-03-06 13:05:34 +0000328 * Parse and import *.asn1 from skeletons/standard-modules
329 */
330static int
331importStandardModules(asn1p_t *asn, const char *skeletons_dir) {
332 asn1p_t *new_asn;
333 asn1p_module_t *mod;
334 const char *filename;
Lev Walkin20a7bf42006-03-17 00:20:52 +0000335 char *fullname;
Lev Walkin46499872006-03-06 13:05:34 +0000336 char *target_dir;
337 int target_dir_len;
338 int len;
339#ifdef WIN32
340 intptr_t dir;
341 struct _finddata_t c_file;
342 char *pattern;
343#else
344 struct dirent *dp;
345 DIR *dir;
346#endif
347 int ret = 0;
348
349 /* Notes for the human reader */
350 assert(asn);
351 assert(skeletons_dir);
352
353 /*
354 * Figure out the standard-modules directory.
355 */
356 target_dir_len = strlen(skeletons_dir)
357 + sizeof("/standard-modules") - 1;
358 target_dir = malloc(target_dir_len + 1);
359 assert(target_dir);
360 snprintf(target_dir, target_dir_len + 1, "%s/standard-modules",
361 skeletons_dir);
362
363#ifdef WIN32
Lev Walkinc4b2be52006-03-16 22:23:57 +0000364 len = target_dir_len + sizeof("/*.asn1");
Lev Walkin46499872006-03-06 13:05:34 +0000365 pattern = malloc(len);
366 assert(pattern);
367 snprintf(pattern, len, "%s/*.asn1", target_dir);
368 dir = _findfirst(pattern, &c_file);
Lev Walkin20a7bf42006-03-17 00:20:52 +0000369 if(dir == -1L) {
Lev Walkin46499872006-03-06 13:05:34 +0000370#else
371 dir = opendir(target_dir);
372 if(!dir) {
373#endif
374 fprintf(stderr,
375 "WARNING: Cannot find standard modules in %s\n",
376 target_dir);
377 return -1;
378 }
379
380#ifdef WIN32
381 do {
382 filename = c_file.name;
383#else
384 while((dp = readdir(dir))) {
Lev Walkin46499872006-03-06 13:05:34 +0000385 filename = dp->d_name;
Lev Walkin20a7bf42006-03-17 00:20:52 +0000386#endif
Lev Walkin46499872006-03-06 13:05:34 +0000387 len = strlen(filename);
388 if(len <= 5 || strcmp(filename + len - 5, ".asn1"))
389 continue;
390 len = target_dir_len + 1 + len + 1;
391 fullname = malloc(len);
392 if(!fullname) continue; /* Just skip it, no big deal */
393 snprintf(fullname, len, "%s/%s", target_dir, filename);
394 filename = fullname;
Lev Walkin46499872006-03-06 13:05:34 +0000395
396 new_asn = asn1p_parse_file(filename, A1P_NOFLAGS);
397 if(new_asn == NULL) {
398 fprintf(stderr, "WARNING: Cannot parse standard module \"%s\"\n", filename);
399 ret = -1;
400 continue;
401 }
402
403 /* Import these modules and mark them as "standard" */
404 while((mod = TQ_REMOVE(&(new_asn->modules), mod_next))) {
405 mod->_tags |= MT_STANDARD_MODULE;
406 TQ_ADD(&(asn->modules), mod, mod_next);
407 }
408 asn1p_free(new_asn);
409
410#ifdef WIN32
411 } while(_findnext(dir, &c_file) == 0);
412 _findclose(dir);
413#else
414 free(fullname);
415 } /* while(readdir()) */
416 closedir(dir);
417#endif
418
419 return ret;
420}
421
422/*
Lev Walkinf15320b2004-06-03 03:38:44 +0000423 * Print the usage screen and exit(EX_USAGE).
424 */
425static void
Lev Walkin06b8d7a2004-09-23 22:06:02 +0000426usage(const char *av0) {
Lev Walkinf15320b2004-06-03 03:38:44 +0000427 fprintf(stderr,
Lev Walkincbf218f2004-08-20 13:24:38 +0000428"ASN.1 Compiler, v" VERSION "\n" COPYRIGHT
Lev Walkin06b8d7a2004-09-23 22:06:02 +0000429"Usage: %s [options] file ...\n"
430"Options:\n"
Lev Walkincbf218f2004-08-20 13:24:38 +0000431" -E Run only the ASN.1 parser and print out the tree\n"
432" -F During -E operation, also perform tree fixing\n"
433"\n"
434" -P Concatenate and print the compiled text\n"
435" -R Restrict output (tables only, no support code)\n"
436" -S <dir> Directory with support (skeleton?) files\n"
437" (Default is \"%s\")\n"
Lev Walkinf7484512004-10-13 09:13:56 +0000438" -X Generate and print the XML DTD\n"
Lev Walkincbf218f2004-08-20 13:24:38 +0000439"\n"
440
Lev Walkincbf218f2004-08-20 13:24:38 +0000441" -Werror Treat warnings as errors; abort if any warning\n"
442" -Wdebug-lexer Enable verbose debugging output from lexer\n"
443" -Wdebug-fixer --//-- semantics processor\n"
444" -Wdebug-compiler --//-- compiler\n"
445"\n"
446
Lev Walkindd32b592004-09-06 08:07:29 +0000447" -fall-defs-global Don't make the asn1_DEF_'s of structure members \"static\"\n"
Lev Walkincbf218f2004-08-20 13:24:38 +0000448" -fbless-SIZE Allow SIZE() constraint for INTEGER etc (non-std.)\n"
Lev Walkin21d00002005-03-04 08:48:53 +0000449" -fcompound-names Disambiguate C's struct NAME's inside top-level types\n"
Lev Walkin72a0f5a2005-07-24 08:28:39 +0000450" -findirect-choice Compile members of CHOICE as indirect pointers\n"
Lev Walkin7c655122005-06-05 09:42:42 +0000451" -fknown-extern-type=<name> Pretend the specified type is known\n"
Lev Walkin87a18962005-02-25 11:49:54 +0000452" -fnative-types Use \"long\" instead of INTEGER_t whenever possible, etc.\n"
Lev Walkin4e940a02004-09-26 13:13:13 +0000453" -fno-constraints Do not generate constraint checking code\n"
Lev Walkinb9b8b952005-03-05 00:33:27 +0000454" -fno-include-deps Do not generate courtesy #includes for dependencies\n"
Lev Walkincbf218f2004-08-20 13:24:38 +0000455" -funnamed-unions Enable unnamed unions in structures\n"
Lev Walkina895afb2005-10-06 10:09:34 +0000456" -fskeletons-copy Force copying the support files\n"
Lev Walkin59b176e2005-11-26 11:25:14 +0000457"\n"
458
459" -gen-PER Generate PER support code\n"
460" -pdu=auto Generate PDU table (discover PDUs automatically)\n"
Lev Walkincbf218f2004-08-20 13:24:38 +0000461"\n"
462
Lev Walkind370e9f2006-03-16 10:03:35 +0000463" -print-class-matrix Print out the collected object class matrix (debug)\n"
Lev Walkindafd95d2006-03-18 06:13:57 +0000464" -print-constraints Explain subtype constraints (debug)\n"
Lev Walkincbf218f2004-08-20 13:24:38 +0000465" -print-lines Generate \"-- #line\" comments in -E output\n"
466
Lev Walkinab4bb292004-08-18 04:52:48 +0000467 ,
468 a1c_basename(av0), DATADIR
Lev Walkinf15320b2004-06-03 03:38:44 +0000469 );
470 exit(EX_USAGE);
471}
472