Commit 83882f48 authored by Botond Baranyi's avatar Botond Baranyi
Browse files

Support for multiple encodings - stage one (bug 517843)



Change-Id: Icc588b1b9cc6a647fb5b2e2d80c90da986a19160
Signed-off-by: Botond Baranyi's avatarBotond Baranyi <botond.baranyi@ericsson.com>
parent 8c48a9e9
This diff is collapsed.
......@@ -277,19 +277,36 @@ namespace Common {
};
/**
* Structure containing the default encoding or decoding settings for a type.
* Structure containing the default encoding or decoding settings for a type
* when using legacy codec handling.
* These settings determine how values of the type are encoded or decoded by
* the following TTCN-3 language elements:
* 'encvalue' (encode), 'encvalue_unichar' (encode), 'decvalue' (decode),
* 'decvalue_unichar' (decode), 'decmatch' (decode) and '@decoded' (decode).
*/
struct coding_t {
struct legacy_coding_t {
coding_type_t type; ///< Type of encoding/decoding
union {
MessageEncodingType_t built_in_coding; ///< Built-in codec (if type is CODING_BUILT_IN)
Assignment* function_def; ///< Pointer to external function definition (if type is CODING_BY_FUNCTION)
};
};
/** Stores information related to an encoding type (codec), when using new
* codec handling. */
struct coding_t {
boolean built_in; ///< built-in or user defined codec
union {
MessageEncodingType_t built_in_coding; ///< built-in codec
struct {
char* name; ///< name of the user defined codec (the string in the 'encode' attribute)
Assignment* enc_func; ///< definition of the encoder function
boolean enc_conflict; ///< indicates whether there are multiple encoder functions for this type and codec
Assignment* dec_func; ///< definition of the decoder function
boolean dec_conflict; ///< indicates whether there are multiple decoder functions for this type and codec
} custom_coding;
};
};
/** Returns the display string of \a encoding_type. */
static const char *get_encoding_name(MessageEncodingType_t encoding_type);
......@@ -334,8 +351,12 @@ namespace Common {
vector<SubTypeParse> *parsed_restr; ///< parsed subtype restrictions are stored here until they are moved to the sub_type member
SubType *sub_type; ///< effective/aggregate subtype of this type, NULL if neither inherited nor own subtype restrictions exist
coding_t default_encoding; ///< default settings for encoding values of this type
coding_t default_decoding; ///< default settings for decoding values of this type
legacy_coding_t default_encoding; ///< default settings for encoding values of this type (when using legacy codec handling)
legacy_coding_t default_decoding; ///< default settings for decoding values of this type (when using legacy codec handling)
/** Stores the list of encodings this type supports (when using new codec
* handling). */
vector<coding_t> coding_table;
/** What kind of AST element owns the type.
* It may not be known at creation type, so it's initially OT_UNKNOWN.
......@@ -442,15 +463,24 @@ namespace Common {
* this type. */
bool needs_any_from_done;
/** True if JSON coder functions need to be generated for this type.
* This is not the same as enabling JSON encoding, since other types that
* refer to this type may have JSON encoding, in which case this type needs
* to have JSON coder functions to code them. */
bool gen_json_coder_functions;
/** True if we already checked this type for default or port field*/
bool checked_incorrect_field;
/** Contains a list of the built-in coder functions that need to be
* generated for this type.
* When using legacy codec handling, only the JSON coders are set with this
* method. */
vector<MessageEncodingType_t> coders_to_generate;
/** Helper class that tracks the execution of a type's 'can_have_coding'
* function to prevent infinite recursions. */
class CodingCheckTracker {
static map<Type*, void> types;
public:
CodingCheckTracker(Type* t) { types.add(t, NULL); }
~CodingCheckTracker() { types.erase(types.get_nth_key(types.size() - 1)); }
static bool is_happening(Type* t) { return types.has_key(t); }
};
/** Copy constructor, for the use of Type::clone() only. */
Type(const Type& p);
......@@ -591,6 +621,34 @@ namespace Common {
virtual void set_my_scope(Scope *p_scope);
/** Checks the type (including tags). */
virtual void chk();
/** Checks the encodings supported by the type (when using new codec handling).
* TTCN-3 types need to have an 'encode' attribute to support an encoding.
* ASN.1 types automatically support BER, PER and JSON encodings, and XER
* encoding, if set by the compiler option. */
void chk_encodings();
/** Adds support for an encoding by the type (when using new codec handling),
* if the type can have that encoding.
* @param name name of the encoding as it appears in the 'encode' attribute;
* this may be the name of a built-in or a user-defined encoding */
void add_coding(const string& name);
/** Sets the encoder or decoder function for the user-defined encoding with
* the specified name (when using new codec handling). */
void set_coding_function(const char* coding_name, boolean encode,
Assignment* function_def);
/** Returns the type that contains this type's coding table (since types
* with no 'encode' attributes of their own inherit the 'encode' attributes
* of a referenced type or a parent type).
* Only used with new codec handling. */
Type* get_type_w_coding_table();
/** Returns whether this type can have the specified encoding.
* Only used with new codec handling. */
bool can_have_coding(MessageEncodingType_t coding);
/** Return whether the two typetypes are compatible. Sometimes, this is
* just a question of \p p_tt1 == \p p_tt2. When there are multiple
* typetypes for a type (e.g. T_ENUM_A and T_ENUM_T) then all
......@@ -694,10 +752,11 @@ namespace Common {
bool is_list_type(bool allow_array);
/** Sets the encoding or decoding function for the type (in case of custom
* or PER encoding). */
void set_coding_function(bool encode, Assignment* function_def);
* or PER encoding). Only used with legacy codec handling. */
void set_legacy_coding_function(bool encode, Assignment* function_def);
/** Sets the codec to use when encoding or decoding the ASN.1 type */
/** Sets the codec to use when encoding or decoding the ASN.1 type.
* Only used with legacy codec handling. */
void set_asn_coding(bool encode, MessageEncodingType_t new_coding);
/** Determines the method of encoding or decoding for values of this type
......@@ -724,7 +783,7 @@ namespace Common {
Assignment* get_coding_function(bool encode) const;
private:
static MessageEncodingType_t get_enc_type(const Ttcn::SingleWithAttrib& enc);
MessageEncodingType_t get_enc_type(const string& enc);
void chk_Int_A();
void chk_Enum_A();
......@@ -1126,6 +1185,7 @@ namespace Common {
void generate_code_Array(output_struct *target);
void generate_code_Fat(output_struct *target);
void generate_code_Signature(output_struct *target);
void generate_code_coding_handlers(output_struct *target);
/** Returns whether the type needs an explicit C++ typedef alias and/or
* an alias to a type descriptor of another type. It returns true for those
* types that are defined in module-level type definitions hence are
......@@ -1148,6 +1208,11 @@ namespace Common {
* or false if it still needs to be generated */
bool is_pregenerated();
public:
/** Returns true if the type supports at least one built-in encoding.
* Only used with new codec handling. */
bool has_built_in_encoding();
/** Generates type specific call for the reference used in isbound call
* into argument \a expr. Argument \a subrefs holds the reference path
* that needs to be checked. Argument \a module is the actual module of
......@@ -1215,6 +1280,7 @@ namespace Common {
/** User visible type name for built-in types */
static const char * get_typename_builtin(typetype_t tt);
string get_genname_typedescriptor(Scope *p_scope);
string get_genname_coder(Scope* p_scope);
private:
/** Returns the name prefix of type descriptors, etc. that belong to the
* equivalent C++ class referenced from the module of scope \a p_scope.
......@@ -1273,7 +1339,8 @@ namespace Common {
inline void set_needs_any_from_done() { needs_any_from_done = true; }
inline void set_gen_json_coder_functions() { gen_json_coder_functions = true; }
bool get_gen_coder_functions(MessageEncodingType_t coding);
void set_gen_coder_functions(MessageEncodingType_t coding);
/** Calculates the type's display name from the genname (replaces double
* underscore characters with single ones) */
......
......@@ -187,6 +187,9 @@ void Type::chk()
break;
}
}
if (!legacy_codec_handling && my_scope != NULL) {
chk_encodings();
}
checked = true;
if(tags) tags->set_plicit(this);
......@@ -629,6 +632,91 @@ void change_name(string &name, XerAttributes::NameChange change) {
} // switch for NAME
}
void Type::chk_encodings()
{
if (legacy_codec_handling) {
FATAL_ERROR("Type::chk_encodings");
}
switch (get_type_refd_last()->get_typetype_ttcn3()) {
case T_NULL:
case T_BOOL:
case T_INT:
case T_REAL:
case T_ENUM_T:
case T_BSTR:
case T_HSTR:
case T_OSTR:
case T_CSTR:
case T_USTR:
case T_OID:
case T_CHOICE_T:
case T_SEQOF:
case T_SETOF:
case T_SEQ_T:
case T_SET_T:
case T_VERDICT:
case T_ARRAY:
case T_ANYTYPE:
if (!is_asn1()) {
WithAttribPath* ap = get_attrib_path();
if (ap != NULL) {
MultiWithAttrib* mwa = ap->get_with_attr();
if (mwa != NULL) {
for (size_t i = 0; i < mwa->get_nof_elements(); ++i) {
const SingleWithAttrib* swa = mwa->get_element(i);
if (swa->get_attribKeyword() == SingleWithAttrib::AT_ENCODE) {
Ttcn::Qualifiers* quals = swa->get_attribQualifiers();
if (quals != NULL && quals->get_nof_qualifiers() != 0) {
for (size_t j = 0; j < quals->get_nof_qualifiers(); ++j) {
Ttcn::Qualifier* qual = const_cast<Ttcn::Qualifier*>(
quals->get_qualifier(j));
get_field_type(qual, EXPECTED_CONSTANT)->
add_coding(swa->get_attribSpec().get_spec());
}
}
else {
add_coding(swa->get_attribSpec().get_spec());
}
}
}
}
if (coding_table.size() == 0) {
const vector<SingleWithAttrib>& real = ap->get_real_attrib();
for (size_t i = 0; i < real.size(); ++i) {
const SingleWithAttrib* swa = real[i];
if (swa->get_attribKeyword() == SingleWithAttrib::AT_ENCODE) {
add_coding(swa->get_attribSpec().get_spec());
}
}
}
}
}
else {
switch (ownertype) {
case OT_TYPE_ASS:
case OT_RECORD_OF:
case OT_COMP_FIELD:
case OT_SELTYPE:
// ASN.1 types automatically have BER, PER, XER and JSON encoding
add_coding(string("BER:2002"));
add_coding(string(get_encoding_name(CT_PER)));
add_coding(string(get_encoding_name(CT_JSON)));
if (asn1_xer) {
// XER encoding for ASN.1 types can be disabled with a command line option
add_coding(string(get_encoding_name(CT_XER)));
}
break;
default:
break;
}
}
break;
default:
// the rest of the types can't have 'encode' attributes
break;
}
}
void Type::chk_xer_any_attributes()
{
Type * const last = get_type_refd_last();
......
......@@ -112,6 +112,9 @@ void Type::generate_code(output_struct *target)
if (sub_type) sub_type->generate_code(*target);
}
CodeGenHelper::update_intervals(target);
if (!legacy_codec_handling) {
generate_code_coding_handlers(target);
}
}
void Type::generate_code_include(const string& sourcefile, output_struct *target)
......@@ -282,33 +285,38 @@ void Type::generate_code_typedescriptor(output_struct *target)
*/
if (gennametypedescriptor == gennameown
|| force_xer) {
Type* last = get_type_refd_last();
// the type has its own type descriptor
bool generate_ber = has_encoding(CT_BER) && enable_ber();
bool generate_ber = enable_ber() && (legacy_codec_handling ?
has_encoding(CT_BER) : last->get_gen_coder_functions(CT_BER));
const string& gennameberdescriptor = get_genname_berdescriptor();
if (generate_ber && gennameberdescriptor == gennameown)
generate_code_berdescriptor(target);
bool generate_raw = has_encoding(CT_RAW) && enable_raw();
bool generate_raw = enable_raw() && (legacy_codec_handling ?
has_encoding(CT_RAW) : last->get_gen_coder_functions(CT_RAW));
const string& gennamerawdescriptor = get_genname_rawdescriptor();
if (generate_raw && gennamerawdescriptor == gennameown)
generate_code_rawdescriptor(target);
bool generate_text = has_encoding(CT_TEXT) && enable_text();
bool generate_text = enable_text() && (legacy_codec_handling ?
has_encoding(CT_TEXT) : last->get_gen_coder_functions(CT_TEXT));
const string& gennametextdescriptor = get_genname_textdescriptor();
if (generate_text && gennametextdescriptor == gennameown)
generate_code_textdescriptor(target);
bool generate_xer = has_encoding(CT_XER) && enable_xer();
bool generate_xer = enable_xer() && (legacy_codec_handling ?
has_encoding(CT_XER) : last->get_gen_coder_functions(CT_XER));
const string& gennamexerdescriptor = get_genname_xerdescriptor();
if (generate_xer && gennamexerdescriptor == gennameown)
generate_code_xerdescriptor(target);
else target->source.global_vars=mputprintf(target->source.global_vars,
"// No XER for %s\n", gennamexerdescriptor.c_str());
bool generate_json = enable_json() && (legacy_codec_handling ?
has_encoding(CT_JSON) : last->get_gen_coder_functions(CT_JSON));
const string& gennamejsondescriptor = get_genname_jsondescriptor();
bool generate_json = has_encoding(CT_JSON) && enable_json() &&
gennamejsondescriptor == gennameown;
if (generate_json) {
if (generate_json && gennamejsondescriptor == gennameown) {
generate_code_jsondescriptor(target);
}
......@@ -356,7 +364,7 @@ void Type::generate_code_typedescriptor(output_struct *target)
target->source.global_vars = mputprintf(target->source.global_vars,
"&%s_json_, ", gennamejsondescriptor.c_str());
} else {
switch(get_type_refd_last()->typetype) {
switch(last->typetype) {
case T_BOOL:
case T_INT:
case T_INT_A:
......@@ -384,23 +392,28 @@ void Type::generate_code_typedescriptor(output_struct *target)
case T_ROID:
case T_ANY:
// use predefined JSON descriptors instead of null pointers for basic types
target->source.global_vars = mputprintf(target->source.global_vars,
"&%s_json_, ", gennamejsondescriptor.c_str());
break;
if (legacy_codec_handling) {
target->source.global_vars = mputprintf(target->source.global_vars,
"&%s_json_, ", last->get_genname_typename(my_scope).c_str());
break;
}
// else fall through (to the default branch)
case T_ENUM_T:
case T_ENUM_A:
// use a predefined JSON descriptor for enumerated types
target->source.global_vars = mputstr(target->source.global_vars,
"&ENUMERATED_json_, ");
break;
if (legacy_codec_handling) {
target->source.global_vars = mputstr(target->source.global_vars,
"&ENUMERATED_json_, ");
break;
}
// else fall through
default:
target->source.global_vars = mputstr(target->source.global_vars,
"NULL, ");
}
}
if (T_SEQOF == get_type_refd_last()->typetype ||
T_SETOF == get_type_refd_last()->typetype) {
if (T_SEQOF == last->typetype || T_SETOF == last->typetype) {
target->source.global_vars=mputprintf(target->source.global_vars,
"&%s_descr_, ", get_type_refd_last()->u.seof.ofType->get_genname_typedescriptor(my_scope).c_str());
}
......@@ -675,6 +688,10 @@ void Type::generate_code_rawdescriptor(output_struct *target)
"extern const TTCN_RAWdescriptor_t %s_raw_;\n", gennameown_str);
char *str = mprintf("const TTCN_RAWdescriptor_t %s_raw_ = {",
gennameown_str);
bool dummy_raw = rawattrib == NULL;
if (dummy_raw) {
rawattrib = new RawAST(get_type_refd_last()->typetype == T_INT);
}
if (rawattrib->intx) {
str = mputstr(str, "RAW_INTX,");
}
......@@ -723,10 +740,18 @@ void Type::generate_code_rawdescriptor(output_struct *target)
(rawattrib->stringformat == CharCoding::UTF16 ? "UTF16" : "UNKNOWN"));
target->source.global_vars = mputstr(target->source.global_vars, str);
Free(str);
if (dummy_raw) {
delete rawattrib;
rawattrib = NULL;
}
}
void Type::generate_code_textdescriptor(output_struct *target)
{
bool dummy_text = textattrib == NULL;
if (dummy_text) {
textattrib = new TextAST();
}
const char *gennameown_str = get_genname_own().c_str();
char *union_member_name=NULL;
Common::Module *mymod=my_scope->get_scope_mod();
......@@ -1007,6 +1032,10 @@ void Type::generate_code_textdescriptor(output_struct *target)
target->source.global_vars = mputstr(target->source.global_vars,
"{NULL}};\n");
}
if (dummy_text) {
delete textattrib;
textattrib = NULL;
}
}
void Type::generate_code_jsondescriptor(output_struct *target)
......@@ -1099,10 +1128,13 @@ void Type::generate_code_Enum(output_struct *target)
Malloc(e_def.nElements*sizeof(*e_def.elements));
e_def.firstUnused = u.enums.first_unused;
e_def.secondUnused = u.enums.second_unused;
e_def.hasText = textattrib!=NULL;
e_def.hasRaw = rawattrib!=NULL;
e_def.hasXer = has_encoding(CT_XER);
e_def.hasJson = gen_json_coder_functions;
e_def.hasText = legacy_codec_handling ? textattrib != NULL :
get_gen_coder_functions(CT_TEXT);
e_def.hasRaw = legacy_codec_handling ? rawattrib != NULL :
get_gen_coder_functions(CT_RAW);
e_def.hasXer = legacy_codec_handling ? has_encoding(CT_XER) :
get_gen_coder_functions(CT_XER);
e_def.hasJson = get_gen_coder_functions(CT_JSON);
if (xerattrib) {
e_def.xerUseNumber = xerattrib->useNumber_;
}
......@@ -1141,9 +1173,13 @@ void Type::generate_code_Choice(output_struct *target)
}
else sdef.kind = UNION;
sdef.isASN1 = is_asn1();
sdef.hasText = textattrib!=NULL;
sdef.hasXer = has_encoding(CT_XER);
sdef.hasJson = gen_json_coder_functions;
sdef.hasRaw = legacy_codec_handling ? rawattrib != NULL :
get_gen_coder_functions(CT_RAW);
sdef.hasText = legacy_codec_handling ? textattrib != NULL :
get_gen_coder_functions(CT_TEXT);
sdef.hasXer = legacy_codec_handling ? has_encoding(CT_XER) :
get_gen_coder_functions(CT_XER);
sdef.hasJson = get_gen_coder_functions(CT_JSON);
sdef.has_opentypes = get_has_opentypes();
sdef.opentype_outermost = get_is_opentype_outermost();
sdef.ot = generate_code_ot(pool);
......@@ -1277,9 +1313,12 @@ void Type::generate_code_Choice(output_struct *target)
sdef.elements[i].jsonAlias = cftype->jsonattrib->alias;
}
}
if(rawattrib) {
if(sdef.hasRaw) {
bool dummy_raw = rawattrib == NULL;
if (dummy_raw) {
rawattrib = new RawAST;
}
copy_rawAST_to_struct(rawattrib,&(sdef.raw));
sdef.hasRaw=TRUE;
// building taglist
for(int c=0;c<rawattrib->taglist.nElements;c++){
if(rawattrib->taglist.tag[c].nElements)
......@@ -1352,7 +1391,11 @@ void Type::generate_code_Choice(output_struct *target)
}
}
}
} else sdef.hasRaw=FALSE;
if (dummy_raw) {
delete rawattrib;
rawattrib = NULL;
}
}
if (xerattrib) {
Module *my_module = get_my_scope()->get_scope_mod();
sdef.xerHasNamespaces = my_module->get_nof_ns() != 0;
......@@ -1367,7 +1410,7 @@ void Type::generate_code_Choice(output_struct *target)
free_code_ot(sdef.ot);
sdef.ot=0;
if (rawattrib) {
if (sdef.hasRaw) {
free_raw_attrib_struct(&sdef.raw);
}
Free(sdef.elements);
......@@ -1538,13 +1581,17 @@ void Type::generate_code_Se(output_struct *target)
default:
FATAL_ERROR("Type::generate_code_Se()");
} // switch
sdef.hasText = textattrib!=NULL;
sdef.hasRaw = legacy_codec_handling ? rawattrib != NULL :
get_gen_coder_functions(CT_RAW);
sdef.hasText = legacy_codec_handling ? textattrib != NULL :
get_gen_coder_functions(CT_TEXT);
sdef.nElements = sdef.totalElements = get_nof_comps();
sdef.has_opentypes = get_has_opentypes();
sdef.opentype_outermost = get_is_opentype_outermost();
sdef.ot = NULL;
sdef.hasXer = has_encoding(CT_XER);
sdef.hasJson = gen_json_coder_functions;
sdef.hasXer = legacy_codec_handling ? has_encoding(CT_XER) :
get_gen_coder_functions(CT_XER);
sdef.hasJson = get_gen_coder_functions(CT_JSON);
if (xerattrib){
Module *my_module = get_my_scope()->get_scope_mod();
sdef.xerHasNamespaces = my_module->get_nof_ns() != 0;
......@@ -1680,9 +1727,12 @@ void Type::generate_code_Se(output_struct *target)
}
se_comps.clear();
if(rawattrib) {
if(sdef.hasRaw) {
bool dummy_raw = rawattrib == NULL;
if (dummy_raw) {
rawattrib = new RawAST;
}
copy_rawAST_to_struct(rawattrib,&(sdef.raw));
sdef.hasRaw=TRUE;
// building taglist
for(int c=0;c<rawattrib->taglist.nElements;c++) {
if(rawattrib->taglist.tag[c].nElements)
......@@ -1928,12 +1978,15 @@ void Type::generate_code_Se(output_struct *target)
sdef.elements[i].hasRaw=FALSE;
}
}
if (dummy_raw) {
delete rawattrib;
rawattrib = NULL;
}
}
else {
for(size_t i = 0; i < sdef.totalElements; i++) {
sdef.elements[i].hasRaw=FALSE;
}
sdef.hasRaw=FALSE;
}
defRecordClass(&sdef, target);
......@@ -1944,7 +1997,7 @@ void Type::generate_code_Se(output_struct *target)
if (sdef.elements[i].xerAnyNum > 0) Free(sdef.elements[i].xerAnyUris);
} // next i
if (rawattrib) {
if (sdef.hasRaw) {
free_raw_attrib_struct(&sdef.raw);
for (size_t i = 0; i < sdef.totalElements; i++) {
if (sdef.elements[i].hasRaw) {
......@@ -2003,9 +2056,13 @@ void Type::generate_code_SeOf(output_struct *target)
sofdef.dispname = get_fullname().c_str();
sofdef.kind = typetype == T_SEQOF ? RECORD_OF : SET_OF;
sofdef.isASN1 = is_asn1();
sofdef.hasText = textattrib!=NULL;
sofdef.hasXer = has_encoding(CT_XER);
sofdef.hasJson = gen_json_coder_functions;
sofdef.hasRaw = legacy_codec_handling ? rawattrib != NULL :
get_gen_coder_functions(CT_RAW);
sofdef.hasText = legacy_codec_handling ? textattrib != NULL :
get_gen_coder_functions(CT_TEXT);
sofdef.hasXer = legacy_codec_handling ? has_encoding(CT_XER) :
get_gen_coder_functions(CT_XER);
sofdef.hasJson = get_gen_coder_functions(CT_JSON);
if (xerattrib) {
//sofdef.xerList = xerattrib->list_;
sofdef.xerAttribute = xerattrib->attribute_;
......@@ -2074,10 +2131,17 @@ void Type::generate_code_SeOf(output_struct *target)
break;
}
if(rawattrib) {
if(sofdef.hasRaw) {
bool dummy_raw = rawattrib == NULL;
if (dummy_raw) {
rawattrib = new RawAST;
}
copy_rawAST_to_struct(rawattrib,&(sofdef.raw));
sofdef.hasRaw=TRUE;
} else sofdef.hasRaw=FALSE;
if (dummy_raw) {
delete rawattrib;
rawattrib = NULL;
}
}
if (optimized_memalloc) {
defRecordOfClassMemAllocOptimized(&sofdef, target);
......@@ -2256,6 +2320,164 @@ void Type::generate_code_Signature(output_struct *target)
Free(sdef.exceptions.elements);
}
void Type::generate_code_coding_handlers(output_struct* target)
{
Type* t = get_type_w_coding_table();
if (t == NULL || get_genname_coder(my_scope) != get_genname_own()) {
return;
}
// default coding (global variable)
string default_coding;
if (t->coding_table.size() == 1) {
default_coding = t->coding_table[0]->built_in ?
get_encoding_name(t->coding_table[0]->built_in_coding) :
t->coding_table[0]->custom_coding.name;
}
target->header.global_vars = mputprintf(target->header.global_vars,
"extern UNIVERSAL_CHARSTRING %s_default_coding;\n", get_genname_own().c_str());
target->source.global_vars = mputprintf(target->source.global_vars,
"UNIVERSAL_CHARSTRING %s_default_coding(\"%s\");\n",
get_genname_own().c_str(), default_coding.c_str());
// encoder and decoder functions
target->header.function_prototypes = mputprintf(
target->header.function_prototypes,