blob: d647c05b6c8a98b09f79e88eea537705c735abaf [file] [log] [blame]
Lev Walkinf15320b2004-06-03 03:38:44 +00001#include "asn1c_internal.h"
2
3static void default_logger_cb(int, const char *fmt, ...);
4static int asn1c_compile_expr(arg_t *arg);
5static int asn1c_attach_streams(asn1p_expr_t *expr);
6
7int
8asn1_compile(asn1p_t *asn, const char *datadir, enum asn1c_flags flags) {
9 arg_t arg_s;
10 arg_t *arg = &arg_s;
11 int ret;
12
13 /*
14 * Initialize target language.
15 */
16 ret = asn1c_with_language(ASN1C_LANGUAGE_C);
17 assert(ret == 0);
18
19 memset(arg, 0, sizeof(*arg));
20 arg->default_cb = asn1c_compile_expr;
21 arg->logger_cb = default_logger_cb;
22 arg->flags = flags;
23 arg->asn = asn;
24
25 /*
26 * Compile each individual top level structure.
27 */
28 TQ_FOR(arg->mod, &(asn->modules), mod_next) {
29 TQ_FOR(arg->expr, &(arg->mod->members), next) {
30 compiler_streams_t *cs = NULL;
31
32 if(asn1c_attach_streams(arg->expr))
33 return -1;
34
35 cs = arg->expr->data;
36 cs->target = OT_TYPE_DECLS;
37 arg->target = cs;
38
39 ret = asn1c_compile_expr(arg);
40 if(ret) {
41 FATAL("Cannot compile %s (%x:%x) at line %d",
42 arg->expr->Identifier,
43 arg->expr->expr_type,
44 arg->expr->meta_type,
45 arg->expr->_lineno);
46 return ret;
47 }
48 }
49 }
50
51 DEBUG("Saving compiled data");
52
53 /*
54 * Save or print out the compiled result.
55 */
56 if(asn1c_save_compiled_output(arg, datadir))
57 return -1;
58
59 return 0;
60}
61
62static int
63asn1c_compile_expr(arg_t *arg) {
64 asn1p_expr_t *expr = arg->expr;
65 int (*type_cb)(arg_t *);
66 int ret;
67
68 assert(expr->meta_type >= AMT_INVALID);
69 assert(expr->meta_type < AMT_EXPR_META_MAX);
70 assert(expr->expr_type >= A1TC_INVALID);
71 assert(expr->expr_type < ASN_EXPR_TYPE_MAX);
72
73 type_cb = asn1_lang_map[expr->meta_type][expr->expr_type].type_cb;
74 if(type_cb) {
75
76 if(arg->indent_level == 0)
77 OUT("\n");
78
79 DEBUG("Compiling %s at line %d",
80 expr->Identifier,
81 expr->_lineno);
82
83 ret = type_cb(arg);
84 } else {
85 ret = -1;
86 /*
87 * Even if the target language compiler does not know
88 * how to compile the given expression, we know that
89 * certain expressions need not to be compiled at all.
90 */
91 switch(expr->meta_type) {
92 case AMT_PARAMTYPE:
93 case AMT_OBJECT:
94 case AMT_OBJECTSET:
95 case AMT_VALUE:
96 case AMT_VALUESET:
97 ret = 0;
98 break;
99 default:
100 break;
101 }
102
103 switch(expr->expr_type) {
104 case A1TC_TYPEID:
105 ret = 0; /* TYPE-IDENTIFIER is a CLASS */
106 default:
107 break;
108 }
109 }
110
111 if(ret == -1) {
112 OUT("#error Cannot compile \"%s\" (%x/%x) at line %d\n",
113 arg->expr->Identifier,
114 arg->expr->meta_type,
115 arg->expr->expr_type,
116 arg->expr->_lineno
117 );
118 }
119
120 return ret;
121}
122
123static int
124asn1c_attach_streams(asn1p_expr_t *expr) {
125 compiler_streams_t *cs;
126 int i;
127
128 if(expr->data)
129 return 0; /* Already attached? */
130
131 expr->data = calloc(1, sizeof(compiler_streams_t));
132 if(expr->data == NULL)
133 return -1;
134
135 cs = expr->data;
136 for(i = 0; i < OT_MAX; i++) {
137 TQ_INIT(&(cs->targets[i]));
138 }
139
140 return 0;
141}
142
143static void
144default_logger_cb(int _severity, const char *fmt, ...) {
145 va_list ap;
146 char *pfx = "";
147
148 switch(_severity) {
149 case -1: pfx = "DEBUG: "; break;
150 case 0: pfx = "WARNING: "; break;
151 case 1: pfx = "FATAL: "; break;
152 }
153
154 fprintf(stderr, "%s", pfx);
155 va_start(ap, fmt);
156 vfprintf(stderr, fmt, ap);
157 va_end(ap);
158 fprintf(stderr, "\n");
159}
160