autoformatted (no semantic change)

This commit is contained in:
Lev Walkin 2016-01-23 08:50:28 -08:00
parent 438fe8796f
commit 41a1da63e5
4 changed files with 1308 additions and 1238 deletions

View File

@ -1,5 +1,5 @@
/*- /*-
* Copyright (c) 2003-2014 * Copyright (c) 2003-2016
* Lev Walkin <vlm@lionet.info>. All rights reserved. * Lev Walkin <vlm@lionet.info>. All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -31,314 +31,306 @@
*/ */
#include "sys-common.h" #include "sys-common.h"
#undef COPYRIGHT #undef COPYRIGHT
#define COPYRIGHT \ #define COPYRIGHT "Copyright (c) 2003-2016 Lev Walkin <vlm@lionet.info>\n"
"Copyright (c) 2003-2014 Lev Walkin <vlm@lionet.info>\n"
#include <asn1parser.h> /* Parse the ASN.1 file and build a tree */ #include <asn1parser.h> /* Parse the ASN.1 file and build a tree */
#include <asn1fix.h> /* Fix the ASN.1 tree */ #include <asn1fix.h> /* Fix the ASN.1 tree */
#include <asn1print.h> /* Print the ASN.1 tree */ #include <asn1print.h> /* Print the ASN.1 tree */
#include <asn1compiler.h> /* Compile the ASN.1 tree */ #include <asn1compiler.h> /* Compile the ASN.1 tree */
#include <asn1c_compat.h> /* Portable basename(3) and dirname(3) */ #include <asn1c_compat.h> /* Portable basename(3) and dirname(3) */
#ifdef _WIN32 #ifdef _WIN32
#include <io.h> #include <io.h>
#include <direct.h> #include <direct.h>
#else #else
#include <dirent.h> #include <dirent.h>
#endif #endif
static void usage(const char *av0); /* Print the Usage screen and exit */ static void usage(const char *av0); /* Print the Usage screen and exit */
static int importStandardModules(asn1p_t *asn, const char *skeletons_dir); static int importStandardModules(asn1p_t *asn, const char *skeletons_dir);
int int
main(int ac, char **av) { main(int ac, char **av) {
enum asn1p_flags asn1_parser_flags = A1P_NOFLAGS; enum asn1p_flags asn1_parser_flags = A1P_NOFLAGS;
enum asn1f_flags asn1_fixer_flags = A1F_NOFLAGS; enum asn1f_flags asn1_fixer_flags = A1F_NOFLAGS;
enum asn1c_flags asn1_compiler_flags= A1C_NO_C99; enum asn1c_flags asn1_compiler_flags = A1C_NO_C99;
enum asn1print_flags asn1_printer_flags = APF_NOFLAGS; enum asn1print_flags asn1_printer_flags = APF_NOFLAGS;
int print_arg__print_out = 0; /* Don't compile, just print parsed */ int print_arg__print_out = 0; /* Don't compile, just print parsed */
int print_arg__fix_n_print = 0; /* Fix and print */ int print_arg__fix_n_print = 0; /* Fix and print */
int warnings_as_errors = 0; /* Treat warnings as errors */ int warnings_as_errors = 0; /* Treat warnings as errors */
char *skeletons_dir = NULL; /* Directory with supplementary stuff */ char *skeletons_dir = NULL; /* Directory with supplementary stuff */
asn1p_t *asn = 0; /* An ASN.1 parsed tree */ asn1p_t *asn = 0; /* An ASN.1 parsed tree */
int ret; /* Return value from misc functions */ int ret; /* Return value from misc functions */
int ch; /* Command line character */ int ch; /* Command line character */
int i; /* Index in some loops */ int i; /* Index in some loops */
/* /*
* Process command-line options. * Process command-line options.
*/ */
while((ch = getopt(ac, av, "EFf:g:hLPp:RS:vW:X")) != -1) while((ch = getopt(ac, av, "EFf:g:hLPp:RS:vW:X")) != -1) switch(ch) {
switch(ch) { case 'E':
case 'E': print_arg__print_out = 1;
print_arg__print_out = 1; break;
break; case 'F':
case 'F': print_arg__fix_n_print = 1;
print_arg__fix_n_print = 1; break;
break; case 'f':
case 'f': if(strcmp(optarg, "all-defs-global") == 0) {
if(strcmp(optarg, "all-defs-global") == 0) { asn1_compiler_flags |= A1C_ALL_DEFS_GLOBAL;
asn1_compiler_flags |= A1C_ALL_DEFS_GLOBAL; } else if(strcmp(optarg, "bless-SIZE") == 0) {
} else if(strcmp(optarg, "bless-SIZE") == 0) { asn1_fixer_flags |= A1F_EXTENDED_SizeConstraint;
asn1_fixer_flags |= A1F_EXTENDED_SizeConstraint; } else if(strcmp(optarg, "compound-names") == 0) {
} else if(strcmp(optarg, "compound-names") == 0) { asn1_compiler_flags |= A1C_COMPOUND_NAMES;
asn1_compiler_flags |= A1C_COMPOUND_NAMES; } else if(strcmp(optarg, "indirect-choice") == 0) {
} else if(strcmp(optarg, "indirect-choice") == 0) { asn1_compiler_flags |= A1C_INDIRECT_CHOICE;
asn1_compiler_flags |= A1C_INDIRECT_CHOICE; } else if(strncmp(optarg, "known-extern-type=", 18) == 0) {
} else if(strncmp(optarg, "known-extern-type=", 18) == 0) { char *known_type = optarg + 18;
char *known_type = optarg + 18; ret = asn1f_make_known_external_type(known_type);
ret = asn1f_make_known_external_type(known_type); assert(ret == 0 || errno == EEXIST);
assert(ret == 0 || errno == EEXIST); } else if(strcmp(optarg, "native-types") == 0) {
} else if(strcmp(optarg, "native-types") == 0) { fprintf(stderr, "-f%s: Deprecated option\n", optarg);
fprintf(stderr, "-f%s: Deprecated option\n", optarg); asn1_compiler_flags &= ~A1C_USE_WIDE_TYPES;
asn1_compiler_flags &= ~A1C_USE_WIDE_TYPES; } else if(strcmp(optarg, "wide-types") == 0) {
} else if(strcmp(optarg, "wide-types") == 0) { asn1_compiler_flags |= A1C_USE_WIDE_TYPES;
asn1_compiler_flags |= A1C_USE_WIDE_TYPES; } else if(strcmp(optarg, "line-refs") == 0) {
} else if(strcmp(optarg, "line-refs") == 0) { asn1_compiler_flags |= A1C_LINE_REFS;
asn1_compiler_flags |= A1C_LINE_REFS; } else if(strcmp(optarg, "no-constraints") == 0) {
} else if(strcmp(optarg, "no-constraints") == 0) { asn1_compiler_flags |= A1C_NO_CONSTRAINTS;
asn1_compiler_flags |= A1C_NO_CONSTRAINTS; } else if(strcmp(optarg, "no-include-deps") == 0) {
} else if(strcmp(optarg, "no-include-deps") == 0) { asn1_compiler_flags |= A1C_NO_INCLUDE_DEPS;
asn1_compiler_flags |= A1C_NO_INCLUDE_DEPS; } else if(strcmp(optarg, "includes-quoted") == 0) {
} else if(strcmp(optarg, "includes-quoted") == 0) { asn1_compiler_flags |= A1C_INCLUDES_QUOTED;
asn1_compiler_flags |= A1C_INCLUDES_QUOTED; } else if(strcmp(optarg, "unnamed-unions") == 0) {
} else if(strcmp(optarg, "unnamed-unions") == 0) { asn1_compiler_flags |= A1C_UNNAMED_UNIONS;
asn1_compiler_flags |= A1C_UNNAMED_UNIONS; } else if(strcmp(optarg, "skeletons-copy") == 0) {
} else if(strcmp(optarg, "skeletons-copy") == 0) { fprintf(stderr, "-f%s: Deprecated option\n", optarg);
fprintf(stderr, "-f%s: Deprecated option\n", optarg); asn1_compiler_flags &= ~A1C_LINK_SKELETONS;
asn1_compiler_flags &= ~A1C_LINK_SKELETONS; } else if(strcmp(optarg, "link-skeletons") == 0) {
} else if(strcmp(optarg, "link-skeletons") == 0) { asn1_compiler_flags |= A1C_LINK_SKELETONS;
asn1_compiler_flags |= A1C_LINK_SKELETONS; } else {
} else { fprintf(stderr, "-f%s: Invalid argument\n", optarg);
fprintf(stderr, "-f%s: Invalid argument\n", optarg); exit(EX_USAGE);
exit(EX_USAGE); }
} break;
break; case 'g':
case 'g': if(strcmp(optarg, "en-PER") == 0) {
if(strcmp(optarg, "en-PER") == 0) { asn1_compiler_flags |= A1C_GEN_PER;
asn1_compiler_flags |= A1C_GEN_PER; } else {
} else { fprintf(stderr, "-g%s: Invalid argument\n", optarg);
fprintf(stderr, "-g%s: Invalid argument\n", optarg); exit(EX_USAGE);
exit(EX_USAGE); }
} break;
break; case 'h':
case 'h': usage(av[0]);
usage(av[0]); case 'P':
case 'P': asn1_compiler_flags |= A1C_PRINT_COMPILED;
asn1_compiler_flags |= A1C_PRINT_COMPILED; asn1_compiler_flags &= ~A1C_NO_C99;
asn1_compiler_flags &= ~A1C_NO_C99; break;
break; case 'p':
case 'p': if(strncmp(optarg, "du=", 3) == 0) {
if(strncmp(optarg, "du=", 3) == 0) { char *pduname = optarg + 3;
char *pduname = optarg + 3; if(strcmp(pduname, "all") == 0) {
if(strcmp(pduname, "all") == 0) { asn1_compiler_flags |= A1C_PDU_ALL;
asn1_compiler_flags |= A1C_PDU_ALL; } else if(strcmp(pduname, "auto") == 0) {
} else if(strcmp(pduname, "auto") == 0) { asn1_compiler_flags |= A1C_PDU_AUTO;
asn1_compiler_flags |= A1C_PDU_AUTO; } else if(pduname[0] >= 'A' && pduname[0] <= 'Z') {
} else if(pduname[0] >= 'A' && pduname[0] <= 'Z') { asn1c__add_pdu_type(pduname);
asn1c__add_pdu_type(pduname); asn1_compiler_flags |= A1C_PDU_TYPE;
asn1_compiler_flags |= A1C_PDU_TYPE; } else {
} else { fprintf(stderr, "-pdu=%s: expected -pdu={all|auto|Type}\n",
fprintf(stderr, "-pdu=%s" pduname);
": expected -pdu={all|auto|Type}\n", exit(EX_USAGE);
pduname); }
exit(EX_USAGE); } else if(strcmp(optarg, "rint-class-matrix") == 0) {
} asn1_printer_flags |= APF_PRINT_CLASS_MATRIX;
} else if(strcmp(optarg, "rint-class-matrix") == 0) { } else if(strcmp(optarg, "rint-constraints") == 0) {
asn1_printer_flags |= APF_PRINT_CLASS_MATRIX; asn1_printer_flags |= APF_PRINT_CONSTRAINTS;
} else if(strcmp(optarg, "rint-constraints") == 0) { } else if(strcmp(optarg, "rint-lines") == 0) {
asn1_printer_flags |= APF_PRINT_CONSTRAINTS; asn1_printer_flags |= APF_LINE_COMMENTS;
} else if(strcmp(optarg, "rint-lines") == 0) { } else {
asn1_printer_flags |= APF_LINE_COMMENTS; fprintf(stderr, "-p%s: Invalid argument\n", optarg);
} else { exit(EX_USAGE);
fprintf(stderr, "-p%s: Invalid argument\n", optarg); }
exit(EX_USAGE); break;
} case 'R':
break; asn1_compiler_flags |= A1C_OMIT_SUPPORT_CODE;
case 'R': break;
asn1_compiler_flags |= A1C_OMIT_SUPPORT_CODE; case 'S':
break; skeletons_dir = optarg;
case 'S': break;
skeletons_dir = optarg; case 'v':
break; fprintf(stderr, "ASN.1 Compiler, v" VERSION "\n" COPYRIGHT);
case 'v': exit(0);
fprintf(stderr, "ASN.1 Compiler, v" VERSION "\n" COPYRIGHT); break;
exit(0); case 'W':
break; if(strcmp(optarg, "error") == 0) {
case 'W': warnings_as_errors = 1;
if(strcmp(optarg, "error") == 0) { break;
warnings_as_errors = 1; } else if(strcmp(optarg, "debug-lexer") == 0) {
break; asn1_parser_flags |= A1P_LEXER_DEBUG;
} else if(strcmp(optarg, "debug-lexer") == 0) { break;
asn1_parser_flags |= A1P_LEXER_DEBUG; } else if(strcmp(optarg, "debug-fixer") == 0) {
break; asn1_fixer_flags |= A1F_DEBUG;
} else if(strcmp(optarg, "debug-fixer") == 0) { break;
asn1_fixer_flags |= A1F_DEBUG; } else if(strcmp(optarg, "debug-compiler") == 0) {
break; asn1_compiler_flags |= A1C_DEBUG;
} else if(strcmp(optarg, "debug-compiler") == 0) { break;
asn1_compiler_flags |= A1C_DEBUG; } else {
break; fprintf(stderr, "-W%s: Invalid argument\n", optarg);
} else { exit(EX_USAGE);
fprintf(stderr, "-W%s: Invalid argument\n", optarg); }
exit(EX_USAGE); break;
} case 'X':
break; print_arg__print_out = 1; /* Implicit -E */
case 'X': print_arg__fix_n_print = 1; /* Implicit -F */
print_arg__print_out = 1; /* Implicit -E */ asn1_printer_flags |= APF_PRINT_XML_DTD;
print_arg__fix_n_print = 1; /* Implicit -F */ break;
asn1_printer_flags |= APF_PRINT_XML_DTD; default:
break; usage(av[0]);
default: }
usage(av[0]);
}
/* /*
* Validate the options combination. * Validate the options combination.
*/ */
if(!print_arg__print_out) { if(!print_arg__print_out) {
if(print_arg__fix_n_print) { if(print_arg__fix_n_print) {
fprintf(stderr, "Error: -F requires -E\n"); fprintf(stderr, "Error: -F requires -E\n");
exit(EX_USAGE); exit(EX_USAGE);
} }
if(asn1_printer_flags) { if(asn1_printer_flags) {
fprintf(stderr, "Error: " fprintf(stderr, "Error: -print-... arguments require -E\n");
"-print-... arguments require -E\n"); exit(EX_USAGE);
exit(EX_USAGE); }
} }
}
/* /*
* Ensure that there are some input files present. * Ensure that there are some input files present.
*/ */
if(ac > optind) { if(ac > optind) {
ac -= optind; ac -= optind;
av += optind; av += optind;
} else { } else {
char *bin_name = a1c_basename(av[0]); char *bin_name = a1c_basename(av[0]);
fprintf(stderr, "%s: No input files specified. " fprintf(stderr,
"Try '%s -h' for more information\n", "%s: No input files specified. "
bin_name, bin_name); "Try '%s -h' for more information\n",
exit(1); bin_name, bin_name);
} exit(1);
}
/* /*
* Make sure the skeleton directory is out there. * Make sure the skeleton directory is out there.
*/ */
if(skeletons_dir == NULL) { if(skeletons_dir == NULL) {
struct stat sb; struct stat sb;
skeletons_dir = DATADIR; skeletons_dir = DATADIR;
if((av[-optind][0] == '.' || av[-optind][1] == '/') if((av[-optind][0] == '.' || av[-optind][1] == '/')
&& stat(skeletons_dir, &sb)) { && stat(skeletons_dir, &sb)) {
/* /*
* The default skeletons directory does not exist, * The default skeletons directory does not exist,
* compute it from my file name: * compute it from my file name:
* ./asn1c/asn1c -> ./skeletons * ./asn1c/asn1c -> ./skeletons
*/ */
char *p; char *p;
size_t len; size_t len;
p = a1c_dirname(av[-optind]); p = a1c_dirname(av[-optind]);
len = strlen(p) + sizeof("/../skeletons"); len = strlen(p) + sizeof("/../skeletons");
skeletons_dir = malloc(len); skeletons_dir = malloc(len);
assert(skeletons_dir); assert(skeletons_dir);
snprintf(skeletons_dir, len, "%s/../skeletons", p); snprintf(skeletons_dir, len, "%s/../skeletons", p);
if(stat(skeletons_dir, &sb)) { if(stat(skeletons_dir, &sb)) {
fprintf(stderr, fprintf(stderr,
"WARNING: skeletons are neither in " "WARNING: skeletons are neither in "
"\"%s\" nor in \"%s\"!\n", "\"%s\" nor in \"%s\"!\n",
DATADIR, skeletons_dir); DATADIR, skeletons_dir);
if(warnings_as_errors) if(warnings_as_errors) exit(EX_OSFILE);
exit(EX_OSFILE); }
} }
} }
}
/* /*
* Iterate over input files and parse each. * Iterate over input files and parse each.
* All syntax trees from all files will be bundled together. * All syntax trees from all files will be bundled together.
*/ */
for(i = 0; i < ac; i++) { for(i = 0; i < ac; i++) {
asn1p_t *new_asn; asn1p_t *new_asn;
new_asn = asn1p_parse_file(av[i], asn1_parser_flags); new_asn = asn1p_parse_file(av[i], asn1_parser_flags);
if(new_asn == NULL) { if(new_asn == NULL) {
fprintf(stderr, "Cannot parse \"%s\"\n", av[i]); fprintf(stderr, "Cannot parse \"%s\"\n", av[i]);
exit(EX_DATAERR); exit(EX_DATAERR);
} }
/* /*
* Bundle the parsed tree with existing one. * Bundle the parsed tree with existing one.
*/ */
if(asn) { if(asn) {
asn1p_module_t *mod; asn1p_module_t *mod;
while((mod = TQ_REMOVE(&(new_asn->modules), mod_next))) while((mod = TQ_REMOVE(&(new_asn->modules), mod_next)))
TQ_ADD(&(asn->modules), mod, mod_next); TQ_ADD(&(asn->modules), mod, mod_next);
asn1p_delete(new_asn); asn1p_delete(new_asn);
} else { } else {
asn = new_asn; asn = new_asn;
} }
} }
/* These are mostly notes for the human readers */ /* These are mostly notes for the human readers */
assert(asn); assert(asn);
assert(skeletons_dir); assert(skeletons_dir);
/* /*
* Dump the parsed ASN.1 tree if -E specified and -F is NOT given. * 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(print_arg__print_out && !print_arg__fix_n_print) {
if(asn1print(asn, asn1_printer_flags)) if(asn1print(asn, asn1_printer_flags)) exit(EX_SOFTWARE);
exit(EX_SOFTWARE); return 0;
return 0; }
}
/* /*
* Read in the files from skeletons/standard-modules * Read in the files from skeletons/standard-modules
*/ */
if(importStandardModules(asn, skeletons_dir)) { if(importStandardModules(asn, skeletons_dir)) {
if(warnings_as_errors) if(warnings_as_errors) exit(EX_DATAERR);
exit(EX_DATAERR); }
}
/* /*
* Process the ASN.1 specification: perform semantic checks, * Process the ASN.1 specification: perform semantic checks,
* expand references, etc, etc. * expand references, etc, etc.
* This function will emit necessary warnings and error messages. * This function will emit necessary warnings and error messages.
*/ */
ret = asn1f_process(asn, asn1_fixer_flags, ret = asn1f_process(asn, asn1_fixer_flags,
NULL /* default fprintf(stderr) */); NULL /* default fprintf(stderr) */);
switch(ret) { switch(ret) {
case 1: case 1:
if(!warnings_as_errors) if(!warnings_as_errors) /* Fall through */
/* Fall through */ case 0:
case 0: break; /* All clear */
break; /* All clear */ case -1:
case -1: exit(EX_DATAERR); /* Fatal failure */
exit(EX_DATAERR); /* Fatal failure */ }
}
/* /*
* Dump the parsed ASN.1 tree if -E specified and -F is given. * Dump the parsed ASN.1 tree if -E specified and -F is given.
*/ */
if(print_arg__print_out && print_arg__fix_n_print) { if(print_arg__print_out && print_arg__fix_n_print) {
if(asn1print(asn, asn1_printer_flags)) if(asn1print(asn, asn1_printer_flags)) exit(EX_SOFTWARE);
exit(EX_SOFTWARE); return 0;
return 0; }
}
/* /*
* Compile the ASN.1 tree into a set of source files * Compile the ASN.1 tree into a set of source files
* of another language. * of another language.
*/ */
if(asn1_compile(asn, skeletons_dir, asn1_compiler_flags, if(asn1_compile(asn, skeletons_dir, asn1_compiler_flags, ac + optind,
ac + optind, optind - 1, av - optind)) { optind - 1, av - optind)) {
exit(EX_SOFTWARE); exit(EX_SOFTWARE);
} }
return 0; return 0;
} }
/* /*
@ -346,94 +338,92 @@ main(int ac, char **av) {
*/ */
static int static int
importStandardModules(asn1p_t *asn, const char *skeletons_dir) { importStandardModules(asn1p_t *asn, const char *skeletons_dir) {
asn1p_t *new_asn; asn1p_t *new_asn;
asn1p_module_t *mod; asn1p_module_t *mod;
const char *filename; const char *filename;
char *fullname; char *fullname;
char *target_dir; char *target_dir;
int target_dir_len; int target_dir_len;
int len; int len;
#ifdef _WIN32 #ifdef _WIN32
intptr_t dir; intptr_t dir;
struct _finddata_t c_file; struct _finddata_t c_file;
char *pattern; char *pattern;
#else #else
struct dirent *dp; struct dirent *dp;
DIR *dir; DIR *dir;
#endif #endif
int ret = 0; int ret = 0;
/* Notes for the human reader */ /* Notes for the human reader */
assert(asn); assert(asn);
assert(skeletons_dir); assert(skeletons_dir);
/* /*
* Figure out the standard-modules directory. * Figure out the standard-modules directory.
*/ */
target_dir_len = strlen(skeletons_dir) target_dir_len = strlen(skeletons_dir) + sizeof("/standard-modules") - 1;
+ sizeof("/standard-modules") - 1; target_dir = malloc(target_dir_len + 1);
target_dir = malloc(target_dir_len + 1); assert(target_dir);
assert(target_dir); snprintf(target_dir, target_dir_len + 1, "%s/standard-modules",
snprintf(target_dir, target_dir_len + 1, "%s/standard-modules", skeletons_dir);
skeletons_dir);
#ifdef _WIN32 #ifdef _WIN32
len = target_dir_len + sizeof("/*.asn1"); len = target_dir_len + sizeof("/*.asn1");
pattern = malloc(len); pattern = malloc(len);
assert(pattern); assert(pattern);
snprintf(pattern, len, "%s/*.asn1", target_dir); snprintf(pattern, len, "%s/*.asn1", target_dir);
dir = _findfirst(pattern, &c_file); dir = _findfirst(pattern, &c_file);
if(dir == -1L) { if(dir == -1L) {
#else #else
dir = opendir(target_dir); dir = opendir(target_dir);
if(!dir) { if(!dir) {
#endif #endif
fprintf(stderr, fprintf(stderr, "WARNING: Cannot find standard modules in %s\n",
"WARNING: Cannot find standard modules in %s\n", target_dir);
target_dir); return -1;
return -1; }
}
#ifdef _WIN32 #ifdef _WIN32
do { do {
filename = c_file.name; filename = c_file.name;
#else #else
while((dp = readdir(dir))) { while((dp = readdir(dir))) {
filename = dp->d_name; filename = dp->d_name;
#endif #endif
len = strlen(filename); len = strlen(filename);
if(len <= 5 || strcmp(filename + len - 5, ".asn1")) if(len <= 5 || strcmp(filename + len - 5, ".asn1")) continue;
continue; len = target_dir_len + 1 + len + 1;
len = target_dir_len + 1 + len + 1; fullname = malloc(len);
fullname = malloc(len); if(!fullname) continue; /* Just skip it, no big deal */
if(!fullname) continue; /* Just skip it, no big deal */ snprintf(fullname, len, "%s/%s", target_dir, filename);
snprintf(fullname, len, "%s/%s", target_dir, filename); filename = fullname;
filename = fullname;
new_asn = asn1p_parse_file(filename, A1P_NOFLAGS); new_asn = asn1p_parse_file(filename, A1P_NOFLAGS);
if(new_asn == NULL) { if(new_asn == NULL) {
fprintf(stderr, "WARNING: Cannot parse standard module \"%s\"\n", filename); fprintf(stderr, "WARNING: Cannot parse standard module \"%s\"\n",
ret = -1; filename);
continue; ret = -1;
} continue;
}
/* Import these modules and mark them as "standard" */ /* Import these modules and mark them as "standard" */
while((mod = TQ_REMOVE(&(new_asn->modules), mod_next))) { while((mod = TQ_REMOVE(&(new_asn->modules), mod_next))) {
mod->_tags |= MT_STANDARD_MODULE; mod->_tags |= MT_STANDARD_MODULE;
TQ_ADD(&(asn->modules), mod, mod_next); TQ_ADD(&(asn->modules), mod, mod_next);
} }
asn1p_delete(new_asn); asn1p_delete(new_asn);
#ifdef _WIN32 #ifdef _WIN32
} while(_findnext(dir, &c_file) == 0); } while(_findnext(dir, &c_file) == 0);
_findclose(dir); _findclose(dir);
#else #else
free(fullname); free(fullname);
} /* while(readdir()) */ } /* while(readdir()) */
closedir(dir); closedir(dir);
#endif #endif
return ret; return ret;
} }
/* /*
@ -441,6 +431,7 @@ importStandardModules(asn1p_t *asn, const char *skeletons_dir) {
*/ */
static void static void
usage(const char *av0) { usage(const char *av0) {
/* clang-format off */
fprintf(stderr, fprintf(stderr,
"ASN.1 Compiler, v" VERSION "\n" COPYRIGHT "ASN.1 Compiler, v" VERSION "\n" COPYRIGHT
"Usage: %s [options] file ...\n" "Usage: %s [options] file ...\n"
@ -482,8 +473,7 @@ usage(const char *av0) {
" -print-lines Generate \"-- #line\" comments in -E output\n" " -print-lines Generate \"-- #line\" comments in -E output\n"
, ,
a1c_basename(av0), DATADIR a1c_basename(av0), DATADIR);
); /* clang-format on */
exit(EX_USAGE); exit(EX_USAGE);
} }

View File

@ -26,67 +26,64 @@
*/ */
#include "sys-common.h" #include "sys-common.h"
#include <asn1parser.h> /* For static string tables */ #include <asn1parser.h> /* For static string tables */
#include <asn_application.h> #include <asn_application.h>
#include <constraints.c> #include <constraints.c>
#include <ber_tlv_tag.c> #include <ber_tlv_tag.c>
#include <ber_tlv_length.c> #include <ber_tlv_length.c>
#undef COPYRIGHT #undef COPYRIGHT
#define COPYRIGHT \ #define COPYRIGHT "Copyright (c) 2004, 2005 Lev Walkin <vlm@lionet.info>\n"
"Copyright (c) 2004, 2005 Lev Walkin <vlm@lionet.info>\n"
static void usage(const char *av0, int);/* Print the Usage screen and exit */ static void usage(const char *av0, int); /* Print the Usage screen and exit */
static int process(const char *fname); /* Perform the BER decoding */ static int process(const char *fname); /* Perform the BER decoding */
static int process_line(const char *fname, char *line, int lineno); static int process_line(const char *fname, char *line, int lineno);
static int no_validation; /* -n */ static int no_validation; /* -n */
int int
main(int ac, char **av) { main(int ac, char **av) {
int ch; /* Command line character */ int ch; /* Command line character */
int i; /* Index in some loops */ int i; /* Index in some loops */
/* /*
* Process command-line options. * Process command-line options.
*/ */
while((ch = getopt(ac, av, "nhv")) != -1) while((ch = getopt(ac, av, "nhv")) != -1) switch(ch) {
switch(ch) { case 'n':
case 'n': no_validation++;
no_validation++; break;
break; case 'v':
case 'v': usage(av[0], 1);
usage(av[0], 1); break;
break; case 'h':
case 'h': default:
default: usage(av[0], 0);
usage(av[0], 0); }
}
/* /*
* Ensure that there are some input files present. * Ensure that there are some input files present.
*/ */
if(ac > optind) { if(ac > optind) {
ac -= optind; ac -= optind;
av += optind; av += optind;
} else { } else {
fprintf(stderr, "%s: No input files specified\n", av[0]); fprintf(stderr, "%s: No input files specified\n", av[0]);
exit(1); exit(1);
} }
setvbuf(stdout, 0, _IOLBF, 0); setvbuf(stdout, 0, _IOLBF, 0);
/* /*
* Iterate over input files and parse each. * Iterate over input files and parse each.
* All syntax trees from all files will be bundled together. * All syntax trees from all files will be bundled together.
*/ */
for(i = 0; i < ac; i++) { for(i = 0; i < ac; i++) {
if(process(av[i])) if(process(av[i])) exit(EX_DATAERR);
exit(EX_DATAERR); }
}
return 0; return 0;
} }
/* /*
@ -94,15 +91,16 @@ main(int ac, char **av) {
*/ */
static void static void
usage(const char *av0, int copyright_only) { usage(const char *av0, int copyright_only) {
fprintf(stderr, fprintf(stderr,
"Convert unber(1)'s output back into BER, " "Convert unber(1)'s output back into BER, "
"v" VERSION "\n" COPYRIGHT); "v" VERSION "\n" COPYRIGHT);
if(copyright_only) exit(0); if(copyright_only) exit(0);
fprintf(stderr, fprintf(stderr,
"Usage: %s [-n] [-] [file ...]\n" "Usage: %s [-n] [-] [file ...]\n"
"Options:\n" "Options:\n"
" -n Disable XML input validation\n", av0); " -n Disable XML input validation\n",
exit(EX_USAGE); av0);
exit(EX_USAGE);
} }
/* /*
@ -110,169 +108,175 @@ usage(const char *av0, int copyright_only) {
*/ */
static int static int
process(const char *fname) { process(const char *fname) {
char buf[8192]; char buf[8192];
char *collector = 0; char *collector = 0;
size_t collector_size = sizeof(buf); size_t collector_size = sizeof(buf);
size_t collector_offset = 0; size_t collector_offset = 0;
int lineno = 0; int lineno = 0;
FILE *fp; FILE *fp;
if(strcmp(fname, "-")) { if(strcmp(fname, "-")) {
fp = fopen(fname, "r"); fp = fopen(fname, "r");
if(!fp) { if(!fp) {
perror(fname); perror(fname);
return -1; return -1;
} }
} else { } else {
fp = stdin; fp = stdin;
} }
while(fgets(buf, sizeof(buf), fp) || !feof(fp)) { while(fgets(buf, sizeof(buf), fp) || !feof(fp)) {
size_t len = strlen(buf); size_t len = strlen(buf);
if(!len) continue; if(!len) continue;
if(collector_offset || buf[len-1] != '\n') { if(collector_offset || buf[len - 1] != '\n') {
if((collector_size - collector_offset) <= len if((collector_size - collector_offset) <= len || !collector) {
|| !collector) { collector_size <<= 1;
collector_size <<= 1; collector = REALLOC(collector, collector_size);
collector = REALLOC(collector, collector_size); if(!collector) {
if(!collector) { perror("realloc()");
perror("realloc()"); exit(EX_OSERR);
exit(EX_OSERR); }
} }
} memcpy(collector + collector_offset, buf, len + 1);
memcpy(collector + collector_offset, buf, len + 1); collector_offset += len;
collector_offset += len; }
} if(buf[len - 1] != '\n') continue;
if(buf[len-1] != '\n') continue;
if(collector_offset) { if(collector_offset) {
assert(collector[collector_offset-1] == '\n'); assert(collector[collector_offset - 1] == '\n');
process_line(fname, collector, ++lineno); process_line(fname, collector, ++lineno);
collector_offset = 0; collector_offset = 0;
} else { } else {
process_line(fname, buf, ++lineno); process_line(fname, buf, ++lineno);
} }
} }
if(fp != stdin) if(fp != stdin) fclose(fp);
fclose(fp);
return 0; return 0;
} }
static int static int
process_line(const char *fname, char *line, int lineno) { process_line(const char *fname, char *line, int lineno) {
char buf[32]; char buf[32];
char *op; /* '<' */ char *op; /* '<' */
char *cl; /* '>' */ char *cl; /* '>' */
char *tcl_pos; /* tag class (T=") position */ char *tcl_pos; /* tag class (T=") position */
char *tl_pos; /* tag length (TL=") position */ char *tl_pos; /* tag length (TL=") position */
char *v_pos; /* value length (V=") position */ char *v_pos; /* value length (V=") position */
int constr; int constr;
ber_tlv_tag_t tag_value; ber_tlv_tag_t tag_value;
ber_tlv_tag_t tag_class; ber_tlv_tag_t tag_class;
ber_tlv_tag_t tlv_tag; ber_tlv_tag_t tlv_tag;
ber_tlv_len_t tlv_len; ber_tlv_len_t tlv_len;
ber_tlv_len_t opt_tl_len; /* optional TL length */ ber_tlv_len_t opt_tl_len; /* optional TL length */
ssize_t ret; ssize_t ret;
(void)fname; (void)fname;
/* Skip the whitespace */ /* Skip the whitespace */
for(; *line == ' ' || *line == '\t'; line++); for(; *line == ' ' || *line == '\t'; line++)
;
/* Find a tag opening angle bracket */ /* Find a tag opening angle bracket */
op = line; op = line;
switch(*op) { switch(*op) {
case '<': /* That's what we want! A tag opening */ case '<': /* That's what we want! A tag opening */
break; break;
case '-': /* This is a comment (dash-dash) */ case '-': /* This is a comment (dash-dash) */
if(op[1] == *op) if(op[1] == *op) case '\r':
case '\r': case '\n':
case '\n': case '#': /* This is a comment */
case '#': /* This is a comment */ return 0;
return 0; default:
default: fprintf(stderr, "%s: Missing '<' after whitespace at line %d\n", fname,
fprintf(stderr, lineno);
"%s: Missing '<' after whitespace at line %d\n", exit(EX_DATAERR);
fname, lineno); }
exit(EX_DATAERR);
}
/* Find a tag closing angle bracket */ /* Find a tag closing angle bracket */
for(; *line && *line != '>'; line++) { for(; *line && *line != '>'; line++) {
if(*line < ' ') { if(*line < ' ') {
fprintf(stderr, "%s: Invalid charset (%d) at line %d\n", fprintf(stderr, "%s: Invalid charset (%d) at line %d\n", fname,
fname, *(const unsigned char *)line, lineno); *(const unsigned char *)line, lineno);
exit(EX_DATAERR); exit(EX_DATAERR);
} }
} }
cl = line; cl = line;
if(*cl != '>') { if(*cl != '>') {
fprintf(stderr, "%s: Missing '>' at line %d\n", fname, lineno); fprintf(stderr, "%s: Missing '>' at line %d\n", fname, lineno);
exit(EX_DATAERR); exit(EX_DATAERR);
} }
/* Ignore closing tags */ /* Ignore closing tags */
if(op[1] == '/') { if(op[1] == '/') {
if(strchr(cl, '<')) { /* We are not very robust */ if(strchr(cl, '<')) { /* We are not very robust */
fprintf(stderr, fprintf(stderr, "%s: Multiple tags per line at line %d\n", fname,
"%s: Multiple tags per line at line %d\n", lineno);
fname, lineno); exit(EX_DATAERR);
exit(EX_DATAERR); }
} /* End-of-content octets */
/* End-of-content octets */ if(op[2] == 'I') {
if(op[2] == 'I') { buf[0] = buf[1] = 0x00;
buf[0] = buf[1] = 0x00; fwrite(buf, 1, 2, stdout);
fwrite(buf, 1, 2, stdout); }
} return 0;
return 0; }
}
switch(op[1]) { switch(op[1]) {
case '!': return 0; /* A comment */ case '!':
case '?': return 0; /* An XML preamble */ return 0; /* A comment */
case 'C': constr = 1; break; case '?':
case 'P': constr = 0; break; return 0; /* An XML preamble */
case 'I': constr = 2; break; case 'C':
default: constr = 1;
fprintf(stderr, break;
"%s: Expected \"C\"/\"P\"/\"I\" as the XML tag name (%c) at line %d\n", case 'P':
fname, op[1], lineno); constr = 0;
exit(EX_DATAERR); break;
} case 'I':
constr = 2;
break;
default:
fprintf(stderr,
"%s: Expected \"C\"/\"P\"/\"I\" as the XML tag name (%c) at "
"line %d\n",
fname, op[1], lineno);
exit(EX_DATAERR);
}
*cl = '\0'; *cl = '\0';
if(cl[-1] == 'F') { if(cl[-1] == 'F') {
fprintf(stderr, fprintf(stderr,
"%s: Detected pretty-printing of primitive types at line %d. " "%s: Detected pretty-printing of primitive types at line %d. "
"Re-run `unber` with -p option to disable pretty-printing.\n", fname, lineno); "Re-run `unber` with -p option to disable pretty-printing.\n",
exit(EX_DATAERR); fname, lineno);
} exit(EX_DATAERR);
}
tcl_pos = strstr(op, "T=\"["); tcl_pos = strstr(op, "T=\"[");
tl_pos = strstr(op, "TL=\""); tl_pos = strstr(op, "TL=\"");
v_pos = strstr(op, "V=\""); v_pos = strstr(op, "V=\"");
if(!tcl_pos || (!v_pos && constr != 2)) { if(!tcl_pos || (!v_pos && constr != 2)) {
fprintf(stderr, fprintf(stderr, "%s: Mandatory attribute %s is not found at line %d\n",
"%s: Mandatory attribute %s is not found at line %d\n", fname, (!tcl_pos) ? "T" : "V", lineno);
fname, (!tcl_pos)?"T":"V", lineno); exit(EX_DATAERR);
exit(EX_DATAERR); }
} errno = 0;
errno = 0; opt_tl_len = tl_pos ? strtoul(tl_pos + 4, 0, 10) : 0;
opt_tl_len = tl_pos ? strtoul(tl_pos + 4, 0, 10) : 0; if(constr == 2) {
if(constr == 2) { tlv_len = 0;
tlv_len = 0; } else {
} else { tlv_len = strtoul(v_pos + 3, 0, 10);
tlv_len = strtoul(v_pos + 3, 0, 10); }
} if(errno || (opt_tl_len && opt_tl_len < 2) || tlv_len < 0) {
if(errno || (opt_tl_len && opt_tl_len < 2) || tlv_len < 0) { fprintf(stderr, "%s: Invalid TL or V value at line %d\n", fname,
fprintf(stderr, "%s: Invalid TL or V value at line %d\n", lineno);
fname, lineno); exit(EX_DATAERR);
exit(EX_DATAERR); }
}
/* clang-format off */
tcl_pos += 4; tcl_pos += 4;
switch(*tcl_pos) { switch(*tcl_pos) {
case 'U': /* UNIVERSAL */ case 'U': /* UNIVERSAL */
@ -300,61 +304,63 @@ process_line(const char *fname, char *line, int lineno) {
} }
break; break;
} }
unsigned long tag_value_UL; /* clang-format on */
errno = 0;
if(!*tcl_pos
|| ((tag_value_UL = strtoul(tcl_pos, 0, 10)) > UINT_MAX)
|| errno) {
fprintf(stderr, "%s: Invalid tag value (%c) at line %d\n",
fname, *tcl_pos, lineno);
exit(EX_DATAERR);
} else {
tag_value = tag_value_UL;
}
tlv_tag = ((tag_value << 2) | tag_class);
ret = ber_tlv_tag_serialize(tlv_tag, buf, sizeof(buf)); unsigned long tag_value_UL;
assert(ret >= 1 && (size_t)ret < sizeof(buf)); errno = 0;
if(constr == 2) { if(!*tcl_pos || ((tag_value_UL = strtoul(tcl_pos, 0, 10)) > UINT_MAX)
buf[ret] = 0x80; || errno) {
ret += 1; fprintf(stderr, "%s: Invalid tag value (%c) at line %d\n", fname,
} else { *tcl_pos, lineno);
ret += der_tlv_length_serialize(tlv_len, exit(EX_DATAERR);
buf + ret, sizeof(buf) - ret); } else {
assert(ret >= 2 && (size_t)ret < sizeof(buf)); tag_value = tag_value_UL;
} }
if(opt_tl_len && ret != opt_tl_len) { tlv_tag = ((tag_value << 2) | tag_class);
fprintf(stderr, "%s: Cannot encode TL at line %d "
"in the given number of bytes (%ld!=%ld)\n",
fname, lineno, (long)ret, (long)opt_tl_len);
exit(EX_DATAERR);
}
if(constr) *buf |= 0x20; /* Enable "constructed" bit */
fwrite(buf, 1, ret, stdout);
if(!constr) { ret = ber_tlv_tag_serialize(tlv_tag, buf, sizeof(buf));
ber_tlv_len_t len; assert(ret >= 1 && (size_t)ret < sizeof(buf));
for(len = 0, cl++; *cl && *cl != '<'; cl++, len++) { if(constr == 2) {
unsigned char v; buf[ret] = 0x80;
int h; ret += 1;
if(*cl != '&') { } else {
fputc(*cl, stdout); ret += der_tlv_length_serialize(tlv_len, buf + ret, sizeof(buf) - ret);
continue; assert(ret >= 2 && (size_t)ret < sizeof(buf));
} }
cl++; if(opt_tl_len && ret != opt_tl_len) {
if(*cl != '#') { fprintf(stderr,
fputc(*cl, stdout); "%s: Cannot encode TL at line %d "
continue; "in the given number of bytes (%ld!=%ld)\n",
} fname, lineno, (long)ret, (long)opt_tl_len);
cl++; exit(EX_DATAERR);
if(*cl != 'x') { }
fprintf(stderr, "%s: Expected \"&#xNN;\" at line %d\n", if(constr) *buf |= 0x20; /* Enable "constructed" bit */
fname, lineno); fwrite(buf, 1, ret, stdout);
exit(EX_DATAERR);
} if(!constr) {
for(v = 0, h = 0; h < 2; h++) { ber_tlv_len_t len;
unsigned char clv = *++cl; for(len = 0, cl++; *cl && *cl != '<'; cl++, len++) {
v <<= 4; unsigned char v;
int h;
if(*cl != '&') {
fputc(*cl, stdout);
continue;
}
cl++;
if(*cl != '#') {
fputc(*cl, stdout);
continue;
}
cl++;
if(*cl != 'x') {
fprintf(stderr, "%s: Expected \"&#xNN;\" at line %d\n", fname,
lineno);
exit(EX_DATAERR);
}
for(v = 0, h = 0; h < 2; h++) {
unsigned char clv = *++cl;
v <<= 4;
/* clang-format off */
switch(clv) { switch(clv) {
case '0': case '1': case '2': case '3': case '4': case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9': case '5': case '6': case '7': case '8': case '9':
@ -371,26 +377,25 @@ process_line(const char *fname, char *line, int lineno) {
fname, lineno, clv); fname, lineno, clv);
exit(EX_DATAERR); exit(EX_DATAERR);
} }
} /* clang-format on */
cl++; }
if(*cl != ';') { cl++;
fprintf(stderr, if(*cl != ';') {
"%s: Expected \"&#xNN;\" at line %d\n", fprintf(stderr, "%s: Expected \"&#xNN;\" at line %d\n", fname,
fname, lineno); lineno);
exit(EX_DATAERR); exit(EX_DATAERR);
} }
fputc(v, stdout); fputc(v, stdout);
} }
if(len != tlv_len) { if(len != tlv_len) {
if(no_validation) fprintf(stderr, "Warning: "); if(no_validation) fprintf(stderr, "Warning: ");
fprintf(stderr, fprintf(stderr,
"%s: Could not encode value of %ld chars " "%s: Could not encode value of %ld chars "
"at line %d in %ld bytes\n", "at line %d in %ld bytes\n",
fname, (long)len, lineno, (long)tlv_len); fname, (long)len, lineno, (long)tlv_len);
if(!no_validation) exit(EX_DATAERR); if(!no_validation) exit(EX_DATAERR);
} }
} }
return 0;
}
return 0;
}

View File

@ -24,7 +24,7 @@
* *
* $Id$ * $Id$
*/ */
#ifdef HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
#include <config.h> #include <config.h>
#endif #endif
@ -34,39 +34,38 @@
#include <assert.h> #include <assert.h>
#include <errno.h> #include <errno.h>
#ifdef HAVE_UNISTD_H #ifdef HAVE_UNISTD_H
#include <unistd.h> #include <unistd.h>
#endif #endif
#ifdef HAVE_SYS_TYPES_H #ifdef HAVE_SYS_TYPES_H
#include <sys/types.h> #include <sys/types.h>
#endif #endif
#ifdef HAVE_SYS_STAT_H #ifdef HAVE_SYS_STAT_H
#include <sys/stat.h> /* for stat(2) */ #include <sys/stat.h> /* for stat(2) */
#endif #endif
#ifndef _WIN32 #ifndef _WIN32
#include <sysexits.h> /* for EX_USAGE & others */ #include <sysexits.h> /* for EX_USAGE & others */
#else /* _WIN32 */ #else /* _WIN32 */
#ifndef EX_USAGE #ifndef EX_USAGE
#define EX_USAGE 64 #define EX_USAGE 64
#endif #endif
#ifndef EX_DATAERR #ifndef EX_DATAERR
#define EX_DATAERR 65 #define EX_DATAERR 65
#endif #endif
#ifndef EX_SOFTWARE #ifndef EX_SOFTWARE
#define EX_SOFTWARE 70 #define EX_SOFTWARE 70
#endif #endif
#ifndef EX_OSERR #ifndef EX_OSERR
#define EX_OSERR 71 #define EX_OSERR 71
#endif #endif
#ifndef EX_OSFILE #ifndef EX_OSFILE
#define EX_OSFILE 72 #define EX_OSFILE 72
#endif #endif
#if defined HAVE_DECL_ALLOCA && !HAVE_DECL_ALLOCA #if defined HAVE_DECL_ALLOCA && !HAVE_DECL_ALLOCA
#define alloca _alloca #define alloca _alloca
#endif #endif
#define snprintf _snprintf #define snprintf _snprintf
#endif /* _WIN32 */ #endif /* _WIN32 */

File diff suppressed because it is too large Load Diff