Lev Walkin | f15320b | 2004-06-03 03:38:44 +0000 | [diff] [blame] | 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 { |
Lev Walkin | 61c7069 | 2004-09-08 00:28:47 +0000 | [diff] [blame] | 16 | OT_IGNORE, /* Ignore this output */ |
Lev Walkin | 3dcaafa | 2004-08-11 05:21:32 +0000 | [diff] [blame] | 17 | OT_INCLUDES, /* #include files */ |
| 18 | OT_DEPS, /* Dependencies (other than #includes) */ |
Lev Walkin | c828571 | 2005-03-04 22:18:20 +0000 | [diff] [blame] | 19 | OT_FWD_DECLS, /* Forward declarations */ |
Lev Walkin | f15320b | 2004-06-03 03:38:44 +0000 | [diff] [blame] | 20 | OT_TYPE_DECLS, /* Type declarations */ |
| 21 | OT_FUNC_DECLS, /* Function declarations */ |
Lev Walkin | c828571 | 2005-03-04 22:18:20 +0000 | [diff] [blame] | 22 | OT_POST_INCLUDE,/* #include after type definition */ |
Lev Walkin | 59004fa | 2004-08-20 13:37:01 +0000 | [diff] [blame] | 23 | OT_CTABLES, /* Constraint tables */ |
Lev Walkin | f15320b | 2004-06-03 03:38:44 +0000 | [diff] [blame] | 24 | OT_CODE, /* Some code */ |
Lev Walkin | 725883b | 2006-10-09 12:07:58 +0000 | [diff] [blame] | 25 | OT_CTDEFS, /* Constraint definitions */ |
Lev Walkin | 59004fa | 2004-08-20 13:37:01 +0000 | [diff] [blame] | 26 | OT_STAT_DEFS, /* Static definitions */ |
Lev Walkin | f15320b | 2004-06-03 03:38:44 +0000 | [diff] [blame] | 27 | OT_MAX |
| 28 | } target; |
Lev Walkin | 59004fa | 2004-08-20 13:37:01 +0000 | [diff] [blame] | 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]; |
Lev Walkin | f15320b | 2004-06-03 03:38:44 +0000 | [diff] [blame] | 35 | } compiler_streams_t; |
| 36 | |
| 37 | static char *_compiler_stream2str[] __attribute__ ((unused)) |
Lev Walkin | 725883b | 2006-10-09 12:07:58 +0000 | [diff] [blame] | 38 | = { "IGNORE", "INCLUDES", "DEPS", "FWD-DECLS", "TYPE-DECLS", "FUNC-DECLS", "POST-INCLUDE", "CTABLES", "CODE", "CTDEFS", "STAT-DEFS" }; |
Lev Walkin | f15320b | 2004-06-03 03:38:44 +0000 | [diff] [blame] | 39 | |
| 40 | int asn1c_compiled_output(arg_t *arg, const char *fmt, ...); |
| 41 | |
Lev Walkin | 3dcaafa | 2004-08-11 05:21:32 +0000 | [diff] [blame] | 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) |
Lev Walkin | 59004fa | 2004-08-20 13:37:01 +0000 | [diff] [blame] | 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); \ |
Lev Walkin | 3dcaafa | 2004-08-11 05:21:32 +0000 | [diff] [blame] | 56 | } while(0) |
| 57 | |
Lev Walkin | 3dcaafa | 2004-08-11 05:21:32 +0000 | [diff] [blame] | 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--; \ |
Lev Walkin | 6fec44d | 2004-08-22 03:10:23 +0000 | [diff] [blame] | 67 | if(ev->expr_type != A1TC_EXTENSIBLE) \ |
| 68 | OUT(";\n"); \ |
Lev Walkin | 3dcaafa | 2004-08-11 05:21:32 +0000 | [diff] [blame] | 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) |
Lev Walkin | 59004fa | 2004-08-20 13:37:01 +0000 | [diff] [blame] | 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; \ |
Lev Walkin | 3dcaafa | 2004-08-11 05:21:32 +0000 | [diff] [blame] | 80 | } while(0) |
Lev Walkin | e0b56e0 | 2005-02-25 12:10:27 +0000 | [diff] [blame] | 81 | #define OUT_DEBUG(fmt, args...) do { \ |
| 82 | if(arg->flags & A1C_DEBUG) OUT(fmt, ##args); \ |
| 83 | } while(0) |
Lev Walkin | 3dcaafa | 2004-08-11 05:21:32 +0000 | [diff] [blame] | 84 | |
| 85 | /* Generate #include line */ |
Lev Walkin | 22b5ed4 | 2006-09-13 02:51:20 +0000 | [diff] [blame] | 86 | #define GEN_INCLUDE_STD(typename) GEN_INCLUDE("<" typename ".h>") |
Lev Walkin | 3dcaafa | 2004-08-11 05:21:32 +0000 | [diff] [blame] | 87 | #define GEN_INCLUDE(filename) do { \ |
| 88 | int saved_target = arg->target->target; \ |
Lev Walkin | 0913f24 | 2006-03-06 00:30:30 +0000 | [diff] [blame] | 89 | if(!filename) break; \ |
Lev Walkin | 3dcaafa | 2004-08-11 05:21:32 +0000 | [diff] [blame] | 90 | REDIR(OT_INCLUDES); \ |
Lev Walkin | 22b5ed4 | 2006-09-13 02:51:20 +0000 | [diff] [blame] | 91 | OUT_NOINDENT("#include %s\n", filename); \ |
Lev Walkin | 3dcaafa | 2004-08-11 05:21:32 +0000 | [diff] [blame] | 92 | REDIR(saved_target); \ |
| 93 | } while(0) |
Lev Walkin | c828571 | 2005-03-04 22:18:20 +0000 | [diff] [blame] | 94 | #define GEN_POSTINCLUDE(filename) do { \ |
| 95 | int saved_target = arg->target->target; \ |
Lev Walkin | 0913f24 | 2006-03-06 00:30:30 +0000 | [diff] [blame] | 96 | if(!filename) break; \ |
Lev Walkin | c828571 | 2005-03-04 22:18:20 +0000 | [diff] [blame] | 97 | REDIR(OT_POST_INCLUDE); \ |
Lev Walkin | 22b5ed4 | 2006-09-13 02:51:20 +0000 | [diff] [blame] | 98 | OUT_NOINDENT("#include %s\n", filename); \ |
Lev Walkin | c828571 | 2005-03-04 22:18:20 +0000 | [diff] [blame] | 99 | REDIR(saved_target); \ |
| 100 | } while(0) |
Lev Walkin | 3dcaafa | 2004-08-11 05:21:32 +0000 | [diff] [blame] | 101 | |
| 102 | /* Generate ASN.1 type declaration */ |
| 103 | #define GEN_DECLARE(expr) do { \ |
| 104 | int saved_target = arg->target->target; \ |
Lev Walkin | c828571 | 2005-03-04 22:18:20 +0000 | [diff] [blame] | 105 | REDIR(OT_FUNC_DECLS); \ |
Lev Walkin | 05363a7 | 2004-09-29 13:16:40 +0000 | [diff] [blame] | 106 | OUT_NOINDENT("extern asn_TYPE_descriptor_t " \ |
Lev Walkin | a00d6b3 | 2006-03-21 03:40:38 +0000 | [diff] [blame] | 107 | "asn_DEF_%s;\n", MKID(expr)); \ |
Lev Walkin | 3dcaafa | 2004-08-11 05:21:32 +0000 | [diff] [blame] | 108 | REDIR(saved_target); \ |
| 109 | } while(0) |
| 110 | |
Lev Walkin | f15320b | 2004-06-03 03:38:44 +0000 | [diff] [blame] | 111 | #endif /* _ASN1_COMPILED_OUTPUT_H_ */ |