Exemplo n.º 1
0
/*
 * Print the usage screen and exit(EX_USAGE).
 */
static void
usage(const char *av0) {
	fprintf(stderr,
"ASN.1 Compiler, v" VERSION "\n" COPYRIGHT
"Usage: %s [options] file ...\n"
"Options:\n"
"  -E                    Run only the ASN.1 parser and print out the tree\n"
"  -F                    During -E operation, also perform tree fixing\n"
"\n"
"  -P                    Concatenate and print the compiled text\n"
"  -R                    Restrict output (tables only, no support code)\n"
"  -S <dir>              Directory with support (skeleton?) files\n"
"                        (Default is \"%s\")\n"
"  -X                    Generate and print the XML DTD\n"
"\n"

"  -Werror               Treat warnings as errors; abort if any warning\n"
"  -Wdebug-lexer         Enable verbose debugging output from lexer\n"
"  -Wdebug-fixer         --//-- semantics processor\n"
"  -Wdebug-compiler      --//-- compiler\n"
"\n"

"  -fbless-SIZE          Allow SIZE() constraint for INTEGER etc (non-std.)\n"
"  -fcompound-names      Disambiguate C's struct NAME's inside top-level types\n"
"  -fdirect-choice       Compile members of CHOICE as direct members\n"
"  -fincludes-quoted     Generate #includes in \"double\" instead of <angle> quotes\n"
"  -fknown-extern-type=<name>    Pretend the specified type is known\n"
"  -fline-refs           Include ASN.1 module's line numbers in comments\n"
"  -fno-constraints      Do not generate constraint checking code\n"
"  -fno-include-deps     Do not generate courtesy #includes for dependencies\n"
"  -fwide-types          Use INTEGER instead of \"long\" by default, etc.\n"
"  -fno-namespace        Disable generating namespace.\n"
"  -finsecure-pointers   Use raw pointers instead of smart (safe) pointers.\n"
"  -fno-switch           Use member tables instead of switch for getting pointer to member by index.\n"
"  -fptr-choice-getters  Use pointers instead of references as return types of getters of classes for CHOICE.\n"
"  -fshort-ifdef         Use short form (without module name) of #ifdef directive in *.hpp files.\n"
"  -fsingle-unit=<name>  Generate single translation unit (with given name if specified) for entire  ASN.1-file  instead  of generating a translation unit for each type in ASN.1-file.\n"
"\n"

//"  -gen-PER              Generate PER support code\n"
"  -pdu={all|auto|Type}  Generate PDU table (discover PDUs automatically)\n"
"\n"

"  -print-class-matrix   Print out the collected object class matrix (debug)\n"
"  -print-constraints    Explain subtype constraints (debug)\n"
"  -print-lines          Generate \"-- #line\" comments in -E output\n"

	,
	a1c_basename(av0), DATADIR
	);
	exit(EX_USAGE);
}
Exemplo n.º 2
0
/*
 * Print the usage screen and exit(EX_USAGE).
 */
static void
usage(const char *av0) {
    /* clang-format off */
	fprintf(stderr,
"ASN.1 Compiler, v" VERSION "\n" COPYRIGHT
"Usage: %s [options] file ...\n"
"Options:\n"
"  -E                    Run only the ASN.1 parser and print out the tree\n"
"  -F                    During -E operation, also perform tree fixing\n"
"\n"
"  -P                    Concatenate and print the compiled text\n"
"  -R                    Restrict output (tables only, no support code)\n"
"  -S <dir>              Directory with support (skeleton?) files\n"
"                        (Default is \"%s\")\n"
"  -X                    Generate and print the XML DTD\n"
"\n"

"  -Werror               Treat warnings as errors; abort if any warning\n"
"  -Wdebug-lexer         Enable verbose debugging output from lexer\n"
"  -Wdebug-fixer         --//-- semantics processor\n"
"  -Wdebug-compiler      --//-- compiler\n"
"\n"

"  -fbless-SIZE          Allow SIZE() constraint for INTEGER etc (non-std.)\n"
"  -fcompound-names      Disambiguate C's struct NAME's inside top-level types\n"
"  -findirect-choice     Compile members of CHOICE as indirect pointers\n"
"  -fincludes-quoted     Generate #includes in \"double\" instead of <angle> quotes\n"
"  -fknown-extern-type=<name>    Pretend the specified type is known\n"
"  -fline-refs           Include ASN.1 module's line numbers in comments\n"
"  -fno-constraints      Do not generate constraint checking code\n"
"  -fno-include-deps     Do not generate courtesy #includes for dependencies\n"
"  -funnamed-unions      Enable unnamed unions in structures\n"
"  -fwide-types          Use INTEGER_t instead of \"long\" by default, etc.\n"
"\n"

"  -gen-PER              Generate PER support code\n"
"  -pdu={all|auto|Type}  Generate PDU table (discover PDUs automatically)\n"
"\n"

"  -print-class-matrix   Print out the collected object class matrix (debug)\n"
"  -print-constraints    Explain subtype constraints (debug)\n"
"  -print-lines          Generate \"-- #line\" comments in -E output\n"

	,
	a1c_basename(av0), DATADIR);
    /* clang-format on */
    exit(EX_USAGE);
}
Exemplo n.º 3
0
Arquivo: asn1c.c Projeto: Arcen/asn1c
int
main(int ac, char **av) {
	enum asn1p_flags     asn1_parser_flags	= A1P_NOFLAGS;
	enum asn1f_flags     asn1_fixer_flags	= A1F_NOFLAGS;
	enum asn1c_flags     asn1_compiler_flags= A1C_NO_C99;
	enum asn1print_flags asn1_printer_flags	= APF_NOFLAGS;
	int print_arg__print_out = 0;	/* Don't compile, just print parsed */
	int print_arg__fix_n_print = 0;	/* Fix and print */
	int warnings_as_errors = 0;	/* Treat warnings as errors */
	char *skeletons_dir = NULL;	/* Directory with supplementary stuff */
	asn1p_t *asn = 0;		/* An ASN.1 parsed tree */
	int ret;			/* Return value from misc functions */
	int ch;				/* Command line character */
	int i;				/* Index in some loops */

	/*
	 * Process command-line options.
	 */
	while((ch = getopt(ac, av, "EFf:g:hLPp:RS:vW:X")) != -1)
	switch(ch) {
	case 'E':
		print_arg__print_out = 1;
		break;
	case 'F':
		print_arg__fix_n_print = 1;
		break;
	case 'f':
		if(strcmp(optarg, "all-defs-global") == 0) {
			asn1_compiler_flags |= A1C_ALL_DEFS_GLOBAL;
		} else if(strcmp(optarg, "bless-SIZE") == 0) {
			asn1_fixer_flags |= A1F_EXTENDED_SizeConstraint;
		} else if(strcmp(optarg, "compound-names") == 0) {
			asn1_compiler_flags |= A1C_COMPOUND_NAMES;
		} else if(strcmp(optarg, "indirect-choice") == 0) {
			asn1_compiler_flags |= A1C_INDIRECT_CHOICE;
		} else if(strncmp(optarg, "known-extern-type=", 18) == 0) {
			char *known_type = optarg + 18;
			ret = asn1f_make_known_external_type(known_type);
			assert(ret == 0 || errno == EEXIST);
		} else if(strcmp(optarg, "native-types") == 0) {
			fprintf(stderr, "-f%s: Deprecated option\n", optarg);
			asn1_compiler_flags &= ~A1C_USE_WIDE_TYPES;
		} else if(strcmp(optarg, "wide-types") == 0) {
			asn1_compiler_flags |= A1C_USE_WIDE_TYPES;
		} else if(strcmp(optarg, "line-refs") == 0) {
			asn1_compiler_flags |= A1C_LINE_REFS;
		} else if(strcmp(optarg, "no-constraints") == 0) {
			asn1_compiler_flags |= A1C_NO_CONSTRAINTS;
		} else if(strcmp(optarg, "no-include-deps") == 0) {
			asn1_compiler_flags |= A1C_NO_INCLUDE_DEPS;
		} else if(strcmp(optarg, "includes-quoted") == 0) {
			asn1_compiler_flags |= A1C_INCLUDES_QUOTED;
		} else if(strcmp(optarg, "unnamed-unions") == 0) {
			asn1_compiler_flags |= A1C_UNNAMED_UNIONS;
		} else if(strcmp(optarg, "skeletons-copy") == 0) {
			fprintf(stderr, "-f%s: Deprecated option\n", optarg);
			asn1_compiler_flags &= ~A1C_LINK_SKELETONS;
		} else if(strcmp(optarg, "link-skeletons") == 0) {
			asn1_compiler_flags |= A1C_LINK_SKELETONS;
		} else {
			fprintf(stderr, "-f%s: Invalid argument\n", optarg);
			exit(EX_USAGE);
		}
		break;
	case 'g':
		if(strcmp(optarg, "en-PER") == 0) {
			asn1_compiler_flags |= A1C_GEN_PER;
		} else {
			fprintf(stderr, "-g%s: Invalid argument\n", optarg);
			exit(EX_USAGE);
		}
		break;
	case 'h':
		usage(av[0]);
	case 'P':
		asn1_compiler_flags |= A1C_PRINT_COMPILED;
		asn1_compiler_flags &= ~A1C_NO_C99;
		break;
	case 'p':
		if(strncmp(optarg, "du=", 3) == 0) {
			char *pduname = optarg + 3;
			if(strcmp(pduname, "all") == 0) {
				asn1_compiler_flags |= A1C_PDU_ALL;
			} else if(strcmp(pduname, "auto") == 0) {
				asn1_compiler_flags |= A1C_PDU_AUTO;
			} else if(pduname[0] >= 'A' && pduname[0] <= 'Z') {
				asn1c__add_pdu_type(pduname);
				asn1_compiler_flags |= A1C_PDU_TYPE;
			} else {
				fprintf(stderr, "-pdu=%s"
					": expected -pdu={all|auto|Type}\n",
					pduname);
				exit(EX_USAGE);
			}
		} else if(strcmp(optarg, "rint-class-matrix") == 0) {
			asn1_printer_flags |= APF_PRINT_CLASS_MATRIX;
		} else if(strcmp(optarg, "rint-constraints") == 0) {
			asn1_printer_flags |= APF_PRINT_CONSTRAINTS;
		} else if(strcmp(optarg, "rint-lines") == 0) {
			asn1_printer_flags |= APF_LINE_COMMENTS;
		} else {
			fprintf(stderr, "-p%s: Invalid argument\n", optarg);
			exit(EX_USAGE);
		}
		break;
	case 'R':
		asn1_compiler_flags |= A1C_OMIT_SUPPORT_CODE;
		break;
	case 'S':
		skeletons_dir = optarg;
		break;
	case 'v':
		fprintf(stderr, "ASN.1 Compiler, v" VERSION "\n" COPYRIGHT);
		exit(0);
		break;
	case 'W':
		if(strcmp(optarg, "error") == 0) {
			warnings_as_errors = 1;
			break;
		} else if(strcmp(optarg, "debug-lexer") == 0) {
			asn1_parser_flags |= A1P_LEXER_DEBUG;
			break;
		} else if(strcmp(optarg, "debug-fixer") == 0) {
			asn1_fixer_flags |= A1F_DEBUG;
			break;
		} else if(strcmp(optarg, "debug-compiler") == 0) {
			asn1_compiler_flags |= A1C_DEBUG;
			break;
		} else {
			fprintf(stderr, "-W%s: Invalid argument\n", optarg);
			exit(EX_USAGE);
		}
		break;
	case 'X':
		print_arg__print_out = 1;	/* Implicit -E */
		print_arg__fix_n_print = 1;	/* Implicit -F */
		asn1_printer_flags |= APF_PRINT_XML_DTD;
		break;
	default:
		usage(av[0]);
	}

	/*
	 * Validate the options combination.
	 */
	if(!print_arg__print_out) {
		if(print_arg__fix_n_print) {
			fprintf(stderr, "Error: -F requires -E\n");
			exit(EX_USAGE);
		}
		if(asn1_printer_flags) {
			fprintf(stderr, "Error: "
				"-print-... arguments require -E\n");
			exit(EX_USAGE);
		}
	}

	/*
	 * Ensure that there are some input files present.
	 */
	if(ac > optind) {
		ac -= optind;
		av += optind;
	} else {
		char *bin_name = a1c_basename(av[0]);
		fprintf(stderr, "%s: No input files specified. "
			"Try '%s -h' for more information\n",
			bin_name, bin_name);
		exit(1);
	}

	/*
	 * Make sure the skeleton directory is out there.
	 */
	if(skeletons_dir == NULL) {
		struct stat sb;
		skeletons_dir = DATADIR;
		if((av[-optind][0] == '.' || av[-optind][1] == '/')
		&& stat(skeletons_dir, &sb)) {
			/*
			 * The default skeletons directory does not exist,
			 * compute it from my file name:
			 * ./asn1c/asn1c -> ./skeletons
			 */
			char *p;
			size_t len;

			p = a1c_dirname(av[-optind]);

			len = strlen(p) + sizeof("/../skeletons");
			skeletons_dir = malloc(len);
			assert(skeletons_dir);
			snprintf(skeletons_dir, len, "%s/../skeletons", p);
			if(stat(skeletons_dir, &sb)) {
				fprintf(stderr,
					"WARNING: skeletons are neither in "
					"\"%s\" nor in \"%s\"!\n",
					DATADIR, skeletons_dir);
				if(warnings_as_errors)
					exit(EX_OSFILE);
			}
		}
	}

	/*
	 * Iterate over input files and parse each.
	 * All syntax trees from all files will be bundled together.
	 */
	for(i = 0; i < ac; i++) {
		asn1p_t *new_asn;

		new_asn = asn1p_parse_file(av[i], asn1_parser_flags);
		if(new_asn == NULL) {
			fprintf(stderr, "Cannot parse \"%s\"\n", av[i]);
			exit(EX_DATAERR);
		}

		/*
		 * Bundle the parsed tree with existing one.
		 */
		if(asn) {
			asn1p_module_t *mod;
			while((mod = TQ_REMOVE(&(new_asn->modules), mod_next)))
				TQ_ADD(&(asn->modules), mod, mod_next);
			asn1p_delete(new_asn);
		} else {
			asn = new_asn;
		}
	}

	/* These are mostly notes for the human readers */
	assert(asn);
	assert(skeletons_dir);

	/*
	 * Dump the parsed ASN.1 tree if -E specified and -F is NOT given.
	 */
	if(print_arg__print_out && !print_arg__fix_n_print) {
		if(asn1print(asn, asn1_printer_flags))
			exit(EX_SOFTWARE);
		return 0;
	}

	/*
	 * Read in the files from skeletons/standard-modules
	 */
	if(importStandardModules(asn, skeletons_dir)) {
		if(warnings_as_errors)
			exit(EX_DATAERR);
	}

	/*
	 * Process the ASN.1 specification: perform semantic checks,
	 * expand references, etc, etc.
	 * This function will emit necessary warnings and error messages.
	 */
	ret = asn1f_process(asn, asn1_fixer_flags,
		NULL /* default fprintf(stderr) */);
	switch(ret) {
	case 1:
		if(!warnings_as_errors)
			/* Fall through */
	case 0:
		break;			/* All clear */
	case -1:
		exit(EX_DATAERR);	/* Fatal failure */
	}

	/*
	 * Dump the parsed ASN.1 tree if -E specified and -F is given.
	 */
	if(print_arg__print_out && print_arg__fix_n_print) {
		if(asn1print(asn, asn1_printer_flags))
			exit(EX_SOFTWARE);
		return 0;
	}

	/*
	 * Compile the ASN.1 tree into a set of source files
	 * of another language.
	 */
	if(asn1_compile(asn, skeletons_dir, asn1_compiler_flags,
			ac + optind, optind - 1, av - optind)) {
		exit(EX_SOFTWARE);
	}

	return 0;
}