Commit 4696c74b authored by Lev Walkin's avatar Lev Walkin

asn1c code generator modifier: <asn1c:pointer>

parent b85a8135
...@@ -5,6 +5,8 @@ ...@@ -5,6 +5,8 @@
should be necessary anymore to produce reference-free code: should be necessary anymore to produce reference-free code:
recursive dependencies are resolved automatically. recursive dependencies are resolved automatically.
* Test cases 73 & 92 keep track of various circular references. * Test cases 73 & 92 keep track of various circular references.
* Introduced asn1c-specific modifier to allow finer control over the
generated code ("<asn1c:pointer>" in comments), (Test case 93).
0.9.18: 2005-Aug-14 0.9.18: 2005-Aug-14
......
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -25,6 +25,8 @@ int asn1p_lexer_types_year = 0; ...@@ -25,6 +25,8 @@ int asn1p_lexer_types_year = 0;
int asn1p_lexer_constructs_year = 0; int asn1p_lexer_constructs_year = 0;
static asn1c_integer_t asn1p_atoi(char *ptr); /* errno is either 0 or ERANGE */ static asn1c_integer_t asn1p_atoi(char *ptr); /* errno is either 0 or ERANGE */
int asn1p_as_pointer;
/* /*
* Check that the type is defined in the year of the standard choosen. * Check that the type is defined in the year of the standard choosen.
*/ */
...@@ -100,15 +102,27 @@ WSP [\t\r\v\f\n ] ...@@ -100,15 +102,27 @@ WSP [\t\r\v\f\n ]
{NL} yy_pop_state(); {NL} yy_pop_state();
"<asn1c:"[^\r\v\f\n>-]{1,80}">" {
if(strcmp(yytext, "<asn1c:pointer>") == 0)
asn1p_as_pointer = 1;
/* Eat modifier */
}
"<" /* Eat stand-alone left angle brace */
-- yy_pop_state(); /* End of comment */ -- yy_pop_state(); /* End of comment */
- /* Eat single dash */ - /* Eat single dash */
[^\r\v\f\n-]+ /* Eat */ [^\r\v\f\n<-]+ /* Eat */
} }
<INITIAL,cpp_comment>"/*" yy_push_state(cpp_comment); <INITIAL,cpp_comment>"/*" yy_push_state(cpp_comment);
<cpp_comment>{ <cpp_comment>{
[^*/] /* Eat */ [^*/<] /* Eat */
"*/" yy_pop_state(); "*/" yy_pop_state();
"<asn1c:"[^\r\v\f\n>-]{1,80}">" {
if(strcmp(yytext, "<asn1c:pointer>") == 0)
asn1p_as_pointer = 1;
/* Eat modifier */
}
. /* Eat */ . /* Eat */
} }
......
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -23,6 +23,13 @@ void asn1p_lexer_hack_push_encoding_control(void); ...@@ -23,6 +23,13 @@ void asn1p_lexer_hack_push_encoding_control(void);
#define yylineno asn1p_lineno #define yylineno asn1p_lineno
extern int asn1p_lineno; extern int asn1p_lineno;
/*
* Process modifiers as <asn1c:pointer>
*/
extern int asn1p_as_pointer;
static asn1p_expr_t *asn1p_last_type;
static void apply_nonstd_mods(void);
/* /*
* This temporary variable is used to solve the shortcomings of 1-lookahead * This temporary variable is used to solve the shortcomings of 1-lookahead
* parser. * parser.
...@@ -231,6 +238,7 @@ static void _fixup_anonymous_identifier(asn1p_expr_t *expr); ...@@ -231,6 +238,7 @@ static void _fixup_anonymous_identifier(asn1p_expr_t *expr);
%type <a_expr> ExportsElement %type <a_expr> ExportsElement
%type <a_expr> ExtensionAndException %type <a_expr> ExtensionAndException
%type <a_expr> TypeDeclaration %type <a_expr> TypeDeclaration
%type <a_expr> TypeDeclarationSet
%type <a_ref> ComplexTypeReference %type <a_ref> ComplexTypeReference
%type <a_ref> ComplexTypeReferenceAmpList %type <a_ref> ComplexTypeReferenceAmpList
%type <a_refcomp> ComplexTypeReferenceElement %type <a_refcomp> ComplexTypeReferenceElement
...@@ -1086,26 +1094,32 @@ Type: ...@@ -1086,26 +1094,32 @@ Type:
$$->constraints = $3; $$->constraints = $3;
} }
} }
asn1p_last_type = $$;
} }
; ;
TypeDeclaration: TypeDeclaration:
{apply_nonstd_mods();} TypeDeclarationSet {
$$ = $2;
}
TypeDeclarationSet:
BasicType { BasicType {
$$ = $1; $$ = $1;
} }
| TOK_CHOICE '{' AlternativeTypeLists '}' { | TOK_CHOICE '{' AlternativeTypeLists {apply_nonstd_mods();} '}' {
$$ = $3; $$ = $3;
assert($$->expr_type == A1TC_INVALID); assert($$->expr_type == A1TC_INVALID);
$$->expr_type = ASN_CONSTR_CHOICE; $$->expr_type = ASN_CONSTR_CHOICE;
$$->meta_type = AMT_TYPE; $$->meta_type = AMT_TYPE;
} }
| TOK_SEQUENCE '{' optComponentTypeLists '}' { | TOK_SEQUENCE '{' optComponentTypeLists {apply_nonstd_mods();} '}' {
$$ = $3; $$ = $3;
assert($$->expr_type == A1TC_INVALID); assert($$->expr_type == A1TC_INVALID);
$$->expr_type = ASN_CONSTR_SEQUENCE; $$->expr_type = ASN_CONSTR_SEQUENCE;
$$->meta_type = AMT_TYPE; $$->meta_type = AMT_TYPE;
} }
| TOK_SET '{' optComponentTypeLists '}' { | TOK_SET '{' optComponentTypeLists {apply_nonstd_mods();} '}' {
$$ = $3; $$ = $3;
assert($$->expr_type == A1TC_INVALID); assert($$->expr_type == A1TC_INVALID);
$$->expr_type = ASN_CONSTR_SET; $$->expr_type = ASN_CONSTR_SET;
...@@ -2235,6 +2249,22 @@ _fixup_anonymous_identifier(asn1p_expr_t *expr) { ...@@ -2235,6 +2249,22 @@ _fixup_anonymous_identifier(asn1p_expr_t *expr) {
expr->Identifier); expr->Identifier);
} }
static void
apply_nonstd_mods() {
if(!asn1p_as_pointer) return;
asn1p_as_pointer = 0;
if(asn1p_last_type) {
asn1p_last_type->marker.flags |= EM_INDIRECT;
fprintf(stderr, "INFO: Modifier <asn1c:pointer> "
"applied to \"%s\" at line %d\n",
asn1p_last_type->Identifier
? asn1p_last_type->Identifier : "<anonymous>",
asn1p_last_type->_lineno);
asn1p_last_type = 0;
}
}
extern char *asn1p_text; extern char *asn1p_text;
int int
......
...@@ -623,11 +623,15 @@ asn1print_expr(asn1p_t *asn, asn1p_module_t *mod, asn1p_expr_t *tc, enum asn1pri ...@@ -623,11 +623,15 @@ asn1print_expr(asn1p_t *asn, asn1p_module_t *mod, asn1p_expr_t *tc, enum asn1pri
== EM_OPTIONAL) { == EM_OPTIONAL) {
printf(" OPTIONAL"); printf(" OPTIONAL");
} }
if(TQ_NEXT(se, next)) { if(TQ_NEXT(se, next))
printf(","); printf(",");
if(!(flags & APF_NOINDENT)) /* Reconstruct modifier information */
INDENT("\n"); if((se->marker.flags & EM_OMITABLE)
} != EM_OMITABLE
&& se->marker.flags & EM_INDIRECT)
printf("\t/* <asn1c:pointer> */");
if(TQ_NEXT(se, next) && !(flags & APF_NOINDENT))
INDENT("\n");
} }
if(put_braces && TQ_FIRST(&tc->members)) { if(put_braces && TQ_FIRST(&tc->members)) {
......
...@@ -11,7 +11,8 @@ ...@@ -11,7 +11,8 @@
#endif #endif
#include <stdio.h> #include <stdio.h>
#include <sys/types.h> #include <sys/types.h>
#include <unistd.h> /* for getopt */ #include <stdlib.h> /* for atoi(3) */
#include <unistd.h> /* for getopt(3) */
#include <string.h> /* for strerror(3) */ #include <string.h> /* for strerror(3) */
#include <sysexits.h> /* for EX_* exit codes */ #include <sysexits.h> /* for EX_* exit codes */
#include <assert.h> /* for assert(3) */ #include <assert.h> /* for assert(3) */
......
-- OK: Everything is fine
-- iso.org.dod.internet.private.enterprise (1.3.6.1.4.1)
-- .spelio.software.asn1c.test (9363.1.5.1)
-- .93
Module-asn1c-controls
{ iso org(3) dod(6) internet (1) private(4) enterprise(1)
spelio(9363) software(1) asn1c(5) test(1) 93 }
DEFINITIONS AUTOMATIC TAGS ::=
BEGIN
Sequence ::= SEQUENCE {
ainl INTEGER,
aptr INTEGER /* <asn1c:pointer> */
}
Set ::= SET {
ainl Sequence,
aptr Sequence -- <asn1c:pointer>
}
Choice ::= CHOICE {
setof SET OF INTEGER, -- <asn1c:pointer>
aptr Sequence, -- <asn1c:pointer>
ainl Sequence
}
END
Module-asn1c-controls { iso org(3) dod(6) internet(1) private(4) enterprise(1)
spelio(9363) software(1) asn1c(5) test(1) 93 }
DEFINITIONS AUTOMATIC TAGS ::=
BEGIN
Sequence ::= SEQUENCE {
ainl [0] IMPLICIT INTEGER,
aptr [1] IMPLICIT INTEGER /* <asn1c:pointer> */
}
Set ::= SET {
ainl [0] IMPLICIT Sequence,
aptr [1] IMPLICIT Sequence /* <asn1c:pointer> */
}
Choice ::= CHOICE {
setof [0] IMPLICIT SET OF INTEGER, /* <asn1c:pointer> */
aptr [1] IMPLICIT Sequence, /* <asn1c:pointer> */
ainl [2] IMPLICIT Sequence
}
END
/*** <<< INCLUDES [Sequence] >>> ***/
#include <INTEGER.h>
#include <constr_SEQUENCE.h>
/*** <<< TYPE-DECLS [Sequence] >>> ***/
typedef struct Sequence {
INTEGER_t ainl;
INTEGER_t *aptr;
/* Context for parsing across buffer boundaries */
asn_struct_ctx_t _asn_ctx;
} Sequence_t;
/*** <<< FUNC-DECLS [Sequence] >>> ***/
extern asn_TYPE_descriptor_t asn_DEF_Sequence;
/*** <<< STAT-DEFS [Sequence] >>> ***/
static asn_TYPE_member_t asn_MBR_Sequence_1[] = {
{ ATF_NOFLAGS, 0, offsetof(struct Sequence, ainl),
.tag = (ASN_TAG_CLASS_CONTEXT | (0 << 2)),
.tag_mode = -1, /* IMPLICIT tag at current level */
.type = (void *)&asn_DEF_INTEGER,
.memb_constraints = 0, /* Defer constraints checking to the member type */
.name = "ainl"
},
{ ATF_POINTER, 0, offsetof(struct Sequence, aptr),
.tag = (ASN_TAG_CLASS_CONTEXT | (1 << 2)),
.tag_mode = -1, /* IMPLICIT tag at current level */
.type = (void *)&asn_DEF_INTEGER,
.memb_constraints = 0, /* Defer constraints checking to the member type */
.name = "aptr"
},
};
static ber_tlv_tag_t asn_DEF_Sequence_1_tags[] = {
(ASN_TAG_CLASS_UNIVERSAL | (16 << 2))
};
static asn_TYPE_tag2member_t asn_MAP_Sequence_1_tag2el[] = {
{ (ASN_TAG_CLASS_CONTEXT | (0 << 2)), 0, 0, 0 }, /* ainl at 15 */
{ (ASN_TAG_CLASS_CONTEXT | (1 << 2)), 1, 0, 0 } /* aptr at 17 */
};
static asn_SEQUENCE_specifics_t asn_SPC_Sequence_1_specs = {
sizeof(struct Sequence),
offsetof(struct Sequence, _asn_ctx),
asn_MAP_Sequence_1_tag2el,
2, /* Count of tags in the map */
-1, /* Start extensions */
-1 /* Stop extensions */
};
asn_TYPE_descriptor_t asn_DEF_Sequence = {
"Sequence",
"Sequence",
SEQUENCE_free,
SEQUENCE_print,
SEQUENCE_constraint,
SEQUENCE_decode_ber,
SEQUENCE_encode_der,
SEQUENCE_decode_xer,
SEQUENCE_encode_xer,
0, /* Use generic outmost tag fetcher */
asn_DEF_Sequence_1_tags,
sizeof(asn_DEF_Sequence_1_tags)
/sizeof(asn_DEF_Sequence_1_tags[0]), /* 1 */
asn_DEF_Sequence_1_tags, /* Same as above */
sizeof(asn_DEF_Sequence_1_tags)
/sizeof(asn_DEF_Sequence_1_tags[0]), /* 1 */
asn_MBR_Sequence_1,
2, /* Elements count */
&asn_SPC_Sequence_1_specs /* Additional specs */
};
/*** <<< INCLUDES [Set] >>> ***/
#include <Sequence.h>
#include <constr_SET.h>
/*** <<< DEPS [Set] >>> ***/
/*
* Method of determining the components presence
*/
typedef enum Set_PR {
Set_PR_ainl, /* Member ainl is present */
Set_PR_aptr, /* Member aptr is present */
} Set_PR;
/*** <<< FWD-DECLS [Set] >>> ***/
struct Sequence;
/*** <<< TYPE-DECLS [Set] >>> ***/
typedef struct Set {
Sequence_t ainl;
struct Sequence *aptr;
/* Presence bitmask: ASN_SET_ISPRESENT(pSet, Set_PR_x) */
unsigned int _presence_map
[((2+(8*sizeof(unsigned int))-1)/(8*sizeof(unsigned int)))];
/* Context for parsing across buffer boundaries */
asn_struct_ctx_t _asn_ctx;
} Set_t;
/*** <<< FUNC-DECLS [Set] >>> ***/
extern asn_TYPE_descriptor_t asn_DEF_Set;
/*** <<< POST-INCLUDE [Set] >>> ***/
#include <Sequence.h>
/*** <<< STAT-DEFS [Set] >>> ***/
static asn_TYPE_member_t asn_MBR_Set_1[] = {
{ ATF_NOFLAGS, 0, offsetof(struct Set, ainl),
.tag = (ASN_TAG_CLASS_CONTEXT | (0 << 2)),
.tag_mode = -1, /* IMPLICIT tag at current level */
.type = (void *)&asn_DEF_Sequence,
.memb_constraints = 0, /* Defer constraints checking to the member type */
.name = "ainl"
},
{ ATF_POINTER, 0, offsetof(struct Set, aptr),
.tag = (ASN_TAG_CLASS_CONTEXT | (1 << 2)),
.tag_mode = -1, /* IMPLICIT tag at current level */
.type = (void *)&asn_DEF_Sequence,
.memb_constraints = 0, /* Defer constraints checking to the member type */
.name = "aptr"
},
};
static ber_tlv_tag_t asn_DEF_Set_1_tags[] = {
(ASN_TAG_CLASS_UNIVERSAL | (17 << 2))
};
static asn_TYPE_tag2member_t asn_MAP_Set_1_tag2el[] = {
{ (ASN_TAG_CLASS_CONTEXT | (0 << 2)), 0, 0, 0 }, /* ainl at 20 */
{ (ASN_TAG_CLASS_CONTEXT | (1 << 2)), 1, 0, 0 } /* aptr at 22 */
};
static uint8_t asn_MAP_Set_1_mmap[(2 + (8 * sizeof(unsigned int)) - 1) / 8] = {
(1 << 7) | (1 << 6)
};
static asn_SET_specifics_t asn_SPC_Set_1_specs = {
sizeof(struct Set),
offsetof(struct Set, _asn_ctx),
offsetof(struct Set, _presence_map),
asn_MAP_Set_1_tag2el,
2, /* Count of tags in the map */
asn_MAP_Set_1_tag2el, /* Same as above */
2, /* Count of tags in the CXER map */
0, /* Whether extensible */
(unsigned int *)asn_MAP_Set_1_mmap /* Mandatory elements map */
};
asn_TYPE_descriptor_t asn_DEF_Set = {
"Set",
"Set",
SET_free,
SET_print,
SET_constraint,
SET_decode_ber,
SET_encode_der,
SET_decode_xer,
SET_encode_xer,
0, /* Use generic outmost tag fetcher */
asn_DEF_Set_1_tags,
sizeof(asn_DEF_Set_1_tags)
/sizeof(asn_DEF_Set_1_tags[0]), /* 1 */
asn_DEF_Set_1_tags, /* Same as above */
sizeof(asn_DEF_Set_1_tags)
/sizeof(asn_DEF_Set_1_tags[0]), /* 1 */
asn_MBR_Set_1,
2, /* Elements count */
&asn_SPC_Set_1_specs /* Additional specs */
};
/*** <<< INCLUDES [Choice] >>> ***/
#include <Sequence.h>
#include <INTEGER.h>
#include <asn_SET_OF.h>
#include <constr_SET_OF.h>
#include <constr_CHOICE.h>
/*** <<< DEPS [Choice] >>> ***/
typedef enum Choice_PR {
Choice_PR_NOTHING, /* No components present */
Choice_PR_setof,
Choice_PR_aptr,
Choice_PR_ainl,
} Choice_PR;
/*** <<< FWD-DECLS [Choice] >>> ***/
struct Sequence;
/*** <<< TYPE-DECLS [Choice] >>> ***/
typedef struct Choice {
Choice_PR present;
union Choice_u {
struct setof {
A_SET_OF(INTEGER_t) list;
/* Context for parsing across buffer boundaries */
asn_struct_ctx_t _asn_ctx;
} *setof;
struct Sequence *aptr;
Sequence_t ainl;
} choice;
/* Context for parsing across buffer boundaries */
asn_struct_ctx_t _asn_ctx;
} Choice_t;
/*** <<< FUNC-DECLS [Choice] >>> ***/
extern asn_TYPE_descriptor_t asn_DEF_Choice;
/*** <<< POST-INCLUDE [Choice] >>> ***/
#include <Sequence.h>
/*** <<< STAT-DEFS [Choice] >>> ***/
static asn_TYPE_member_t asn_MBR_setof_2[] = {
{ ATF_POINTER, 0, 0,
.tag = (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)),
.tag_mode = 0,
.type = (void *)&asn_DEF_INTEGER,
.memb_constraints = 0, /* Defer constraints checking to the member type */
.name = ""
},
};
static ber_tlv_tag_t asn_DEF_setof_2_tags[] = {
(ASN_TAG_CLASS_CONTEXT | (0 << 2)),
(ASN_TAG_CLASS_UNIVERSAL | (17 << 2))
};
static asn_SET_OF_specifics_t asn_SPC_setof_2_specs = {
sizeof(struct setof),
offsetof(struct setof, _asn_ctx),
0, /* XER encoding is XMLDelimitedItemList */
};
static /* Use -fall-defs-global to expose */
asn_TYPE_descriptor_t asn_DEF_setof_2 = {
"setof",
"setof",
SET_OF_free,
SET_OF_print,
SET_OF_constraint,
SET_OF_decode_ber,
SET_OF_encode_der,
SET_OF_decode_xer,
SET_OF_encode_xer,
0, /* Use generic outmost tag fetcher */
asn_DEF_setof_2_tags,
sizeof(asn_DEF_setof_2_tags)
/sizeof(asn_DEF_setof_2_tags[0]) - 1, /* 1 */
asn_DEF_setof_2_tags, /* Same as above */
sizeof(asn_DEF_setof_2_tags)
/sizeof(asn_DEF_setof_2_tags[0]), /* 2 */
asn_MBR_setof_2,
1, /* Single element */
&asn_SPC_setof_2_specs /* Additional specs */
};
static asn_TYPE_member_t asn_MBR_Choice_1[] = {
{ ATF_POINTER, 0, offsetof(struct Choice, choice.setof),
.tag = (ASN_TAG_CLASS_CONTEXT | (0 << 2)),
.tag_mode = -1, /* IMPLICIT tag at current level */
.type = (void *)&asn_DEF_setof_2,
.memb_constraints = 0, /* Defer constraints checking to the member type */
.name = "setof"
},
{ ATF_POINTER, 0, offsetof(struct Choice, choice.aptr),
.tag = (ASN_TAG_CLASS_CONTEXT | (1 << 2)),
.tag_mode = -1, /* IMPLICIT tag at current level */
.type = (void *)&asn_DEF_Sequence,
.memb_constraints = 0, /* Defer constraints checking to the member type */
.name = "aptr"
},
{ ATF_NOFLAGS, 0, offsetof(struct Choice, choice.ainl),
.tag = (ASN_TAG_CLASS_CONTEXT | (2 << 2)),
.tag_mode = -1, /* IMPLICIT tag at current level */
.type = (void *)&asn_DEF_Sequence,
.memb_constraints = 0, /* Defer constraints checking to the member type */
.name = "ainl"
},
};
static asn_TYPE_tag2member_t asn_MAP_Choice_1_tag2el[] = {
{ (ASN_TAG_CLASS_CONTEXT | (0 << 2)), 0, 0, 0 }, /* setof at 25 */
{ (ASN_TAG_CLASS_CONTEXT | (1 << 2)), 1, 0, 0 }, /* aptr at 26 */
{ (ASN_TAG_CLASS_CONTEXT | (2 << 2)), 2, 0, 0 } /* ainl at 28 */
};
static asn_CHOICE_specifics_t asn_SPC_Choice_1_specs = {
sizeof(struct Choice),
offsetof(struct Choice, _asn_ctx),
offsetof(struct Choice, present),
sizeof(((struct Choice *)0)->present),
asn_MAP_Choice_1_tag2el,
3, /* Count of tags in the map */
0 /* Whether extensible */
};
asn_TYPE_descriptor_t asn_DEF_Choice = {
"Choice",
"Choice",
CHOICE_free,
CHOICE_print,
CHOICE_constraint,
CHOICE_decode_ber,
CHOICE_encode_der,
CHOICE_decode_xer,
CHOICE_encode_xer,
CHOICE_outmost_tag,
0, /* No effective tags (pointer) */
0, /* No effective tags (count) */
0, /* No tags (pointer) */
0, /* No tags (count) */
asn_MBR_Choice_1,
3, /* Elements count */
&asn_SPC_Choice_1_specs /* Additional specs */
};
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment