Commit 825da4ab authored by Botond Baranyi's avatar Botond Baranyi
Browse files

Fixed memory leaks in regression tests, and allowed the tests to be run in debug mode (artf786863)



Change-Id: If7ea7e4957e27d6c562a32add1b45da2ec193c87
Signed-off-by: Botond Baranyi's avatarBotond Baranyi <botond.baranyi@ericsson.com>
parent 12ffc869
......@@ -29,7 +29,7 @@ namespace Common {
// ===== Code
// =================================
void Code::init_output(output_struct *output)
void Code::init_output(output_struct *output, boolean no_alloc)
{
output->header.includes = NULL;
output->header.class_decls = NULL;
......@@ -65,7 +65,7 @@ namespace Common {
output->intervals.function_bodies_max_size = 1;
output->intervals.static_conversion_function_bodies_max_size = 1;
output->intervals.static_function_bodies_max_size = 1;
if (CodeGenHelper::GetInstance().get_split_mode() == CodeGenHelper::SPLIT_TO_SLICES) {
if (!no_alloc && CodeGenHelper::GetInstance().get_split_mode() == CodeGenHelper::SPLIT_TO_SLICES) {
output->intervals.methods = (size_t*)Malloc(output->intervals.methods_max_size * sizeof(size_t));
output->intervals.function_bodies = (size_t*)Malloc(output->intervals.function_bodies_max_size * sizeof(size_t));
output->intervals.static_conversion_function_bodies = (size_t*)Malloc(output->intervals.static_conversion_function_bodies_max_size * sizeof(size_t));
......@@ -173,7 +173,7 @@ namespace Common {
Free(output->intervals.function_bodies);
Free(output->intervals.static_conversion_function_bodies);
Free(output->intervals.static_function_bodies);
init_output(output);
init_output(output, TRUE);
}
void Code::init_cdef(const_def *cdef)
......
......@@ -31,7 +31,7 @@ namespace Common {
class Code {
public:
static void init_output(output_struct *output);
static void init_output(output_struct *output, boolean no_alloc = FALSE);
static void merge_output(output_struct *dest, output_struct *src);
static void free_output(output_struct *output);
......
......@@ -13118,7 +13118,7 @@ void Value::generate_code_expr_encvalue_unichar(expression_struct *expr)
break;
}
const char * v2_code = NULL;
char * v2_code = NULL;
if(u.expr.v2) {
v2_code = generate_code_char_coding_check(expr, u.expr.v2, "encvalue_unichar");
}
......@@ -13175,6 +13175,7 @@ void Value::generate_code_expr_encvalue_unichar(expression_struct *expr)
expr->expr = mputprintf(expr->expr, ")");
}
Code::free_expr(&expr2);
Free(v2_code);
}
void Value::generate_code_expr_decvalue_unichar(expression_struct *expr)
......@@ -13193,7 +13194,7 @@ void Value::generate_code_expr_encvalue_unichar(expression_struct *expr)
expr->preamble = mputprintf(expr->preamble, "%s", expr1.preamble);
if (expr2.preamble)
expr->preamble = mputprintf(expr->preamble, "%s", expr2.preamble);
const char* v3_code = NULL;
char* v3_code = NULL;
if(u.expr.v3) {
v3_code = generate_code_char_coding_check(expr, u.expr.v3, "decvalue_unichar");
}
......@@ -13279,6 +13280,7 @@ void Value::generate_code_expr_encvalue_unichar(expression_struct *expr)
expr->postamble = mputprintf(expr->postamble, "%s", expr2.postamble);
Code::free_expr(&expr1);
Code::free_expr(&expr2);
Free(v3_code);
}
void Value::generate_code_expr_checkstate(expression_struct *expr)
......
......@@ -562,6 +562,7 @@ static char *get_dir_name(const char *path_name, const char *working_dir)
Free(dir_name);
if (absolute_dir == NULL || working_dir == NULL) {
/* an error occurred */
Free(absolute_dir);
return NULL;
} else if (!strcmp(absolute_dir, working_dir)) {
/* the directory is identical to the working dir */
......@@ -2116,7 +2117,7 @@ static void print_makefile(struct makefile_struct *makefile)
#ifdef MEMORY_DEBUG
// enable debug mode for the generated code, too
fputs(" -g -DMEMORY_DEBUG", fp);
fputs(" -DMEMORY_DEBUG", fp);
#endif
if (makefile->use_runtime_2) fputs(" -DTITAN_RUNTIME_2", fp);
......@@ -2214,7 +2215,11 @@ static void print_makefile(struct makefile_struct *makefile)
}
fprintf(fp, "# Flags for the C++ compiler:\n"
"CXXFLAGS = %s%s %s %s\n\n"
"CXXFLAGS = %s%s %s %s"
#ifdef MEMORY_DEBUG
" -g" // enable debug information for the generated code
#endif
"\n\n"
"# Flags for the linker:\n"
"LDFLAGS = %s%s\n\n"
"ifeq ($(PLATFORM), WIN32)\n"
......@@ -5120,7 +5125,7 @@ int main(int argc, char *argv[])
}
if (tpd_processed == TPD_FAILED) {
ERROR("Failed to process %s", tpd_file_name);
exit(EXIT_FAILURE);
goto end;
}
if (zflag) {
WARNING("Compiler option '-z' and its argument will be overwritten by "
......@@ -5156,6 +5161,7 @@ int main(int argc, char *argv[])
}
}
end:
free_string_list(sub_project_dirs);
free_string_list(ttcn3_prep_includes);
free_string_list(ttcn3_prep_defines);
......@@ -5193,7 +5199,7 @@ int main(int argc, char *argv[])
Free(optflags);
if (ttcn3prep)
Free(ttcn3prep);
/* Free(output_file); */
/* Free(output_file); */
for (E = 0; E < argc; ++E) Free(argv[E]);
Free(argv);
}
......
......@@ -4529,12 +4529,12 @@ void defRecordClass1(const struct_def *sdef, output_struct *output)
, sdef->elements[i].name, sdef->elements[i].name, sdef->elements[i].name);
}
src = mputprintf(src,
" JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG, JSON_DEC_FIELD_TOKEN_ERROR, \"%s\");\n"
" JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG, JSON_DEC_FIELD_TOKEN_ERROR, %lu, \"%s\");\n"
" }\n"
" return JSON_ERROR_FATAL;\n"
" }\n"
" dec_len += (size_t)ret_val;\n"
, sdef->elements[i].dispname);
, (unsigned long) strlen(sdef->elements[i].dispname), sdef->elements[i].dispname);
if (has_metainfo_enabled) {
src = mputstr(src, " }\n");
}
......@@ -4545,18 +4545,15 @@ void defRecordClass1(const struct_def *sdef, output_struct *output)
src = mputprintf(src,
"{\n"
// invalid field name
" char* fld_name2 = mcopystrn(fld_name, name_len);\n"
" JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG, %sJSON_DEC_INVALID_NAME_ERROR, fld_name2);\n"
" JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG, %sJSON_DEC_INVALID_NAME_ERROR, (int)name_len, fld_name);\n"
// if this is set to a warning, skip the value of the field
" dec_len += p_tok.get_next_token(&j_token, NULL, NULL);\n"
" if (JSON_TOKEN_NUMBER != j_token && JSON_TOKEN_STRING != j_token &&\n"
" JSON_TOKEN_LITERAL_TRUE != j_token && JSON_TOKEN_LITERAL_FALSE != j_token &&\n"
" JSON_TOKEN_LITERAL_NULL != j_token) {\n"
" JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG, JSON_DEC_FIELD_TOKEN_ERROR, fld_name2);\n"
" Free(fld_name2);\n"
" JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG, JSON_DEC_FIELD_TOKEN_ERROR, (int)name_len, fld_name);\n"
" return JSON_ERROR_FATAL;\n"
" }\n"
" Free(fld_name2);\n"
" }\n"
" }\n"
" }\n\n"
......@@ -4575,11 +4572,13 @@ void defRecordClass1(const struct_def *sdef, output_struct *output)
" }\n"
" else if (JSON_METAINFO_NEEDED == metainfo_%s) {\n"
// no meta info was found for this field, report the delayed error
" JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG, JSON_DEC_FIELD_TOKEN_ERROR, \"%s\");\n"
" JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG, JSON_DEC_FIELD_TOKEN_ERROR, %lu, \"%s\");\n"
" }\n"
" else "
, sdef->elements[i].name, sdef->elements[i].name
, sdef->elements[i].name, sdef->elements[i].dispname);
, sdef->elements[i].name
, (unsigned long) strlen(sdef->elements[i].dispname)
, sdef->elements[i].dispname);
}
src = mputprintf(src,
" if (!%s_found) {\n"
......
......@@ -1210,6 +1210,15 @@ void defRecordOfClass1(const struct_of_def *sdef, output_struct *output)
" UNIVERSAL_CHARSTRING before(sp_at, (const universal_char*)(*val_ptr->value_elements[i]));\n"
" before.XER_encode(UNIVERSAL_CHARSTRING_xer_, p_buf, p_flavor | ANY_ATTRIBUTES, p_flavor2, p_indent, 0);\n"
" p_buf.put_c('\\'');\n"
" p_buf.put_c(' ');\n"
/* Keep just the "b%d" part from ns */
" p_buf.put_s(ns_len - 9, (const unsigned char*)ns + 7);\n"
" p_buf.put_c(':');\n"
" Free(ns);\n"
// Ensure the namespace abides to its restrictions
" if (p_td.xer_bits & (ANY_FROM | ANY_EXCEPT)) {\n"
" TTCN_Buffer ns_buf;\n"
......@@ -1219,13 +1228,6 @@ void defRecordOfClass1(const struct_of_def *sdef, output_struct *output)
" check_namespace_restrictions(p_td, (const char*)cs);\n"
" }\n"
" p_buf.put_c('\\'');\n"
" p_buf.put_c(' ');\n"
/* Keep just the "b%d" part from ns */
" p_buf.put_s(ns_len - 9, (const unsigned char*)ns + 7);\n"
" p_buf.put_c(':');\n"
" Free(ns);\n"
" }\n"
" else {\n"
" p_buf.put_c(' ');\n"
......
......@@ -9801,18 +9801,19 @@ error:
// a value redirect class is generated for this redirect in the expression's
// preamble and instantiated in the expression
Scope* scope = v[0]->get_var_ref()->get_my_scope();
string tmp_id = scope->get_scope_mod_gen()->get_temporary_id();
expr->expr = mputprintf(expr->expr, "new Value_Redirect_%s(", tmp_id.c_str());
string class_id = scope->get_scope_mod_gen()->get_temporary_id();
string instance_id = scope->get_scope_mod_gen()->get_temporary_id();
// go through the value redirect and gather the necessary data for the class
char* members_str = NULL;
char* constr_params_str = NULL;
char* constr_init_list_str = NULL;
char* set_values_str = NULL;
char* inst_params_str = NULL;
if (matched_ti != NULL && has_decoded_modifier()) {
// store a pointer to the matched template, the decoding results from
// decmatch templates might be reused to optimize decoded value redirects
expr->expr = mputprintf(expr->expr, "&(%s), ", matched_ti->get_last_gen_expr());
inst_params_str = mprintf("&(%s), ", matched_ti->get_last_gen_expr());
members_str = mprintf("%s* ptr_matched_temp;\n",
value_type->get_genname_template(scope).c_str());
constr_params_str = mputprintf(constr_params_str, "%s* par_matched_temp, ",
......@@ -9822,14 +9823,24 @@ error:
boolean need_par = FALSE;
for (size_t i = 0; i < v.size(); ++i) {
if (i > 0) {
expr->expr = mputstr(expr->expr, ", ");
inst_params_str = mputstr(inst_params_str, ", ");
constr_params_str = mputstr(constr_params_str, ", ");
constr_init_list_str = mputstr(constr_init_list_str, ", ");
}
// pass the variable references to the new instance's constructor
expr->expr = mputstr(expr->expr, "&(");
v[i]->get_var_ref()->generate_code(expr);
expr->expr = mputc(expr->expr, ')');
expression_struct var_ref_expr;
Code::init_expr(&var_ref_expr);
inst_params_str = mputstr(inst_params_str, "&(");
v[i]->get_var_ref()->generate_code(&var_ref_expr);
inst_params_str = mputstr(inst_params_str, var_ref_expr.expr);
inst_params_str = mputc(inst_params_str, ')');
if (var_ref_expr.preamble != NULL) {
expr->preamble = mputstr(expr->preamble, var_ref_expr.preamble);
}
if (var_ref_expr.postamble != NULL) {
expr->postamble = mputstr(expr->postamble, var_ref_expr.postamble);
}
Code::free_expr(&var_ref_expr);
Type* redir_type = v[i]->get_subrefs() == NULL ? value_type :
value_type->get_field_type(v[i]->get_subrefs(), Type::EXPECTED_DYNAMIC_VALUE);
redir_type = redir_type->get_type_refd_last();
......@@ -10075,8 +10086,18 @@ error:
else {
// the encoding format is not known at compile-time, so an extra
// member and constructor parameter is needed to store it
expr->expr = mputstr(expr->expr, ", ");
v[i]->get_str_enc()->generate_code_expr(expr);
inst_params_str = mputstr(inst_params_str, ", ");
expression_struct str_enc_expr;
Code::init_expr(&str_enc_expr);
v[i]->get_str_enc()->generate_code_expr(&str_enc_expr);
inst_params_str = mputstr(inst_params_str, str_enc_expr.expr);
if (str_enc_expr.preamble != NULL) {
expr->preamble = mputstr(expr->preamble, str_enc_expr.preamble);
}
if (str_enc_expr.postamble != NULL) {
expr->postamble = mputstr(expr->postamble, str_enc_expr.postamble);
}
Code::free_expr(&str_enc_expr);
members_str = mputprintf(members_str, "CHARSTRING enc_fmt_%d;\n",
(int)i);
constr_params_str = mputprintf(constr_params_str,
......@@ -10148,8 +10169,18 @@ error:
else {
// the encoding format is not known at compile-time, so an extra
// member and constructor parameter is needed to store it
expr->expr = mputstr(expr->expr, ", ");
v[i]->get_str_enc()->generate_code_expr(expr);
inst_params_str = mputstr(inst_params_str, ", ");
expression_struct str_enc_expr;
Code::init_expr(&str_enc_expr);
v[i]->get_str_enc()->generate_code_expr(&str_enc_expr);
inst_params_str = mputstr(inst_params_str, str_enc_expr.expr);
if (str_enc_expr.preamble != NULL) {
expr->preamble = mputstr(expr->preamble, str_enc_expr.preamble);
}
if (str_enc_expr.postamble != NULL) {
expr->postamble = mputstr(expr->postamble, str_enc_expr.postamble);
}
Code::free_expr(&str_enc_expr);
members_str = mputprintf(members_str, "CHARSTRING enc_fmt_%d;\n",
(int)i);
constr_params_str = mputprintf(constr_params_str,
......@@ -10229,7 +10260,6 @@ error:
}
Code::free_expr(&subrefs_expr);
}
expr->expr = mputc(expr->expr, ')');
// generate the new class with the gathered data
expr->preamble = mputprintf(expr->preamble,
"class Value_Redirect_%s : public Value_Redirect_Interface {\n"
......@@ -10244,7 +10274,7 @@ error:
// variable; the redirects marked with the '@decoded' modifier are decoded
// here before they are assigned
"void set_values(const Base_Type*%s)\n"
"{\n", tmp_id.c_str(), members_str, tmp_id.c_str(), constr_params_str,
"{\n", class_id.c_str(), members_str, class_id.c_str(), constr_params_str,
constr_init_list_str, need_par ? " p" : "");
if (need_par) {
// don't generate the parameter and its casting if it is never used
......@@ -10254,13 +10284,17 @@ error:
value_type->get_genname_value(scope).c_str());
}
expr->preamble = mputstr(expr->preamble, set_values_str);
expr->preamble = mputstr(expr->preamble,
expr->preamble = mputprintf(expr->preamble,
"}\n"
"};\n");
"};\n"
"Value_Redirect_%s %s(%s);\n",
class_id.c_str(), instance_id.c_str(), inst_params_str);
Free(members_str);
Free(constr_params_str);
Free(constr_init_list_str);
Free(set_values_str);
Free(inst_params_str);
expr->expr = mputprintf(expr->expr, "&%s", instance_id.c_str());
}
else { // RT1
// in this case only the address of the one variable needs to be generated
......
......@@ -9750,6 +9750,7 @@ SelectUnion:
$$->add_id($3.elements[i].id);
}
$$->set_location(infile, @3);
Free($3.elements);
}
| CaseKeyword '(' error ')' StatementBlock optSemiColon
{
......
......@@ -665,8 +665,8 @@ static void generate_receive(char **def_ptr, char **src_ptr,
"if (value_redirect != NULL) {\n", failed_status);
if (use_runtime_2) {
src = mputprintf(src,
"value_redirect->set_values(my_head->message_%lu);\n"
"delete value_redirect;\n", (unsigned long) message_index);
"value_redirect->set_values(my_head->message_%lu);\n",
(unsigned long) message_index);
}
else {
src = mputprintf(src,
......
......@@ -299,12 +299,13 @@ static void yyprint(FILE *file, int type, const YYSTYPE& value);
%type <str>
XEncodeToken XmatchDef XAliasToken XJsonValueSegment XJsonValueCore XJsonValue
XJsonAlias
%type <decodetoken>
XDecodeToken
%type <cstr>
XTextReservedWord XJsonAlias
XTextReservedWord
%type <identifier>
XPointerToDef XRecordFieldRef XIdentifierOrReserved
......@@ -352,6 +353,7 @@ XOstring
Xtoken
Xstring
XAliasToken
XJsonAlias
XJsonValueSegment
XJsonValueCore
XJsonValue
......@@ -1583,28 +1585,28 @@ XOmitAsNull:
;
XNameAs:
XKWname XSpaces XKWas XSpaces XJsonAlias { jsonstruct->alias = mcopystr($5); }
XKWname XSpaces XKWas XSpaces XJsonAlias { jsonstruct->alias = $5; }
;
XJsonAlias: // include all keywords, so they can be used as aliases for fields, too
XAliasToken { $$ = $1; }
| XKWomit { $$ = "omit"; }
| XKWas { $$ = "as"; }
| XKWnull { $$ = "null"; }
| XKWname { $$ = "name"; }
| XKWvalue { $$ = "value"; }
| XKWdefault { $$ = "default"; }
| XKWextend { $$ = "extend"; }
| XKWmetainfo { $$ = "metainfo"; }
| XKWfor { $$ = "for"; }
| XKWunbound { $$ = "unbound"; }
| XKWomit { $$ = mcopystr("omit"); }
| XKWas { $$ = mcopystr("as"); }
| XKWnull { $$ = mcopystr("null"); }
| XKWname { $$ = mcopystr("name"); }
| XKWvalue { $$ = mcopystr("value"); }
| XKWdefault { $$ = mcopystr("default"); }
| XKWextend { $$ = mcopystr("extend"); }
| XKWmetainfo { $$ = mcopystr("metainfo"); }
| XKWfor { $$ = mcopystr("for"); }
| XKWunbound { $$ = mcopystr("unbound"); }
XAsValue:
XKWas XSpaces XKWvalue { jsonstruct->as_value = true; }
;
XDefault:
XKWdefault XOptSpaces XJsonValue { jsonstruct->default_value = mcopystr($3); }
XKWdefault XOptSpaces XJsonValue { jsonstruct->default_value = $3; }
;
XExtend:
......@@ -1613,13 +1615,13 @@ XExtend:
;
XJsonValue:
XJsonValueStart XJsonValueCore XJsonValueEnd { $$ = mcopystr($2); }
XJsonValueStart XJsonValueCore XJsonValueEnd { $$ = $2; }
| XJsonValueStart XJsonValueEnd { $$ = mcopystr(""); }
;
XJsonValueCore:
XJsonValueCore XJsonValueSegment { $$ = mcopystr($1); $$ = mputstr($$, $2); }
| XJsonValueSegment { $$ = mcopystr($1); }
XJsonValueCore XJsonValueSegment { $$ = mputstr($1, $2); Free($2); }
| XJsonValueSegment { $$ = $1; }
;
XMetainfoForUnbound:
......
......@@ -386,15 +386,8 @@ void defSignatureClasses(const signature_def *sdef, output_struct *output)
/* set_parameters function (used for param redirect in getreply) */
if (num_out > 0 || sdef->return_type != NULL) {
if (use_runtime_2 && sdef->return_type != NULL) {
/* destructor (only the return redirect object needs to be deleted) */
def = mputprintf(def, "virtual ~%s_reply_redirect() { "
"if (ret_val_redir != NULL) delete ret_val_redir; }\n", name);
}
else {
/* empty virtual destructor (for the virtual set_parameters function) */
def = mputprintf(def, "virtual ~%s_reply_redirect() { }\n", name);
}
/* empty virtual destructor (for the virtual set_parameters function) */
def = mputprintf(def, "virtual ~%s_reply_redirect() { }\n", name);
/* if there are "out" or "inout" parameters or a "return" ... */
def = mputprintf(def, "virtual void set_parameters(const %s_reply& reply_par) "
"const;\n", name);
......@@ -725,29 +718,6 @@ void defSignatureClasses(const signature_def *sdef, output_struct *output)
sdef->exceptions.elements[i].altname,
sdef->exceptions.elements[i].altname);
}
if (use_runtime_2) {
/* destructor, RT2 only */
def = mputprintf(def, "~%s_exception_template();\n", name);
src = mputprintf(src,
"%s_exception_template::~%s_exception_template()\n"
"{\n"
"switch (exception_selection) {\n", name, name);
for (i = 0; i < sdef->exceptions.nElements; i++) {
src = mputprintf(src,
"case %s_%s:\n"
"if (%s_redir != NULL) delete %s_redir;\n"
"break;", selection_prefix, sdef->exceptions.elements[i].altname,
sdef->exceptions.elements[i].altname,
sdef->exceptions.elements[i].altname);
}
src = mputprintf(src,
"default:\n"
"TTCN_error(\"Internal error: Invalid selector when deleting exception "
"object for signature %s.\");\n"
"}\n"
"}\n\n", dispname);
}
/* match function */
def = mputprintf(def, "boolean match(const %s_exception& other_value,"
......
......@@ -1753,7 +1753,7 @@ void defUnionClass(struct_def const *sdef, output_struct *output)
" %sverify_name(p_reader, p_td, e_xer);\n"
" xml_depth = p_reader.Depth();\n"
, name
, sdef->xerUseTypeAttr ? " char * typeatr = 0;\n" : ""
, sdef->xerUseTypeAttr ? " const char * typeatr = 0;\n" : ""
, sdef->xerUseUnion ? " boolean attribute = (p_td.xer_bits & XER_ATTRIBUTE) ? TRUE : FALSE;\n" : ""
, sdef->xerUseUnion ? "if (!attribute) " : ""
, sdef->xerUseUnion ? " || (p_flavor & USE_TYPE_ATTR)" : ""
......@@ -1768,22 +1768,13 @@ void defUnionClass(struct_def const *sdef, output_struct *output)
" const char *attr_name = (const char*)p_reader.Name();\n"
" if (!strcmp(attr_name, \"%s:type\"))\n"
" {\n"
" typeatr = mcopystr((const char*)p_reader.Value());\n"
" typeatr = (const char*)p_reader.Value();\n"
" }\n"
" else ++other_attributes;\n"
" }\n" /* for */
"%s"
, sdef->control_ns_prefix
, sdef->xerUseUnion ? " rd_ok = p_reader.MoveToElement() | 1;\n" : "");
if (!sdef->xerUseUnion) {
/* USE-TYPE: No type attribute means the first alternative */
src = mputprintf(src,
" if (typeatr == NULL) {\n"
" typeatr = mcopystrn(%s_xer_.names[1], %s_xer_.namelens[1] - 2);\n"
" }\n"
, sdef->elements[0].typegen
, sdef->elements[0].typegen);
}
src = mputstr(src,
" }\n" /* if exer */);
}
......@@ -1820,15 +1811,17 @@ void defUnionClass(struct_def const *sdef, output_struct *output)
if (sdef->xerUseTypeAttr) {
src = mputstr(src,
" if (e_xer) {\n" /* USE-TYPE => no XML element, use typeatr */
" char *token_1 = strtok(typeatr, \":\");\n" /* extract the namespace (if any) */
" char* typeatr_cpy = mcopystr(typeatr);\n" /* copy the string so it can be tokenized */
" char *token_1 = strtok(typeatr_cpy, \":\");\n" /* extract the namespace (if any) */
" char *token_2 = strtok(NULL, \":\");\n"
" if (token_2) {\n" /* namespace found */
" elem_name = token_2;\n"
" elem_name = typeatr + (token_2 - typeatr_cpy);\n" /* save the token's address in the original string, not in the copy */
" ns_uri = get_ns_uri_from_prefix(token_1, p_td);\n"
" }\n"
" else {\n" /* no namespace */
" elem_name = token_1;\n"
" elem_name = typeatr;\n"
" }\n"
" Free(typeatr_cpy);\n"
" flavor_1 |= USE_TYPE_ATTR;\n"
" }\n"
" else" /* no newline, gobbles up the next {} */);
......@@ -1917,13 +1910,14 @@ void defUnionClass(struct_def const *sdef, output_struct *output)
for (i = 0; i < sdef->nElements; i++) {
if(sdef->exerMaybeEmptyIndex != i) {
src = mputprintf(src,
" %sif (%s::can_start(elem_name, ns_uri, %s_xer_, flavor_1, flavor2) || (%s_xer_.xer_bits & ANY_ELEMENT)%s%s%s%s) {\n"
" %sif (%s%s::can_start(elem_name, ns_uri, %s_xer_, flavor_1, flavor2) || (%s_xer_.xer_bits & ANY_ELEMENT)%s%s%s%s) {\n"
" ec_2.set_msg(\"%s': \");\n"
" if (e_xer && (%s_xer_.xer_bits & BLOCKED)) {\n"
" TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_INVAL_MSG,\n"
" \"Attempting to decode blocked or abstract field.\");\n"
" }\n",
i && !(i==1 && sdef->exerMaybeEmptyIndex==0) ? "else " : "", /* print "if(" if generate code for the first field or if the first field is the MaybeEmpty field and we generate the code for the second one*/
i == 0 && sdef->xerUseTypeAttr ? "(e_xer && typeatr == NULL) || " : "", /* USE-TYPE: No type attribute means the first alternative */
sdef->elements[i].type, sdef->elements[i].typegen, sdef->elements[i].typegen,
sdef->elements[i].xsd_type != XSD_NONE ? " || strcmp(elem_name, \"" : "",
sdef->elements[i].xsd_type != XSD_NONE ? XSD_type_to_xml_type(sdef->elements[i].xsd_type) : "",
......@@ -1957,7 +1951,7 @@ void defUnionClass(struct_def const *sdef, output_struct *output)
if(sdef->exerMaybeEmptyIndex>=0 ){
i=sdef->exerMaybeEmptyIndex;
src = mputprintf(src,
" %sif ((e_xer && (type==XML_READER_TYPE_END_ELEMENT || !own_tag)) || %s::can_start(elem_name, ns_uri, %s_xer_, flavor_1, flavor2) || (%s_xer_.xer_bits & ANY_ELEMENT)%s%s%s) {\n"
" %sif (%s(e_xer && (type==XML_READER_TYPE_END_ELEMENT || !own_tag)) || %s::can_start(elem_name, ns_uri, %s_xer_, flavor_1, flavor2) || (%s_xer_.xer_bits & ANY_ELEMENT)%s%s%s) {\n"
"empty_xml: ec_2.set_msg(\"%s': \");\n"
" if (e_xer && (%s_xer_.xer_bits & BLOCKED)) {\n"
" TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_INVAL_MSG,\n"
......@@ -1972,6 +1966,7 @@ void defUnionClass(struct_def const *sdef, output_struct *output)
" }\n"
" }\n",
sdef->nElements>0 ? "else " : "",
i == 0 && sdef->xerUseTypeAttr ? "(e_xer && typeatr == NULL) || " : "", /* USE-TYPE: No type attribute means the first alternative */
sdef->elements[i].type, sdef->elements[i].typegen, sdef->elements[i].typegen,
sdef->elements[i].xsd_type != XSD_NONE ? " || strcmp(elem_name, \"" : "",
sdef->elements[i].xsd_type != XSD_NONE ? XSD_type_to_xml_type(sdef->elements[i].xsd_type) : "",
......@@ -2006,10 +2001,8 @@ void defUnionClass(struct_def const *sdef, output_struct *output)
" break;\n"
" }\n"
" }\n"
"%s"
" return 1;\n"
"}\n\n", sdef->xerUseUnion ? "!attribute && " : "",
sdef->xerUseTypeAttr ? " Free(typeatr);\n" : "");
"}\n\n", sdef->xerUseUnion ? "!attribute && " : "");
}
if (json_needed) {
// JSON encode
......@@ -2275,7 +2268,7 @@ void defUnionClass(struct_def const *sdef, output_struct *output)
" int ret_val = %s%s().JSON_decode(%s_descr_, p_tok, p_silent);\n"
" if (0 > ret_val) {\n"
" if (JSON_ERROR_INVALID_TOKEN) {\n"
" JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG, JSON_DEC_FIELD_TOKEN_ERROR, \"%s\");\n"
" JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG, JSON_DEC_FIELD_TOKEN_ERROR, %lu, \"%s\");\n"
" }\n"
" return JSON_ERROR_FATAL;\n"
" } else {\n"
......@@ -2284,13 +2277,11 @@ void defUnionClass(struct_def const *sdef, output_struct *output)
" } else "
, sdef->elements[i].jsonAlias ? sdef->elements[i].jsonAlias : sdef->elements[i].dispname
, at_field, sdef->elements[i].name, sdef->elements[i].typedescrname
, sdef->elements[i].dispname);
, (unsigned long) strlen(sdef->elements[i].dispname), sdef->elements[i].dispname);
}
src = mputstr(src,
"{\n"
" char* fld_name2 = mcopystrn(fld_name, name_len);\n"
" JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG, JSON_DEC_INVALID_NAME_ERROR, fld_name2);\n"
" Free(fld_name2);\n"
" JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG, JSON_DEC_INVALID_NAME_ERROR, (int)name_len, fld_name);\n"
" return JSON_ERROR_FATAL;\n"
" }\n"
" }\n\n"
......