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 | 6439972 | 2004-08-11 07:17:22 +0000 | [diff] [blame] | 16 | OT_IGNORE = -1, |
| 17 | OT_ASSERT = 0, |
Lev Walkin | 3dcaafa | 2004-08-11 05:21:32 +0000 | [diff] [blame] | 18 | OT_INCLUDES, /* #include files */ |
| 19 | OT_DEPS, /* Dependencies (other than #includes) */ |
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 | 59004fa | 2004-08-20 13:37:01 +0000 | [diff] [blame] | 22 | OT_CTABLES, /* Constraint tables */ |
Lev Walkin | f15320b | 2004-06-03 03:38:44 +0000 | [diff] [blame] | 23 | OT_CODE, /* Some code */ |
Lev Walkin | 59004fa | 2004-08-20 13:37:01 +0000 | [diff] [blame] | 24 | OT_STAT_DEFS, /* Static definitions */ |
Lev Walkin | f15320b | 2004-06-03 03:38:44 +0000 | [diff] [blame] | 25 | OT_MAX |
| 26 | } target; |
Lev Walkin | 59004fa | 2004-08-20 13:37:01 +0000 | [diff] [blame] | 27 | |
| 28 | struct compiler_stream_destination_s { |
| 29 | TQ_HEAD(out_chunk_t) chunks; |
| 30 | int indent_level; |
| 31 | int indented; |
| 32 | } destination[OT_MAX]; |
Lev Walkin | f15320b | 2004-06-03 03:38:44 +0000 | [diff] [blame] | 33 | } compiler_streams_t; |
| 34 | |
| 35 | static char *_compiler_stream2str[] __attribute__ ((unused)) |
Lev Walkin | 59004fa | 2004-08-20 13:37:01 +0000 | [diff] [blame] | 36 | = { "ASSERT", "INCLUDES", "DEPS", "TYPE-DECLS", "FUNC-DECLS", "CTABLES", "CODE", "STAT-DEFS" }; |
Lev Walkin | f15320b | 2004-06-03 03:38:44 +0000 | [diff] [blame] | 37 | |
| 38 | int asn1c_compiled_output(arg_t *arg, const char *fmt, ...); |
| 39 | |
Lev Walkin | 3dcaafa | 2004-08-11 05:21:32 +0000 | [diff] [blame] | 40 | |
| 41 | /***************************************************************** |
| 42 | * Useful macros for invoking asn1c_compiled_output() and friends. |
| 43 | */ |
| 44 | |
| 45 | /* Redirect output to a different stream. */ |
| 46 | #define REDIR(foo) do { arg->target->target = foo; } while(0) |
Lev Walkin | 59004fa | 2004-08-20 13:37:01 +0000 | [diff] [blame] | 47 | #define INDENT_LEVEL \ |
| 48 | arg->target->destination[arg->target->target].indent_level |
| 49 | #define INDENT(val) INDENT_LEVEL += (val) |
| 50 | #define INDENTED(code) do { \ |
| 51 | INDENT(+1); \ |
| 52 | do { code; } while(0); \ |
| 53 | INDENT(-1); \ |
Lev Walkin | 3dcaafa | 2004-08-11 05:21:32 +0000 | [diff] [blame] | 54 | } while(0) |
| 55 | |
Lev Walkin | 59004fa | 2004-08-20 13:37:01 +0000 | [diff] [blame] | 56 | #define FLAT(code) do { \ |
| 57 | int _il = INDENT_LEVEL; \ |
| 58 | INDENT_LEVEL = 0; \ |
| 59 | do { code; } while(0); \ |
| 60 | INDENT_LEVEL = _il; \ |
Lev Walkin | 3dcaafa | 2004-08-11 05:21:32 +0000 | [diff] [blame] | 61 | } while(0) |
| 62 | |
| 63 | #define EMBED(ev) do { \ |
| 64 | int saved_target = arg->target->target; \ |
| 65 | REDIR(OT_TYPE_DECLS); \ |
| 66 | arg->embed++; \ |
| 67 | INDENTED(arg_t _tmp = *arg; \ |
| 68 | _tmp.expr = ev; \ |
| 69 | _tmp.default_cb(&_tmp); \ |
| 70 | ); \ |
| 71 | arg->embed--; \ |
Lev Walkin | 6fec44d | 2004-08-22 03:10:23 +0000 | [diff] [blame] | 72 | if(ev->expr_type != A1TC_EXTENSIBLE) \ |
| 73 | OUT(";\n"); \ |
Lev Walkin | 3dcaafa | 2004-08-11 05:21:32 +0000 | [diff] [blame] | 74 | assert(arg->target->target == OT_TYPE_DECLS); \ |
| 75 | REDIR(saved_target); \ |
| 76 | } while(0) |
| 77 | |
| 78 | /* Output a piece of text into a default stream */ |
| 79 | #define OUT(fmt, args...) asn1c_compiled_output(arg, fmt, ##args) |
Lev Walkin | 59004fa | 2004-08-20 13:37:01 +0000 | [diff] [blame] | 80 | #define OUT_NOINDENT(fmt, args...) do { \ |
| 81 | int _saved_indent = INDENT_LEVEL; \ |
| 82 | INDENT_LEVEL = 0; \ |
| 83 | OUT(fmt, ##args); \ |
| 84 | INDENT_LEVEL = _saved_indent; \ |
Lev Walkin | 3dcaafa | 2004-08-11 05:21:32 +0000 | [diff] [blame] | 85 | } while(0) |
| 86 | |
| 87 | /* Generate #include line */ |
| 88 | #define GEN_INCLUDE(filename) do { \ |
| 89 | int saved_target = arg->target->target; \ |
| 90 | REDIR(OT_INCLUDES); \ |
| 91 | OUT_NOINDENT("#include <%s.h>\n", filename); \ |
| 92 | REDIR(saved_target); \ |
| 93 | } while(0) |
| 94 | |
| 95 | /* Generate ASN.1 type declaration */ |
| 96 | #define GEN_DECLARE(expr) do { \ |
| 97 | int saved_target = arg->target->target; \ |
| 98 | REDIR(OT_DEPS); \ |
| 99 | OUT_NOINDENT("extern asn1_TYPE_descriptor_t " \ |
| 100 | "asn1_DEF_%s;\n", \ |
| 101 | MKID(expr->Identifier)); \ |
| 102 | REDIR(saved_target); \ |
| 103 | } while(0) |
| 104 | |
Lev Walkin | f15320b | 2004-06-03 03:38:44 +0000 | [diff] [blame] | 105 | #endif /* _ASN1_COMPILED_OUTPUT_H_ */ |