mirror of https://gerrit.osmocom.org/asn1c
new constraints generation method
This commit is contained in:
parent
2e3055da17
commit
59004fad9c
|
@ -1,7 +1,7 @@
|
|||
|
||||
AM_CPPFLAGS = \
|
||||
-I${top_srcdir}/libasn1parser \
|
||||
-I${top_srcdir}/libasn1fix
|
||||
-I$(top_srcdir)/libasn1parser \
|
||||
-I$(top_srcdir)/libasn1fix
|
||||
|
||||
noinst_LTLIBRARIES = libasn1compiler.la
|
||||
|
||||
|
@ -17,11 +17,3 @@ libasn1compiler_la_SOURCES = \
|
|||
asn1c_compat.c asn1c_compat.h \
|
||||
asn1c_fdeps.c asn1c_fdeps.h \
|
||||
asn1c_internal.h
|
||||
|
||||
TESTS = $(check_PROGRAMS)
|
||||
|
||||
check_PROGRAMS = check_compiler
|
||||
|
||||
check_compiler_LDADD = $(noinst_LTLIBRARIES) \
|
||||
$(top_builddir)/libasn1parser/libasn1parser.la \
|
||||
$(top_builddir)/libasn1fix/libasn1fix.la
|
||||
|
|
|
@ -5,6 +5,8 @@
|
|||
#include "asn1c_internal.h"
|
||||
#include "asn1c_C.h"
|
||||
#include "asn1c_constraint.h"
|
||||
#include "asn1c_out.h"
|
||||
#include "asn1c_misc.h"
|
||||
#include <asn1fix_export.h> /* Stuff exported by libasn1fix */
|
||||
|
||||
typedef struct tag2el_s {
|
||||
|
@ -17,6 +19,8 @@ typedef struct tag2el_s {
|
|||
|
||||
static int _fill_tag2el_map(arg_t *arg, tag2el_t **tag2el, int *count, int el_no);
|
||||
static int _add_tag2el_member(arg_t *arg, tag2el_t **tag2el, int *count, int el_no);
|
||||
static int _expr_elements_count(arg_t *arg, asn1p_expr_t *expr);
|
||||
static int _emit_member_table(arg_t *arg, asn1p_expr_t *expr);
|
||||
|
||||
static int asn1c_lang_C_type_SEQUENCE_def(arg_t *arg);
|
||||
static int asn1c_lang_C_type_SET_def(arg_t *arg);
|
||||
|
@ -27,7 +31,7 @@ static int check_if_extensible(asn1p_expr_t *expr);
|
|||
static int emit_tags_vector(arg_t *arg, asn1p_expr_t *expr, int *tags_impl_skip, int choice_mode);
|
||||
static int emit_tag2member_map(arg_t *arg, tag2el_t *tag2el, int tag2el_count);
|
||||
|
||||
#define C99_MODE (arg->flags & A1C_NO_C99)
|
||||
#define C99_MODE (!(arg->flags & A1C_NO_C99))
|
||||
#define UNNAMED_UNIONS (arg->flags & A1C_UNNAMED_UNIONS)
|
||||
|
||||
#define PCTX_DEF INDENTED( \
|
||||
|
@ -176,7 +180,7 @@ asn1c_lang_C_type_SEQUENCE_def(arg_t *arg) {
|
|||
* Print out the table according to which the parsing is performed.
|
||||
*/
|
||||
p = MKID(expr->Identifier);
|
||||
OUT("static asn1_SEQUENCE_element_t asn1_DEF_%s_elements[] = {\n", p);
|
||||
OUT("static asn1_TYPE_member_t asn1_MBR_%s[] = {\n", p);
|
||||
|
||||
elements = 0;
|
||||
INDENTED(TQ_FOR(v, &(expr->members), next) {
|
||||
|
@ -187,43 +191,8 @@ asn1c_lang_C_type_SEQUENCE_def(arg_t *arg) {
|
|||
ext_stop = elements - 1;
|
||||
continue;
|
||||
}
|
||||
OUT("{ ");
|
||||
elements++;
|
||||
OUT("offsetof(struct %s, ", MKID(expr->Identifier));
|
||||
OUT("%s), ", MKID(v->Identifier));
|
||||
if(v->marker) {
|
||||
asn1p_expr_t *tv;
|
||||
int opts = 0;
|
||||
for(tv = v; tv && tv->marker;
|
||||
tv = TQ_NEXT(tv, next), opts++) {
|
||||
if(tv->expr_type == A1TC_EXTENSIBLE)
|
||||
opts--;
|
||||
}
|
||||
OUT("%d,", opts);
|
||||
} else {
|
||||
OUT("0,");
|
||||
}
|
||||
OUT("\n");
|
||||
INDENT(+1);
|
||||
if(C99_MODE) OUT(".tag = ");
|
||||
_print_tag(arg, v, NULL);
|
||||
OUT(",\n");
|
||||
if(C99_MODE) OUT(".tag_mode = ");
|
||||
if(v->tag.tag_class) {
|
||||
if(v->tag.tag_mode == TM_IMPLICIT)
|
||||
OUT("-1,\t/* IMPLICIT tag at current level */\n");
|
||||
else
|
||||
OUT("+1,\t/* EXPLICIT tag at current level */\n");
|
||||
} else {
|
||||
OUT("0,\n");
|
||||
}
|
||||
if(C99_MODE) OUT(".type = ");
|
||||
OUT("(void *)&asn1_DEF_%s,\n",
|
||||
asn1c_type_name(arg, v, TNF_SAFE));
|
||||
if(C99_MODE) OUT(".name = ");
|
||||
OUT("\"%s\"\n", v->Identifier);
|
||||
OUT("},\n");
|
||||
INDENT(-1);
|
||||
_emit_member_table(arg, v);
|
||||
});
|
||||
OUT("};\n");
|
||||
|
||||
|
@ -242,8 +211,6 @@ asn1c_lang_C_type_SEQUENCE_def(arg_t *arg) {
|
|||
INDENTED(
|
||||
OUT("sizeof(struct %s),\n", p);
|
||||
OUT("offsetof(struct %s, _ber_dec_ctx),\n", p);
|
||||
OUT("asn1_DEF_%s_elements,\n", p);
|
||||
OUT("%d,\t/* Elements count */\n", elements);
|
||||
OUT("asn1_DEF_%s_tag2el,\n", p);
|
||||
OUT("%d,\t/* Count of tags in the map */\n", tag2el_count);
|
||||
OUT("%d,\t/* Start extensions */\n",
|
||||
|
@ -272,6 +239,8 @@ asn1c_lang_C_type_SEQUENCE_def(arg_t *arg) {
|
|||
}
|
||||
OUT("%d,\t/* Tags to skip */\n", tags_impl_skip);
|
||||
OUT("%d,\t/* Whether CONSTRUCTED */\n", 1);
|
||||
OUT("asn1_MBR_%s,\n", p);
|
||||
OUT("%d,\t/* Elements count */\n", elements);
|
||||
OUT("&asn1_DEF_%s_specs\t/* Additional specs */\n", p);
|
||||
);
|
||||
OUT("};\n");
|
||||
|
@ -405,48 +374,19 @@ asn1c_lang_C_type_SET_def(arg_t *arg) {
|
|||
* Print out the table according to which the parsing is performed.
|
||||
*/
|
||||
p = MKID(expr->Identifier);
|
||||
OUT("static asn1_SET_element_t asn1_DEF_%s_elements[] = {\n", p);
|
||||
OUT("static asn1_TYPE_member_t asn1_MBR_%s[] = {\n", p);
|
||||
|
||||
elements = 0;
|
||||
INDENTED(TQ_FOR(v, &(expr->members), next) {
|
||||
if(v->expr_type != A1TC_EXTENSIBLE) {
|
||||
if(comp_mode == 1)
|
||||
v->marker = EM_OPTIONAL;
|
||||
elements++;
|
||||
} else {
|
||||
if(comp_mode < 3) comp_mode++;
|
||||
continue;
|
||||
}
|
||||
OUT("{ ");
|
||||
p = MKID(expr->Identifier);
|
||||
OUT("offsetof(struct %s, ", p);
|
||||
p = MKID(v->Identifier);
|
||||
OUT("%s), ", p);
|
||||
if(v->marker) {
|
||||
OUT("1, /* Optional element */\n");
|
||||
} else {
|
||||
OUT("0,\n");
|
||||
}
|
||||
INDENT(+1);
|
||||
if(C99_MODE) OUT(".tag = ");
|
||||
_print_tag(arg, v, NULL);
|
||||
OUT(",\n");
|
||||
if(C99_MODE) OUT(".tag_mode = ");
|
||||
if(v->tag.tag_class) {
|
||||
if(v->tag.tag_mode == TM_IMPLICIT)
|
||||
OUT("-1,\t/* IMPLICIT tag at current level */\n");
|
||||
else
|
||||
OUT("+1,\t/* EXPLICIT tag at current level */\n");
|
||||
} else {
|
||||
OUT("0,\n");
|
||||
}
|
||||
if(C99_MODE) OUT(".type = ");
|
||||
OUT("(void *)&asn1_DEF_%s,\n",
|
||||
asn1c_type_name(arg, v, TNF_SAFE));
|
||||
if(C99_MODE) OUT(".name = ");
|
||||
OUT("\"%s\"\n", v->Identifier);
|
||||
OUT("},\n");
|
||||
INDENT(-1);
|
||||
elements++;
|
||||
_emit_member_table(arg, v);
|
||||
});
|
||||
OUT("};\n");
|
||||
|
||||
|
@ -496,8 +436,6 @@ asn1c_lang_C_type_SET_def(arg_t *arg) {
|
|||
OUT("sizeof(struct %s),\n", p);
|
||||
OUT("offsetof(struct %s, _ber_dec_ctx),\n", p);
|
||||
OUT("offsetof(struct %s, _presence_map),\n", p);
|
||||
OUT("asn1_DEF_%s_elements,\n", p);
|
||||
OUT("%d,\t/* Elements count */\n", elements);
|
||||
OUT("asn1_DEF_%s_tag2el,\n", p);
|
||||
OUT("%d,\t/* Count of tags in the map */\n", tag2el_count);
|
||||
OUT("%d,\t/* Whether extensible */\n",
|
||||
|
@ -525,6 +463,8 @@ asn1c_lang_C_type_SET_def(arg_t *arg) {
|
|||
}
|
||||
OUT("%d,\t/* Tags to skip */\n", tags_impl_skip);
|
||||
OUT("%d,\t/* Whether CONSTRUCTED */\n", 1);
|
||||
OUT("asn1_MBR_%s,\n", p);
|
||||
OUT("%d,\t/* Elements count */\n", elements);
|
||||
OUT("&asn1_DEF_%s_specs\t/* Additional specs */\n", p);
|
||||
);
|
||||
OUT("};\n");
|
||||
|
@ -589,20 +529,11 @@ asn1c_lang_C_type_SEx_OF_def(arg_t *arg, int seq_of) {
|
|||
* Print out the table according to which the parsing is performed.
|
||||
*/
|
||||
p = MKID(expr->Identifier);
|
||||
OUT("static asn1_SET_OF_element_t asn1_DEF_%s_elements[] = {\n", p);
|
||||
OUT("static asn1_TYPE_member_t asn1_MBR_%s[] = {\n", p);
|
||||
|
||||
INDENTED(OUT("{ ");
|
||||
INDENTED(
|
||||
v = TQ_FIRST(&(expr->members));
|
||||
INDENT(+1);
|
||||
if(C99_MODE) OUT(".tag = ");
|
||||
_print_tag(arg, v, NULL);
|
||||
OUT(",\n");
|
||||
if(C99_MODE) OUT(".type = ");
|
||||
OUT("(void *)&asn1_DEF_%s",
|
||||
asn1c_type_name(arg, v, TNF_SAFE));
|
||||
OUT(" ");
|
||||
OUT("},\n");
|
||||
INDENT(-1);
|
||||
_emit_member_table(arg, v);
|
||||
);
|
||||
OUT("};\n");
|
||||
|
||||
|
@ -616,7 +547,6 @@ asn1c_lang_C_type_SEx_OF_def(arg_t *arg, int seq_of) {
|
|||
INDENTED(
|
||||
OUT("sizeof(struct %s),\n", p);
|
||||
OUT("offsetof(struct %s, _ber_dec_ctx),\n", p);
|
||||
OUT("asn1_DEF_%s_elements\n", p);
|
||||
);
|
||||
OUT("};\n");
|
||||
OUT("asn1_TYPE_descriptor_t asn1_DEF_%s = {\n", p);
|
||||
|
@ -647,6 +577,8 @@ asn1c_lang_C_type_SEx_OF_def(arg_t *arg, int seq_of) {
|
|||
}
|
||||
OUT("%d,\t/* Tags to skip */\n", tags_impl_skip);
|
||||
OUT("%d,\t/* Whether CONSTRUCTED */\n", 1);
|
||||
OUT("asn1_MBR_%s,\n", p);
|
||||
OUT("1,\t/* Single element */\n");
|
||||
OUT("&asn1_DEF_%s_specs\t/* Additional specs */\n", p);
|
||||
);
|
||||
OUT("};\n");
|
||||
|
@ -742,49 +674,19 @@ asn1c_lang_C_type_CHOICE_def(arg_t *arg) {
|
|||
* Print out the table according to which the parsing is performed.
|
||||
*/
|
||||
p = MKID(expr->Identifier);
|
||||
OUT("static asn1_CHOICE_element_t asn1_DEF_%s_elements[] = {\n", p);
|
||||
OUT("static asn1_TYPE_member_t asn1_MBR_%s[] = {\n", p);
|
||||
|
||||
elements = 0;
|
||||
INDENTED(TQ_FOR(v, &(expr->members), next) {
|
||||
if(v->expr_type != A1TC_EXTENSIBLE) {
|
||||
if(comp_mode == 1)
|
||||
v->marker = EM_OPTIONAL;
|
||||
elements++;
|
||||
} else {
|
||||
if(comp_mode < 3) comp_mode++;
|
||||
continue;
|
||||
}
|
||||
OUT("{ ");
|
||||
p = MKID(expr->Identifier);
|
||||
OUT("offsetof(struct %s, ", p);
|
||||
p = MKID(v->Identifier);
|
||||
if(!UNNAMED_UNIONS) OUT("choice.");
|
||||
OUT("%s), ", p);
|
||||
if(v->marker) {
|
||||
OUT("1, /* Optional element */\n");
|
||||
} else {
|
||||
OUT("0,\n");
|
||||
}
|
||||
INDENT(+1);
|
||||
if(C99_MODE) OUT(".tag = ");
|
||||
_print_tag(arg, v, NULL);
|
||||
OUT(",\n");
|
||||
if(C99_MODE) OUT(".tag_mode = ");
|
||||
if(v->tag.tag_class) {
|
||||
if(v->tag.tag_mode == TM_IMPLICIT)
|
||||
OUT("-1,\t/* IMPLICIT tag at current level */\n");
|
||||
else
|
||||
OUT("+1,\t/* EXPLICIT tag at current level */\n");
|
||||
} else {
|
||||
OUT("0,\n");
|
||||
}
|
||||
if(C99_MODE) OUT(".type = ");
|
||||
OUT("(void *)&asn1_DEF_%s,\n",
|
||||
asn1c_type_name(arg, v, TNF_SAFE));
|
||||
if(C99_MODE) OUT(".name = ");
|
||||
OUT("\"%s\"\n", v->Identifier);
|
||||
OUT("},\n");
|
||||
INDENT(-1);
|
||||
elements++;
|
||||
_emit_member_table(arg, v);
|
||||
});
|
||||
OUT("};\n");
|
||||
|
||||
|
@ -810,8 +712,6 @@ asn1c_lang_C_type_CHOICE_def(arg_t *arg) {
|
|||
OUT("offsetof(struct %s, _ber_dec_ctx),\n", p);
|
||||
OUT("offsetof(struct %s, present),\n", p);
|
||||
OUT("sizeof(((struct %s *)0)->present),\n", p);
|
||||
OUT("asn1_DEF_%s_elements,\n", p);
|
||||
OUT("%d,\t/* Elements count */\n", elements);
|
||||
OUT("asn1_DEF_%s_tag2el,\n", p);
|
||||
OUT("%d,\t/* Count of tags in the map */\n", tag2el_count);
|
||||
OUT("%d\t/* Whether extensible */\n",
|
||||
|
@ -838,6 +738,8 @@ asn1c_lang_C_type_CHOICE_def(arg_t *arg) {
|
|||
}
|
||||
OUT("%d,\t/* Tags to skip */\n", tags_impl_skip);
|
||||
OUT("%d,\t/* Whether CONSTRUCTED */\n", 1);
|
||||
OUT("asn1_MBR_%s,\n", p);
|
||||
OUT("%d,\t/* Elements count */\n", elements);
|
||||
OUT("&asn1_DEF_%s_specs\t/* Additional specs */\n", p);
|
||||
);
|
||||
OUT("};\n");
|
||||
|
@ -910,6 +812,8 @@ asn1c_lang_C_type_SIMPLE_TYPE(arg_t *arg) {
|
|||
if(expr->marker) OUT("\t/* %s */",
|
||||
(expr->marker==EM_OPTIONAL)?"OPTIONAL":"DEFAULT");
|
||||
OUT("\n");
|
||||
|
||||
REDIR(OT_TYPE_DECLS);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -951,17 +855,20 @@ asn1c_lang_C_type_SIMPLE_TYPE(arg_t *arg) {
|
|||
}
|
||||
OUT("%d,\t/* Tags to skip */\n", tags_impl_skip);
|
||||
OUT("-0,\t/* Unknown yet */\n");
|
||||
if(_expr_elements_count(arg, expr))
|
||||
OUT("0, 0,\t/* Defined elsewhere */\n");
|
||||
else
|
||||
OUT("0, 0,\t/* No members */\n");
|
||||
OUT("0\t/* No specifics */\n");
|
||||
);
|
||||
OUT("};\n");
|
||||
OUT("\n");
|
||||
|
||||
REDIR(OT_CODE);
|
||||
|
||||
/*
|
||||
* Constraint checking.
|
||||
*/
|
||||
/* Emit FROM() tables and others */
|
||||
asn1c_emit_constraint_tables(arg, 0);
|
||||
|
||||
p = MKID(expr->Identifier);
|
||||
OUT("int\n");
|
||||
OUT("%s_constraint(asn1_TYPE_descriptor_t *td, const void *sptr,\n", p);
|
||||
|
@ -990,37 +897,41 @@ asn1c_lang_C_type_SIMPLE_TYPE(arg_t *arg) {
|
|||
* Emit suicidal functions.
|
||||
*/
|
||||
|
||||
{
|
||||
/*
|
||||
* This function replaces certain fields from the definition
|
||||
* of a type with the corresponding fields from the basic type
|
||||
* (from which the current type is inherited).
|
||||
*/
|
||||
char *type_name = asn1c_type_name(arg, expr, TNF_SAFE);
|
||||
OUT("/*\n");
|
||||
OUT(" * This type is implemented using %s,\n", type_name);
|
||||
OUT(" * This type is implemented using %s,\n",
|
||||
asn1c_type_name(arg, expr, TNF_SAFE));
|
||||
OUT(" * so adjust the DEF appropriately.\n");
|
||||
OUT(" */\n");
|
||||
OUT("static void\n");
|
||||
OUT("inherit_TYPE_descriptor(asn1_TYPE_descriptor_t *td) {\n");
|
||||
p = MKID(expr->Identifier);
|
||||
OUT("%s_inherit_TYPE_descriptor(asn1_TYPE_descriptor_t *td) {\n", p);
|
||||
INDENT(+1);
|
||||
OUT("td->ber_decoder = asn1_DEF_%s.ber_decoder;\n", type_name);
|
||||
OUT("td->der_encoder = asn1_DEF_%s.der_encoder;\n", type_name);
|
||||
OUT("td->free_struct = asn1_DEF_%s.free_struct;\n", type_name);
|
||||
OUT("td->print_struct = asn1_DEF_%s.print_struct;\n", type_name);
|
||||
OUT("td->last_tag_form = asn1_DEF_%s.last_tag_form;\n", type_name);
|
||||
OUT("td->specifics = asn1_DEF_%s.specifics;\n", type_name);
|
||||
{
|
||||
char *type_name = asn1c_type_name(arg, expr, TNF_SAFE);
|
||||
OUT("td->ber_decoder = asn1_DEF_%s.ber_decoder;\n", type_name);
|
||||
OUT("td->der_encoder = asn1_DEF_%s.der_encoder;\n", type_name);
|
||||
OUT("td->free_struct = asn1_DEF_%s.free_struct;\n", type_name);
|
||||
OUT("td->print_struct = asn1_DEF_%s.print_struct;\n", type_name);
|
||||
OUT("td->last_tag_form = asn1_DEF_%s.last_tag_form;\n", type_name);
|
||||
OUT("td->elements = asn1_DEF_%s.elements;\n", type_name);
|
||||
OUT("td->elements_count = asn1_DEF_%s.elements_count;\n", type_name);
|
||||
OUT("td->specifics = asn1_DEF_%s.specifics;\n", type_name);
|
||||
}
|
||||
INDENT(-1);
|
||||
OUT("}\n");
|
||||
OUT("\n");
|
||||
}
|
||||
|
||||
p = MKID(expr->Identifier);
|
||||
OUT("ber_dec_rval_t\n");
|
||||
OUT("%s_decode_ber(asn1_TYPE_descriptor_t *td,\n", p);
|
||||
INDENTED(
|
||||
OUT("\tvoid **structure, void *bufptr, size_t size, int tag_mode) {\n");
|
||||
OUT("inherit_TYPE_descriptor(td);\n");
|
||||
OUT("%s_inherit_TYPE_descriptor(td);\n", p);
|
||||
OUT("return td->ber_decoder(td, structure,\n");
|
||||
OUT("\tbufptr, size, tag_mode);\n");
|
||||
);
|
||||
|
@ -1033,7 +944,7 @@ asn1c_lang_C_type_SIMPLE_TYPE(arg_t *arg) {
|
|||
INDENTED(
|
||||
OUT("\tvoid *structure, int tag_mode, ber_tlv_tag_t tag,\n");
|
||||
OUT("\tasn_app_consume_bytes_f *cb, void *app_key) {\n");
|
||||
OUT("inherit_TYPE_descriptor(td);\n");
|
||||
OUT("%s_inherit_TYPE_descriptor(td);\n", p);
|
||||
OUT("return td->der_encoder(td, structure, tag_mode, tag, cb, app_key);\n");
|
||||
);
|
||||
OUT("}\n");
|
||||
|
@ -1044,7 +955,7 @@ asn1c_lang_C_type_SIMPLE_TYPE(arg_t *arg) {
|
|||
OUT("%s_print(asn1_TYPE_descriptor_t *td, const void *struct_ptr,\n", p);
|
||||
INDENTED(
|
||||
OUT("\tint ilevel, asn_app_consume_bytes_f *cb, void *app_key) {\n");
|
||||
OUT("inherit_TYPE_descriptor(td);\n");
|
||||
OUT("%s_inherit_TYPE_descriptor(td);\n", p);
|
||||
OUT("return td->print_struct(td, struct_ptr, ilevel, cb, app_key);\n");
|
||||
);
|
||||
OUT("}\n");
|
||||
|
@ -1055,7 +966,7 @@ asn1c_lang_C_type_SIMPLE_TYPE(arg_t *arg) {
|
|||
OUT("%s_free(asn1_TYPE_descriptor_t *td,\n", p);
|
||||
INDENTED(
|
||||
OUT("\tvoid *struct_ptr, int contents_only) {\n");
|
||||
OUT("inherit_TYPE_descriptor(td);\n");
|
||||
OUT("%s_inherit_TYPE_descriptor(td);\n", p);
|
||||
OUT("td->free_struct(td, struct_ptr, contents_only);\n");
|
||||
);
|
||||
OUT("}\n");
|
||||
|
@ -1355,3 +1266,112 @@ emit_tags_vector(arg_t *arg, asn1p_expr_t *expr, int *tags_impl_skip, int choice
|
|||
|
||||
return tags_count;
|
||||
}
|
||||
|
||||
static int
|
||||
_expr_elements_count(arg_t *arg, asn1p_expr_t *expr) {
|
||||
asn1p_expr_t *topmost_parent;
|
||||
asn1p_expr_t *v;
|
||||
int elements = 0;
|
||||
|
||||
topmost_parent = asn1f_find_terminal_type_ex(arg->asn,
|
||||
arg->mod, expr, 0);
|
||||
if(!topmost_parent) return 0;
|
||||
|
||||
if(!(topmost_parent->expr_type & ASN_CONSTR_MASK))
|
||||
return 0;
|
||||
|
||||
TQ_FOR(v, &(topmost_parent->members), next) {
|
||||
if(v->expr_type != A1TC_EXTENSIBLE)
|
||||
elements++;
|
||||
}
|
||||
|
||||
return elements;
|
||||
}
|
||||
|
||||
static int
|
||||
_emit_member_table(arg_t *arg, asn1p_expr_t *expr) {
|
||||
int save_target;
|
||||
arg_t tmp_arg;
|
||||
char *p;
|
||||
|
||||
OUT("{ ");
|
||||
if(expr->marker) {
|
||||
asn1p_expr_t *tv;
|
||||
int opts = 0;
|
||||
for(tv = expr; tv && tv->marker;
|
||||
tv = TQ_NEXT(tv, next), opts++) {
|
||||
if(tv->expr_type == A1TC_EXTENSIBLE)
|
||||
opts--;
|
||||
}
|
||||
OUT("%d, ", opts);
|
||||
} else {
|
||||
OUT("0, ");
|
||||
}
|
||||
if(expr->Identifier) {
|
||||
OUT("offsetof(struct %s, ", MKID(arg->expr->Identifier));
|
||||
if(arg->expr->expr_type == ASN_CONSTR_CHOICE
|
||||
&& (!UNNAMED_UNIONS)) OUT("choice.");
|
||||
OUT("%s),\n", MKID(expr->Identifier));
|
||||
} else {
|
||||
assert(arg->expr->expr_type == ASN_CONSTR_SET_OF
|
||||
|| arg->expr->expr_type == ASN_CONSTR_SEQUENCE_OF);
|
||||
OUT("0,\n");
|
||||
}
|
||||
INDENT(+1);
|
||||
if(C99_MODE) OUT(".tag = ");
|
||||
_print_tag(arg, expr , NULL);
|
||||
OUT(",\n");
|
||||
if(C99_MODE) OUT(".tag_mode = ");
|
||||
if(expr->tag.tag_class) {
|
||||
if(expr->tag.tag_mode == TM_IMPLICIT)
|
||||
OUT("-1,\t/* IMPLICIT tag at current level */\n");
|
||||
else
|
||||
OUT("+1,\t/* EXPLICIT tag at current level */\n");
|
||||
} else {
|
||||
OUT("0,\n");
|
||||
}
|
||||
if(C99_MODE) OUT(".type = ");
|
||||
OUT("(void *)&asn1_DEF_%s,\n",
|
||||
asn1c_type_name(arg, expr, TNF_SAFE));
|
||||
if(C99_MODE) OUT(".memb_constraints = ");
|
||||
if(expr->constraints) {
|
||||
p = MKID(expr->Identifier);
|
||||
if(!expr->Identifier)
|
||||
p = asn1c_type_name(arg, expr, TNF_SAFE);
|
||||
OUT("memb_%s_constraint,\n", p);
|
||||
} else {
|
||||
OUT("0,\t/* Defer to actual type */\n");
|
||||
}
|
||||
if(C99_MODE) OUT(".name = ");
|
||||
OUT("\"%s\"\n", expr->Identifier ? expr->Identifier : "");
|
||||
OUT("},\n");
|
||||
INDENT(-1);
|
||||
|
||||
if(!expr->constraints)
|
||||
return 0;
|
||||
|
||||
save_target = arg->target->target;
|
||||
REDIR(OT_CODE);
|
||||
|
||||
if(expr->Identifier)
|
||||
p = MKID(expr->Identifier);
|
||||
else
|
||||
p = asn1c_type_name(arg, expr, TNF_SAFE);
|
||||
OUT("static int\n");
|
||||
OUT("memb_%s_constraint(asn1_TYPE_descriptor_t *td, const void *sptr,\n", p);
|
||||
INDENT(+1);
|
||||
OUT("\t\tasn_app_consume_bytes_f *app_errlog, void *app_key) {\n");
|
||||
tmp_arg = *arg;
|
||||
tmp_arg.expr = expr;
|
||||
if(asn1c_emit_constraint_checking_code(&tmp_arg) == 1) {
|
||||
OUT("return td->check_constraints\n");
|
||||
OUT("\t(td, sptr, app_errlog, app_key);\n");
|
||||
}
|
||||
INDENT(-1);
|
||||
OUT("}\n");
|
||||
OUT("\n");
|
||||
|
||||
REDIR(save_target);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -1,9 +1,12 @@
|
|||
#include "asn1c_internal.h"
|
||||
#include "asn1c_constraint.h"
|
||||
#include "asn1c_misc.h"
|
||||
#include "asn1c_out.h"
|
||||
|
||||
#include <asn1fix_crange.h> /* constraint groker from libasn1fix */
|
||||
#include <asn1fix_export.h> /* other exportable stuff from libasn1fix */
|
||||
|
||||
static int asn1c_emit_constraint_tables(arg_t *arg, int got_size);
|
||||
static int emit_alphabet_check_loop(arg_t *arg, asn1cnst_range_t *range);
|
||||
static int emit_value_determination_code(arg_t *arg, asn1p_expr_type_e etype);
|
||||
static int emit_size_determination_code(arg_t *arg, asn1p_expr_type_e etype);
|
||||
|
@ -22,6 +25,7 @@ asn1c_emit_constraint_checking_code(arg_t *arg) {
|
|||
asn1p_expr_type_e etype;
|
||||
asn1p_constraint_t *ct;
|
||||
int got_something = 0;
|
||||
int produce_st = 0;
|
||||
|
||||
ct = expr->combined_constraints;
|
||||
if(ct == NULL)
|
||||
|
@ -57,6 +61,24 @@ asn1c_emit_constraint_checking_code(arg_t *arg) {
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Do we really need an "*st = sptr" pointer?
|
||||
*/
|
||||
switch(etype) {
|
||||
case ASN_BASIC_INTEGER:
|
||||
case ASN_BASIC_ENUMERATED:
|
||||
if(!(arg->flags & A1C_USE_NATIVE_INTEGERS))
|
||||
produce_st = 1;
|
||||
break;
|
||||
case ASN_BASIC_OCTET_STRING:
|
||||
produce_st = 1;
|
||||
break;
|
||||
default:
|
||||
if(etype & ASN_STRING_MASK)
|
||||
produce_st = 1;
|
||||
break;
|
||||
}
|
||||
if(produce_st)
|
||||
OUT("const %s_t *st = sptr;\n", MKID(arg->expr->Identifier));
|
||||
|
||||
if(r_size || r_value) {
|
||||
|
@ -96,6 +118,13 @@ asn1c_emit_constraint_checking_code(arg_t *arg) {
|
|||
if(r_size)
|
||||
emit_size_determination_code(arg, etype);
|
||||
|
||||
INDENT(-1);
|
||||
REDIR(OT_CTABLES);
|
||||
/* Emit FROM() tables */
|
||||
asn1c_emit_constraint_tables(arg, r_size?1:0);
|
||||
REDIR(OT_CODE);
|
||||
INDENT(+1);
|
||||
|
||||
/*
|
||||
* Here is an if() {} else {} constaint checking code.
|
||||
*/
|
||||
|
@ -126,6 +155,12 @@ asn1c_emit_constraint_checking_code(arg_t *arg) {
|
|||
}
|
||||
if(!got_something) {
|
||||
OUT("1 /* No applicable constraints whatsoever */");
|
||||
OUT(") {\n");
|
||||
INDENT(-1);
|
||||
INDENTED(OUT("/* Nothing is here. See below */\n"));
|
||||
OUT("}\n");
|
||||
OUT("\n");
|
||||
return 1;
|
||||
}
|
||||
INDENT(-1);
|
||||
OUT(") {\n");
|
||||
|
@ -144,16 +179,19 @@ asn1c_emit_constraint_checking_code(arg_t *arg) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
asn1c_emit_constraint_tables(arg_t *arg, asn1p_constraint_t *ct) {
|
||||
static int
|
||||
asn1c_emit_constraint_tables(arg_t *arg, int got_size) {
|
||||
asn1_integer_t range_start;
|
||||
asn1_integer_t range_stop;
|
||||
asn1p_expr_type_e etype;
|
||||
asn1cnst_range_t *range;
|
||||
asn1p_constraint_t *ct;
|
||||
int utf8_full_alphabet_check = 0;
|
||||
int max_table_size = 256;
|
||||
int table[256];
|
||||
int use_table;
|
||||
|
||||
if(!ct) ct = arg->expr->combined_constraints;
|
||||
ct = arg->expr->combined_constraints;
|
||||
if(!ct) return 0;
|
||||
|
||||
etype = _find_terminal_type(arg);
|
||||
|
@ -180,10 +218,21 @@ asn1c_emit_constraint_tables(arg_t *arg, asn1p_constraint_t *ct) {
|
|||
* Check if we need a test table to check the alphabet.
|
||||
*/
|
||||
use_table = 1;
|
||||
if(range->el_count == 0) {
|
||||
/*
|
||||
* It's better to have a short if() check
|
||||
* than waste 4k of table space
|
||||
*/
|
||||
use_table = 0;
|
||||
}
|
||||
if((range_stop - range_start) > 255)
|
||||
use_table = 0;
|
||||
if(range->el_count == 0)
|
||||
use_table = 0;
|
||||
if(etype == ASN_STRING_UTF8String) {
|
||||
if(range_stop >= 0x80)
|
||||
use_table = 0;
|
||||
else
|
||||
max_table_size = 128;
|
||||
}
|
||||
|
||||
if(!ct->_compile_mark)
|
||||
ct->_compile_mark = ++global_compile_mark;
|
||||
|
@ -203,15 +252,15 @@ asn1c_emit_constraint_tables(arg_t *arg, asn1p_constraint_t *ct) {
|
|||
}
|
||||
for(v = r->left.value; v <= r->right.value; v++) {
|
||||
assert((v - range_start) >= 0);
|
||||
assert((v - range_start) < 256);
|
||||
assert((v - range_start) < max_table_size);
|
||||
table[v - range_start] = ++n;
|
||||
}
|
||||
}
|
||||
|
||||
OUT("static int permitted_alphabet_table_%d[256] = {\n",
|
||||
ct->_compile_mark);
|
||||
untl = (range_stop - range_start) + 1;
|
||||
untl += (untl % 16)?16 - (untl % 16):0;
|
||||
OUT("static int permitted_alphabet_table_%d[%d] = {\n",
|
||||
ct->_compile_mark, max_table_size);
|
||||
for(n = 0; n < untl; n++) {
|
||||
OUT("%d,", table[n]?1:0);
|
||||
if(!((n+1) % 16)) {
|
||||
|
@ -238,11 +287,42 @@ asn1c_emit_constraint_tables(arg_t *arg, asn1p_constraint_t *ct) {
|
|||
}
|
||||
OUT("};\n");
|
||||
OUT("\n");
|
||||
} else if(etype == ASN_STRING_UTF8String) {
|
||||
/*
|
||||
* UTF8String type is a special case in many respects.
|
||||
*/
|
||||
assert(range_stop > 255); /* This one's unobvious */
|
||||
if(got_size) {
|
||||
/*
|
||||
* Size has been already determined.
|
||||
* The UTF8String length checker also checks
|
||||
* for the syntax validity, so we don't have
|
||||
* to repeat this process twice.
|
||||
*/
|
||||
ct->_compile_mark = 0; /* Don't generate code */
|
||||
asn1constraint_range_free(range);
|
||||
return 0;
|
||||
} else {
|
||||
utf8_full_alphabet_check = 1;
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
* This permitted alphabet check will be
|
||||
* expressed using conditional statements
|
||||
* instead of table lookups. Table would be
|
||||
* to large or otherwise inappropriate (too sparse?).
|
||||
*/
|
||||
}
|
||||
|
||||
OUT("static int check_permitted_alphabet_%d(const void *sptr) {\n",
|
||||
ct->_compile_mark);
|
||||
INDENT(+1);
|
||||
INDENT(+1);
|
||||
if(utf8_full_alphabet_check) {
|
||||
OUT("if(UTF8String_length((UTF8String_t *)sptr, td->name, \n");
|
||||
OUT("\tapp_errlog, app_key) == -1)\n");
|
||||
OUT("\t\treturn 0; /* Alphabet (sic!) test failed. */\n");
|
||||
OUT("\n");
|
||||
} else {
|
||||
if(use_table) {
|
||||
OUT("int *table = permitted_alphabet_table_%d;\n",
|
||||
ct->_compile_mark);
|
||||
|
@ -250,8 +330,9 @@ asn1c_emit_constraint_tables(arg_t *arg, asn1p_constraint_t *ct) {
|
|||
} else {
|
||||
emit_alphabet_check_loop(arg, range);
|
||||
}
|
||||
OUT("return 1;\n");
|
||||
INDENT(-1);
|
||||
}
|
||||
OUT("return 1;\n");
|
||||
INDENT(-1);
|
||||
OUT("}\n");
|
||||
OUT("\n");
|
||||
|
||||
|
@ -338,6 +419,7 @@ static int
|
|||
emit_range_comparison_code(arg_t *arg, asn1cnst_range_t *range, const char *varname, asn1_integer_t natural_start, asn1_integer_t natural_stop) {
|
||||
int ignore_left;
|
||||
int ignore_right;
|
||||
int generated_something = 0;
|
||||
int i;
|
||||
|
||||
for(i = -1; i < range->el_count; i++) {
|
||||
|
@ -381,9 +463,10 @@ emit_range_comparison_code(arg_t *arg, asn1cnst_range_t *range, const char *varn
|
|||
(long long)r->right.value);
|
||||
}
|
||||
if(r != range) OUT(")");
|
||||
generated_something = 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
return generated_something;
|
||||
}
|
||||
|
||||
static int
|
||||
|
@ -412,16 +495,18 @@ emit_size_determination_code(arg_t *arg, asn1p_expr_type_e etype) {
|
|||
case ASN_CONSTR_SEQUENCE_OF:
|
||||
OUT("{ /* Determine the number of elements */\n");
|
||||
INDENT(+1);
|
||||
OUT("A_%s_OF(void) *list;\n",
|
||||
OUT("const A_%s_OF(void) *list;\n",
|
||||
etype==ASN_CONSTR_SET_OF?"SET":"SEQUENCE");
|
||||
OUT("(void *)list = st;\n");
|
||||
OUT("(const void *)list = sptr;\n");
|
||||
OUT("size = list->count;\n");
|
||||
INDENT(-1);
|
||||
OUT("}\n");
|
||||
break;
|
||||
case ASN_BASIC_OCTET_STRING:
|
||||
OUT("size = st->size;\n");
|
||||
break;
|
||||
default:
|
||||
if((etype & ASN_STRING_MASK)
|
||||
|| etype == ASN_BASIC_OCTET_STRING) {
|
||||
if(etype & ASN_STRING_MASK) {
|
||||
OUT("size = st->size;\n");
|
||||
break;
|
||||
} else {
|
||||
|
@ -446,7 +531,7 @@ emit_value_determination_code(arg_t *arg, asn1p_expr_type_e etype) {
|
|||
case ASN_BASIC_INTEGER:
|
||||
case ASN_BASIC_ENUMERATED:
|
||||
if(arg->flags & A1C_USE_NATIVE_INTEGERS) {
|
||||
OUT("value = *(int *)st;\n");
|
||||
OUT("value = *(int *)sptr;\n");
|
||||
} else {
|
||||
OUT("if(asn1_INTEGER2long(st, &value)) {\n");
|
||||
INDENT(+1);
|
||||
|
@ -458,7 +543,7 @@ emit_value_determination_code(arg_t *arg, asn1p_expr_type_e etype) {
|
|||
}
|
||||
break;
|
||||
case ASN_BASIC_BOOLEAN:
|
||||
OUT("value = (*(int *)st) ? 1 : 0;\n");
|
||||
OUT("value = (*(int *)sptr) ? 1 : 0;\n");
|
||||
break;
|
||||
default:
|
||||
WARNING("Value cannot be determined "
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
#ifndef _ASN1C_CONSTRAINT_H_
|
||||
#define _ASN1C_CONSTRAINT_H_
|
||||
|
||||
int asn1c_emit_constraint_tables(arg_t *arg, asn1p_constraint_t *ct);
|
||||
int asn1c_emit_constraint_checking_code(arg_t *arg);
|
||||
|
||||
#endif /* _ASN1C_CONSTRAINT_H_ */
|
||||
|
|
|
@ -33,16 +33,9 @@ typedef struct arg_s {
|
|||
asn1p_module_t *mod;
|
||||
asn1p_expr_t *expr;
|
||||
|
||||
int indent_level;
|
||||
int indented;
|
||||
int embed;
|
||||
} arg_t;
|
||||
|
||||
#include "asn1c_lang.h" /* Target language initialization */
|
||||
#include "asn1c_misc.h" /* Miscellaneous functions */
|
||||
#include "asn1c_out.h" /* Handle output during compilation */
|
||||
#include "asn1c_save.h" /* Save compiled output */
|
||||
|
||||
/*
|
||||
* Logging.
|
||||
*/
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
#include "asn1c_internal.h"
|
||||
#include "asn1c_misc.h"
|
||||
|
||||
#include <asn1fix_export.h>
|
||||
|
||||
/*
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
#include "asn1c_internal.h"
|
||||
#include "asn1c_out.h"
|
||||
|
||||
/*
|
||||
* Add an elementary chunk of target language text
|
||||
|
@ -6,6 +7,7 @@
|
|||
*/
|
||||
int
|
||||
asn1c_compiled_output(arg_t *arg, const char *fmt, ...) {
|
||||
struct compiler_stream_destination_s *dst;
|
||||
const char *p;
|
||||
int lf_found;
|
||||
va_list ap;
|
||||
|
@ -20,6 +22,7 @@ asn1c_compiled_output(arg_t *arg, const char *fmt, ...) {
|
|||
assert(arg->target->target != OT_ASSERT);
|
||||
return -1;
|
||||
default:
|
||||
dst = &arg->target->destination[arg->target->target];
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -37,16 +40,16 @@ asn1c_compiled_output(arg_t *arg, const char *fmt, ...) {
|
|||
/*
|
||||
* Print out the indentation.
|
||||
*/
|
||||
if(arg->indented == 0) {
|
||||
int i = arg->indent_level;
|
||||
arg->indented = 1;
|
||||
if(dst->indented == 0) {
|
||||
int i = dst->indent_level;
|
||||
dst->indented = 1;
|
||||
while(i--) {
|
||||
ret = asn1c_compiled_output(arg, "\t");
|
||||
if(ret == -1) return -1;
|
||||
}
|
||||
}
|
||||
if(lf_found)
|
||||
arg->indented = 0;
|
||||
dst->indented = 0;
|
||||
|
||||
/*
|
||||
* Estimate necessary size.
|
||||
|
@ -80,7 +83,7 @@ asn1c_compiled_output(arg_t *arg, const char *fmt, ...) {
|
|||
|
||||
if(arg->target->target == OT_INCLUDES) {
|
||||
out_chunk_t *v;
|
||||
TQ_FOR(v, &(arg->target->targets[OT_INCLUDES]), next) {
|
||||
TQ_FOR(v, &dst->chunks, next) {
|
||||
if(m->len == v->len
|
||||
&& !memcmp(m->buf, v->buf, m->len))
|
||||
break;
|
||||
|
@ -93,7 +96,7 @@ asn1c_compiled_output(arg_t *arg, const char *fmt, ...) {
|
|||
}
|
||||
}
|
||||
|
||||
TQ_ADD(&(arg->target->targets[arg->target->target]), m, next);
|
||||
TQ_ADD(&dst->chunks, m, next);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -19,15 +19,21 @@ typedef struct compiler_streams {
|
|||
OT_DEPS, /* Dependencies (other than #includes) */
|
||||
OT_TYPE_DECLS, /* Type declarations */
|
||||
OT_FUNC_DECLS, /* Function declarations */
|
||||
OT_STAT_DEFS, /* Static definitions */
|
||||
OT_CTABLES, /* Constraint tables */
|
||||
OT_CODE, /* Some code */
|
||||
OT_STAT_DEFS, /* Static definitions */
|
||||
OT_MAX
|
||||
} target;
|
||||
TQ_HEAD(out_chunk_t) targets[OT_MAX];
|
||||
|
||||
struct compiler_stream_destination_s {
|
||||
TQ_HEAD(out_chunk_t) chunks;
|
||||
int indent_level;
|
||||
int indented;
|
||||
} destination[OT_MAX];
|
||||
} compiler_streams_t;
|
||||
|
||||
static char *_compiler_stream2str[] __attribute__ ((unused))
|
||||
= { "ASSERT", "INCLUDES", "DEPS", "TYPE-DECLS", "FUNC-DECLS", "STAT-DEFS", "CODE" };
|
||||
= { "ASSERT", "INCLUDES", "DEPS", "TYPE-DECLS", "FUNC-DECLS", "CTABLES", "CODE", "STAT-DEFS" };
|
||||
|
||||
int asn1c_compiled_output(arg_t *arg, const char *fmt, ...);
|
||||
|
||||
|
@ -38,19 +44,20 @@ int asn1c_compiled_output(arg_t *arg, const char *fmt, ...);
|
|||
|
||||
/* Redirect output to a different stream. */
|
||||
#define REDIR(foo) do { arg->target->target = foo; } while(0)
|
||||
|
||||
#define INDENT(val) arg->indent_level += (val)
|
||||
#define INDENTED(code) do { \
|
||||
INDENT(+1); \
|
||||
do { code; } while(0); \
|
||||
INDENT(-1); \
|
||||
#define INDENT_LEVEL \
|
||||
arg->target->destination[arg->target->target].indent_level
|
||||
#define INDENT(val) INDENT_LEVEL += (val)
|
||||
#define INDENTED(code) do { \
|
||||
INDENT(+1); \
|
||||
do { code; } while(0); \
|
||||
INDENT(-1); \
|
||||
} while(0)
|
||||
|
||||
#define FLAT(code) do { \
|
||||
int _il = arg->indent_level; \
|
||||
arg->indent_level = 0; \
|
||||
do { code; } while(0); \
|
||||
arg->indent_level = _il; \
|
||||
#define FLAT(code) do { \
|
||||
int _il = INDENT_LEVEL; \
|
||||
INDENT_LEVEL = 0; \
|
||||
do { code; } while(0); \
|
||||
INDENT_LEVEL = _il; \
|
||||
} while(0)
|
||||
|
||||
#define EMBED(ev) do { \
|
||||
|
@ -68,11 +75,11 @@ int asn1c_compiled_output(arg_t *arg, const char *fmt, ...);
|
|||
|
||||
/* Output a piece of text into a default stream */
|
||||
#define OUT(fmt, args...) asn1c_compiled_output(arg, fmt, ##args)
|
||||
#define OUT_NOINDENT(fmt, args...) do { \
|
||||
int _saved_indent = arg->indent_level; \
|
||||
arg->indent_level = 0; \
|
||||
OUT(fmt, ##args); \
|
||||
arg->indent_level = _saved_indent; \
|
||||
#define OUT_NOINDENT(fmt, args...) do { \
|
||||
int _saved_indent = INDENT_LEVEL; \
|
||||
INDENT_LEVEL = 0; \
|
||||
OUT(fmt, ##args); \
|
||||
INDENT_LEVEL = _saved_indent; \
|
||||
} while(0)
|
||||
|
||||
/* Generate #include line */
|
||||
|
|
|
@ -1,6 +1,10 @@
|
|||
#include "asn1c_internal.h"
|
||||
#include "asn1c_compat.h"
|
||||
#include "asn1c_fdeps.h"
|
||||
#include "asn1c_lang.h"
|
||||
#include "asn1c_misc.h"
|
||||
#include "asn1c_save.h"
|
||||
#include "asn1c_out.h"
|
||||
|
||||
static int asn1c_dump_streams(arg_t *arg, asn1c_fdeps_t *);
|
||||
static int asn1c_print_streams(arg_t *arg);
|
||||
|
@ -114,14 +118,14 @@ asn1c_print_streams(arg_t *arg) {
|
|||
|
||||
for(i = 1; i < OT_MAX; i++) {
|
||||
out_chunk_t *ot;
|
||||
if(TQ_FIRST(&cs->targets[i]) == NULL)
|
||||
if(TQ_FIRST(&cs->destination[i].chunks) == NULL)
|
||||
continue;
|
||||
|
||||
printf("\n/*** <<< %s [%s] >>> ***/\n\n",
|
||||
_compiler_stream2str[i],
|
||||
expr->Identifier);
|
||||
|
||||
TQ_FOR(ot, &(cs->targets[i]), next) {
|
||||
TQ_FOR(ot, &(cs->destination[i].chunks), next) {
|
||||
fwrite(ot->buf, ot->len, 1, stdout);
|
||||
}
|
||||
}
|
||||
|
@ -178,18 +182,18 @@ asn1c_save_streams(arg_t *arg, asn1c_fdeps_t *deps) {
|
|||
|
||||
fprintf(fp_h, "#include <constr_TYPE.h>\n\n");
|
||||
|
||||
TQ_FOR(ot, &(cs->targets[OT_INCLUDES]), next) {
|
||||
TQ_FOR(ot, &(cs->destination[OT_INCLUDES].chunks), next) {
|
||||
asn1c_activate_dependency(deps, 0, ot->buf);
|
||||
fwrite(ot->buf, ot->len, 1, fp_h);
|
||||
}
|
||||
fprintf(fp_h, "\n");
|
||||
TQ_FOR(ot, &(cs->targets[OT_DEPS]), next)
|
||||
TQ_FOR(ot, &(cs->destination[OT_DEPS].chunks), next)
|
||||
fwrite(ot->buf, ot->len, 1, fp_h);
|
||||
fprintf(fp_h, "\n");
|
||||
TQ_FOR(ot, &(cs->targets[OT_TYPE_DECLS]), next)
|
||||
TQ_FOR(ot, &(cs->destination[OT_TYPE_DECLS].chunks), next)
|
||||
fwrite(ot->buf, ot->len, 1, fp_h);
|
||||
fprintf(fp_h, "\n");
|
||||
TQ_FOR(ot, &(cs->targets[OT_FUNC_DECLS]), next)
|
||||
TQ_FOR(ot, &(cs->destination[OT_FUNC_DECLS].chunks), next)
|
||||
fwrite(ot->buf, ot->len, 1, fp_h);
|
||||
|
||||
fprintf(fp_h, "\n#ifdef __cplusplus\n}\n#endif\n\n"
|
||||
|
@ -197,12 +201,14 @@ asn1c_save_streams(arg_t *arg, asn1c_fdeps_t *deps) {
|
|||
header_id);
|
||||
|
||||
fprintf(fp_c, "#include <%s.h>\n\n", expr->Identifier); /* Myself */
|
||||
TQ_FOR(ot, &(cs->targets[OT_STAT_DEFS]), next)
|
||||
TQ_FOR(ot, &(cs->destination[OT_CTABLES].chunks), next)
|
||||
fwrite(ot->buf, ot->len, 1, fp_c);
|
||||
TQ_FOR(ot, &(cs->targets[OT_CODE]), next)
|
||||
TQ_FOR(ot, &(cs->destination[OT_CODE].chunks), next)
|
||||
fwrite(ot->buf, ot->len, 1, fp_c);
|
||||
TQ_FOR(ot, &(cs->destination[OT_STAT_DEFS].chunks), next)
|
||||
fwrite(ot->buf, ot->len, 1, fp_c);
|
||||
|
||||
assert(OT_MAX == 7);
|
||||
assert(OT_MAX == 8);
|
||||
|
||||
fclose(fp_c);
|
||||
fclose(fp_h);
|
||||
|
|
|
@ -1,4 +1,7 @@
|
|||
#include "asn1c_internal.h"
|
||||
#include "asn1c_lang.h"
|
||||
#include "asn1c_out.h"
|
||||
#include "asn1c_save.h"
|
||||
|
||||
static void default_logger_cb(int, const char *fmt, ...);
|
||||
static int asn1c_compile_expr(arg_t *arg);
|
||||
|
@ -73,7 +76,7 @@ asn1c_compile_expr(arg_t *arg) {
|
|||
type_cb = asn1_lang_map[expr->meta_type][expr->expr_type].type_cb;
|
||||
if(type_cb) {
|
||||
|
||||
if(arg->indent_level == 0)
|
||||
if(arg->target->destination[OT_TYPE_DECLS].indent_level == 0)
|
||||
OUT("\n");
|
||||
|
||||
DEBUG("Compiling %s at line %d",
|
||||
|
@ -134,7 +137,7 @@ asn1c_attach_streams(asn1p_expr_t *expr) {
|
|||
|
||||
cs = expr->data;
|
||||
for(i = 0; i < OT_MAX; i++) {
|
||||
TQ_INIT(&(cs->targets[i]));
|
||||
TQ_INIT(&(cs->destination[i].chunks));
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
Loading…
Reference in New Issue