1 #include "asn1c_internal.h"
4 #include "asn1c_misc.h"
5 #include <asn1fix_export.h>
8 #define MKID(expr) asn1c_make_identifier(AMI_USE_PREFIX, (expr), 0)
11 * Given the table constraint or component relation constraint
12 * ({ObjectSetName}{...}) returns "ObjectSetName" as a reference.
15 asn1c_get_information_object_set_reference_from_constraint(arg_t *arg,
16 const asn1p_constraint_t *ct) {
19 assert(ct->type == ACT_CA_CRC);
20 assert(ct->el_count >= 1);
22 DEBUG("Component Relation Constraint: %s", asn1p_constraint_string(ct));
24 assert(ct->elements[0]->type == ACT_EL_VALUE);
26 asn1p_value_t *val = ct->elements[0]->value;
27 if(val->type == ATV_VALUESET && val->value.constraint->type == ACT_EL_TYPE) {
28 asn1p_value_t *csub = val->value.constraint->containedSubtype;
31 } else if(csub->type == ATV_REFERENCED) {
32 return csub->value.reference;
33 } else if(csub->type == ATV_TYPE) {
34 if(csub->value.v_type->expr_type == A1TC_REFERENCE) {
35 assert(csub->value.v_type->reference);
36 return csub->value.v_type->reference;
40 if(val->type != ATV_REFERENCED) {
41 FATAL("Set reference: %s", asn1f_printable_value(val));
42 assert(val->type == ATV_REFERENCED);
45 return val->value.reference;
48 static asn1c_ioc_table_and_objset_t
49 asn1c_get_ioc_table_from_objset(arg_t *arg, const asn1p_ref_t *objset_ref, asn1p_expr_t *objset) {
50 asn1c_ioc_table_and_objset_t ioc_tao = { 0, 0, 1 };
54 if(objset->ioc_table) {
55 ioc_tao.ioct = objset->ioc_table;
56 ioc_tao.objset = objset;
57 ioc_tao.fatal_error = 0;
59 FATAL("Information Object Set %s contains no objects at line %d",
60 objset->Identifier, objset->_lineno);
66 asn1c_ioc_table_and_objset_t
67 asn1c_get_ioc_table(arg_t *arg) {
68 asn1p_expr_t *expr = arg->expr;
70 asn1p_expr_t *objset = 0;
71 const asn1p_ref_t *objset_ref = NULL;
72 asn1c_ioc_table_and_objset_t safe_ioc_tao = {0, 0, 0};
73 asn1c_ioc_table_and_objset_t failed_ioc_tao = { 0, 0, 1 };
75 TQ_FOR(memb, &(expr->members), next) {
76 const asn1p_constraint_t *cr_ct =
77 asn1p_get_component_relation_constraint(memb->constraints);
78 const asn1p_ref_t *tmpref =
79 asn1c_get_information_object_set_reference_from_constraint(arg,
82 if(objset_ref && asn1p_ref_compare(objset_ref, tmpref) != 0) {
84 "Object set reference on line %d differs from object set "
85 "reference on line %d",
86 objset_ref->_lineno, tmpref->_lineno);
87 return failed_ioc_tao;
98 objset = WITH_MODULE_NAMESPACE(
99 arg->expr->module, expr_ns,
100 asn1f_lookup_symbol_ex(arg->asn, expr_ns, arg->expr, objset_ref));
102 FATAL("Cannot found %s", asn1p_ref_string(objset_ref));
103 return failed_ioc_tao;
106 return asn1c_get_ioc_table_from_objset(arg, objset_ref, objset);
110 emit_ioc_value(arg_t *arg, struct asn1p_ioc_cell_s *cell) {
112 if(cell->value && cell->value->meta_type == AMT_VALUE) {
113 const char *prim_type = NULL;
114 int primitive_representation = 0;
116 asn1p_expr_t *cv_type =
117 asn1f_find_terminal_type_ex(arg->asn, arg->ns, cell->value);
119 switch(cv_type->expr_type) {
120 case ASN_BASIC_INTEGER:
121 case ASN_BASIC_ENUMERATED:
122 switch(asn1c_type_fits_long(arg, cell->value /* sic */)) {
124 GEN_INCLUDE_STD("INTEGER");
125 prim_type = "INTEGER_t";
129 primitive_representation = 1;
133 prim_type = "unsigned long";
134 primitive_representation = 1;
138 case ASN_BASIC_OBJECT_IDENTIFIER:
139 prim_type = "OBJECT_IDENTIFIER_t";
141 case ASN_BASIC_RELATIVE_OID:
142 prim_type = "RELATIVE_OID_t";
145 char *p = strdup(MKID(cell->value));
146 FATAL("Unsupported type %s for value %s",
147 asn1c_type_name(arg, cell->value, TNF_UNMODIFIED), p);
152 OUT("static const %s asn_VAL_%d_%s = ", prim_type,
153 cell->value->_type_unique_index, MKID(cell->value));
155 asn1p_expr_t *expr_value = cell->value;
156 while(expr_value->value->type == ATV_REFERENCED) {
157 expr_value = WITH_MODULE_NAMESPACE(
158 expr_value->module, expr_ns,
159 asn1f_lookup_symbol_ex(arg->asn, expr_ns, expr_value,
160 expr_value->value->value.reference));
162 FATAL("Unrecognized value type for %s", MKID(cell->value));
167 if(!primitive_representation) OUT("{ ");
169 switch(expr_value->value->type) {
171 if(primitive_representation) {
172 OUT("%s", asn1p_itoa(expr_value->value->value.v_integer));
175 asn1c_integer_t v = expr_value->value->value.v_integer;
178 OUT("\"\\x%02x\", 1", (int)v);
180 } else if(v <= 32767) {
181 OUT("\"\\x%02x\\x%02x\", 2", (int)(v >> 8), (int)(v & 0xff));
185 FATAL("Unsupported value %s range for type %s",
186 asn1f_printable_value(expr_value->value),
191 OUT("\"not supported\", 0 };\n");
192 FATAL("Inappropriate value %s for type %s",
193 asn1f_printable_value(expr_value->value), MKID(cell->value));
194 return 0; /* TEMPORARY FIXME FIXME */
196 FATAL("Inappropriate value %s for type %s",
197 asn1f_printable_value(expr_value->value), MKID(cell->value));
201 if(primitive_representation) {
205 OUT(" /* %s */\n", asn1f_printable_value(expr_value->value));
213 emit_ioc_cell(arg_t *arg, struct asn1p_ioc_cell_s *cell) {
214 OUT("{ \"%s\", ", cell->field->Identifier);
218 } else if(cell->value->meta_type == AMT_VALUE) {
219 GEN_INCLUDE(asn1c_type_name(arg, cell->value, TNF_INCLUDE));
220 OUT("aioc__value, ");
221 OUT("&asn_DEF_%s, ", asn1c_type_name(arg, cell->value, TNF_SAFE));
222 OUT("&asn_VAL_%d_%s", cell->value->_type_unique_index,
225 } else if(cell->value->meta_type == AMT_TYPEREF) {
226 GEN_INCLUDE(asn1c_type_name(arg, cell->value, TNF_INCLUDE));
227 OUT("aioc__type, &asn_DEF_%s", MKID(cell->value));
228 } else if(cell->value->meta_type == AMT_TYPE) {
229 GEN_INCLUDE(asn1c_type_name(arg, cell->value, TNF_INCLUDE));
230 OUT("aioc__type, &asn_DEF_%s", asn1c_type_name(arg, cell->value, TNF_SAFE));
241 * Refer to skeletons/asn_ioc.h
244 emit_ioc_table(arg_t *arg, asn1p_expr_t *context, asn1c_ioc_table_and_objset_t ioc_tao) {
248 GEN_INCLUDE_STD("asn_ioc");
250 REDIR(OT_IOC_TABLES);
252 /* Emit values that are used in the Information Object Set table first */
253 for(size_t rn = 0; rn < ioc_tao.ioct->rows; rn++) {
254 asn1p_ioc_row_t *row = ioc_tao.ioct->row[rn];
255 for(size_t cn = 0; cn < row->columns; cn++) {
256 if(emit_ioc_value(arg, &row->column[cn])) {
262 if(ioc_tao.ioct->rows == 0)
265 /* Emit the Information Object Set */
266 OUT("static const asn_ioc_cell_t asn_IOS_%s_%d_rows[] = {\n",
267 MKID(ioc_tao.objset), ioc_tao.objset->_type_unique_index);
270 for(size_t rn = 0; rn < ioc_tao.ioct->rows; rn++) {
271 asn1p_ioc_row_t *row = ioc_tao.ioct->row[rn];
272 columns = columns ? columns : row->columns;
273 if(columns != row->columns) {
274 FATAL("Information Object Set %s row column mismatch on line %d",
275 ioc_tao.objset->Identifier, ioc_tao.objset->_lineno);
278 for(size_t cn = 0; cn < row->columns; cn++) {
279 if(rn || cn) OUT(",\n");
280 emit_ioc_cell(arg, &row->column[cn]);
288 OUT("static const asn_ioc_set_t asn_IOS_%s_%d[] = {\n",
289 MKID(ioc_tao.objset), ioc_tao.objset->_type_unique_index);
291 OUT("{ %zu, %zu, asn_IOS_%s_%d_rows }\n", ioc_tao.ioct->rows, columns,
292 MKID(ioc_tao.objset), ioc_tao.objset->_type_unique_index);