From 4649987b1fa638eed2318b02f067434fdf3f80f8 Mon Sep 17 00:00:00 2001 From: Lev Walkin Date: Mon, 6 Mar 2006 13:05:34 +0000 Subject: [PATCH] import standard modules --- asn1c/asn1c.c | 187 ++++++++++++++++++++++++++++------- asn1c/sys-common.h | 3 + libasn1parser/asn1p_module.h | 6 ++ libasn1print/asn1print.c | 3 + 4 files changed, 161 insertions(+), 38 deletions(-) diff --git a/asn1c/asn1c.c b/asn1c/asn1c.c index b73848df..c097d556 100644 --- a/asn1c/asn1c.c +++ b/asn1c/asn1c.c @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2003, 2004, 2005 + * Copyright (c) 2003, 2004, 2005, 2006 * Lev Walkin . All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -38,11 +38,19 @@ #include /* Portable basename(3) and dirname(3) */ +#ifdef WIN32 +#include +#include +#else +#include +#endif + #undef COPYRIGHT #define COPYRIGHT \ "Copyright (c) 2003, 2004, 2005, 2006 Lev Walkin \n" static void usage(const char *av0); /* Print the Usage screen and exit */ +static int importStandardModules(asn1p_t *asn, const char *skeletons_dir); int main(int ac, char **av) { @@ -83,9 +91,7 @@ main(int ac, char **av) { char *known_type = optarg + 18; ret = asn1f_make_known_external_type(known_type); assert(ret == 0 || errno == EEXIST); - } else if( - strcmp(optarg, "native-integers") == 0 /* Legacy */ - || strcmp(optarg, "native-types") == 0) { + } else if(strcmp(optarg, "native-types") == 0) { asn1_compiler_flags |= A1C_USE_NATIVE_TYPES; } else if(strcmp(optarg, "no-constraints") == 0) { asn1_compiler_flags |= A1C_NO_CONSTRAINTS; @@ -198,6 +204,39 @@ main(int ac, char **av) { 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. @@ -222,9 +261,12 @@ main(int ac, char **av) { } 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. */ @@ -234,6 +276,13 @@ main(int ac, char **av) { 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, @@ -261,39 +310,6 @@ main(int ac, char **av) { return 0; } - /* - * Make sure the skeleton directory is out there. - */ - if((asn1_compiler_flags & A1C_OMIT_SUPPORT_CODE) == 0 - && 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 = alloca(len); - 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_SOFTWARE); - } - } - } - /* * Compile the ASN.1 tree into a set of source files * of another language. @@ -306,6 +322,101 @@ main(int ac, char **av) { return 0; } +/* + * Parse and import *.asn1 from skeletons/standard-modules + */ +static int +importStandardModules(asn1p_t *asn, const char *skeletons_dir) { + asn1p_t *new_asn; + asn1p_module_t *mod; + const char *filename; + char *target_dir; + int target_dir_len; + int len; +#ifdef WIN32 + intptr_t dir; + struct _finddata_t c_file; + char *pattern; +#else + struct dirent *dp; + DIR *dir; +#endif + int ret = 0; + + /* Notes for the human reader */ + assert(asn); + assert(skeletons_dir); + + /* + * Figure out the standard-modules directory. + */ + target_dir_len = strlen(skeletons_dir) + + sizeof("/standard-modules") - 1; + target_dir = malloc(target_dir_len + 1); + assert(target_dir); + snprintf(target_dir, target_dir_len + 1, "%s/standard-modules", + skeletons_dir); + +#ifdef WIN32 + len = target_dir_len + sizeof("/*.asn1")); + pattern = malloc(len); + assert(pattern); + snprintf(pattern, len, "%s/*.asn1", target_dir); + dir = _findfirst(pattern, &c_file); + if(dir != -1L) { +#else + dir = opendir(target_dir); + if(!dir) { +#endif + fprintf(stderr, + "WARNING: Cannot find standard modules in %s\n", + target_dir); + return -1; + } + +#ifdef WIN32 + do { + filename = c_file.name; +#else + while((dp = readdir(dir))) { + char *fullname; + filename = dp->d_name; + len = strlen(filename); + if(len <= 5 || strcmp(filename + len - 5, ".asn1")) + continue; + len = target_dir_len + 1 + len + 1; + fullname = malloc(len); + if(!fullname) continue; /* Just skip it, no big deal */ + snprintf(fullname, len, "%s/%s", target_dir, filename); + filename = fullname; +#endif + + new_asn = asn1p_parse_file(filename, A1P_NOFLAGS); + if(new_asn == NULL) { + fprintf(stderr, "WARNING: Cannot parse standard module \"%s\"\n", filename); + ret = -1; + continue; + } + + /* Import these modules and mark them as "standard" */ + while((mod = TQ_REMOVE(&(new_asn->modules), mod_next))) { + mod->_tags |= MT_STANDARD_MODULE; + TQ_ADD(&(asn->modules), mod, mod_next); + } + asn1p_free(new_asn); + +#ifdef WIN32 + } while(_findnext(dir, &c_file) == 0); + _findclose(dir); +#else + free(fullname); + } /* while(readdir()) */ + closedir(dir); +#endif + + return ret; +} + /* * Print the usage screen and exit(EX_USAGE). */ diff --git a/asn1c/sys-common.h b/asn1c/sys-common.h index 8447c6d6..514a20cd 100644 --- a/asn1c/sys-common.h +++ b/asn1c/sys-common.h @@ -61,6 +61,9 @@ #ifndef EX_OSERR #define EX_OSERR 71 #endif +#ifndef EX_OSFILE +#define EX_OSFILE 72 +#endif #define alloca _alloca #define snprintf _snprintf #endif /* WIN32 */ diff --git a/libasn1parser/asn1p_module.h b/libasn1parser/asn1p_module.h index e34ffde9..618c6e7d 100644 --- a/libasn1parser/asn1p_module.h +++ b/libasn1parser/asn1p_module.h @@ -71,6 +71,12 @@ typedef struct asn1p_module_s { TQ_ENTRY(struct asn1p_module_s) mod_next; + /* + * Internally useful properties. + */ + enum { + MT_STANDARD_MODULE = 0x01, /* Module came from standard-modules */ + } _tags; } asn1p_module_t; /* diff --git a/libasn1print/asn1print.c b/libasn1print/asn1print.c index 86175f1d..cb1445b7 100644 --- a/libasn1print/asn1print.c +++ b/libasn1print/asn1print.c @@ -62,6 +62,9 @@ static int asn1print_module(asn1p_t *asn, asn1p_module_t *mod, enum asn1print_flags flags) { asn1p_expr_t *tc; + if(mod->_tags & MT_STANDARD_MODULE) + return 0; /* Ignore modules imported from skeletons */ + if(flags & APF_PRINT_XML_DTD) printf("