blob: e87438bfd2f0f0bc9943e91ee45bfbdda0ab0798 [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;
Lev Walkind1c28aa2017-11-11 18:04:26 -080059 enum asn1c_flags asn1_compiler_flags =
60 A1C_NO_C99 | A1C_GEN_OER | A1C_GEN_PER | A1C_GEN_EXAMPLE;
Lev Walkin41a1da62016-01-23 08:50:28 -080061 enum asn1print_flags asn1_printer_flags = APF_NOFLAGS;
62 int print_arg__print_out = 0; /* Don't compile, just print parsed */
63 int print_arg__fix_n_print = 0; /* Fix and print */
64 int warnings_as_errors = 0; /* Treat warnings as errors */
65 char *skeletons_dir = NULL; /* Directory with supplementary stuff */
66 asn1p_t *asn = 0; /* An ASN.1 parsed tree */
67 int ret; /* Return value from misc functions */
68 int ch; /* Command line character */
69 int i; /* Index in some loops */
Bi-Ruei, Chiu3dcf05b2017-05-04 21:45:05 +080070 int exit_code = 0; /* Exit code */
Lev Walkinf15320b2004-06-03 03:38:44 +000071
Lev Walkin41a1da62016-01-23 08:50:28 -080072 /*
73 * Process command-line options.
74 */
Lev Walkind1c28aa2017-11-11 18:04:26 -080075 while((ch = getopt(ac, av, "EFf:g:hn:LPp:RS:vW:X")) != -1) switch(ch) {
Lev Walkin41a1da62016-01-23 08:50:28 -080076 case 'E':
77 print_arg__print_out = 1;
78 break;
79 case 'F':
80 print_arg__fix_n_print = 1;
81 break;
82 case 'f':
83 if(strcmp(optarg, "all-defs-global") == 0) {
84 asn1_compiler_flags |= A1C_ALL_DEFS_GLOBAL;
85 } else if(strcmp(optarg, "bless-SIZE") == 0) {
86 asn1_fixer_flags |= A1F_EXTENDED_SizeConstraint;
87 } else if(strcmp(optarg, "compound-names") == 0) {
88 asn1_compiler_flags |= A1C_COMPOUND_NAMES;
89 } else if(strcmp(optarg, "indirect-choice") == 0) {
90 asn1_compiler_flags |= A1C_INDIRECT_CHOICE;
91 } else if(strncmp(optarg, "known-extern-type=", 18) == 0) {
92 char *known_type = optarg + 18;
93 ret = asn1f_make_known_external_type(known_type);
94 assert(ret == 0 || errno == EEXIST);
95 } else if(strcmp(optarg, "native-types") == 0) {
96 fprintf(stderr, "-f%s: Deprecated option\n", optarg);
97 asn1_compiler_flags &= ~A1C_USE_WIDE_TYPES;
98 } else if(strcmp(optarg, "wide-types") == 0) {
99 asn1_compiler_flags |= A1C_USE_WIDE_TYPES;
100 } else if(strcmp(optarg, "line-refs") == 0) {
101 asn1_compiler_flags |= A1C_LINE_REFS;
102 } else if(strcmp(optarg, "no-constraints") == 0) {
103 asn1_compiler_flags |= A1C_NO_CONSTRAINTS;
104 } else if(strcmp(optarg, "no-include-deps") == 0) {
105 asn1_compiler_flags |= A1C_NO_INCLUDE_DEPS;
106 } else if(strcmp(optarg, "includes-quoted") == 0) {
107 asn1_compiler_flags |= A1C_INCLUDES_QUOTED;
108 } else if(strcmp(optarg, "unnamed-unions") == 0) {
109 asn1_compiler_flags |= A1C_UNNAMED_UNIONS;
110 } else if(strcmp(optarg, "skeletons-copy") == 0) {
111 fprintf(stderr, "-f%s: Deprecated option\n", optarg);
112 asn1_compiler_flags &= ~A1C_LINK_SKELETONS;
113 } else if(strcmp(optarg, "link-skeletons") == 0) {
114 asn1_compiler_flags |= A1C_LINK_SKELETONS;
115 } else {
116 fprintf(stderr, "-f%s: Invalid argument\n", optarg);
117 exit(EX_USAGE);
118 }
119 break;
120 case 'g':
121 if(strcmp(optarg, "en-PER") == 0) {
122 asn1_compiler_flags |= A1C_GEN_PER;
Lev Walkinba68c912017-07-06 07:52:39 -0700123 } else if(strcmp(optarg, "en-OER") == 0) {
124 asn1_compiler_flags |= A1C_GEN_OER;
Lev Walkind1c28aa2017-11-11 18:04:26 -0800125 } else if(strcmp(optarg, "en-example") == 0) {
126 asn1_compiler_flags |= A1C_GEN_EXAMPLE;
Lev Walkin41a1da62016-01-23 08:50:28 -0800127 } else {
128 fprintf(stderr, "-g%s: Invalid argument\n", optarg);
129 exit(EX_USAGE);
130 }
131 break;
132 case 'h':
133 usage(av[0]);
Lev Walkind1c28aa2017-11-11 18:04:26 -0800134 case 'n':
135 if(strcmp(optarg, "o-gen-PER") == 0) {
136 asn1_compiler_flags &= ~A1C_GEN_PER;
137 } else if(strcmp(optarg, "o-gen-OER") == 0) {
138 asn1_compiler_flags &= ~A1C_GEN_OER;
139 } else if(strcmp(optarg, "o-gen-example") == 0) {
140 asn1_compiler_flags &= ~A1C_GEN_EXAMPLE;
141 } else {
142 fprintf(stderr, "-n%s: Invalid argument\n", optarg);
143 exit(EX_USAGE);
144 }
145 break;
Lev Walkin41a1da62016-01-23 08:50:28 -0800146 case 'P':
147 asn1_compiler_flags |= A1C_PRINT_COMPILED;
148 asn1_compiler_flags &= ~A1C_NO_C99;
149 break;
150 case 'p':
151 if(strncmp(optarg, "du=", 3) == 0) {
152 char *pduname = optarg + 3;
153 if(strcmp(pduname, "all") == 0) {
154 asn1_compiler_flags |= A1C_PDU_ALL;
155 } else if(strcmp(pduname, "auto") == 0) {
156 asn1_compiler_flags |= A1C_PDU_AUTO;
157 } else if(pduname[0] >= 'A' && pduname[0] <= 'Z') {
158 asn1c__add_pdu_type(pduname);
159 asn1_compiler_flags |= A1C_PDU_TYPE;
160 } else {
161 fprintf(stderr, "-pdu=%s: expected -pdu={all|auto|Type}\n",
162 pduname);
163 exit(EX_USAGE);
164 }
165 } else if(strcmp(optarg, "rint-class-matrix") == 0) {
166 asn1_printer_flags |= APF_PRINT_CLASS_MATRIX;
167 } else if(strcmp(optarg, "rint-constraints") == 0) {
168 asn1_printer_flags |= APF_PRINT_CONSTRAINTS;
169 } else if(strcmp(optarg, "rint-lines") == 0) {
170 asn1_printer_flags |= APF_LINE_COMMENTS;
171 } else {
172 fprintf(stderr, "-p%s: Invalid argument\n", optarg);
173 exit(EX_USAGE);
174 }
175 break;
176 case 'R':
177 asn1_compiler_flags |= A1C_OMIT_SUPPORT_CODE;
178 break;
179 case 'S':
180 skeletons_dir = optarg;
181 break;
182 case 'v':
183 fprintf(stderr, "ASN.1 Compiler, v" VERSION "\n" COPYRIGHT);
184 exit(0);
185 break;
186 case 'W':
187 if(strcmp(optarg, "error") == 0) {
188 warnings_as_errors = 1;
189 break;
190 } else if(strcmp(optarg, "debug-lexer") == 0) {
Lev Walkin0c686452017-09-07 22:59:36 -0700191 asn1_parser_flags |= A1P_DEBUG_LEXER;
192 break;
193 } else if(strcmp(optarg, "debug-parser") == 0) {
194 asn1_parser_flags |= A1P_DEBUG_PARSER;
Lev Walkin41a1da62016-01-23 08:50:28 -0800195 break;
196 } else if(strcmp(optarg, "debug-fixer") == 0) {
197 asn1_fixer_flags |= A1F_DEBUG;
198 break;
199 } else if(strcmp(optarg, "debug-compiler") == 0) {
200 asn1_compiler_flags |= A1C_DEBUG;
201 break;
202 } else {
203 fprintf(stderr, "-W%s: Invalid argument\n", optarg);
204 exit(EX_USAGE);
205 }
206 break;
207 case 'X':
208 print_arg__print_out = 1; /* Implicit -E */
209 print_arg__fix_n_print = 1; /* Implicit -F */
210 asn1_printer_flags |= APF_PRINT_XML_DTD;
211 break;
212 default:
213 usage(av[0]);
214 }
Lev Walkinf15320b2004-06-03 03:38:44 +0000215
Lev Walkin41a1da62016-01-23 08:50:28 -0800216 /*
217 * Validate the options combination.
218 */
Lev Walkin6f50a3f2017-07-26 18:46:55 -0700219 if(print_arg__print_out) {
220 if((asn1_printer_flags & APF_PRINT_CONSTRAINTS)
221 && !print_arg__fix_n_print) {
222 fprintf(stderr,
223 "Error: -print-constraints argument requires -E -F\n");
224 exit(EX_USAGE);
225 }
226 } else {
Lev Walkin41a1da62016-01-23 08:50:28 -0800227 if(print_arg__fix_n_print) {
228 fprintf(stderr, "Error: -F requires -E\n");
229 exit(EX_USAGE);
230 }
231 if(asn1_printer_flags) {
232 fprintf(stderr, "Error: -print-... arguments require -E\n");
233 exit(EX_USAGE);
234 }
235 }
Lev Walkinf15320b2004-06-03 03:38:44 +0000236
Lev Walkin41a1da62016-01-23 08:50:28 -0800237 /*
238 * Ensure that there are some input files present.
239 */
240 if(ac > optind) {
241 ac -= optind;
242 av += optind;
243 } else {
Lev Walkina4f8e942017-10-08 19:28:20 -0700244 const char *bin_name = a1c_basename(av[0]);
Lev Walkin41a1da62016-01-23 08:50:28 -0800245 fprintf(stderr,
246 "%s: No input files specified. "
247 "Try '%s -h' for more information\n",
248 bin_name, bin_name);
249 exit(1);
250 }
Lev Walkinf15320b2004-06-03 03:38:44 +0000251
Lev Walkin41a1da62016-01-23 08:50:28 -0800252 /*
253 * Make sure the skeleton directory is out there.
254 */
255 if(skeletons_dir == NULL) {
256 struct stat sb;
257 skeletons_dir = DATADIR;
258 if((av[-optind][0] == '.' || av[-optind][1] == '/')
259 && stat(skeletons_dir, &sb)) {
260 /*
261 * The default skeletons directory does not exist,
262 * compute it from my file name:
263 * ./asn1c/asn1c -> ./skeletons
264 */
Lev Walkina4f8e942017-10-08 19:28:20 -0700265 const char *skel_dir;
Lev Walkin41a1da62016-01-23 08:50:28 -0800266 size_t len;
Lev Walkin46499872006-03-06 13:05:34 +0000267
Lev Walkina4f8e942017-10-08 19:28:20 -0700268 skel_dir = a1c_dirname(av[-optind]);
Lev Walkin46499872006-03-06 13:05:34 +0000269
Lev Walkina4f8e942017-10-08 19:28:20 -0700270 len = strlen(skel_dir) + sizeof("/../skeletons");
Lev Walkin41a1da62016-01-23 08:50:28 -0800271 skeletons_dir = malloc(len);
272 assert(skeletons_dir);
Lev Walkina4f8e942017-10-08 19:28:20 -0700273 snprintf(skeletons_dir, len, "%s/../skeletons", skel_dir);
Lev Walkin41a1da62016-01-23 08:50:28 -0800274 if(stat(skeletons_dir, &sb)) {
275 fprintf(stderr,
276 "WARNING: skeletons are neither in "
277 "\"%s\" nor in \"%s\"!\n",
278 DATADIR, skeletons_dir);
279 if(warnings_as_errors) exit(EX_OSFILE);
280 }
281 }
282 }
Lev Walkin46499872006-03-06 13:05:34 +0000283
Lev Walkin41a1da62016-01-23 08:50:28 -0800284 /*
285 * Iterate over input files and parse each.
286 * All syntax trees from all files will be bundled together.
287 */
288 for(i = 0; i < ac; i++) {
289 asn1p_t *new_asn;
Lev Walkinf15320b2004-06-03 03:38:44 +0000290
Lev Walkin41a1da62016-01-23 08:50:28 -0800291 new_asn = asn1p_parse_file(av[i], asn1_parser_flags);
292 if(new_asn == NULL) {
293 fprintf(stderr, "Cannot parse \"%s\"\n", av[i]);
Bi-Ruei, Chiu3dcf05b2017-05-04 21:45:05 +0800294 exit_code = EX_DATAERR;
295 goto cleanup;
Lev Walkin41a1da62016-01-23 08:50:28 -0800296 }
Lev Walkinf15320b2004-06-03 03:38:44 +0000297
Lev Walkin41a1da62016-01-23 08:50:28 -0800298 /*
299 * Bundle the parsed tree with existing one.
300 */
301 if(asn) {
302 asn1p_module_t *mod;
303 while((mod = TQ_REMOVE(&(new_asn->modules), mod_next)))
304 TQ_ADD(&(asn->modules), mod, mod_next);
305 asn1p_delete(new_asn);
306 } else {
307 asn = new_asn;
308 }
309 }
Lev Walkinf15320b2004-06-03 03:38:44 +0000310
Lev Walkin41a1da62016-01-23 08:50:28 -0800311 /* These are mostly notes for the human readers */
312 assert(asn);
313 assert(skeletons_dir);
Lev Walkin46499872006-03-06 13:05:34 +0000314
Lev Walkin41a1da62016-01-23 08:50:28 -0800315 /*
316 * Dump the parsed ASN.1 tree if -E specified and -F is NOT given.
317 */
318 if(print_arg__print_out && !print_arg__fix_n_print) {
Bi-Ruei, Chiu3dcf05b2017-05-04 21:45:05 +0800319 if(asn1print(asn, asn1_printer_flags)) {
320 exit_code = EX_SOFTWARE;
321 goto cleanup;
322 }
Lev Walkin41a1da62016-01-23 08:50:28 -0800323 return 0;
324 }
Lev Walkinf15320b2004-06-03 03:38:44 +0000325
Lev Walkin41a1da62016-01-23 08:50:28 -0800326 /*
327 * Read in the files from skeletons/standard-modules
328 */
329 if(importStandardModules(asn, skeletons_dir)) {
Bi-Ruei, Chiu3dcf05b2017-05-04 21:45:05 +0800330 if(warnings_as_errors) {
331 exit_code = EX_DATAERR;
332 goto cleanup;
333 }
Lev Walkinc0e03b92017-08-22 01:48:23 -0700334 } else {
335 asn1f_use_standard_namespaces(asn);
Lev Walkin41a1da62016-01-23 08:50:28 -0800336 }
Lev Walkinf15320b2004-06-03 03:38:44 +0000337
Lev Walkin41a1da62016-01-23 08:50:28 -0800338 /*
339 * Process the ASN.1 specification: perform semantic checks,
340 * expand references, etc, etc.
341 * This function will emit necessary warnings and error messages.
342 */
343 ret = asn1f_process(asn, asn1_fixer_flags,
344 NULL /* default fprintf(stderr) */);
345 switch(ret) {
Lev Walkin48e82d12017-10-19 03:06:35 -0700346 case 0:
Lev Walkin41a1da62016-01-23 08:50:28 -0800347 break; /* All clear */
Lev Walkin48e82d12017-10-19 03:06:35 -0700348 case 1:
349 if(!warnings_as_errors) {
350 break;
351 }
352 /* Fall through */
Lev Walkin41a1da62016-01-23 08:50:28 -0800353 case -1:
Bi-Ruei, Chiu3dcf05b2017-05-04 21:45:05 +0800354 exit_code = EX_DATAERR; /* Fatal failure */
355 goto cleanup;
Lev Walkin41a1da62016-01-23 08:50:28 -0800356 }
Lev Walkinf15320b2004-06-03 03:38:44 +0000357
Lev Walkin41a1da62016-01-23 08:50:28 -0800358 /*
359 * Dump the parsed ASN.1 tree if -E specified and -F is given.
360 */
361 if(print_arg__print_out && print_arg__fix_n_print) {
Bi-Ruei, Chiu3dcf05b2017-05-04 21:45:05 +0800362 if(asn1print(asn, asn1_printer_flags)) {
363 exit_code = EX_SOFTWARE;
364 goto cleanup;
365 }
Lev Walkin41a1da62016-01-23 08:50:28 -0800366 return 0;
367 }
Lev Walkinf15320b2004-06-03 03:38:44 +0000368
Lev Walkin41a1da62016-01-23 08:50:28 -0800369 /*
370 * Compile the ASN.1 tree into a set of source files
371 * of another language.
372 */
373 if(asn1_compile(asn, skeletons_dir, asn1_compiler_flags, ac + optind,
Lev Walkinf95c4992016-12-02 11:35:00 -0800374 optind, av - optind)) {
Bi-Ruei, Chiu3dcf05b2017-05-04 21:45:05 +0800375 exit_code = EX_SOFTWARE;
Lev Walkin41a1da62016-01-23 08:50:28 -0800376 }
Lev Walkinf15320b2004-06-03 03:38:44 +0000377
Bi-Ruei, Chiu3dcf05b2017-05-04 21:45:05 +0800378cleanup:
Bi-Ruei, Chiub9adfc52016-11-09 00:17:25 +0800379 asn1p_delete(asn);
Bi-Ruei, Chiu3dcf05b2017-05-04 21:45:05 +0800380 asn1p_lex_destroy();
381 if (exit_code) exit(exit_code);
Bi-Ruei, Chiub9adfc52016-11-09 00:17:25 +0800382
Lev Walkin41a1da62016-01-23 08:50:28 -0800383 return 0;
Lev Walkinf15320b2004-06-03 03:38:44 +0000384}
385
386/*
Lev Walkin46499872006-03-06 13:05:34 +0000387 * Parse and import *.asn1 from skeletons/standard-modules
388 */
389static int
390importStandardModules(asn1p_t *asn, const char *skeletons_dir) {
Lev Walkin41a1da62016-01-23 08:50:28 -0800391 asn1p_t *new_asn;
392 asn1p_module_t *mod;
393 const char *filename;
394 char *fullname;
395 char *target_dir;
396 int target_dir_len;
397 int len;
398#ifdef _WIN32
399 intptr_t dir;
400 struct _finddata_t c_file;
401 char *pattern;
Lev Walkin46499872006-03-06 13:05:34 +0000402#else
Lev Walkin41a1da62016-01-23 08:50:28 -0800403 struct dirent *dp;
404 DIR *dir;
Lev Walkin46499872006-03-06 13:05:34 +0000405#endif
Lev Walkin41a1da62016-01-23 08:50:28 -0800406 int ret = 0;
Lev Walkin46499872006-03-06 13:05:34 +0000407
Lev Walkin41a1da62016-01-23 08:50:28 -0800408 /* Notes for the human reader */
409 assert(asn);
410 assert(skeletons_dir);
Lev Walkin46499872006-03-06 13:05:34 +0000411
Lev Walkin41a1da62016-01-23 08:50:28 -0800412 /*
413 * Figure out the standard-modules directory.
414 */
415 target_dir_len = strlen(skeletons_dir) + sizeof("/standard-modules") - 1;
416 target_dir = malloc(target_dir_len + 1);
417 assert(target_dir);
418 snprintf(target_dir, target_dir_len + 1, "%s/standard-modules",
419 skeletons_dir);
Lev Walkin46499872006-03-06 13:05:34 +0000420
Lev Walkin41a1da62016-01-23 08:50:28 -0800421#ifdef _WIN32
422 len = target_dir_len + sizeof("/*.asn1");
423 pattern = malloc(len);
424 assert(pattern);
425 snprintf(pattern, len, "%s/*.asn1", target_dir);
426 dir = _findfirst(pattern, &c_file);
427 if(dir == -1L) {
Lev Walkin46499872006-03-06 13:05:34 +0000428#else
Lev Walkin41a1da62016-01-23 08:50:28 -0800429 dir = opendir(target_dir);
430 if(!dir) {
Lev Walkin46499872006-03-06 13:05:34 +0000431#endif
Lev Walkin41a1da62016-01-23 08:50:28 -0800432 fprintf(stderr, "WARNING: Cannot find standard modules in %s\n",
433 target_dir);
434 return -1;
435 }
Lev Walkin46499872006-03-06 13:05:34 +0000436
Lev Walkin41a1da62016-01-23 08:50:28 -0800437#ifdef _WIN32
438 do {
439 filename = c_file.name;
Lev Walkin46499872006-03-06 13:05:34 +0000440#else
Lev Walkin41a1da62016-01-23 08:50:28 -0800441 while((dp = readdir(dir))) {
442 filename = dp->d_name;
Lev Walkin20a7bf42006-03-17 00:20:52 +0000443#endif
Lev Walkin41a1da62016-01-23 08:50:28 -0800444 len = strlen(filename);
445 if(len <= 5 || strcmp(filename + len - 5, ".asn1")) continue;
446 len = target_dir_len + 1 + len + 1;
447 fullname = malloc(len);
448 if(!fullname) continue; /* Just skip it, no big deal */
449 snprintf(fullname, len, "%s/%s", target_dir, filename);
450 filename = fullname;
Lev Walkin46499872006-03-06 13:05:34 +0000451
Lev Walkin41a1da62016-01-23 08:50:28 -0800452 new_asn = asn1p_parse_file(filename, A1P_NOFLAGS);
453 if(new_asn == NULL) {
454 fprintf(stderr, "WARNING: Cannot parse standard module \"%s\"\n",
455 filename);
456 ret = -1;
457 continue;
458 }
Lev Walkin46499872006-03-06 13:05:34 +0000459
Lev Walkin41a1da62016-01-23 08:50:28 -0800460 /* Import these modules and mark them as "standard" */
461 while((mod = TQ_REMOVE(&(new_asn->modules), mod_next))) {
462 mod->_tags |= MT_STANDARD_MODULE;
463 TQ_ADD(&(asn->modules), mod, mod_next);
464 }
465 asn1p_delete(new_asn);
Bi-Ruei, Chiu3dcf05b2017-05-04 21:45:05 +0800466 asn1p_lex_destroy();
Lev Walkin46499872006-03-06 13:05:34 +0000467
Lev Walkin41a1da62016-01-23 08:50:28 -0800468#ifdef _WIN32
469 } while(_findnext(dir, &c_file) == 0);
470 _findclose(dir);
Lev Walkin46499872006-03-06 13:05:34 +0000471#else
Lev Walkin41a1da62016-01-23 08:50:28 -0800472 free(fullname);
473 } /* while(readdir()) */
474 closedir(dir);
Lev Walkin46499872006-03-06 13:05:34 +0000475#endif
476
Bi-Ruei, Chiu4661dae2016-11-09 00:59:41 +0800477#ifdef _WIN32
478 free(pattern);
479#endif
480 free(target_dir);
481
Lev Walkin41a1da62016-01-23 08:50:28 -0800482 return ret;
Lev Walkin46499872006-03-06 13:05:34 +0000483}
484
485/*
Lev Walkinf15320b2004-06-03 03:38:44 +0000486 * Print the usage screen and exit(EX_USAGE).
487 */
Lev Walkin48e82d12017-10-19 03:06:35 -0700488static void __attribute__((noreturn))
Lev Walkin06b8d7a2004-09-23 22:06:02 +0000489usage(const char *av0) {
Lev Walkin41a1da62016-01-23 08:50:28 -0800490 /* clang-format off */
Lev Walkinf15320b2004-06-03 03:38:44 +0000491 fprintf(stderr,
Lev Walkincbf218f2004-08-20 13:24:38 +0000492"ASN.1 Compiler, v" VERSION "\n" COPYRIGHT
Lev Walkin06b8d7a2004-09-23 22:06:02 +0000493"Usage: %s [options] file ...\n"
494"Options:\n"
Lev Walkincbf218f2004-08-20 13:24:38 +0000495" -E Run only the ASN.1 parser and print out the tree\n"
496" -F During -E operation, also perform tree fixing\n"
497"\n"
498" -P Concatenate and print the compiled text\n"
499" -R Restrict output (tables only, no support code)\n"
500" -S <dir> Directory with support (skeleton?) files\n"
501" (Default is \"%s\")\n"
Lev Walkinf7484512004-10-13 09:13:56 +0000502" -X Generate and print the XML DTD\n"
Lev Walkincbf218f2004-08-20 13:24:38 +0000503"\n"
504
Lev Walkincbf218f2004-08-20 13:24:38 +0000505" -Werror Treat warnings as errors; abort if any warning\n"
506" -Wdebug-lexer Enable verbose debugging output from lexer\n"
Lev Walkin0c686452017-09-07 22:59:36 -0700507" -Wdebug-parser Enable verbose debugging output from parser\n"
Lev Walkincbf218f2004-08-20 13:24:38 +0000508" -Wdebug-fixer --//-- semantics processor\n"
509" -Wdebug-compiler --//-- compiler\n"
510"\n"
511
512" -fbless-SIZE Allow SIZE() constraint for INTEGER etc (non-std.)\n"
Lev Walkin21d00002005-03-04 08:48:53 +0000513" -fcompound-names Disambiguate C's struct NAME's inside top-level types\n"
Lev Walkin72a0f5a2005-07-24 08:28:39 +0000514" -findirect-choice Compile members of CHOICE as indirect pointers\n"
Lev Walkin34944f22010-10-07 08:25:37 +0000515" -fincludes-quoted Generate #includes in \"double\" instead of <angle> quotes\n"
Lev Walkin7c655122005-06-05 09:42:42 +0000516" -fknown-extern-type=<name> Pretend the specified type is known\n"
Lev Walkin4062b012013-10-11 14:29:38 -0700517" -fline-refs Include ASN.1 module's line numbers in comments\n"
Lev Walkind1c28aa2017-11-11 18:04:26 -0800518" -fno-constraints Do not generate the constraint checking code\n"
519" -fno-include-deps Do not generate the courtesy #includes for dependencies\n"
Lev Walkincbf218f2004-08-20 13:24:38 +0000520" -funnamed-unions Enable unnamed unions in structures\n"
Lev Walkin2a744a72013-03-27 01:56:23 -0700521" -fwide-types Use INTEGER_t instead of \"long\" by default, etc.\n"
Lev Walkin59b176e2005-11-26 11:25:14 +0000522"\n"
523
Lev Walkind1c28aa2017-11-11 18:04:26 -0800524" -no-gen-OER Do not generate the OER (X.696) support code\n"
525" -no-gen-PER Do not generate the PER (X.691) support code\n"
526" -no-gen-example Do not generate the ASN.1 format converter example\n"
Lev Walkin66adab42006-09-23 02:52:12 +0000527" -pdu={all|auto|Type} Generate PDU table (discover PDUs automatically)\n"
Lev Walkincbf218f2004-08-20 13:24:38 +0000528"\n"
529
Lev Walkind370e9f2006-03-16 10:03:35 +0000530" -print-class-matrix Print out the collected object class matrix (debug)\n"
Lev Walkindafd95d2006-03-18 06:13:57 +0000531" -print-constraints Explain subtype constraints (debug)\n"
Lev Walkincbf218f2004-08-20 13:24:38 +0000532" -print-lines Generate \"-- #line\" comments in -E output\n"
533
Lev Walkinab4bb292004-08-18 04:52:48 +0000534 ,
Lev Walkin41a1da62016-01-23 08:50:28 -0800535 a1c_basename(av0), DATADIR);
536 /* clang-format on */
537 exit(EX_USAGE);
Lev Walkinf15320b2004-06-03 03:38:44 +0000538}