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