blob: 5e425d65fa3cc2f4c8368ff6eb7c1c8e6340ff9d [file] [log] [blame]
Lev Walkinf15320b2004-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
Lev Walkinc3b8f6d2004-06-03 05:06:25 +0000148 fprintf(fp_c,
149 "/*\n"
150 " * Generated by asn1c-" VERSION " (http://lionet.info/asn1c)\n"
151 " * From ASN.1 module \"%s\" found in \"%s\"\n"
152 " */\n\n",
153 arg->mod->Identifier,
154 arg->mod->source_file_name
155 );
156 fprintf(fp_h,
157 "/*\n"
158 " * Generated by asn1c-" VERSION " (http://lionet.info/asn1c)\n"
159 " * From ASN.1 module \"%s\" found in \"%s\"\n"
160 " */\n\n",
161 arg->mod->Identifier,
162 arg->mod->source_file_name
163 );
164
Lev Walkinf15320b2004-06-03 03:38:44 +0000165 header_id = alloca(strlen(expr->Identifier) + 1);
166 if(1) {
167 char *src, *dst;
168 for(src = expr->Identifier, dst = header_id;
169 (*dst=*src); src++, dst++)
170 if(!isalnum(*src)) *dst = '_';
171 *dst = '\0';
172 }
173
174 fprintf(fp_h,
175 "#ifndef\t_%s_H_\n"
176 "#define\t_%s_H_\n"
177 "\n", header_id, header_id);
178
179 fprintf(fp_h, "#include <constr_TYPE.h>\n\n");
180
181 TQ_FOR(ot, &(cs->targets[OT_DEPS]), next)
182 fwrite(ot->buf, ot->len, 1, fp_h);
183 fprintf(fp_h, "\n");
184 TQ_FOR(ot, &(cs->targets[OT_TYPE_DECLS]), next)
185 fwrite(ot->buf, ot->len, 1, fp_h);
186 fprintf(fp_h, "\n");
187 TQ_FOR(ot, &(cs->targets[OT_FUNC_DECLS]), next)
188 fwrite(ot->buf, ot->len, 1, fp_h);
189
190 fprintf(fp_c, "#include <%s.h>\n\n", expr->Identifier);
191 TQ_FOR(ot, &(cs->targets[OT_STAT_DEFS]), next)
192 fwrite(ot->buf, ot->len, 1, fp_c);
193 TQ_FOR(ot, &(cs->targets[OT_CODE]), next)
194 fwrite(ot->buf, ot->len, 1, fp_c);
195
196 assert(OT_MAX == 5);
197
198 fprintf(fp_h, "\n#endif\t/* _%s_H_ */\n", header_id);
199
200 fclose(fp_c);
201 fclose(fp_h);
202 fprintf(stderr, "Compiled %s.c\n", expr->Identifier);
203 fprintf(stderr, "Compiled %s.h\n", expr->Identifier);
204 return 0;
205}
206
207static int
208asn1c_copy_over(arg_t *arg, char *path) {
209 char *fname = basename(path);
210
Lev Walkind9bd7752004-06-05 08:17:50 +0000211 (void)arg; /* Unused argument */
212
Lev Walkinf15320b2004-06-03 03:38:44 +0000213 if(symlink(path, fname)) {
214 if(errno == EEXIST) {
215 struct stat sb1, sb2;
216 if(stat(path, &sb1) == 0
217 && stat(fname, &sb2) == 0
218 && sb1.st_dev == sb2.st_dev
219 && sb1.st_ino == sb2.st_ino) {
220 /*
221 * Nothing to do.
222 */
223 fprintf(stderr,
224 "File %s is already here as %s\n",
225 path, fname);
226 return 0;
227 } else {
228 fprintf(stderr,
229 "Retaining local %s (%s suggested)\n",
230 fname, path);
231 return 0;
232 }
233 } else {
234 fprintf(stderr, "Symlink %s -> %s failed: %s\n",
235 path, fname, strerror(errno));
236 return -1;
237 }
238 }
239
240 fprintf(stderr, "Symlinked %s\t-> %s\n", path, fname);
241
242 return 0;
243}
244