aboutsummaryrefslogtreecommitdiffstats
path: root/libasn1compiler
diff options
context:
space:
mode:
authorLev Walkin <vlm@lionet.info>2007-06-27 01:54:57 +0000
committerLev Walkin <vlm@lionet.info>2007-06-27 01:54:57 +0000
commit8032f7ab447fb09b2fdcf5743509c0a8880fc825 (patch)
tree34bf1b55bfdcd7f7cbf004c3857fa41a2e51e1b6 /libasn1compiler
parent9774fd15fef655341f062c6fb488610ca2df0766 (diff)
optionality handling
Diffstat (limited to 'libasn1compiler')
-rw-r--r--libasn1compiler/asn1c_C.c90
1 files changed, 83 insertions, 7 deletions
diff --git a/libasn1compiler/asn1c_C.c b/libasn1compiler/asn1c_C.c
index d8aa01fb..ef0c8688 100644
--- a/libasn1compiler/asn1c_C.c
+++ b/libasn1compiler/asn1c_C.c
@@ -2057,6 +2057,35 @@ emit_member_PER_constraints(arg_t *arg, asn1p_expr_t *expr, const char *pfx) {
}
static int
+safe_string(const uint8_t *buf, int size) {
+ const uint8_t *end = buf + size;
+ for(; buf < end; buf++) {
+ int ch = *buf;
+ if((ch < 0x20 || ch > 0x7e) || ch == '"')
+ return 0;
+ }
+ return 1;
+}
+
+static void
+emit_default_value(arg_t *arg, asn1p_value_t *v) {
+
+ OUT("static uint8_t defv[] = ");
+ assert(v->type == ATV_STRING);
+
+ if(safe_string(v->value.string.buf, v->value.string.size)) {
+ OUT("\"%s\";\n", v->value.string.buf);
+ } else {
+ uint8_t *b = v->value.string.buf;
+ uint8_t *e = v->value.string.size + b;
+ OUT("{ ");
+ for(;b < e; b++)
+ OUT("0x%02x, ", *b);
+ OUT("0 };\n");
+ }
+}
+
+static int
try_inline_default(arg_t *arg, asn1p_expr_t *expr, int out) {
int save_target = arg->target->target;
asn1p_expr_type_e etype = expr_get_type(arg, expr);
@@ -2074,7 +2103,14 @@ try_inline_default(arg_t *arg, asn1p_expr_t *expr, int out) {
fits_long = asn1c_type_fits_long(arg, expr)!=FL_NOTFIT;
if(fits_long && !expr->marker.default_value->value.v_integer)
expr->marker.flags &= ~EM_INDIRECT;
- if(!out) return 1;
+ if(!out) {
+ OUT("asn_DFL_%d_set_%" PRIdASN
+ ",\t/* DEFAULT %" PRIdASN " */\n",
+ expr->_type_unique_index,
+ expr->marker.default_value->value.v_integer,
+ expr->marker.default_value->value.v_integer);
+ return 1;
+ }
REDIR(OT_STAT_DEFS);
OUT("static int asn_DFL_%d_set_%" PRIdASN "(int set_value, void **sptr) {\n",
expr->_type_unique_index,
@@ -2125,7 +2161,52 @@ try_inline_default(arg_t *arg, asn1p_expr_t *expr, int out) {
//expr->marker.flags &= ~EM_INDIRECT;
return 0;
default:
- break;
+ if(etype & ASN_STRING_KM_MASK) {
+ if(expr->marker.default_value == NULL
+ || expr->marker.default_value->type != ATV_STRING)
+ break;
+ if(!out) {
+ OUT("asn_DFL_%d_set,\t/* DEFAULT \"%s\" */\n",
+ expr->_type_unique_index,
+ expr->marker.default_value->value.string.buf);
+ return 1;
+ }
+ REDIR(OT_STAT_DEFS);
+ OUT("static int asn_DFL_%d_set(int set_value, void **sptr) {\n", expr->_type_unique_index);
+ INDENT(+1);
+ emit_default_value(arg, expr->marker.default_value);
+ OUT("%s *st = *sptr;\n", asn1c_type_name(arg, expr, TNF_CTYPE));
+ OUT("\n");
+ OUT("if(!st) {\n");
+ OUT("\tif(!set_value) return -1;\t/* Not a default value */\n");
+ OUT("\tst = (*sptr = CALLOC(1, sizeof(*st)));\n");
+ OUT("\tif(!st) return -1;\n");
+ OUT("}\n");
+ OUT("\n");
+ OUT("if(set_value) {\n");
+ INDENT(+1);
+ OUT("uint8_t *ptr = MALLOC(sizeof(defv));\n");
+ OUT("if(!ptr) return -1;\n");
+ OUT("memcpy(ptr, &defv, sizeof(defv));\n");
+ OUT("FREEMEM(st->buf);\n");
+ OUT("st->buf = ptr;\n");
+ OUT("st->size = sizeof(defv) - 1;\n");
+ OUT("return 0;\n");
+ INDENT(-1);
+ OUT("} else {\n");
+ INDENT(+1);
+ OUT("if(st->size != (sizeof(defv) - 1)\n");
+ OUT("|| memcmp(st->buf, &defv, sizeof(defv) - 1))\n");
+ OUT("\treturn 0;\n");
+ OUT("return 1;\n");
+ INDENT(-1);
+ OUT("}\n"); OUT("\n");
+ INDENT(-1);
+ OUT("}\n");
+ REDIR(save_target);
+ return 1;
+ }
+ break;
}
return 0;
}
@@ -2247,11 +2328,6 @@ emit_member_table(arg_t *arg, asn1p_expr_t *expr) {
}
if(C99_MODE) OUT(".default_value = ");
if(try_inline_default(arg, expr, 0)) {
- OUT("asn_DFL_%d_set_%" PRIdASN
- ",\t/* DEFAULT %" PRIdASN " */\n",
- expr->_type_unique_index,
- expr->marker.default_value->value.v_integer,
- expr->marker.default_value->value.v_integer);
} else {
OUT("0,\n");
}