blob: 0e5b0fbc5e2eafd84ca107d7fb001d200db27647 [file] [log] [blame]
vlmfa67ddc2004-06-03 03:38:44 +00001#include "asn1c_internal.h"
2
3static int asn1c_dump_streams(arg_t *arg);
4static int asn1c_print_streams(arg_t *arg);
5static int asn1c_save_streams(arg_t *arg);
6static int asn1c_copy_over(arg_t *arg, char *path);
7
8int
9asn1c_save_compiled_output(arg_t *arg, const char *datadir) {
10
11 (void)datadir;
12
13 TQ_FOR(arg->mod, &(arg->asn->modules), mod_next) {
14 TQ_FOR(arg->expr, &(arg->mod->members), next) {
15 if(asn1_lang_map[arg->expr->meta_type]
16 [arg->expr->expr_type].type_cb) {
17 if(asn1c_dump_streams(arg))
18 return -1;
19 }
20 }
21 }
22
23 /*
24 * Dump out the Makefile template and the rest of the support code.
25 */
26 if((arg->flags & A1C_PRINT_COMPILED) == 0
27 && (arg->flags & A1C_OMIT_SUPPORT_CODE) == 0) {
28 glob_t pg;
29 FILE *mkf;
30 char *p;
31 int i;
32
33 i = strlen(datadir) + sizeof("/*.[ch]");
34 p = alloca(i);
35 snprintf(p, i, "%s/*.[ch]", datadir);
36
37 memset(&pg, 0, sizeof(pg));
38 if(glob(p, GLOB_ERR
39#ifdef GLOB_TILDE
40 | GLOB_TILDE
41#endif /* GLOB_TILDE */
42 , NULL, &pg)) {
43 fprintf(stderr,
44 "Bad skeletons directory (-S) %s: %s\n",
45 datadir, strerror(errno));
46 return -1;
47 }
48
49 mkf = asn1c_open_file(arg, "Makefile.am", ".sample");
50 if(mkf == NULL) {
51 globfree(&pg);
52 perror("Makefile.am.sample");
53 return -1;
54 }
55
56 fprintf(mkf, "ASN_SRCS=");
57 TQ_FOR(arg->mod, &(arg->asn->modules), mod_next) {
58 TQ_FOR(arg->expr, &(arg->mod->members), next) {
59 if(asn1_lang_map[arg->expr->meta_type]
60 [arg->expr->expr_type].type_cb) {
61 fprintf(mkf, "\t\\\n\t%s.c %s.h",
62 arg->expr->Identifier,
63 arg->expr->Identifier);
64 }
65 }
66 }
67
68 for(i = 0; i < pg.gl_pathc; i++) {
69 if(asn1c_copy_over(arg, pg.gl_pathv[i])) {
70 fprintf(mkf, ">>>ABORTED<<<");
71 fclose(mkf);
72 globfree(&pg);
73 return -1;
74 } else {
75 fprintf(mkf, "\t\\\n\t%s",
76 basename(pg.gl_pathv[i]));
77 }
78 }
79
80 fprintf(mkf, "\n\n");
81 fprintf(mkf, "lib_LTLIBRARIES=libsomething.la\n");
82 fprintf(mkf, "libsomething_la_SOURCES=${ASN_SRCS}\n");
83 fclose(mkf);
84 fprintf(stderr, "Generated Makefile.am.sample\n");
85 globfree(&pg);
86 }
87
88 return 0;
89}
90
91/*
92 * Dump the streams.
93 */
94static int
95asn1c_dump_streams(arg_t *arg) {
96 if(arg->flags & A1C_PRINT_COMPILED) {
97 return asn1c_print_streams(arg);
98 } else {
99 return asn1c_save_streams(arg);
100 }
101}
102
103static int
104asn1c_print_streams(arg_t *arg) {
105 compiler_streams_t *cs = arg->expr->data;
106 asn1p_expr_t *expr = arg->expr;
107 int i;
108
109 for(i = 0; i < OT_MAX; i++) {
110 out_chunk_t *ot;
111 if(TQ_FIRST(&cs->targets[i]) == NULL)
112 continue;
113
114 printf("\n/*** <<< %s [%s] >>> ***/\n\n",
115 _compiler_stream2str[i],
116 expr->Identifier);
117
118 TQ_FOR(ot, &(cs->targets[i]), next) {
119 fwrite(ot->buf, ot->len, 1, stdout);
120 }
121 }
122
123 return 0;
124}
125
126static int
127asn1c_save_streams(arg_t *arg) {
128 asn1p_expr_t *expr = arg->expr;
129 compiler_streams_t *cs = expr->data;
130 out_chunk_t *ot;
131 FILE *fp_c, *fp_h;
132 char *header_id;
133
134 if(cs == NULL) {
135 fprintf(stderr, "Cannot compile %s at line %d\n",
136 expr->Identifier, expr->_lineno);
137 return -1;
138 }
139
140 fp_c = asn1c_open_file(arg, expr->Identifier, ".c");
141 fp_h = asn1c_open_file(arg, expr->Identifier, ".h");
142 if(fp_c == NULL || fp_h == NULL) {
143 if(fp_c) fclose(fp_c); /* lacks unlink() */
144 if(fp_h) fclose(fp_h); /* lacks unlink() */
145 return -1;
146 }
147
148 header_id = alloca(strlen(expr->Identifier) + 1);
149 if(1) {
150 char *src, *dst;
151 for(src = expr->Identifier, dst = header_id;
152 (*dst=*src); src++, dst++)
153 if(!isalnum(*src)) *dst = '_';
154 *dst = '\0';
155 }
156
157 fprintf(fp_h,
158 "#ifndef\t_%s_H_\n"
159 "#define\t_%s_H_\n"
160 "\n", header_id, header_id);
161
162 fprintf(fp_h, "#include <constr_TYPE.h>\n\n");
163
164 TQ_FOR(ot, &(cs->targets[OT_DEPS]), next)
165 fwrite(ot->buf, ot->len, 1, fp_h);
166 fprintf(fp_h, "\n");
167 TQ_FOR(ot, &(cs->targets[OT_TYPE_DECLS]), next)
168 fwrite(ot->buf, ot->len, 1, fp_h);
169 fprintf(fp_h, "\n");
170 TQ_FOR(ot, &(cs->targets[OT_FUNC_DECLS]), next)
171 fwrite(ot->buf, ot->len, 1, fp_h);
172
173 fprintf(fp_c, "#include <%s.h>\n\n", expr->Identifier);
174 TQ_FOR(ot, &(cs->targets[OT_STAT_DEFS]), next)
175 fwrite(ot->buf, ot->len, 1, fp_c);
176 TQ_FOR(ot, &(cs->targets[OT_CODE]), next)
177 fwrite(ot->buf, ot->len, 1, fp_c);
178
179 assert(OT_MAX == 5);
180
181 fprintf(fp_h, "\n#endif\t/* _%s_H_ */\n", header_id);
182
183 fclose(fp_c);
184 fclose(fp_h);
185 fprintf(stderr, "Compiled %s.c\n", expr->Identifier);
186 fprintf(stderr, "Compiled %s.h\n", expr->Identifier);
187 return 0;
188}
189
190static int
191asn1c_copy_over(arg_t *arg, char *path) {
192 char *fname = basename(path);
193
194 if(symlink(path, fname)) {
195 if(errno == EEXIST) {
196 struct stat sb1, sb2;
197 if(stat(path, &sb1) == 0
198 && stat(fname, &sb2) == 0
199 && sb1.st_dev == sb2.st_dev
200 && sb1.st_ino == sb2.st_ino) {
201 /*
202 * Nothing to do.
203 */
204 fprintf(stderr,
205 "File %s is already here as %s\n",
206 path, fname);
207 return 0;
208 } else {
209 fprintf(stderr,
210 "Retaining local %s (%s suggested)\n",
211 fname, path);
212 return 0;
213 }
214 } else {
215 fprintf(stderr, "Symlink %s -> %s failed: %s\n",
216 path, fname, strerror(errno));
217 return -1;
218 }
219 }
220
221 fprintf(stderr, "Symlinked %s\t-> %s\n", path, fname);
222
223 return 0;
224}
225