blob: 3c4e55201e6e48c2204a3f06d258a415b3866a5f [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 */
Jon Ringle6431b1c2017-11-15 01:22:02 -050066 char destdir[PATH_MAX]; /* Destination directory for generated files */
Lev Walkin41a1da62016-01-23 08:50:28 -080067 asn1p_t *asn = 0; /* An ASN.1 parsed tree */
68 int ret; /* Return value from misc functions */
69 int ch; /* Command line character */
70 int i; /* Index in some loops */
Bi-Ruei, Chiu3dcf05b2017-05-04 21:45:05 +080071 int exit_code = 0; /* Exit code */
Lev Walkinf15320b2004-06-03 03:38:44 +000072
Jon Ringle6431b1c2017-11-15 01:22:02 -050073 destdir[0] = '\0';
74
Lev Walkin41a1da62016-01-23 08:50:28 -080075 /*
76 * Process command-line options.
77 */
Jon Ringle6431b1c2017-11-15 01:22:02 -050078 while((ch = getopt(ac, av, "EFf:g:hn:LPp:RS:D:vW:X")) != -1) switch(ch) {
Lev Walkin41a1da62016-01-23 08:50:28 -080079 case 'E':
80 print_arg__print_out = 1;
81 break;
82 case 'F':
83 print_arg__fix_n_print = 1;
84 break;
85 case 'f':
86 if(strcmp(optarg, "all-defs-global") == 0) {
87 asn1_compiler_flags |= A1C_ALL_DEFS_GLOBAL;
88 } else if(strcmp(optarg, "bless-SIZE") == 0) {
89 asn1_fixer_flags |= A1F_EXTENDED_SizeConstraint;
90 } else if(strcmp(optarg, "compound-names") == 0) {
91 asn1_compiler_flags |= A1C_COMPOUND_NAMES;
92 } else if(strcmp(optarg, "indirect-choice") == 0) {
93 asn1_compiler_flags |= A1C_INDIRECT_CHOICE;
94 } else if(strncmp(optarg, "known-extern-type=", 18) == 0) {
95 char *known_type = optarg + 18;
96 ret = asn1f_make_known_external_type(known_type);
97 assert(ret == 0 || errno == EEXIST);
98 } else if(strcmp(optarg, "native-types") == 0) {
99 fprintf(stderr, "-f%s: Deprecated option\n", optarg);
100 asn1_compiler_flags &= ~A1C_USE_WIDE_TYPES;
101 } else if(strcmp(optarg, "wide-types") == 0) {
102 asn1_compiler_flags |= A1C_USE_WIDE_TYPES;
103 } else if(strcmp(optarg, "line-refs") == 0) {
104 asn1_compiler_flags |= A1C_LINE_REFS;
105 } else if(strcmp(optarg, "no-constraints") == 0) {
106 asn1_compiler_flags |= A1C_NO_CONSTRAINTS;
107 } else if(strcmp(optarg, "no-include-deps") == 0) {
108 asn1_compiler_flags |= A1C_NO_INCLUDE_DEPS;
109 } else if(strcmp(optarg, "includes-quoted") == 0) {
110 asn1_compiler_flags |= A1C_INCLUDES_QUOTED;
111 } else if(strcmp(optarg, "unnamed-unions") == 0) {
112 asn1_compiler_flags |= A1C_UNNAMED_UNIONS;
113 } else if(strcmp(optarg, "skeletons-copy") == 0) {
114 fprintf(stderr, "-f%s: Deprecated option\n", optarg);
115 asn1_compiler_flags &= ~A1C_LINK_SKELETONS;
116 } else if(strcmp(optarg, "link-skeletons") == 0) {
117 asn1_compiler_flags |= A1C_LINK_SKELETONS;
118 } else {
119 fprintf(stderr, "-f%s: Invalid argument\n", optarg);
120 exit(EX_USAGE);
121 }
122 break;
123 case 'g':
124 if(strcmp(optarg, "en-PER") == 0) {
125 asn1_compiler_flags |= A1C_GEN_PER;
Lev Walkinba68c912017-07-06 07:52:39 -0700126 } else if(strcmp(optarg, "en-OER") == 0) {
127 asn1_compiler_flags |= A1C_GEN_OER;
Lev Walkind1c28aa2017-11-11 18:04:26 -0800128 } else if(strcmp(optarg, "en-example") == 0) {
129 asn1_compiler_flags |= A1C_GEN_EXAMPLE;
Jon Ringle3aa33c02017-11-14 11:16:03 -0500130 } else if(strcmp(optarg, "en-autotools") == 0) {
131 asn1_compiler_flags |= A1C_GEN_AUTOTOOLS_EXAMPLE;
Lev Walkin41a1da62016-01-23 08:50:28 -0800132 } else {
133 fprintf(stderr, "-g%s: Invalid argument\n", optarg);
134 exit(EX_USAGE);
135 }
136 break;
137 case 'h':
138 usage(av[0]);
Lev Walkind1c28aa2017-11-11 18:04:26 -0800139 case 'n':
140 if(strcmp(optarg, "o-gen-PER") == 0) {
141 asn1_compiler_flags &= ~A1C_GEN_PER;
142 } else if(strcmp(optarg, "o-gen-OER") == 0) {
143 asn1_compiler_flags &= ~A1C_GEN_OER;
144 } else if(strcmp(optarg, "o-gen-example") == 0) {
145 asn1_compiler_flags &= ~A1C_GEN_EXAMPLE;
Jon Ringle3aa33c02017-11-14 11:16:03 -0500146 } else if(strcmp(optarg, "o-gen-autotools") == 0) {
147 asn1_compiler_flags &= ~A1C_GEN_AUTOTOOLS_EXAMPLE;
Lev Walkind1c28aa2017-11-11 18:04:26 -0800148 } else {
149 fprintf(stderr, "-n%s: Invalid argument\n", optarg);
150 exit(EX_USAGE);
151 }
152 break;
Lev Walkin41a1da62016-01-23 08:50:28 -0800153 case 'P':
154 asn1_compiler_flags |= A1C_PRINT_COMPILED;
155 asn1_compiler_flags &= ~A1C_NO_C99;
156 break;
157 case 'p':
158 if(strncmp(optarg, "du=", 3) == 0) {
159 char *pduname = optarg + 3;
160 if(strcmp(pduname, "all") == 0) {
161 asn1_compiler_flags |= A1C_PDU_ALL;
162 } else if(strcmp(pduname, "auto") == 0) {
163 asn1_compiler_flags |= A1C_PDU_AUTO;
164 } else if(pduname[0] >= 'A' && pduname[0] <= 'Z') {
165 asn1c__add_pdu_type(pduname);
166 asn1_compiler_flags |= A1C_PDU_TYPE;
167 } else {
168 fprintf(stderr, "-pdu=%s: expected -pdu={all|auto|Type}\n",
169 pduname);
170 exit(EX_USAGE);
171 }
172 } else if(strcmp(optarg, "rint-class-matrix") == 0) {
173 asn1_printer_flags |= APF_PRINT_CLASS_MATRIX;
174 } else if(strcmp(optarg, "rint-constraints") == 0) {
175 asn1_printer_flags |= APF_PRINT_CONSTRAINTS;
176 } else if(strcmp(optarg, "rint-lines") == 0) {
177 asn1_printer_flags |= APF_LINE_COMMENTS;
178 } else {
179 fprintf(stderr, "-p%s: Invalid argument\n", optarg);
180 exit(EX_USAGE);
181 }
182 break;
183 case 'R':
184 asn1_compiler_flags |= A1C_OMIT_SUPPORT_CODE;
185 break;
186 case 'S':
187 skeletons_dir = optarg;
188 break;
Jon Ringle6431b1c2017-11-15 01:22:02 -0500189 case 'D':
190 strncat(destdir, optarg, PATH_MAX - 2); /* leave room for possible trailing '/' */
191 if(destdir[strlen(destdir)-1] != '/')
192 strcat(destdir, "/");
193 break;
Lev Walkin41a1da62016-01-23 08:50:28 -0800194 case 'v':
195 fprintf(stderr, "ASN.1 Compiler, v" VERSION "\n" COPYRIGHT);
196 exit(0);
197 break;
198 case 'W':
199 if(strcmp(optarg, "error") == 0) {
200 warnings_as_errors = 1;
201 break;
202 } else if(strcmp(optarg, "debug-lexer") == 0) {
Lev Walkin0c686452017-09-07 22:59:36 -0700203 asn1_parser_flags |= A1P_DEBUG_LEXER;
204 break;
205 } else if(strcmp(optarg, "debug-parser") == 0) {
206 asn1_parser_flags |= A1P_DEBUG_PARSER;
Lev Walkin41a1da62016-01-23 08:50:28 -0800207 break;
208 } else if(strcmp(optarg, "debug-fixer") == 0) {
209 asn1_fixer_flags |= A1F_DEBUG;
210 break;
211 } else if(strcmp(optarg, "debug-compiler") == 0) {
212 asn1_compiler_flags |= A1C_DEBUG;
213 break;
214 } else {
215 fprintf(stderr, "-W%s: Invalid argument\n", optarg);
216 exit(EX_USAGE);
217 }
218 break;
219 case 'X':
220 print_arg__print_out = 1; /* Implicit -E */
221 print_arg__fix_n_print = 1; /* Implicit -F */
222 asn1_printer_flags |= APF_PRINT_XML_DTD;
223 break;
224 default:
225 usage(av[0]);
226 }
Lev Walkinf15320b2004-06-03 03:38:44 +0000227
Lev Walkin41a1da62016-01-23 08:50:28 -0800228 /*
229 * Validate the options combination.
230 */
Lev Walkin6f50a3f2017-07-26 18:46:55 -0700231 if(print_arg__print_out) {
232 if((asn1_printer_flags & APF_PRINT_CONSTRAINTS)
233 && !print_arg__fix_n_print) {
234 fprintf(stderr,
235 "Error: -print-constraints argument requires -E -F\n");
236 exit(EX_USAGE);
237 }
238 } else {
Lev Walkin41a1da62016-01-23 08:50:28 -0800239 if(print_arg__fix_n_print) {
240 fprintf(stderr, "Error: -F requires -E\n");
241 exit(EX_USAGE);
242 }
243 if(asn1_printer_flags) {
244 fprintf(stderr, "Error: -print-... arguments require -E\n");
245 exit(EX_USAGE);
246 }
247 }
Lev Walkinf15320b2004-06-03 03:38:44 +0000248
Lev Walkin41a1da62016-01-23 08:50:28 -0800249 /*
250 * Ensure that there are some input files present.
251 */
252 if(ac > optind) {
253 ac -= optind;
254 av += optind;
255 } else {
Jon Ringle6431b1c2017-11-15 01:22:02 -0500256 const char *bin_name = a1c_basename(av[0], NULL);
Lev Walkin41a1da62016-01-23 08:50:28 -0800257 fprintf(stderr,
258 "%s: No input files specified. "
259 "Try '%s -h' for more information\n",
260 bin_name, bin_name);
261 exit(1);
262 }
Lev Walkinf15320b2004-06-03 03:38:44 +0000263
Lev Walkin41a1da62016-01-23 08:50:28 -0800264 /*
265 * Make sure the skeleton directory is out there.
266 */
267 if(skeletons_dir == NULL) {
268 struct stat sb;
269 skeletons_dir = DATADIR;
270 if((av[-optind][0] == '.' || av[-optind][1] == '/')
271 && stat(skeletons_dir, &sb)) {
272 /*
273 * The default skeletons directory does not exist,
274 * compute it from my file name:
275 * ./asn1c/asn1c -> ./skeletons
276 */
Lev Walkina4f8e942017-10-08 19:28:20 -0700277 const char *skel_dir;
Lev Walkin41a1da62016-01-23 08:50:28 -0800278 size_t len;
Lev Walkin46499872006-03-06 13:05:34 +0000279
Lev Walkina4f8e942017-10-08 19:28:20 -0700280 skel_dir = a1c_dirname(av[-optind]);
Lev Walkin46499872006-03-06 13:05:34 +0000281
Lev Walkina4f8e942017-10-08 19:28:20 -0700282 len = strlen(skel_dir) + sizeof("/../skeletons");
Lev Walkin41a1da62016-01-23 08:50:28 -0800283 skeletons_dir = malloc(len);
284 assert(skeletons_dir);
Lev Walkina4f8e942017-10-08 19:28:20 -0700285 snprintf(skeletons_dir, len, "%s/../skeletons", skel_dir);
Lev Walkin41a1da62016-01-23 08:50:28 -0800286 if(stat(skeletons_dir, &sb)) {
287 fprintf(stderr,
288 "WARNING: skeletons are neither in "
289 "\"%s\" nor in \"%s\"!\n",
290 DATADIR, skeletons_dir);
291 if(warnings_as_errors) exit(EX_OSFILE);
292 }
293 }
294 }
Lev Walkin46499872006-03-06 13:05:34 +0000295
Lev Walkin41a1da62016-01-23 08:50:28 -0800296 /*
297 * Iterate over input files and parse each.
298 * All syntax trees from all files will be bundled together.
299 */
300 for(i = 0; i < ac; i++) {
301 asn1p_t *new_asn;
Lev Walkinf15320b2004-06-03 03:38:44 +0000302
Lev Walkin41a1da62016-01-23 08:50:28 -0800303 new_asn = asn1p_parse_file(av[i], asn1_parser_flags);
304 if(new_asn == NULL) {
305 fprintf(stderr, "Cannot parse \"%s\"\n", av[i]);
Bi-Ruei, Chiu3dcf05b2017-05-04 21:45:05 +0800306 exit_code = EX_DATAERR;
307 goto cleanup;
Lev Walkin41a1da62016-01-23 08:50:28 -0800308 }
Lev Walkinf15320b2004-06-03 03:38:44 +0000309
Lev Walkin41a1da62016-01-23 08:50:28 -0800310 /*
311 * Bundle the parsed tree with existing one.
312 */
313 if(asn) {
314 asn1p_module_t *mod;
315 while((mod = TQ_REMOVE(&(new_asn->modules), mod_next)))
316 TQ_ADD(&(asn->modules), mod, mod_next);
317 asn1p_delete(new_asn);
318 } else {
319 asn = new_asn;
320 }
321 }
Lev Walkinf15320b2004-06-03 03:38:44 +0000322
Lev Walkin41a1da62016-01-23 08:50:28 -0800323 /* These are mostly notes for the human readers */
324 assert(asn);
325 assert(skeletons_dir);
Lev Walkin46499872006-03-06 13:05:34 +0000326
Lev Walkin41a1da62016-01-23 08:50:28 -0800327 /*
328 * Dump the parsed ASN.1 tree if -E specified and -F is NOT given.
329 */
330 if(print_arg__print_out && !print_arg__fix_n_print) {
Bi-Ruei, Chiu3dcf05b2017-05-04 21:45:05 +0800331 if(asn1print(asn, asn1_printer_flags)) {
332 exit_code = EX_SOFTWARE;
333 goto cleanup;
334 }
Lev Walkin41a1da62016-01-23 08:50:28 -0800335 return 0;
336 }
Lev Walkinf15320b2004-06-03 03:38:44 +0000337
Lev Walkin41a1da62016-01-23 08:50:28 -0800338 /*
339 * Read in the files from skeletons/standard-modules
340 */
341 if(importStandardModules(asn, skeletons_dir)) {
Bi-Ruei, Chiu3dcf05b2017-05-04 21:45:05 +0800342 if(warnings_as_errors) {
343 exit_code = EX_DATAERR;
344 goto cleanup;
345 }
Lev Walkinc0e03b92017-08-22 01:48:23 -0700346 } else {
347 asn1f_use_standard_namespaces(asn);
Lev Walkin41a1da62016-01-23 08:50:28 -0800348 }
Lev Walkinf15320b2004-06-03 03:38:44 +0000349
Lev Walkin41a1da62016-01-23 08:50:28 -0800350 /*
351 * Process the ASN.1 specification: perform semantic checks,
352 * expand references, etc, etc.
353 * This function will emit necessary warnings and error messages.
354 */
355 ret = asn1f_process(asn, asn1_fixer_flags,
356 NULL /* default fprintf(stderr) */);
357 switch(ret) {
Lev Walkin48e82d12017-10-19 03:06:35 -0700358 case 0:
Lev Walkin41a1da62016-01-23 08:50:28 -0800359 break; /* All clear */
Lev Walkin48e82d12017-10-19 03:06:35 -0700360 case 1:
361 if(!warnings_as_errors) {
362 break;
363 }
364 /* Fall through */
Lev Walkin41a1da62016-01-23 08:50:28 -0800365 case -1:
Bi-Ruei, Chiu3dcf05b2017-05-04 21:45:05 +0800366 exit_code = EX_DATAERR; /* Fatal failure */
367 goto cleanup;
Lev Walkin41a1da62016-01-23 08:50:28 -0800368 }
Lev Walkinf15320b2004-06-03 03:38:44 +0000369
Lev Walkin41a1da62016-01-23 08:50:28 -0800370 /*
371 * Dump the parsed ASN.1 tree if -E specified and -F is given.
372 */
373 if(print_arg__print_out && print_arg__fix_n_print) {
Bi-Ruei, Chiu3dcf05b2017-05-04 21:45:05 +0800374 if(asn1print(asn, asn1_printer_flags)) {
375 exit_code = EX_SOFTWARE;
376 goto cleanup;
377 }
Lev Walkin41a1da62016-01-23 08:50:28 -0800378 return 0;
379 }
Lev Walkinf15320b2004-06-03 03:38:44 +0000380
Lev Walkin41a1da62016-01-23 08:50:28 -0800381 /*
382 * Compile the ASN.1 tree into a set of source files
383 * of another language.
384 */
Jon Ringle6431b1c2017-11-15 01:22:02 -0500385 if(asn1_compile(asn, skeletons_dir, destdir, asn1_compiler_flags, ac + optind,
Lev Walkinf95c4992016-12-02 11:35:00 -0800386 optind, av - optind)) {
Bi-Ruei, Chiu3dcf05b2017-05-04 21:45:05 +0800387 exit_code = EX_SOFTWARE;
Lev Walkin41a1da62016-01-23 08:50:28 -0800388 }
Lev Walkinf15320b2004-06-03 03:38:44 +0000389
Bi-Ruei, Chiu3dcf05b2017-05-04 21:45:05 +0800390cleanup:
Bi-Ruei, Chiub9adfc52016-11-09 00:17:25 +0800391 asn1p_delete(asn);
Bi-Ruei, Chiu3dcf05b2017-05-04 21:45:05 +0800392 asn1p_lex_destroy();
393 if (exit_code) exit(exit_code);
Bi-Ruei, Chiub9adfc52016-11-09 00:17:25 +0800394
Lev Walkin41a1da62016-01-23 08:50:28 -0800395 return 0;
Lev Walkinf15320b2004-06-03 03:38:44 +0000396}
397
398/*
Lev Walkin46499872006-03-06 13:05:34 +0000399 * Parse and import *.asn1 from skeletons/standard-modules
400 */
401static int
402importStandardModules(asn1p_t *asn, const char *skeletons_dir) {
Lev Walkin41a1da62016-01-23 08:50:28 -0800403 asn1p_t *new_asn;
404 asn1p_module_t *mod;
405 const char *filename;
406 char *fullname;
407 char *target_dir;
408 int target_dir_len;
409 int len;
410#ifdef _WIN32
411 intptr_t dir;
412 struct _finddata_t c_file;
413 char *pattern;
Lev Walkin46499872006-03-06 13:05:34 +0000414#else
Lev Walkin41a1da62016-01-23 08:50:28 -0800415 struct dirent *dp;
416 DIR *dir;
Lev Walkin46499872006-03-06 13:05:34 +0000417#endif
Lev Walkin41a1da62016-01-23 08:50:28 -0800418 int ret = 0;
Lev Walkin46499872006-03-06 13:05:34 +0000419
Lev Walkin41a1da62016-01-23 08:50:28 -0800420 /* Notes for the human reader */
421 assert(asn);
422 assert(skeletons_dir);
Lev Walkin46499872006-03-06 13:05:34 +0000423
Lev Walkin41a1da62016-01-23 08:50:28 -0800424 /*
425 * Figure out the standard-modules directory.
426 */
427 target_dir_len = strlen(skeletons_dir) + sizeof("/standard-modules") - 1;
428 target_dir = malloc(target_dir_len + 1);
429 assert(target_dir);
430 snprintf(target_dir, target_dir_len + 1, "%s/standard-modules",
431 skeletons_dir);
Lev Walkin46499872006-03-06 13:05:34 +0000432
Lev Walkin41a1da62016-01-23 08:50:28 -0800433#ifdef _WIN32
434 len = target_dir_len + sizeof("/*.asn1");
435 pattern = malloc(len);
436 assert(pattern);
437 snprintf(pattern, len, "%s/*.asn1", target_dir);
438 dir = _findfirst(pattern, &c_file);
439 if(dir == -1L) {
Lev Walkin46499872006-03-06 13:05:34 +0000440#else
Lev Walkin41a1da62016-01-23 08:50:28 -0800441 dir = opendir(target_dir);
442 if(!dir) {
Lev Walkin46499872006-03-06 13:05:34 +0000443#endif
Lev Walkin41a1da62016-01-23 08:50:28 -0800444 fprintf(stderr, "WARNING: Cannot find standard modules in %s\n",
445 target_dir);
446 return -1;
447 }
Lev Walkin46499872006-03-06 13:05:34 +0000448
Lev Walkin41a1da62016-01-23 08:50:28 -0800449#ifdef _WIN32
450 do {
451 filename = c_file.name;
Lev Walkin46499872006-03-06 13:05:34 +0000452#else
Lev Walkin41a1da62016-01-23 08:50:28 -0800453 while((dp = readdir(dir))) {
454 filename = dp->d_name;
Lev Walkin20a7bf42006-03-17 00:20:52 +0000455#endif
Lev Walkin41a1da62016-01-23 08:50:28 -0800456 len = strlen(filename);
457 if(len <= 5 || strcmp(filename + len - 5, ".asn1")) continue;
458 len = target_dir_len + 1 + len + 1;
459 fullname = malloc(len);
460 if(!fullname) continue; /* Just skip it, no big deal */
461 snprintf(fullname, len, "%s/%s", target_dir, filename);
462 filename = fullname;
Lev Walkin46499872006-03-06 13:05:34 +0000463
Lev Walkin41a1da62016-01-23 08:50:28 -0800464 new_asn = asn1p_parse_file(filename, A1P_NOFLAGS);
465 if(new_asn == NULL) {
466 fprintf(stderr, "WARNING: Cannot parse standard module \"%s\"\n",
467 filename);
468 ret = -1;
469 continue;
470 }
Lev Walkin46499872006-03-06 13:05:34 +0000471
Lev Walkin41a1da62016-01-23 08:50:28 -0800472 /* Import these modules and mark them as "standard" */
473 while((mod = TQ_REMOVE(&(new_asn->modules), mod_next))) {
474 mod->_tags |= MT_STANDARD_MODULE;
475 TQ_ADD(&(asn->modules), mod, mod_next);
476 }
477 asn1p_delete(new_asn);
Bi-Ruei, Chiu3dcf05b2017-05-04 21:45:05 +0800478 asn1p_lex_destroy();
Lev Walkin46499872006-03-06 13:05:34 +0000479
Lev Walkin41a1da62016-01-23 08:50:28 -0800480#ifdef _WIN32
481 } while(_findnext(dir, &c_file) == 0);
482 _findclose(dir);
Lev Walkin46499872006-03-06 13:05:34 +0000483#else
Lev Walkin41a1da62016-01-23 08:50:28 -0800484 free(fullname);
485 } /* while(readdir()) */
486 closedir(dir);
Lev Walkin46499872006-03-06 13:05:34 +0000487#endif
488
Bi-Ruei, Chiu4661dae2016-11-09 00:59:41 +0800489#ifdef _WIN32
490 free(pattern);
491#endif
492 free(target_dir);
493
Lev Walkin41a1da62016-01-23 08:50:28 -0800494 return ret;
Lev Walkin46499872006-03-06 13:05:34 +0000495}
496
497/*
Lev Walkinf15320b2004-06-03 03:38:44 +0000498 * Print the usage screen and exit(EX_USAGE).
499 */
Lev Walkin48e82d12017-10-19 03:06:35 -0700500static void __attribute__((noreturn))
Lev Walkin06b8d7a2004-09-23 22:06:02 +0000501usage(const char *av0) {
Lev Walkin41a1da62016-01-23 08:50:28 -0800502 /* clang-format off */
Lev Walkinf15320b2004-06-03 03:38:44 +0000503 fprintf(stderr,
Lev Walkincbf218f2004-08-20 13:24:38 +0000504"ASN.1 Compiler, v" VERSION "\n" COPYRIGHT
Lev Walkin06b8d7a2004-09-23 22:06:02 +0000505"Usage: %s [options] file ...\n"
506"Options:\n"
Lev Walkincbf218f2004-08-20 13:24:38 +0000507" -E Run only the ASN.1 parser and print out the tree\n"
508" -F During -E operation, also perform tree fixing\n"
509"\n"
510" -P Concatenate and print the compiled text\n"
511" -R Restrict output (tables only, no support code)\n"
512" -S <dir> Directory with support (skeleton?) files\n"
513" (Default is \"%s\")\n"
Jon Ringle6431b1c2017-11-15 01:22:02 -0500514" -D <dir> Destination directory for generated files (default current dir)\n"
Lev Walkinf7484512004-10-13 09:13:56 +0000515" -X Generate and print the XML DTD\n"
Lev Walkincbf218f2004-08-20 13:24:38 +0000516"\n"
517
Lev Walkincbf218f2004-08-20 13:24:38 +0000518" -Werror Treat warnings as errors; abort if any warning\n"
519" -Wdebug-lexer Enable verbose debugging output from lexer\n"
Lev Walkin0c686452017-09-07 22:59:36 -0700520" -Wdebug-parser Enable verbose debugging output from parser\n"
Lev Walkincbf218f2004-08-20 13:24:38 +0000521" -Wdebug-fixer --//-- semantics processor\n"
522" -Wdebug-compiler --//-- compiler\n"
523"\n"
524
525" -fbless-SIZE Allow SIZE() constraint for INTEGER etc (non-std.)\n"
Lev Walkin21d00002005-03-04 08:48:53 +0000526" -fcompound-names Disambiguate C's struct NAME's inside top-level types\n"
Lev Walkin72a0f5a2005-07-24 08:28:39 +0000527" -findirect-choice Compile members of CHOICE as indirect pointers\n"
Lev Walkin34944f22010-10-07 08:25:37 +0000528" -fincludes-quoted Generate #includes in \"double\" instead of <angle> quotes\n"
Lev Walkin7c655122005-06-05 09:42:42 +0000529" -fknown-extern-type=<name> Pretend the specified type is known\n"
Lev Walkin4062b012013-10-11 14:29:38 -0700530" -fline-refs Include ASN.1 module's line numbers in comments\n"
Lev Walkind1c28aa2017-11-11 18:04:26 -0800531" -fno-constraints Do not generate the constraint checking code\n"
532" -fno-include-deps Do not generate the courtesy #includes for dependencies\n"
Lev Walkincbf218f2004-08-20 13:24:38 +0000533" -funnamed-unions Enable unnamed unions in structures\n"
Lev Walkin2a744a72013-03-27 01:56:23 -0700534" -fwide-types Use INTEGER_t instead of \"long\" by default, etc.\n"
Lev Walkin59b176e2005-11-26 11:25:14 +0000535"\n"
536
Lev Walkind1c28aa2017-11-11 18:04:26 -0800537" -no-gen-OER Do not generate the OER (X.696) support code\n"
538" -no-gen-PER Do not generate the PER (X.691) support code\n"
539" -no-gen-example Do not generate the ASN.1 format converter example\n"
Jon Ringle3aa33c02017-11-14 11:16:03 -0500540" -gen-autotools Generate example top-level configure.ac and Makefile.am\n"
Lev Walkin66adab42006-09-23 02:52:12 +0000541" -pdu={all|auto|Type} Generate PDU table (discover PDUs automatically)\n"
Lev Walkincbf218f2004-08-20 13:24:38 +0000542"\n"
543
Lev Walkind370e9f2006-03-16 10:03:35 +0000544" -print-class-matrix Print out the collected object class matrix (debug)\n"
Lev Walkindafd95d2006-03-18 06:13:57 +0000545" -print-constraints Explain subtype constraints (debug)\n"
Lev Walkincbf218f2004-08-20 13:24:38 +0000546" -print-lines Generate \"-- #line\" comments in -E output\n"
547
Lev Walkinab4bb292004-08-18 04:52:48 +0000548 ,
Jon Ringle6431b1c2017-11-15 01:22:02 -0500549 a1c_basename(av0, NULL), DATADIR);
Lev Walkin41a1da62016-01-23 08:50:28 -0800550 /* clang-format on */
551 exit(EX_USAGE);
Lev Walkinf15320b2004-06-03 03:38:44 +0000552}