| #include "asn1c_internal.h" |
| |
| /* |
| * Add an elementary chunk of target language text |
| * into appropriate output stream. |
| */ |
| int |
| asn1c_compiled_output(arg_t *arg, const char *fmt, ...) { |
| const char *p; |
| int lf_found; |
| va_list ap; |
| out_chunk_t *m; |
| char *buf; |
| int ret; |
| |
| /* |
| * Make sure the output has a single LF and only at the end. |
| */ |
| for(lf_found = 0, p = fmt; *p; p++) { |
| if(*p == '\n') { |
| lf_found++; |
| assert(p[1] == '\0'); |
| } |
| } |
| assert(lf_found <= 1); |
| |
| /* |
| * Print out the indentation. |
| */ |
| if(arg->indented == 0) { |
| int i = arg->indent_level; |
| arg->indented = 1; |
| while(i--) { |
| ret = asn1c_compiled_output(arg, "\t"); |
| if(ret == -1) return -1; |
| } |
| } |
| |
| /* |
| * Estimate necessary size. |
| */ |
| buf = ""; |
| va_start(ap, fmt); |
| ret = vsnprintf(buf, 0, fmt, ap); |
| va_end(ap); |
| assert(ret >= 0); |
| |
| /* |
| * Allocate buffer. |
| */ |
| m = calloc(1, sizeof(out_chunk_t)); |
| if(m == NULL) return -1; |
| m->len = ret + 1; |
| m->buf = malloc(ret + 1); |
| if(m->buf == NULL) { |
| free(m); |
| return -1; |
| } |
| |
| /* |
| * Fill the buffer. |
| */ |
| va_start(ap, fmt); |
| ret = vsnprintf(m->buf, m->len, fmt, ap); |
| assert(ret < m->len); |
| m->len = ret; |
| va_end(ap); |
| |
| TQ_ADD(&(arg->target->targets[arg->target->target]), m, next); |
| |
| if(lf_found) |
| arg->indented = 0; |
| |
| return 0; |
| } |