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_TYPE_DECLS, /* Type declarations */ 21 OT_FUNC_DECLS, /* Function declarations */ 22 OT_POST_INCLUDE,/* #include after type definition */ 23 OT_CTABLES, /* Constraint tables */ 24 OT_CODE, /* Some code */ 25 OT_CTDEFS, /* Constraint definitions */ 26 OT_STAT_DEFS, /* Static definitions */ 27 OT_MAX 28 } target; 29 30 struct compiler_stream_destination_s { 31 TQ_HEAD(out_chunk_t) chunks; 32 int indent_level; 33 int indented; 34 } destination[OT_MAX]; 35 } compiler_streams_t; 36 37 static char *_compiler_stream2str[] __attribute__ ((unused)) 38 = { "IGNORE", "INCLUDES", "DEPS", "FWD-DECLS", "TYPE-DECLS", "FUNC-DECLS", "POST-INCLUDE", "CTABLES", "CODE", "CTDEFS", "STAT-DEFS" }; 39 40 int asn1c_compiled_output(arg_t *arg, const char *fmt, ...); 41 42 43 /***************************************************************** 44 * Useful macros for invoking asn1c_compiled_output() and friends. 45 */ 46 47 /* Redirect output to a different stream. */ 48 #define REDIR(foo) do { arg->target->target = foo; } while(0) 49 #define INDENT_LEVEL \ 50 arg->target->destination[arg->target->target].indent_level 51 #define INDENT(val) INDENT_LEVEL += (val) 52 #define INDENTED(code) do { \ 53 INDENT(+1); \ 54 do { code; } while(0); \ 55 INDENT(-1); \ 56 } while(0) 57 58 #define EMBED(ev) do { \ 59 int saved_target = arg->target->target; \ 60 REDIR(OT_TYPE_DECLS); \ 61 arg->embed++; \ 62 INDENTED(arg_t _tmp = *arg; \ 63 _tmp.expr = ev; \ 64 _tmp.default_cb(&_tmp); \ 65 ); \ 66 arg->embed--; \ 67 if(ev->expr_type != A1TC_EXTENSIBLE) \ 68 OUT(";\n"); \ 69 assert(arg->target->target == OT_TYPE_DECLS); \ 70 REDIR(saved_target); \ 71 } while(0) 72 73 /* Output a piece of text into a default stream */ 74 #define OUT(fmt, args...) asn1c_compiled_output(arg, fmt, ##args) 75 #define OUT_NOINDENT(fmt, args...) do { \ 76 int _saved_indent = INDENT_LEVEL; \ 77 INDENT_LEVEL = 0; \ 78 OUT(fmt, ##args); \ 79 INDENT_LEVEL = _saved_indent; \ 80 } while(0) 81 #define OUT_DEBUG(fmt, args...) do { \ 82 if(arg->flags & A1C_DEBUG) OUT(fmt, ##args); \ 83 } while(0) 84 85 /* Generate #include line */ 86 #define GEN_INCLUDE_STD(typename) do { \ 87 if((arg->flags & A1C_INCLUDES_QUOTED)) { \ 88 GEN_INCLUDE("\"" typename ".h\""); \ 89 } else { \ 90 GEN_INCLUDE("<" typename ".h>"); \ 91 } } while(0) 92 #define GEN_INCLUDE(filename) do { \ 93 int saved_target = arg->target->target; \ 94 if(!filename) break; \ 95 REDIR(OT_INCLUDES); \ 96 OUT_NOINDENT("#include %s\n", filename); \ 97 REDIR(saved_target); \ 98 } while(0) 99 #define GEN_POSTINCLUDE(filename) do { \ 100 int saved_target = arg->target->target; \ 101 if(!filename) break; \ 102 REDIR(OT_POST_INCLUDE); \ 103 OUT_NOINDENT("#include %s\n", filename); \ 104 REDIR(saved_target); \ 105 } while(0) 106 107 /* Generate ASN.1 type declaration */ 108 #define GEN_DECLARE(expr) do { \ 109 int saved_target = arg->target->target; \ 110 REDIR(OT_FUNC_DECLS); \ 111 OUT_NOINDENT("extern asn_TYPE_descriptor_t " \ 112 "asn_DEF_%s;\n", MKID(expr)); \ 113 REDIR(saved_target); \ 114 } while(0) 115 116 /* 117 * Format LONG_MIN according to C90 rules. 118 */ 119 #define OINT(iv) do { \ 120 if(iv == (-2147483647L - 1)) \ 121 OUT("(-2147483647L - 1)"); \ 122 else \ 123 OUT("%" PRIdASN, iv); \ 124 } while(0) 125 126 #define OINTS(iv) do { \ 127 if(iv == (-2147483647L - 1)) \ 128 OUT("(-2147483647L - 1)"); \ 129 else \ 130 OUT("% " PRIdASN, iv); \ 131 } while(0) 132 133 #endif /* _ASN1_COMPILED_OUTPUT_H_ */ 134