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