static asn1p_expr_type_e _find_terminal_type(arg_t *arg) { asn1p_expr_t *expr; expr = asn1f_find_terminal_type_ex(arg->asn, arg->expr); if(expr) return expr->expr_type; return A1TC_INVALID; }
static char* make_type_for_constraint(arg_t *arg, asn1p_expr_t *expr) { asn1p_expr_t *terminal; terminal = asn1f_find_terminal_type_ex(arg->asn, arg->expr); if (!terminal) terminal = expr; return asn1c_type_name(arg, terminal, TNF_SAFE); }
char * asn1c_type_name(arg_t *arg, asn1p_expr_t *expr, enum tnfmt _format) { asn1p_expr_t *exprid = 0; asn1p_expr_t *top_parent; asn1p_expr_t *terminal; int stdname = 0; char *typename; /* Rewind to the topmost parent expression */ if((top_parent = expr->parent_expr)) while(top_parent->parent_expr) top_parent = top_parent->parent_expr; if(0) DEBUG("asn1c_type_name(%s: 0x%x)", expr->Identifier, expr->expr_type); switch(expr->expr_type) { case A1TC_REFERENCE: typename = expr->reference->components[ expr->reference->comp_count-1].name; if(typename[0] == '&') { arg_t tmp = *arg; /* * This is a reference to a type defined in a class. * Resolve it and use instead. */ tmp.expr = asn1f_class_access_ex(arg->asn, arg->expr->module, arg->expr, expr->rhs_pspecs, expr->reference); if(!tmp.expr) return NULL; return asn1c_type_name(&tmp, tmp.expr, _format); } terminal = asn1f_find_terminal_type_ex(arg->asn, expr); if(_format == TNF_RSAFE) { if(terminal && terminal->expr_type & ASN_CONSTR_MASK) { typename = terminal->Identifier; } } if(_format == TNF_CTYPE) { /* * If the component references the type itself, * switch to a recursion-safe type naming * ("struct foo" instead of "foo_t"). */ if(terminal && terminal == top_parent) { _format = TNF_RSAFE; } } if(terminal && terminal->spec_index != -1) { exprid = terminal; typename = 0; }
static int emit_alphabet_check_loop(arg_t *arg, asn1cnst_range_t *range) { asn1c_integer_t natural_stop; asn1p_expr_t *terminal; char *tname; terminal = asn1f_find_terminal_type_ex(arg->asn, arg->expr); if(terminal) { OUT("/* The underlying type is %s */\n", ASN_EXPR_TYPE2STR(terminal->expr_type)); } else { terminal = arg->expr; } tname = asn1c_type_name(arg, terminal, TNF_SAFE); OUT("const %s_t *st = (const %s_t *)sptr;\n", tname, tname); switch(terminal->expr_type) { case ASN_STRING_UTF8String: OUT("const uint8_t *ch = st->buf;\n"); OUT("const uint8_t *end = ch + st->size;\n"); OUT("\n"); OUT("for(; ch < end; ch++) {\n"); INDENT(+1); OUT("uint8_t cv = *ch;\n"); if(!range) OUT("if(cv >= 0x80) return -1;\n"); natural_stop = 0xffffffffUL; break; case ASN_STRING_UniversalString: OUT("const uint8_t *ch = st->buf;\n"); OUT("const uint8_t *end = ch + st->size;\n"); OUT("\n"); OUT("if(st->size %% 4) return -1; /* (size%%4)! */\n"); OUT("for(; ch < end; ch += 4) {\n"); INDENT(+1); OUT("uint32_t cv = (ch[0] << 24)\n"); OUT("\t\t| (ch[1] << 16)\n"); OUT("\t\t| (ch[2] << 8)\n"); OUT("\t\t| ch[3];\n"); if(!range) OUT("if(cv > 255) return -1;\n"); natural_stop = 0xffffffffUL; break; case ASN_STRING_BMPString: OUT("const uint8_t *ch = st->buf;\n"); OUT("const uint8_t *end = ch + st->size;\n"); OUT("\n"); OUT("if(st->size %% 2) return -1; /* (size%%2)! */\n"); OUT("for(; ch < end; ch += 2) {\n"); INDENT(+1); OUT("uint16_t cv = (ch[0] << 8)\n"); OUT("\t\t| ch[1];\n"); if(!range) OUT("if(cv > 255) return -1;\n"); natural_stop = 0xffff; break; case ASN_BASIC_OCTET_STRING: default: OUT("const uint8_t *ch = st->buf;\n"); OUT("const uint8_t *end = ch + st->size;\n"); OUT("\n"); OUT("for(; ch < end; ch++) {\n"); INDENT(+1); OUT("uint8_t cv = *ch;\n"); natural_stop = 0xff; break; } if(range) { OUT("if(!("); emit_range_comparison_code(arg, range, "cv", 0, natural_stop); OUT(")) return -1;\n"); } else { OUT("if(!table[cv]) return -1;\n"); } INDENT(-1); OUT("}\n"); return 0; }