1 #include "asn1c_internal.h"
2 #include "asn1c_lang.h"
4 #include "asn1c_save.h"
6 #include "asn1c_naming.h"
8 static void default_logger_cb(int, const char *fmt, ...);
9 static int asn1c_compile_expr(arg_t *arg, const asn1c_ioc_table_and_objset_t *);
10 static int asn1c_detach_streams(asn1p_expr_t *expr);
13 asn1_compile(asn1p_t *asn, const char *datadir, const char *destdir, enum asn1c_flags flags,
14 int argc, int optc, char **argv) {
20 c_name_clash_finder_init();
23 * Initialize target language.
25 ret = asn1c_with_language(ASN1C_LANGUAGE_C);
28 memset(arg, 0, sizeof(*arg));
29 arg->default_cb = asn1c_compile_expr;
30 arg->logger_cb = default_logger_cb;
35 * Compile each individual top level structure.
37 TQ_FOR(mod, &(asn->modules), mod_next) {
38 TQ_FOR(arg->expr, &(mod->members), next) {
39 arg->ns = asn1_namespace_new_from_module(mod, 0);
41 compiler_streams_t *cs = NULL;
43 if(asn1c_attach_streams(arg->expr))
47 cs->target = OT_TYPE_DECLS;
50 ret = asn1c_compile_expr(arg, NULL);
52 FATAL("Cannot compile \"%s\" (%x:%x) at line %d",
53 arg->expr->Identifier,
60 asn1_namespace_free(arg->ns);
65 if(c_name_clash(arg)) {
66 if(arg->flags & A1C_COMPOUND_NAMES) {
67 FATAL("Name clashes encountered even with -fcompound-names flag");
68 /* Proceed further for better debugging. */
70 FATAL("Use \"-fcompound-names\" flag to asn1c to resolve name clashes");
71 if(arg->flags & A1C_PRINT_COMPILED) {
72 /* Proceed further for better debugging. */
79 DEBUG("Saving compiled data");
81 c_name_clash_finder_destroy();
84 * Save or print out the compiled result.
86 if(asn1c_save_compiled_output(arg, datadir, destdir, argc, optc, argv))
89 TQ_FOR(mod, &(asn->modules), mod_next) {
90 TQ_FOR(arg->expr, &(mod->members), next) {
91 asn1c_detach_streams(arg->expr);
99 asn1c_compile_expr(arg_t *arg, const asn1c_ioc_table_and_objset_t *opt_ioc) {
100 asn1p_expr_t *expr = arg->expr;
101 int (*type_cb)(arg_t *);
104 assert((int)expr->meta_type >= AMT_INVALID);
105 assert(expr->meta_type < AMT_EXPR_META_MAX);
106 assert((int)expr->expr_type >= A1TC_INVALID);
107 assert(expr->expr_type < ASN_EXPR_TYPE_MAX);
109 type_cb = asn1_lang_map[expr->meta_type][expr->expr_type].type_cb;
112 DEBUG("Compiling %s at line %d",
116 if(expr->lhs_params && expr->spec_index == -1) {
119 DEBUG("Parameterized type %s at line %d: %s (%d)",
120 expr->Identifier, expr->_lineno,
121 expr->specializations.pspecs_count
122 ? "compiling" : "unused, skipping",
123 expr->specializations.pspecs_count);
124 for(i = 0; i<expr->specializations.pspecs_count; i++) {
125 arg->expr = expr->specializations
127 ret = asn1c_compile_expr(arg, opt_ioc);
130 arg->expr = expr; /* Restore */
137 * Even if the target language compiler does not know
138 * how to compile the given expression, we know that
139 * certain expressions need not to be compiled at all.
141 switch(expr->meta_type) {
143 case AMT_OBJECTCLASS:
144 case AMT_OBJECTFIELD:
155 FATAL("Cannot compile \"%s\" (%x:%x) at line %d",
156 arg->expr->Identifier,
157 arg->expr->expr_type,
158 arg->expr->meta_type,
160 OUT("#error Cannot compile \"%s\" (%x/%x) at line %d\n",
161 arg->expr->Identifier,
162 arg->expr->meta_type,
163 arg->expr->expr_type,
172 asn1c_attach_streams(asn1p_expr_t *expr) {
173 compiler_streams_t *cs;
177 return 0; /* Already attached? */
179 expr->data = calloc(1, sizeof(compiler_streams_t));
180 if(expr->data == NULL)
184 for(i = 0; i < OT_MAX; i++) {
185 TQ_INIT(&(cs->destination[i].chunks));
192 asn1c_detach_streams(asn1p_expr_t *expr) {
193 compiler_streams_t *cs;
198 return 0; /* Already detached? */
201 for(i = 0; i < OT_MAX; i++) {
202 while((m = TQ_REMOVE(&(cs->destination[i].chunks), next))) {
208 expr->data = (void *)NULL;
214 default_logger_cb(int _severity, const char *fmt, ...) {
219 case -1: pfx = "DEBUG: "; break;
220 case 0: pfx = "WARNING: "; break;
221 case 1: pfx = "FATAL: "; break;
224 fprintf(stderr, "%s", pfx);
226 vfprintf(stderr, fmt, ap);
228 fprintf(stderr, "\n");
232 asn1c_debug_expr_naming(arg_t *arg) {
233 asn1p_expr_t *expr = arg->expr;
235 printf("%s: ", expr->Identifier);
236 printf("%s\n", c_names_format(c_name(arg)));
243 asn1c_debug_type_naming(asn1p_t *asn, enum asn1c_flags flags,
244 char **asn_type_names) {
249 memset(arg, 0, sizeof(*arg));
250 arg->logger_cb = default_logger_cb;
254 c_name_clash_finder_init();
257 * Compile each individual top level structure.
259 TQ_FOR(mod, &(asn->modules), mod_next) {
260 int namespace_shown = 0;
261 TQ_FOR(arg->expr, &(mod->members), next) {
262 arg->ns = asn1_namespace_new_from_module(mod, 0);
264 for(char **t = asn_type_names; *t; t++) {
265 if(strcmp(*t, arg->expr->Identifier) == 0) {
266 if(!namespace_shown) {
268 printf("Namespace %s\n",
269 asn1_namespace_string(arg->ns));
271 asn1c_debug_expr_naming(arg);
275 asn1_namespace_free(arg->ns);
280 c_name_clash_finder_destroy();