blob: 15d1b676d5bffaed0928922954126899a071a907 [file] [log] [blame]
Lev Walkinf15320b2004-06-03 03:38:44 +00001#include "asn1c_internal.h"
Lev Walkin79f54952004-08-13 16:58:19 +00002#include "asn1c_compat.h"
Lev Walkinf15320b2004-06-03 03:38:44 +00003
4static int asn1c_dump_streams(arg_t *arg);
5static int asn1c_print_streams(arg_t *arg);
6static int asn1c_save_streams(arg_t *arg);
7static int asn1c_copy_over(arg_t *arg, char *path);
8
9int
10asn1c_save_compiled_output(arg_t *arg, const char *datadir) {
11
12 (void)datadir;
13
14 TQ_FOR(arg->mod, &(arg->asn->modules), mod_next) {
15 TQ_FOR(arg->expr, &(arg->mod->members), next) {
16 if(asn1_lang_map[arg->expr->meta_type]
17 [arg->expr->expr_type].type_cb) {
18 if(asn1c_dump_streams(arg))
19 return -1;
20 }
21 }
22 }
23
24 /*
25 * Dump out the Makefile template and the rest of the support code.
26 */
27 if((arg->flags & A1C_PRINT_COMPILED) == 0
28 && (arg->flags & A1C_OMIT_SUPPORT_CODE) == 0) {
29 glob_t pg;
30 FILE *mkf;
31 char *p;
32 int i;
33
34 i = strlen(datadir) + sizeof("/*.[ch]");
35 p = alloca(i);
36 snprintf(p, i, "%s/*.[ch]", datadir);
37
38 memset(&pg, 0, sizeof(pg));
39 if(glob(p, GLOB_ERR
40#ifdef GLOB_TILDE
41 | GLOB_TILDE
42#endif /* GLOB_TILDE */
43 , NULL, &pg)) {
44 fprintf(stderr,
45 "Bad skeletons directory (-S) %s: %s\n",
46 datadir, strerror(errno));
47 return -1;
48 }
49
50 mkf = asn1c_open_file(arg, "Makefile.am", ".sample");
51 if(mkf == NULL) {
52 globfree(&pg);
53 perror("Makefile.am.sample");
54 return -1;
55 }
56
57 fprintf(mkf, "ASN_SRCS=");
58 TQ_FOR(arg->mod, &(arg->asn->modules), mod_next) {
59 TQ_FOR(arg->expr, &(arg->mod->members), next) {
60 if(asn1_lang_map[arg->expr->meta_type]
61 [arg->expr->expr_type].type_cb) {
62 fprintf(mkf, "\t\\\n\t%s.c %s.h",
63 arg->expr->Identifier,
64 arg->expr->Identifier);
65 }
66 }
67 }
68
69 for(i = 0; i < pg.gl_pathc; i++) {
70 if(asn1c_copy_over(arg, pg.gl_pathv[i])) {
71 fprintf(mkf, ">>>ABORTED<<<");
72 fclose(mkf);
73 globfree(&pg);
74 return -1;
75 } else {
76 fprintf(mkf, "\t\\\n\t%s",
Lev Walkin79f54952004-08-13 16:58:19 +000077 a1c_basename(pg.gl_pathv[i]));
Lev Walkinf15320b2004-06-03 03:38:44 +000078 }
79 }
80
81 fprintf(mkf, "\n\n");
82 fprintf(mkf, "lib_LTLIBRARIES=libsomething.la\n");
83 fprintf(mkf, "libsomething_la_SOURCES=${ASN_SRCS}\n");
84 fclose(mkf);
85 fprintf(stderr, "Generated Makefile.am.sample\n");
86 globfree(&pg);
87 }
88
89 return 0;
90}
91
92/*
93 * Dump the streams.
94 */
95static int
96asn1c_dump_streams(arg_t *arg) {
97 if(arg->flags & A1C_PRINT_COMPILED) {
98 return asn1c_print_streams(arg);
99 } else {
100 return asn1c_save_streams(arg);
101 }
102}
103
104static int
105asn1c_print_streams(arg_t *arg) {
106 compiler_streams_t *cs = arg->expr->data;
107 asn1p_expr_t *expr = arg->expr;
108 int i;
109
Lev Walkin64399722004-08-11 07:17:22 +0000110 for(i = 1; i < OT_MAX; i++) {
Lev Walkinf15320b2004-06-03 03:38:44 +0000111 out_chunk_t *ot;
112 if(TQ_FIRST(&cs->targets[i]) == NULL)
113 continue;
114
115 printf("\n/*** <<< %s [%s] >>> ***/\n\n",
116 _compiler_stream2str[i],
117 expr->Identifier);
118
119 TQ_FOR(ot, &(cs->targets[i]), next) {
120 fwrite(ot->buf, ot->len, 1, stdout);
121 }
122 }
123
124 return 0;
125}
126
127static int
128asn1c_save_streams(arg_t *arg) {
129 asn1p_expr_t *expr = arg->expr;
130 compiler_streams_t *cs = expr->data;
131 out_chunk_t *ot;
132 FILE *fp_c, *fp_h;
133 char *header_id;
134
135 if(cs == NULL) {
136 fprintf(stderr, "Cannot compile %s at line %d\n",
137 expr->Identifier, expr->_lineno);
138 return -1;
139 }
140
141 fp_c = asn1c_open_file(arg, expr->Identifier, ".c");
142 fp_h = asn1c_open_file(arg, expr->Identifier, ".h");
143 if(fp_c == NULL || fp_h == NULL) {
144 if(fp_c) fclose(fp_c); /* lacks unlink() */
145 if(fp_h) fclose(fp_h); /* lacks unlink() */
146 return -1;
147 }
148
Lev Walkinc3b8f6d2004-06-03 05:06:25 +0000149 fprintf(fp_c,
150 "/*\n"
151 " * Generated by asn1c-" VERSION " (http://lionet.info/asn1c)\n"
152 " * From ASN.1 module \"%s\" found in \"%s\"\n"
153 " */\n\n",
154 arg->mod->Identifier,
155 arg->mod->source_file_name
156 );
157 fprintf(fp_h,
158 "/*\n"
159 " * Generated by asn1c-" VERSION " (http://lionet.info/asn1c)\n"
160 " * From ASN.1 module \"%s\" found in \"%s\"\n"
161 " */\n\n",
162 arg->mod->Identifier,
163 arg->mod->source_file_name
164 );
165
Lev Walkinf15320b2004-06-03 03:38:44 +0000166 header_id = alloca(strlen(expr->Identifier) + 1);
167 if(1) {
168 char *src, *dst;
169 for(src = expr->Identifier, dst = header_id;
170 (*dst=*src); src++, dst++)
171 if(!isalnum(*src)) *dst = '_';
172 *dst = '\0';
173 }
174
175 fprintf(fp_h,
176 "#ifndef\t_%s_H_\n"
177 "#define\t_%s_H_\n"
178 "\n", header_id, header_id);
179
Lev Walkin43634792004-08-10 01:14:29 +0000180 fprintf(fp_h, "#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n");
181
Lev Walkinf15320b2004-06-03 03:38:44 +0000182 fprintf(fp_h, "#include <constr_TYPE.h>\n\n");
183
Lev Walkin3dcaafa2004-08-11 05:21:32 +0000184 TQ_FOR(ot, &(cs->targets[OT_INCLUDES]), next)
185 fwrite(ot->buf, ot->len, 1, fp_h);
186 fprintf(fp_h, "\n");
Lev Walkinf15320b2004-06-03 03:38:44 +0000187 TQ_FOR(ot, &(cs->targets[OT_DEPS]), next)
188 fwrite(ot->buf, ot->len, 1, fp_h);
189 fprintf(fp_h, "\n");
190 TQ_FOR(ot, &(cs->targets[OT_TYPE_DECLS]), next)
191 fwrite(ot->buf, ot->len, 1, fp_h);
192 fprintf(fp_h, "\n");
193 TQ_FOR(ot, &(cs->targets[OT_FUNC_DECLS]), next)
194 fwrite(ot->buf, ot->len, 1, fp_h);
195
Lev Walkin3dcaafa2004-08-11 05:21:32 +0000196 fprintf(fp_h, "\n#ifdef __cplusplus\n}\n#endif\n\n"
197 "#endif\t/* _%s_H_ */\n",
198 header_id);
199
200 fprintf(fp_c, "#include <%s.h>\n\n", expr->Identifier); /* Myself */
Lev Walkinf15320b2004-06-03 03:38:44 +0000201 TQ_FOR(ot, &(cs->targets[OT_STAT_DEFS]), next)
202 fwrite(ot->buf, ot->len, 1, fp_c);
203 TQ_FOR(ot, &(cs->targets[OT_CODE]), next)
204 fwrite(ot->buf, ot->len, 1, fp_c);
205
Lev Walkin64399722004-08-11 07:17:22 +0000206 assert(OT_MAX == 7);
Lev Walkinf15320b2004-06-03 03:38:44 +0000207
208 fclose(fp_c);
209 fclose(fp_h);
210 fprintf(stderr, "Compiled %s.c\n", expr->Identifier);
211 fprintf(stderr, "Compiled %s.h\n", expr->Identifier);
212 return 0;
213}
214
215static int
216asn1c_copy_over(arg_t *arg, char *path) {
Lev Walkin79f54952004-08-13 16:58:19 +0000217 char *fname;
Lev Walkinf15320b2004-06-03 03:38:44 +0000218
Lev Walkind9bd7752004-06-05 08:17:50 +0000219 (void)arg; /* Unused argument */
220
Lev Walkin79f54952004-08-13 16:58:19 +0000221 fname = a1c_basename(path);
222 if(!fname || symlink(path, fname)) {
Lev Walkinf15320b2004-06-03 03:38:44 +0000223 if(errno == EEXIST) {
224 struct stat sb1, sb2;
225 if(stat(path, &sb1) == 0
226 && stat(fname, &sb2) == 0
227 && sb1.st_dev == sb2.st_dev
228 && sb1.st_ino == sb2.st_ino) {
229 /*
230 * Nothing to do.
231 */
232 fprintf(stderr,
233 "File %s is already here as %s\n",
234 path, fname);
235 return 0;
236 } else {
237 fprintf(stderr,
238 "Retaining local %s (%s suggested)\n",
239 fname, path);
240 return 0;
241 }
242 } else {
243 fprintf(stderr, "Symlink %s -> %s failed: %s\n",
244 path, fname, strerror(errno));
245 return -1;
246 }
247 }
248
249 fprintf(stderr, "Symlinked %s\t-> %s\n", path, fname);
250
251 return 0;
252}
253