mirror of https://gerrit.osmocom.org/asn1c
autoformatted (no semantic change)
This commit is contained in:
parent
438fe8796f
commit
41a1da63e5
702
asn1c/asn1c.c
702
asn1c/asn1c.c
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
549
asn1c/enber.c
549
asn1c/enber.c
|
@ -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;
|
||||||
|
}
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
||||||
|
|
1252
asn1c/unber.c
1252
asn1c/unber.c
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue