-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathasn1c_out.h
157 lines (140 loc) · 5.49 KB
/
asn1c_out.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
#ifndef ASN1_COMPILED_OUTPUT_H
#define ASN1_COMPILED_OUTPUT_H
/*
* An elementary chunk of target language text.
*/
typedef struct out_chunk {
char *buf;
int len;
TQ_ENTRY(struct out_chunk) next;
} out_chunk_t;
typedef struct compiler_streams {
enum {
OT_IGNORE, /* Ignore this output */
OT_INCLUDES, /* #include files */
OT_DEPS, /* Dependencies (other than #includes) */
OT_FWD_DECLS, /* Forward declarations */
OT_FWD_DEFS, /* Forward definitions */
OT_TYPE_DECLS, /* Type declarations */
OT_FUNC_DECLS, /* Function declarations */
OT_POST_INCLUDE,/* #include after type definition */
OT_IOC_TABLES, /* Information Object Class tables */
OT_CTABLES, /* Constraint tables */
OT_CODE, /* Some code */
OT_CTDEFS, /* Constraint definitions */
OT_STAT_DEFS, /* Static definitions */
OT_MAX
} target;
struct compiler_stream_destination_s {
TQ_HEAD(out_chunk_t) chunks;
int indent_level;
int indented;
} destination[OT_MAX];
} compiler_streams_t;
static char *_compiler_stream2str[] __attribute__ ((unused))
= { "IGNORE", "INCLUDES", "DEPS", "FWD-DECLS", "FWD-DEFS", "TYPE-DECLS", "FUNC-DECLS", "POST-INCLUDE", "IOC-TABLES", "CTABLES", "CODE", "CTDEFS", "STAT-DEFS" };
int asn1c_compiled_output(arg_t *arg, const char *file, int lineno,
const char *func, const char *fmt, ...)
__attribute__((format(printf, 5, 6)));
/*****************************************************************
* Useful macros for invoking asn1c_compiled_output() and friends.
*/
/* Redirect output to a different stream. */
#define REDIR(foo) do { arg->target->target = foo; } while(0)
#define INDENT_LEVEL \
arg->target->destination[arg->target->target].indent_level
#define INDENT(val) INDENT_LEVEL += (val)
#define INDENTED(code) do { \
INDENT(+1); \
do { code; } while(0); \
INDENT(-1); \
} while(0)
#define EMBED(ev) \
do { \
arg->embed++; \
INDENTED(arg_t _tmp = *arg; _tmp.expr = ev; \
_tmp.default_cb(&_tmp, NULL);); \
arg->embed--; \
if(ev->expr_type != A1TC_EXTENSIBLE) OUT(";\n"); \
assert(arg->target->target == OT_TYPE_DECLS \
|| arg->target->target == OT_FWD_DEFS); \
} while(0)
#define EMBED_WITH_IOCT(ev, ioc) \
do { \
arg->embed++; \
INDENTED(arg_t _tmp = *arg; _tmp.expr = ev; \
_tmp.default_cb(&_tmp, ((ioc).ioct ? &ioc : 0));); \
arg->embed--; \
if(ev->expr_type != A1TC_EXTENSIBLE) OUT(";\n"); \
assert(arg->target->target == OT_TYPE_DECLS \
|| arg->target->target == OT_FWD_DEFS); \
} while(0)
/* Output a piece of text into a default stream */
#define OUT(fmt, args...) \
asn1c_compiled_output(arg, __FILE__, __LINE__, __func__, fmt, ##args)
#define OUT_NOINDENT(fmt, args...) do { \
int _saved_indent = INDENT_LEVEL; \
INDENT_LEVEL = 0; \
OUT(fmt, ##args); \
INDENT_LEVEL = _saved_indent; \
} while(0)
#define OUT_DEBUG(fmt, args...) do { \
if(arg->flags & A1C_DEBUG) OUT(fmt, ##args); \
} while(0)
/* Generate #include line */
#define GEN_INCLUDE_STD(typename) do { \
if((arg->flags & A1C_INCLUDES_QUOTED)) { \
GEN_INCLUDE("\"" typename ".h\""); \
} else { \
GEN_INCLUDE("<" typename ".h>"); \
} } while(0)
#define GEN_INCLUDE(filename) do { \
int saved_target = arg->target->target; \
if(!filename) break; \
REDIR(OT_INCLUDES); \
OUT_NOINDENT("#include %s\n", filename); \
REDIR(saved_target); \
} while(0)
#define GEN_POSTINCLUDE(filename) do { \
int saved_target = arg->target->target; \
if(!filename) break; \
REDIR(OT_POST_INCLUDE); \
OUT_NOINDENT("#include %s\n", filename); \
REDIR(saved_target); \
} while(0)
/* Generate ASN.1 type declaration */
#define GEN_DECLARE(type_name, expr) do { \
int saved_target = arg->target->target; \
REDIR(OT_FUNC_DECLS); \
OUT_NOINDENT("extern asn_TYPE_descriptor_t " \
"asn_DEF_%s;\n", MKID(expr)); \
if (expr->_type_referenced) { \
OUT_NOINDENT("extern asn_%s_specifics_t " \
"asn_SPC_%s_specs_%d;\n", type_name, \
MKID(expr), expr->_type_unique_index); \
if(expr_elements_count(arg, expr)) \
OUT_NOINDENT("extern asn_TYPE_member_t " \
"asn_MBR_%s_%d[%d];\n", \
MKID(expr), expr->_type_unique_index, \
expr_elements_count(arg, expr)); \
} \
REDIR(saved_target); \
} while(0)
/*
* Format LONG_MIN according to C90 rules.
*/
#define OINT(iv) \
do { \
if(iv == (-2147483647L - 1)) \
OUT("(-2147483647L - 1)"); \
else \
OUT("%s", asn1p_itoa(iv)); \
} while(0)
#define OINTS(iv) \
do { \
if(iv == (-2147483647L - 1)) \
OUT("(-2147483647L - 1)"); \
else \
OUT("%s%s", (iv >= 0) ? " " : "", asn1p_itoa(iv)); \
} while(0)
#endif /* ASN1_COMPILED_OUTPUT_H */