blob: 2f7c5732c47e74cfea9a686a180173dcf1fe95d7 [file] [log] [blame]
vlmfa67ddc2004-06-03 03:38:44 +00001#include "asn1c_internal.h"
2
3/*
4 * Add an elementary chunk of target language text
5 * into appropriate output stream.
6 */
7int
8asn1c_compiled_output(arg_t *arg, const char *fmt, ...) {
9 const char *p;
10 int lf_found;
11 va_list ap;
12 out_chunk_t *m;
13 char *buf;
14 int ret;
15
16 /*
17 * Make sure the output has a single LF and only at the end.
18 */
19 for(lf_found = 0, p = fmt; *p; p++) {
20 if(*p == '\n') {
21 lf_found++;
22 assert(p[1] == '\0');
23 }
24 }
25 assert(lf_found <= 1);
26
27 /*
28 * Print out the indentation.
29 */
30 if(arg->indented == 0) {
31 int i = arg->indent_level;
32 arg->indented = 1;
33 while(i--) {
34 ret = asn1c_compiled_output(arg, "\t");
35 if(ret == -1) return -1;
36 }
37 }
vlm33a4ff12004-08-11 05:21:32 +000038 if(lf_found)
39 arg->indented = 0;
vlmfa67ddc2004-06-03 03:38:44 +000040
41 /*
42 * Estimate necessary size.
43 */
44 buf = "";
45 va_start(ap, fmt);
46 ret = vsnprintf(buf, 0, fmt, ap);
47 va_end(ap);
48 assert(ret >= 0);
49
50 /*
51 * Allocate buffer.
52 */
53 m = calloc(1, sizeof(out_chunk_t));
54 if(m == NULL) return -1;
55 m->len = ret + 1;
56 m->buf = malloc(ret + 1);
57 if(m->buf == NULL) {
58 free(m);
59 return -1;
60 }
61
62 /*
63 * Fill the buffer.
64 */
65 va_start(ap, fmt);
66 ret = vsnprintf(m->buf, m->len, fmt, ap);
67 assert(ret < m->len);
68 m->len = ret;
69 va_end(ap);
70
vlm33a4ff12004-08-11 05:21:32 +000071 if(arg->target->target == OT_INCLUDES) {
72 out_chunk_t *v;
73 TQ_FOR(v, &(arg->target->targets[OT_INCLUDES]), next) {
74 if(m->len == v->len
75 && !memcmp(m->buf, v->buf, m->len))
76 break;
77 }
78 if(v) {
79 /* Entry is already present. Skip it. */
80 free(m->buf);
81 free(m);
82 return 0;
83 }
84 }
vlmfa67ddc2004-06-03 03:38:44 +000085
vlm33a4ff12004-08-11 05:21:32 +000086 TQ_ADD(&(arg->target->targets[arg->target->target]), m, next);
vlmfa67ddc2004-06-03 03:38:44 +000087
88 return 0;
89}