blob: 1d7c6b68d7ad139c987bc6dd6ccd48b8bd378200 [file] [log] [blame]
Lev Walkinfa409762017-03-26 06:37:38 -07001/*
2 * Copyright (c) 2003-2017 Lev Walkin <vlm@lionet.info> and contributors.
3 * 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 Walkin41a1da62016-01-23 08:50:28 -080034#undef COPYRIGHT
Lev Walkinfa409762017-03-26 06:37:38 -070035#define COPYRIGHT "Copyright (c) 2003-2017 Lev Walkin <vlm@lionet.info> and contributors.\n"
Lev Walkinfb872bd2006-03-18 06:53:11 +000036
Lev Walkin41a1da62016-01-23 08:50:28 -080037#include <asn1parser.h> /* Parse the ASN.1 file and build a tree */
38#include <asn1fix.h> /* Fix the ASN.1 tree */
39#include <asn1print.h> /* Print the ASN.1 tree */
40#include <asn1compiler.h> /* Compile the ASN.1 tree */
Lev Walkinc0e03b92017-08-22 01:48:23 -070041#include <asn1fix_export.h>
Lev Walkinf15320b2004-06-03 03:38:44 +000042
Lev Walkin41a1da62016-01-23 08:50:28 -080043#include <asn1c_compat.h> /* Portable basename(3) and dirname(3) */
Lev Walkin79f54952004-08-13 16:58:19 +000044
Lev Walkin41a1da62016-01-23 08:50:28 -080045#ifdef _WIN32
Lev Walkin46499872006-03-06 13:05:34 +000046#include <io.h>
47#include <direct.h>
48#else
49#include <dirent.h>
50#endif
51
Lev Walkin41a1da62016-01-23 08:50:28 -080052static 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 Walkin41a1da62016-01-23 08:50:28 -080057 enum asn1p_flags asn1_parser_flags = A1P_NOFLAGS;
58 enum asn1f_flags asn1_fixer_flags = A1F_NOFLAGS;
59 enum asn1c_flags asn1_compiler_flags = A1C_NO_C99;
60 enum asn1print_flags asn1_printer_flags = APF_NOFLAGS;
61 int print_arg__print_out = 0; /* Don't compile, just print parsed */
62 int print_arg__fix_n_print = 0; /* Fix and print */
63 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 */
Bi-Ruei, Chiu3dcf05b2017-05-04 21:45:05 +080069 int exit_code = 0; /* Exit code */
Lev Walkinf15320b2004-06-03 03:38:44 +000070
Lev Walkin41a1da62016-01-23 08:50:28 -080071 /*
72 * Process command-line options.
73 */
74 while((ch = getopt(ac, av, "EFf:g:hLPp:RS:vW:X")) != -1) 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':
82 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;
86 } else if(strcmp(optarg, "compound-names") == 0) {
87 asn1_compiler_flags |= A1C_COMPOUND_NAMES;
88 } else if(strcmp(optarg, "indirect-choice") == 0) {
89 asn1_compiler_flags |= A1C_INDIRECT_CHOICE;
90 } 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);
94 } else if(strcmp(optarg, "native-types") == 0) {
95 fprintf(stderr, "-f%s: Deprecated option\n", optarg);
96 asn1_compiler_flags &= ~A1C_USE_WIDE_TYPES;
97 } else if(strcmp(optarg, "wide-types") == 0) {
98 asn1_compiler_flags |= A1C_USE_WIDE_TYPES;
99 } else if(strcmp(optarg, "line-refs") == 0) {
100 asn1_compiler_flags |= A1C_LINE_REFS;
101 } else if(strcmp(optarg, "no-constraints") == 0) {
102 asn1_compiler_flags |= A1C_NO_CONSTRAINTS;
103 } else if(strcmp(optarg, "no-include-deps") == 0) {
104 asn1_compiler_flags |= A1C_NO_INCLUDE_DEPS;
105 } else if(strcmp(optarg, "includes-quoted") == 0) {
106 asn1_compiler_flags |= A1C_INCLUDES_QUOTED;
107 } else if(strcmp(optarg, "unnamed-unions") == 0) {
108 asn1_compiler_flags |= A1C_UNNAMED_UNIONS;
109 } else if(strcmp(optarg, "skeletons-copy") == 0) {
110 fprintf(stderr, "-f%s: Deprecated option\n", optarg);
111 asn1_compiler_flags &= ~A1C_LINK_SKELETONS;
112 } else if(strcmp(optarg, "link-skeletons") == 0) {
113 asn1_compiler_flags |= A1C_LINK_SKELETONS;
114 } else {
115 fprintf(stderr, "-f%s: Invalid argument\n", optarg);
116 exit(EX_USAGE);
117 }
118 break;
119 case 'g':
120 if(strcmp(optarg, "en-PER") == 0) {
121 asn1_compiler_flags |= A1C_GEN_PER;
Lev Walkinba68c912017-07-06 07:52:39 -0700122 } else if(strcmp(optarg, "en-OER") == 0) {
123 asn1_compiler_flags |= A1C_GEN_OER;
Lev Walkin41a1da62016-01-23 08:50:28 -0800124 } else {
125 fprintf(stderr, "-g%s: Invalid argument\n", optarg);
126 exit(EX_USAGE);
127 }
128 break;
129 case 'h':
130 usage(av[0]);
131 case 'P':
132 asn1_compiler_flags |= A1C_PRINT_COMPILED;
133 asn1_compiler_flags &= ~A1C_NO_C99;
134 break;
135 case 'p':
136 if(strncmp(optarg, "du=", 3) == 0) {
137 char *pduname = optarg + 3;
138 if(strcmp(pduname, "all") == 0) {
139 asn1_compiler_flags |= A1C_PDU_ALL;
140 } else if(strcmp(pduname, "auto") == 0) {
141 asn1_compiler_flags |= A1C_PDU_AUTO;
142 } else if(pduname[0] >= 'A' && pduname[0] <= 'Z') {
143 asn1c__add_pdu_type(pduname);
144 asn1_compiler_flags |= A1C_PDU_TYPE;
145 } else {
146 fprintf(stderr, "-pdu=%s: expected -pdu={all|auto|Type}\n",
147 pduname);
148 exit(EX_USAGE);
149 }
150 } else if(strcmp(optarg, "rint-class-matrix") == 0) {
151 asn1_printer_flags |= APF_PRINT_CLASS_MATRIX;
152 } else if(strcmp(optarg, "rint-constraints") == 0) {
153 asn1_printer_flags |= APF_PRINT_CONSTRAINTS;
154 } else if(strcmp(optarg, "rint-lines") == 0) {
155 asn1_printer_flags |= APF_LINE_COMMENTS;
156 } else {
157 fprintf(stderr, "-p%s: Invalid argument\n", optarg);
158 exit(EX_USAGE);
159 }
160 break;
161 case 'R':
162 asn1_compiler_flags |= A1C_OMIT_SUPPORT_CODE;
163 break;
164 case 'S':
165 skeletons_dir = optarg;
166 break;
167 case 'v':
168 fprintf(stderr, "ASN.1 Compiler, v" VERSION "\n" COPYRIGHT);
169 exit(0);
170 break;
171 case 'W':
172 if(strcmp(optarg, "error") == 0) {
173 warnings_as_errors = 1;
174 break;
175 } else if(strcmp(optarg, "debug-lexer") == 0) {
Lev Walkin0c686452017-09-07 22:59:36 -0700176 asn1_parser_flags |= A1P_DEBUG_LEXER;
177 break;
178 } else if(strcmp(optarg, "debug-parser") == 0) {
179 asn1_parser_flags |= A1P_DEBUG_PARSER;
Lev Walkin41a1da62016-01-23 08:50:28 -0800180 break;
181 } else if(strcmp(optarg, "debug-fixer") == 0) {
182 asn1_fixer_flags |= A1F_DEBUG;
183 break;
184 } else if(strcmp(optarg, "debug-compiler") == 0) {
185 asn1_compiler_flags |= A1C_DEBUG;
186 break;
187 } else {
188 fprintf(stderr, "-W%s: Invalid argument\n", optarg);
189 exit(EX_USAGE);
190 }
191 break;
192 case 'X':
193 print_arg__print_out = 1; /* Implicit -E */
194 print_arg__fix_n_print = 1; /* Implicit -F */
195 asn1_printer_flags |= APF_PRINT_XML_DTD;
196 break;
197 default:
198 usage(av[0]);
199 }
Lev Walkinf15320b2004-06-03 03:38:44 +0000200
Lev Walkin41a1da62016-01-23 08:50:28 -0800201 /*
202 * Validate the options combination.
203 */
Lev Walkin6f50a3f2017-07-26 18:46:55 -0700204 if(print_arg__print_out) {
205 if((asn1_printer_flags & APF_PRINT_CONSTRAINTS)
206 && !print_arg__fix_n_print) {
207 fprintf(stderr,
208 "Error: -print-constraints argument requires -E -F\n");
209 exit(EX_USAGE);
210 }
211 } else {
Lev Walkin41a1da62016-01-23 08:50:28 -0800212 if(print_arg__fix_n_print) {
213 fprintf(stderr, "Error: -F requires -E\n");
214 exit(EX_USAGE);
215 }
216 if(asn1_printer_flags) {
217 fprintf(stderr, "Error: -print-... arguments require -E\n");
218 exit(EX_USAGE);
219 }
220 }
Lev Walkinf15320b2004-06-03 03:38:44 +0000221
Lev Walkin41a1da62016-01-23 08:50:28 -0800222 /*
223 * Ensure that there are some input files present.
224 */
225 if(ac > optind) {
226 ac -= optind;
227 av += optind;
228 } else {
229 char *bin_name = a1c_basename(av[0]);
230 fprintf(stderr,
231 "%s: No input files specified. "
232 "Try '%s -h' for more information\n",
233 bin_name, bin_name);
234 exit(1);
235 }
Lev Walkinf15320b2004-06-03 03:38:44 +0000236
Lev Walkin41a1da62016-01-23 08:50:28 -0800237 /*
238 * Make sure the skeleton directory is out there.
239 */
240 if(skeletons_dir == NULL) {
241 struct stat sb;
242 skeletons_dir = DATADIR;
243 if((av[-optind][0] == '.' || av[-optind][1] == '/')
244 && stat(skeletons_dir, &sb)) {
245 /*
246 * The default skeletons directory does not exist,
247 * compute it from my file name:
248 * ./asn1c/asn1c -> ./skeletons
249 */
250 char *p;
251 size_t len;
Lev Walkin46499872006-03-06 13:05:34 +0000252
Lev Walkin41a1da62016-01-23 08:50:28 -0800253 p = a1c_dirname(av[-optind]);
Lev Walkin46499872006-03-06 13:05:34 +0000254
Lev Walkin41a1da62016-01-23 08:50:28 -0800255 len = strlen(p) + sizeof("/../skeletons");
256 skeletons_dir = malloc(len);
257 assert(skeletons_dir);
258 snprintf(skeletons_dir, len, "%s/../skeletons", p);
259 if(stat(skeletons_dir, &sb)) {
260 fprintf(stderr,
261 "WARNING: skeletons are neither in "
262 "\"%s\" nor in \"%s\"!\n",
263 DATADIR, skeletons_dir);
264 if(warnings_as_errors) exit(EX_OSFILE);
265 }
266 }
267 }
Lev Walkin46499872006-03-06 13:05:34 +0000268
Lev Walkin41a1da62016-01-23 08:50:28 -0800269 /*
270 * Iterate over input files and parse each.
271 * All syntax trees from all files will be bundled together.
272 */
273 for(i = 0; i < ac; i++) {
274 asn1p_t *new_asn;
Lev Walkinf15320b2004-06-03 03:38:44 +0000275
Lev Walkin41a1da62016-01-23 08:50:28 -0800276 new_asn = asn1p_parse_file(av[i], asn1_parser_flags);
277 if(new_asn == NULL) {
278 fprintf(stderr, "Cannot parse \"%s\"\n", av[i]);
Bi-Ruei, Chiu3dcf05b2017-05-04 21:45:05 +0800279 exit_code = EX_DATAERR;
280 goto cleanup;
Lev Walkin41a1da62016-01-23 08:50:28 -0800281 }
Lev Walkinf15320b2004-06-03 03:38:44 +0000282
Lev Walkin41a1da62016-01-23 08:50:28 -0800283 /*
284 * Bundle the parsed tree with existing one.
285 */
286 if(asn) {
287 asn1p_module_t *mod;
288 while((mod = TQ_REMOVE(&(new_asn->modules), mod_next)))
289 TQ_ADD(&(asn->modules), mod, mod_next);
290 asn1p_delete(new_asn);
291 } else {
292 asn = new_asn;
293 }
294 }
Lev Walkinf15320b2004-06-03 03:38:44 +0000295
Lev Walkin41a1da62016-01-23 08:50:28 -0800296 /* These are mostly notes for the human readers */
297 assert(asn);
298 assert(skeletons_dir);
Lev Walkin46499872006-03-06 13:05:34 +0000299
Lev Walkin41a1da62016-01-23 08:50:28 -0800300 /*
301 * Dump the parsed ASN.1 tree if -E specified and -F is NOT given.
302 */
303 if(print_arg__print_out && !print_arg__fix_n_print) {
Bi-Ruei, Chiu3dcf05b2017-05-04 21:45:05 +0800304 if(asn1print(asn, asn1_printer_flags)) {
305 exit_code = EX_SOFTWARE;
306 goto cleanup;
307 }
Lev Walkin41a1da62016-01-23 08:50:28 -0800308 return 0;
309 }
Lev Walkinf15320b2004-06-03 03:38:44 +0000310
Lev Walkin41a1da62016-01-23 08:50:28 -0800311 /*
312 * Read in the files from skeletons/standard-modules
313 */
314 if(importStandardModules(asn, skeletons_dir)) {
Bi-Ruei, Chiu3dcf05b2017-05-04 21:45:05 +0800315 if(warnings_as_errors) {
316 exit_code = EX_DATAERR;
317 goto cleanup;
318 }
Lev Walkinc0e03b92017-08-22 01:48:23 -0700319 } else {
320 asn1f_use_standard_namespaces(asn);
Lev Walkin41a1da62016-01-23 08:50:28 -0800321 }
Lev Walkinf15320b2004-06-03 03:38:44 +0000322
Lev Walkin41a1da62016-01-23 08:50:28 -0800323 /*
324 * Process the ASN.1 specification: perform semantic checks,
325 * expand references, etc, etc.
326 * This function will emit necessary warnings and error messages.
327 */
328 ret = asn1f_process(asn, asn1_fixer_flags,
329 NULL /* default fprintf(stderr) */);
330 switch(ret) {
331 case 1:
332 if(!warnings_as_errors) /* Fall through */
333 case 0:
334 break; /* All clear */
335 case -1:
Bi-Ruei, Chiu3dcf05b2017-05-04 21:45:05 +0800336 exit_code = EX_DATAERR; /* Fatal failure */
337 goto cleanup;
Lev Walkin41a1da62016-01-23 08:50:28 -0800338 }
Lev Walkinf15320b2004-06-03 03:38:44 +0000339
Lev Walkin41a1da62016-01-23 08:50:28 -0800340 /*
341 * Dump the parsed ASN.1 tree if -E specified and -F is given.
342 */
343 if(print_arg__print_out && print_arg__fix_n_print) {
Bi-Ruei, Chiu3dcf05b2017-05-04 21:45:05 +0800344 if(asn1print(asn, asn1_printer_flags)) {
345 exit_code = EX_SOFTWARE;
346 goto cleanup;
347 }
Lev Walkin41a1da62016-01-23 08:50:28 -0800348 return 0;
349 }
Lev Walkinf15320b2004-06-03 03:38:44 +0000350
Lev Walkin41a1da62016-01-23 08:50:28 -0800351 /*
352 * Compile the ASN.1 tree into a set of source files
353 * of another language.
354 */
355 if(asn1_compile(asn, skeletons_dir, asn1_compiler_flags, ac + optind,
Lev Walkinf95c4992016-12-02 11:35:00 -0800356 optind, av - optind)) {
Bi-Ruei, Chiu3dcf05b2017-05-04 21:45:05 +0800357 exit_code = EX_SOFTWARE;
Lev Walkin41a1da62016-01-23 08:50:28 -0800358 }
Lev Walkinf15320b2004-06-03 03:38:44 +0000359
Bi-Ruei, Chiu3dcf05b2017-05-04 21:45:05 +0800360cleanup:
Bi-Ruei, Chiub9adfc52016-11-09 00:17:25 +0800361 asn1p_delete(asn);
Bi-Ruei, Chiu3dcf05b2017-05-04 21:45:05 +0800362 asn1p_lex_destroy();
363 if (exit_code) exit(exit_code);
Bi-Ruei, Chiub9adfc52016-11-09 00:17:25 +0800364
Lev Walkin41a1da62016-01-23 08:50:28 -0800365 return 0;
Lev Walkinf15320b2004-06-03 03:38:44 +0000366}
367
368/*
Lev Walkin46499872006-03-06 13:05:34 +0000369 * Parse and import *.asn1 from skeletons/standard-modules
370 */
371static int
372importStandardModules(asn1p_t *asn, const char *skeletons_dir) {
Lev Walkin41a1da62016-01-23 08:50:28 -0800373 asn1p_t *new_asn;
374 asn1p_module_t *mod;
375 const char *filename;
376 char *fullname;
377 char *target_dir;
378 int target_dir_len;
379 int len;
380#ifdef _WIN32
381 intptr_t dir;
382 struct _finddata_t c_file;
383 char *pattern;
Lev Walkin46499872006-03-06 13:05:34 +0000384#else
Lev Walkin41a1da62016-01-23 08:50:28 -0800385 struct dirent *dp;
386 DIR *dir;
Lev Walkin46499872006-03-06 13:05:34 +0000387#endif
Lev Walkin41a1da62016-01-23 08:50:28 -0800388 int ret = 0;
Lev Walkin46499872006-03-06 13:05:34 +0000389
Lev Walkin41a1da62016-01-23 08:50:28 -0800390 /* Notes for the human reader */
391 assert(asn);
392 assert(skeletons_dir);
Lev Walkin46499872006-03-06 13:05:34 +0000393
Lev Walkin41a1da62016-01-23 08:50:28 -0800394 /*
395 * Figure out the standard-modules directory.
396 */
397 target_dir_len = strlen(skeletons_dir) + sizeof("/standard-modules") - 1;
398 target_dir = malloc(target_dir_len + 1);
399 assert(target_dir);
400 snprintf(target_dir, target_dir_len + 1, "%s/standard-modules",
401 skeletons_dir);
Lev Walkin46499872006-03-06 13:05:34 +0000402
Lev Walkin41a1da62016-01-23 08:50:28 -0800403#ifdef _WIN32
404 len = target_dir_len + sizeof("/*.asn1");
405 pattern = malloc(len);
406 assert(pattern);
407 snprintf(pattern, len, "%s/*.asn1", target_dir);
408 dir = _findfirst(pattern, &c_file);
409 if(dir == -1L) {
Lev Walkin46499872006-03-06 13:05:34 +0000410#else
Lev Walkin41a1da62016-01-23 08:50:28 -0800411 dir = opendir(target_dir);
412 if(!dir) {
Lev Walkin46499872006-03-06 13:05:34 +0000413#endif
Lev Walkin41a1da62016-01-23 08:50:28 -0800414 fprintf(stderr, "WARNING: Cannot find standard modules in %s\n",
415 target_dir);
416 return -1;
417 }
Lev Walkin46499872006-03-06 13:05:34 +0000418
Lev Walkin41a1da62016-01-23 08:50:28 -0800419#ifdef _WIN32
420 do {
421 filename = c_file.name;
Lev Walkin46499872006-03-06 13:05:34 +0000422#else
Lev Walkin41a1da62016-01-23 08:50:28 -0800423 while((dp = readdir(dir))) {
424 filename = dp->d_name;
Lev Walkin20a7bf42006-03-17 00:20:52 +0000425#endif
Lev Walkin41a1da62016-01-23 08:50:28 -0800426 len = strlen(filename);
427 if(len <= 5 || strcmp(filename + len - 5, ".asn1")) continue;
428 len = target_dir_len + 1 + len + 1;
429 fullname = malloc(len);
430 if(!fullname) continue; /* Just skip it, no big deal */
431 snprintf(fullname, len, "%s/%s", target_dir, filename);
432 filename = fullname;
Lev Walkin46499872006-03-06 13:05:34 +0000433
Lev Walkin41a1da62016-01-23 08:50:28 -0800434 new_asn = asn1p_parse_file(filename, A1P_NOFLAGS);
435 if(new_asn == NULL) {
436 fprintf(stderr, "WARNING: Cannot parse standard module \"%s\"\n",
437 filename);
438 ret = -1;
439 continue;
440 }
Lev Walkin46499872006-03-06 13:05:34 +0000441
Lev Walkin41a1da62016-01-23 08:50:28 -0800442 /* Import these modules and mark them as "standard" */
443 while((mod = TQ_REMOVE(&(new_asn->modules), mod_next))) {
444 mod->_tags |= MT_STANDARD_MODULE;
445 TQ_ADD(&(asn->modules), mod, mod_next);
446 }
447 asn1p_delete(new_asn);
Bi-Ruei, Chiu3dcf05b2017-05-04 21:45:05 +0800448 asn1p_lex_destroy();
Lev Walkin46499872006-03-06 13:05:34 +0000449
Lev Walkin41a1da62016-01-23 08:50:28 -0800450#ifdef _WIN32
451 } while(_findnext(dir, &c_file) == 0);
452 _findclose(dir);
Lev Walkin46499872006-03-06 13:05:34 +0000453#else
Lev Walkin41a1da62016-01-23 08:50:28 -0800454 free(fullname);
455 } /* while(readdir()) */
456 closedir(dir);
Lev Walkin46499872006-03-06 13:05:34 +0000457#endif
458
Bi-Ruei, Chiu4661dae2016-11-09 00:59:41 +0800459#ifdef _WIN32
460 free(pattern);
461#endif
462 free(target_dir);
463
Lev Walkin41a1da62016-01-23 08:50:28 -0800464 return ret;
Lev Walkin46499872006-03-06 13:05:34 +0000465}
466
467/*
Lev Walkinf15320b2004-06-03 03:38:44 +0000468 * Print the usage screen and exit(EX_USAGE).
469 */
470static void
Lev Walkin06b8d7a2004-09-23 22:06:02 +0000471usage(const char *av0) {
Lev Walkin41a1da62016-01-23 08:50:28 -0800472 /* clang-format off */
Lev Walkinf15320b2004-06-03 03:38:44 +0000473 fprintf(stderr,
Lev Walkincbf218f2004-08-20 13:24:38 +0000474"ASN.1 Compiler, v" VERSION "\n" COPYRIGHT
Lev Walkin06b8d7a2004-09-23 22:06:02 +0000475"Usage: %s [options] file ...\n"
476"Options:\n"
Lev Walkincbf218f2004-08-20 13:24:38 +0000477" -E Run only the ASN.1 parser and print out the tree\n"
478" -F During -E operation, also perform tree fixing\n"
479"\n"
480" -P Concatenate and print the compiled text\n"
481" -R Restrict output (tables only, no support code)\n"
482" -S <dir> Directory with support (skeleton?) files\n"
483" (Default is \"%s\")\n"
Lev Walkinf7484512004-10-13 09:13:56 +0000484" -X Generate and print the XML DTD\n"
Lev Walkincbf218f2004-08-20 13:24:38 +0000485"\n"
486
Lev Walkincbf218f2004-08-20 13:24:38 +0000487" -Werror Treat warnings as errors; abort if any warning\n"
488" -Wdebug-lexer Enable verbose debugging output from lexer\n"
Lev Walkin0c686452017-09-07 22:59:36 -0700489" -Wdebug-parser Enable verbose debugging output from parser\n"
Lev Walkincbf218f2004-08-20 13:24:38 +0000490" -Wdebug-fixer --//-- semantics processor\n"
491" -Wdebug-compiler --//-- compiler\n"
492"\n"
493
494" -fbless-SIZE Allow SIZE() constraint for INTEGER etc (non-std.)\n"
Lev Walkin21d00002005-03-04 08:48:53 +0000495" -fcompound-names Disambiguate C's struct NAME's inside top-level types\n"
Lev Walkin72a0f5a2005-07-24 08:28:39 +0000496" -findirect-choice Compile members of CHOICE as indirect pointers\n"
Lev Walkin34944f22010-10-07 08:25:37 +0000497" -fincludes-quoted Generate #includes in \"double\" instead of <angle> quotes\n"
Lev Walkin7c655122005-06-05 09:42:42 +0000498" -fknown-extern-type=<name> Pretend the specified type is known\n"
Lev Walkin4062b012013-10-11 14:29:38 -0700499" -fline-refs Include ASN.1 module's line numbers in comments\n"
Lev Walkin4e940a02004-09-26 13:13:13 +0000500" -fno-constraints Do not generate constraint checking code\n"
Lev Walkinb9b8b952005-03-05 00:33:27 +0000501" -fno-include-deps Do not generate courtesy #includes for dependencies\n"
Lev Walkincbf218f2004-08-20 13:24:38 +0000502" -funnamed-unions Enable unnamed unions in structures\n"
Lev Walkin2a744a72013-03-27 01:56:23 -0700503" -fwide-types Use INTEGER_t instead of \"long\" by default, etc.\n"
Lev Walkin59b176e2005-11-26 11:25:14 +0000504"\n"
505
Lev Walkinba68c912017-07-06 07:52:39 -0700506" -gen-OER Generate OER (X.696) support code\n"
507" -gen-PER Generate PER (X.691) support code\n"
Lev Walkin66adab42006-09-23 02:52:12 +0000508" -pdu={all|auto|Type} Generate PDU table (discover PDUs automatically)\n"
Lev Walkincbf218f2004-08-20 13:24:38 +0000509"\n"
510
Lev Walkind370e9f2006-03-16 10:03:35 +0000511" -print-class-matrix Print out the collected object class matrix (debug)\n"
Lev Walkindafd95d2006-03-18 06:13:57 +0000512" -print-constraints Explain subtype constraints (debug)\n"
Lev Walkincbf218f2004-08-20 13:24:38 +0000513" -print-lines Generate \"-- #line\" comments in -E output\n"
514
Lev Walkinab4bb292004-08-18 04:52:48 +0000515 ,
Lev Walkin41a1da62016-01-23 08:50:28 -0800516 a1c_basename(av0), DATADIR);
517 /* clang-format on */
518 exit(EX_USAGE);
Lev Walkinf15320b2004-06-03 03:38:44 +0000519}