📄 asn1c_c.c
字号:
} OUT("};\n"); return 0;;}static enum tvm_compatemit_tags_vectors(arg_t *arg, asn1p_expr_t *expr, int *tags_count_r, int *all_tags_count_r) { struct asn1p_type_tag_s *tags = 0; /* Effective tags */ struct asn1p_type_tag_s *all_tags = 0; /* The full array */ int tags_count = 0; int all_tags_count = 0; enum tvm_compat tv_mode = _TVM_SAME; int i; /* Cleanup before proceeding. */ *tags_count_r = 0; *all_tags_count_r = 0; /* Fetch a chain of tags */ tags_count = asn1f_fetch_tags(arg->asn, expr->module, expr, &tags, 0); if(tags_count < 0) return -1; /* Fetch a chain of tags */ all_tags_count = asn1f_fetch_tags(arg->asn, expr->module, expr, &all_tags, AFT_FULL_COLLECT); if(all_tags_count < 0) { if(tags) free(tags); return -1; } assert(tags_count <= all_tags_count); assert((tags_count?0:1) == (all_tags_count?0:1)); if(tags_count <= all_tags_count) { for(i = 0; i < tags_count; i++) { if(tags[i].tag_value != all_tags[i].tag_value || tags[i].tag_class != all_tags[i].tag_class) { tv_mode = _TVM_DIFFERENT; break; } } if(i == tags_count && tags_count < all_tags_count) tv_mode = _TVM_SUBSET; } else { tv_mode = _TVM_DIFFERENT; }#define EMIT_TAGS_TABLE(name, tags, tags_count) do { \ OUT("static ber_tlv_tag_t asn_DEF_%s_%d%s_tags[] = {\n",\ MKID(expr->Identifier), \ expr->_type_unique_index, name); \ INDENT(+1); \ /* Print the array of collected tags */ \ for(i = 0; i < tags_count; i++) { \ if(i) OUT(",\n"); \ _print_tag(arg, &tags[i]); \ } \ OUT("\n"); \ INDENT(-1); \ OUT("};\n"); \ } while(0) if(tags_count) { if(tv_mode == _TVM_SUBSET) EMIT_TAGS_TABLE("", all_tags, all_tags_count); else EMIT_TAGS_TABLE("", tags, tags_count); } if(all_tags_count) { if(tv_mode == _TVM_DIFFERENT) EMIT_TAGS_TABLE("_all", all_tags, all_tags_count); } if(tags) free(tags); if(all_tags) free(all_tags); *tags_count_r = tags_count; *all_tags_count_r = all_tags_count; return tv_mode;}static intexpr_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, expr); if(!topmost_parent) return 0; if(!(topmost_parent->expr_type & ASN_CONSTR_MASK) && !topmost_parent->expr_type == ASN_BASIC_INTEGER && !topmost_parent->expr_type == ASN_BASIC_ENUMERATED) return 0; TQ_FOR(v, &(topmost_parent->members), next) { if(v->expr_type != A1TC_EXTENSIBLE) elements++; } return elements;}static intemit_include_dependencies(arg_t *arg) { asn1p_expr_t *expr = arg->expr; asn1p_expr_t *memb; TQ_FOR(memb, &(expr->members), next) { if((memb->meta_type == AMT_TYPEREF && (memb->marker.flags & EM_INDIRECT)) || expr->expr_type == ASN_CONSTR_SET_OF || expr->expr_type == ASN_CONSTR_SEQUENCE_OF ) { asn1p_expr_t *terminal; terminal = asn1f_find_terminal_type_ex(arg->asn, memb); if(terminal && !terminal->parent_expr && (terminal->expr_type & ASN_CONSTR_MASK)) { int saved_target = arg->target->target; REDIR(OT_FWD_DECLS); OUT("%s;\n", asn1c_type_name(arg, memb, TNF_RSAFE)); REDIR(saved_target); memb->marker.flags |= EM_UNRECURSE; } } if((!(memb->expr_type & ASN_CONSTR_MASK) && memb->expr_type > ASN_CONSTR_MASK) || memb->meta_type == AMT_TYPEREF) { if(memb->marker.flags & EM_UNRECURSE) { GEN_POSTINCLUDE(asn1c_type_name(arg, memb, TNF_INCLUDE)); } else { GEN_INCLUDE(asn1c_type_name(arg, memb, TNF_INCLUDE)); } } } return 0;}static intemit_member_table(arg_t *arg, asn1p_expr_t *expr) { int save_target; arg_t tmp_arg; struct asn1p_type_tag_s outmost_tag_s; struct asn1p_type_tag_s *outmost_tag; int complex_contents; char *p; if(asn1f_fetch_outmost_tag(arg->asn, expr->module, expr, &outmost_tag_s, 1)) { outmost_tag = 0; } else { outmost_tag = &outmost_tag_s; } OUT("{ "); if(outmost_tag && outmost_tag->tag_value == -1) OUT("ATF_OPEN_TYPE | "); OUT("%s, ", (expr->marker.flags & EM_INDIRECT)?"ATF_POINTER":"ATF_NOFLAGS"); if((expr->marker.flags & EM_OPTIONAL) == EM_OPTIONAL) { asn1p_expr_t *tv; int opts = 0; for(tv = expr; tv && tv->marker.flags; tv = TQ_NEXT(tv, next), opts++) { if(tv->expr_type == A1TC_EXTENSIBLE) opts--; } OUT("%d, ", opts); } else { OUT("0, "); } if(expr->_anonymous_type) { assert(arg->expr->expr_type == ASN_CONSTR_SET_OF || arg->expr->expr_type == ASN_CONSTR_SEQUENCE_OF); OUT("0,\n"); } else { OUT("offsetof(struct "); out_name_chain(arg, 1); OUT(", "); if(arg->expr->expr_type == ASN_CONSTR_CHOICE && (!UNNAMED_UNIONS)) OUT("choice."); OUT("%s),\n", MKID_safe(expr->Identifier)); } INDENT(+1); if(C99_MODE) OUT(".tag = "); if(outmost_tag) { if(outmost_tag->tag_value == -1) OUT("-1 /* Ambiguous tag (ANY?) */"); else _print_tag(arg, outmost_tag); } else { OUT("-1 /* Ambiguous tag (CHOICE?) */"); } 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"); } complex_contents = (expr->expr_type & ASN_CONSTR_MASK) || expr->expr_type == ASN_BASIC_ENUMERATED || (0 /* -- prohibited by X.693:8.3.4 */ && expr->expr_type == ASN_BASIC_INTEGER && expr_elements_count(arg, expr)); if(C99_MODE) OUT(".type = "); OUT("(void *)&asn_DEF_"); if(complex_contents) { OUT("%s", MKID(expr->Identifier)); if(!(arg->flags & A1C_ALL_DEFS_GLOBAL)) OUT("_%d", expr->_type_unique_index); } else { OUT("%s", asn1c_type_name(arg, expr, TNF_SAFE)); } OUT(",\n"); if(C99_MODE) OUT(".memb_constraints = "); if(expr->constraints) { if(arg->flags & A1C_NO_CONSTRAINTS) { OUT("0,\t/* No check because of -fno-constraints */\n"); } else { char *id = MKID(expr->Identifier); if(expr->_anonymous_type && !strcmp(expr->Identifier, "Member")) id = asn1c_type_name(arg, expr, TNF_SAFE); OUT("memb_%s_%d_constraint,\n", id, arg->expr->_type_unique_index); } } else { OUT("0,\t/* Defer constraints checking to the member type */\n"); } if(C99_MODE) OUT(".name = "); if(1) { if(expr->_anonymous_type && !strcmp(expr->Identifier, "Member")) OUT("\"\"\n"); else OUT("\"%s\"\n", expr->Identifier); } else { OUT("\"%s\"\n", expr->_anonymous_type ? "" : expr->Identifier); } OUT("},\n"); INDENT(-1); if(!expr->constraints || (arg->flags & A1C_NO_CONSTRAINTS)) return 0; save_target = arg->target->target; REDIR(OT_CODE); if(expr->_anonymous_type && !strcmp(expr->Identifier, "Member")) p = asn1c_type_name(arg, expr, TNF_SAFE); else p = MKID(expr->Identifier); OUT("static int\n"); OUT("memb_%s_%d_constraint(asn_TYPE_descriptor_t *td, const void *sptr,\n", p, arg->expr->_type_unique_index); 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" "(td, sptr, app_errlog, app_key);\n"); } INDENT(-1); OUT("}\n"); OUT("\n"); REDIR(save_target); return 0;}/* * Generate "asn_DEF_XXX" type definition. */static intemit_type_DEF(arg_t *arg, asn1p_expr_t *expr, enum tvm_compat tv_mode, int tags_count, int all_tags_count, int elements_count, enum etd_spec spec) { int using_type_name = 0; char *p; if(HIDE_INNER_DEFS) OUT("static /* Use -fall-defs-global to expose */\n"); OUT("asn_TYPE_descriptor_t asn_DEF_%s", MKID(expr->Identifier)); if(HIDE_INNER_DEFS) OUT("_%d", expr->_type_unique_index); OUT(" = {\n"); p = MKID(expr->Identifier); INDENT(+1); OUT("\"%s\",\n", expr->_anonymous_type?"":expr->Identifier); OUT("\"%s\",\n", expr->_anonymous_type?"":expr->Identifier); if(expr->expr_type & ASN_CONSTR_MASK) { using_type_name = 1; p = asn1c_type_name(arg, arg->expr, TNF_SAFE); }#define FUNCREF(foo) do { \ OUT("%s", p); \ if(HIDE_INNER_DEFS && !using_type_name) \ OUT("_%d", expr->_type_unique_index); \ OUT("_" #foo ",\n"); \} while(0) FUNCREF(free); FUNCREF(print); FUNCREF(constraint); FUNCREF(decode_ber); FUNCREF(encode_der); FUNCREF(decode_xer); FUNCREF(encode_xer); if(expr->expr_type == ASN_CONSTR_CHOICE) { OUT("CHOICE_outmost_tag,\n"); } else { OUT("0,\t/* Use generic outmost tag fetcher */\n"); } p = MKID(expr->Identifier); if(tags_count) { OUT("asn_DEF_%s_%d_tags,\n", p, expr->_type_unique_index); OUT("sizeof(asn_DEF_%s_%d_tags)\n", p, expr->_type_unique_index); OUT("\t/sizeof(asn_DEF_%s_%d_tags[0])", p, expr->_type_unique_index); if(tv_mode == _TVM_SUBSET && tags_count != all_tags_count) OUT(" - %d", all_tags_count - tags_count); OUT(", /* %d */\n", tags_count); } else { OUT("0,\t/* No effective tags (pointer) */\n"); OUT("0,\t/* No effective tags (count) */\n"); } if(all_tags_count && tv_mode == _TVM_DIFFERENT) { OUT("asn_DEF_%s_%d_all_tags,\n", p, expr->_type_unique_index); OUT("sizeof(asn_DEF_%s_%d_all_tags)\n", p, expr->_type_unique_index); OUT("\t/sizeof(asn_DEF_%s_%d_all_tags[0]), /* %d */\n", p, expr->_type_unique_index, all_tags_count); } else if(all_tags_count) { OUT("asn_DEF_%s_%d_tags,\t/* Same as above */\n", p, expr->_type_unique_index); OUT("sizeof(asn_DEF_%s_%d_tags)\n", p, expr->_type_unique_index); OUT("\t/sizeof(asn_DEF_%s_%d_tags[0]), /* %d */\n", p, expr->_type_unique_index, all_tags_count); } else { OUT("0,\t/* No tags (pointer) */\n"); OUT("0,\t/* No tags (count) */\n"); } if(elements_count) { OUT("asn_MBR_%s_%d,\n", p, expr->_type_unique_index); if(expr->expr_type == ASN_CONSTR_SEQUENCE_OF || expr->expr_type == ASN_CONSTR_SET_OF) { OUT("%d,\t/* Single element */\n", elements_count); assert(elements_count == 1); } else { OUT("%d,\t/* Elements count */\n", elements_count); } } else { if(expr_elements_count(arg, expr)) OUT("0, 0,\t/* Defined elsewhere */\n"); else OUT("0, 0,\t/* No members */\n"); } switch(spec) { case ETD_NO_SPECIFICS: OUT("0\t/* No specifics */\n"); break; case ETD_HAS_SPECIFICS: OUT("&asn_SPC_%s_%d_specs\t/* Additional specs */\n", p, expr->_type_unique_index); } INDENT(-1); OUT("};\n"); OUT("\n"); return 0;}/* * Check if it is better to make this type indirectly accessed via * a pointer. * This may be the case for the following recursive definition: * Type ::= CHOICE { member Type }; */static intexpr_better_indirect(arg_t *arg, asn1p_expr_t *expr) { asn1p_expr_t *top_parent; asn1p_expr_t *terminal; if(expr->expr_type != A1TC_REFERENCE) return 0; /* Rewind to the topmost parent expression */ if((top_parent = expr->parent_expr)) { while(top_parent->parent_expr) top_parent = top_parent->parent_expr; } else { return 0; } terminal = asn1f_find_terminal_type_ex(arg->asn, expr); return (terminal == top_parent);}static intexpr_as_xmlvaluelist(arg_t *arg, asn1p_expr_t *expr) { expr = asn1f_find_terminal_type_ex(arg->asn, expr); if(!expr) return 0; /* X.680, 25.5, Table 5 */ switch(expr->expr_type) { case ASN_BASIC_BOOLEAN: case ASN_BASIC_ENUMERATED: case ASN_BASIC_NULL: return 1; default: return 0; }}static intout_name_chain(arg_t *arg, int check_reserved_keywords) { asn1p_expr_t *expr = arg->expr; char *id; assert(expr->Identifier); if(arg->flags & A1C_COMPOUND_NAMES && ((expr->expr_type & ASN_CONSTR_MASK) || expr->expr_type == ASN_BASIC_ENUMERATED || (expr->expr_type == ASN_BASIC_INTEGER && expr_elements_count(arg, expr)) ) && expr->parent_expr && expr->parent_expr->Identifier) { arg_t tmparg = *arg; tmparg.expr = expr->parent_expr; if(0) tmparg.flags &= ~A1C_COMPOUND_NAMES; out_name_chain(&tmparg, 0); OUT("__"); /* a separator between id components */ /* Fall through */ } if(check_reserved_keywords) id = MKID_safe(expr->Identifier); else id = MKID(expr->Identifier); OUT("%s", id); return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -