1 #include "asn1c_internal.h"
2 #include "asn1c_out.h"
3 
4 /*
5  * Add an elementary chunk of target language text
6  * into appropriate output stream.
7  */
8 int
asn1c_compiled_output(arg_t * arg,const char * fmt,...)9 asn1c_compiled_output(arg_t *arg, const char *fmt, ...) {
10 	struct compiler_stream_destination_s *dst;
11 	const char *p;
12 	int lf_found;
13 	va_list ap;
14 	out_chunk_t *m;
15 	int ret;
16 
17 	switch(arg->target->target) {
18 	case OT_IGNORE:
19 		return 0;
20 	default:
21 		dst = &arg->target->destination[arg->target->target];
22 		break;
23 	}
24 
25 	/*
26 	 * Make sure the output has a single LF and only at the end.
27 	 */
28 	for(lf_found = 0, p = fmt; *p; p++) {
29 		if(*p == '\n') {
30 			lf_found++;
31 			assert(p[1] == '\0');
32 		}
33 	}
34 	assert(lf_found <= 1);
35 
36 	/*
37 	 * Print out the indentation.
38 	 */
39 	if(dst->indented == 0) {
40 		int i = dst->indent_level;
41 		dst->indented = 1;
42 		while(i--) {
43 			ret = asn1c_compiled_output(arg, "\t");
44 			if(ret == -1) return -1;
45 		}
46 	}
47 	if(lf_found)
48 		dst->indented = 0;
49 
50 	/*
51 	 * Allocate buffer.
52 	 */
53 	m = calloc(1, sizeof(out_chunk_t));
54 	if(m == NULL) return -1;
55 
56 	m->len = 16;
57 	do {
58 		void *tmp;
59 		m->len <<= 2;
60 		tmp = realloc(m->buf, m->len);
61 		if(tmp) {
62 			m->buf = (char *)tmp;
63 		} else {
64 			free(m->buf);
65 			free(m);
66 			return -1;
67 		}
68 		va_start(ap, fmt);
69 		ret = vsnprintf(m->buf, m->len, fmt, ap);
70 		va_end(ap);
71 	} while(ret >= (m->len - 1) || ret < 0);
72 
73 	m->len = ret;
74 
75 	if(arg->target->target == OT_INCLUDES
76 	|| arg->target->target == OT_FWD_DECLS
77 	|| arg->target->target == OT_POST_INCLUDE) {
78 		out_chunk_t *v;
79 		TQ_FOR(v, &dst->chunks, next) {
80 			if(m->len == v->len
81 			&& !memcmp(m->buf, v->buf, m->len))
82 				break;
83 		}
84 		if(v) {
85 			/* Entry is already present. Skip it. */
86 			free(m->buf);
87 			free(m);
88 			return 0;
89 		}
90 	}
91 
92 	TQ_ADD(&dst->chunks, m, next);
93 
94 	return 0;
95 }
96