asn1: Improve option handling; help msg
- Giving asn1_compile the name of an ASN.1 module w/o the ".asn1" stem will cause the compiler to add the ".asn1" stem, and it will cause the compiler to look for a ".opt" file as well. - The default C module name substring derivation from the .asn1 file name is improved. - There is now a --gen-name=NAME option for specifying the C module name substring. This is useful for specifying that in a .opt file. - More options now have helpful usage messages. This will allow simplification of lib/asn1/Makefile.am's invocations of asn1_compile. We may well end up requiring the automatic .opt file finding feature when we eventualy add support for parsing multiple modules in a single invocation for better support of IMPORTs.
This commit is contained in:
@@ -60,8 +60,26 @@ seq_type(const char *p)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const char *
|
||||||
|
my_basename(const char *fn)
|
||||||
|
{
|
||||||
|
const char *base, *p;
|
||||||
|
|
||||||
|
for (p = base = fn; *p; p++) {
|
||||||
|
#ifdef WIN32
|
||||||
|
if (*p == '/' || *p == '\\')
|
||||||
|
base = p + 1;
|
||||||
|
#else
|
||||||
|
if (*p == '/')
|
||||||
|
base = p + 1;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
return base;
|
||||||
|
}
|
||||||
|
|
||||||
const char *fuzzer_string = "";
|
const char *fuzzer_string = "";
|
||||||
const char *enum_prefix;
|
const char *enum_prefix;
|
||||||
|
const char *name;
|
||||||
int prefix_enum;
|
int prefix_enum;
|
||||||
int fuzzer_flag;
|
int fuzzer_flag;
|
||||||
int support_ber;
|
int support_ber;
|
||||||
@@ -83,11 +101,18 @@ struct getargs args[] = {
|
|||||||
{ "enum-prefix", 0, arg_string, &enum_prefix,
|
{ "enum-prefix", 0, arg_string, &enum_prefix,
|
||||||
"prefix for C enum labels for ENUMERATED types and INTEGER types with "
|
"prefix for C enum labels for ENUMERATED types and INTEGER types with "
|
||||||
"enumerated values", "PREFIX" },
|
"enumerated values", "PREFIX" },
|
||||||
{ "encode-rfc1510-bit-string", 0, arg_flag, &rfc1510_bitstring, NULL, NULL },
|
{ "encode-rfc1510-bit-string", 0, arg_flag, &rfc1510_bitstring,
|
||||||
{ "decode-dce-ber", 0, arg_flag, &support_ber, NULL, NULL },
|
"Use RFC1510 incorrect BIT STRING handling for all BIT STRING types "
|
||||||
{ "support-ber", 0, arg_flag, &support_ber, NULL, NULL },
|
"in the module", NULL },
|
||||||
{ "preserve-binary", 0, arg_strings, &preserve, NULL, NULL },
|
{ "decode-dce-ber", 0, arg_flag, &support_ber,
|
||||||
{ "sequence", 0, arg_strings, &seq, NULL, NULL },
|
"Allow DCE-style BER on decode", NULL },
|
||||||
|
{ "support-ber", 0, arg_flag, &support_ber, "Allow BER on decode", NULL },
|
||||||
|
{ "preserve-binary", 0, arg_strings, &preserve,
|
||||||
|
"Names of types for which to generate _save fields, saving original "
|
||||||
|
"encoding, in containing structures (useful for signature "
|
||||||
|
"verification)", "TYPE-NAME" },
|
||||||
|
{ "sequence", 0, arg_strings, &seq,
|
||||||
|
"Generate add/remove functions for SEQUENCE OF types", "TYPE-NAME" },
|
||||||
{ "one-code-file", 0, arg_flag, &one_code_file, NULL, NULL },
|
{ "one-code-file", 0, arg_flag, &one_code_file, NULL, NULL },
|
||||||
{ "gen-name", 0, arg_string, &name,
|
{ "gen-name", 0, arg_string, &name,
|
||||||
"Name of generated module", "NAME" },
|
"Name of generated module", "NAME" },
|
||||||
@@ -99,7 +124,9 @@ struct getargs args[] = {
|
|||||||
"is useful for comparing output to earlier compiler versions.",
|
"is useful for comparing output to earlier compiler versions.",
|
||||||
NULL },
|
NULL },
|
||||||
{ "parse-units", 0, arg_negative_flag, &parse_units_flag, NULL, NULL },
|
{ "parse-units", 0, arg_negative_flag, &parse_units_flag, NULL, NULL },
|
||||||
{ "type-file", 0, arg_string, &type_file_string, NULL, NULL },
|
{ "type-file", 0, arg_string, &type_file_string,
|
||||||
|
"Name of a C header file to generate includes of for base types",
|
||||||
|
"C-HEADER-FILE" },
|
||||||
{ "version", 0, arg_flag, &version_flag, NULL, NULL },
|
{ "version", 0, arg_flag, &version_flag, NULL, NULL },
|
||||||
{ "help", 0, arg_flag, &help_flag, NULL, NULL }
|
{ "help", 0, arg_flag, &help_flag, NULL, NULL }
|
||||||
};
|
};
|
||||||
@@ -119,10 +146,12 @@ main(int argc, char **argv)
|
|||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
const char *file;
|
const char *file;
|
||||||
const char *name = NULL;
|
FILE *opt = NULL;
|
||||||
int optidx = 0;
|
int optidx = 0;
|
||||||
char **arg = NULL;
|
char **arg = NULL;
|
||||||
int len = 0, i;
|
size_t len = 0;
|
||||||
|
size_t sz = 0;
|
||||||
|
int i;
|
||||||
|
|
||||||
setprogname(argv[0]);
|
setprogname(argv[0]);
|
||||||
if (getarg(args, num_args, argc, argv, &optidx))
|
if (getarg(args, num_args, argc, argv, &optidx))
|
||||||
@@ -134,17 +163,39 @@ main(int argc, char **argv)
|
|||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
if (argc == optidx) {
|
if (argc == optidx) {
|
||||||
|
/* Compile the module on stdin */
|
||||||
file = "stdin";
|
file = "stdin";
|
||||||
name = "stdin";
|
name = "stdin";
|
||||||
yyin = stdin;
|
yyin = stdin;
|
||||||
} else {
|
} else {
|
||||||
|
/* Compile a named module */
|
||||||
file = argv[optidx];
|
file = argv[optidx];
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If the .asn1 stem is not given, then assume it, and also assume
|
||||||
|
* --option-file was given if the .opt file exists
|
||||||
|
*/
|
||||||
|
if (strchr(file, '.') == NULL) {
|
||||||
|
char *s = NULL;
|
||||||
|
|
||||||
|
if (asprintf(&s, "%s.opt", file) == -1 || s == NULL)
|
||||||
|
err(1, "Out of memory");
|
||||||
|
if ((opt = fopen(s, "r")))
|
||||||
|
option_file = s;
|
||||||
|
else
|
||||||
|
free(s);
|
||||||
|
if (asprintf(&s, "%s.asn1", file) == -1 || s == NULL)
|
||||||
|
err(1, "Out of memory");
|
||||||
|
file = s;
|
||||||
|
}
|
||||||
yyin = fopen (file, "r");
|
yyin = fopen (file, "r");
|
||||||
if (yyin == NULL)
|
if (yyin == NULL)
|
||||||
err (1, "open %s", file);
|
err (1, "open %s", file);
|
||||||
if (argc == optidx + 1) {
|
if (argc == optidx + 1) {
|
||||||
char *p;
|
char *p;
|
||||||
name = estrdup(file);
|
|
||||||
|
/* C module name substring not given; derive from file name */
|
||||||
|
name = my_basename(estrdup(file));
|
||||||
p = strrchr(name, '.');
|
p = strrchr(name, '.');
|
||||||
if (p)
|
if (p)
|
||||||
*p = '\0';
|
*p = '\0';
|
||||||
@@ -157,13 +208,10 @@ main(int argc, char **argv)
|
|||||||
*/
|
*/
|
||||||
if (option_file) {
|
if (option_file) {
|
||||||
char buf[1024];
|
char buf[1024];
|
||||||
FILE *opt;
|
|
||||||
|
|
||||||
opt = fopen(option_file, "r");
|
if (opt == NULL &&
|
||||||
if (opt == NULL) {
|
(opt = fopen(option_file, "r")) == NULL)
|
||||||
perror("open");
|
err(1, "Could not open given option file %s", option_file);
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
arg = calloc(2, sizeof(arg[0]));
|
arg = calloc(2, sizeof(arg[0]));
|
||||||
if (arg == NULL) {
|
if (arg == NULL) {
|
||||||
@@ -173,15 +221,19 @@ main(int argc, char **argv)
|
|||||||
arg[0] = option_file;
|
arg[0] = option_file;
|
||||||
arg[1] = NULL;
|
arg[1] = NULL;
|
||||||
len = 1;
|
len = 1;
|
||||||
|
sz = 2;
|
||||||
|
|
||||||
while (fgets(buf, sizeof(buf), opt) != NULL) {
|
while (fgets(buf, sizeof(buf), opt) != NULL) {
|
||||||
buf[strcspn(buf, "\n\r")] = '\0';
|
buf[strcspn(buf, "\n\r")] = '\0';
|
||||||
|
|
||||||
arg = realloc(arg, (len + 2) * sizeof(arg[0]));
|
if (len + 1 >= sz) {
|
||||||
if (arg == NULL) {
|
arg = realloc(arg, (sz + (sz>>1) + 2) * sizeof(arg[0]));
|
||||||
perror("malloc");
|
if (arg == NULL) {
|
||||||
exit(1);
|
perror("malloc");
|
||||||
}
|
exit(1);
|
||||||
|
}
|
||||||
|
sz += (sz>>1) + 2;
|
||||||
|
}
|
||||||
arg[len] = strdup(buf);
|
arg[len] = strdup(buf);
|
||||||
if (arg[len] == NULL) {
|
if (arg[len] == NULL) {
|
||||||
perror("strdup");
|
perror("strdup");
|
||||||
|
Reference in New Issue
Block a user