1 /***************************************************************************
2 begin : Mon Mar 01 2004
3 copyright : (C) 2004-2010 by Martin Preuss
4 email : martin@libchipcard.de
5
6 ***************************************************************************
7 * Please see toplevel file COPYING for license details *
8 ***************************************************************************/
9
10 #ifdef HAVE_CONFIG_H
11 # include <config.h>
12 #endif
13
14
15
16 #include "args.h"
17 #include "typemaker_p.h"
18 #include <gwenhywfar/debug.h>
19 #include <gwenhywfar/logger.h>
20 #include <gwenhywfar/xml.h>
21 #include <gwenhywfar/syncio_file.h>
22
23 #include <stdlib.h>
24 #include <assert.h>
25
26 #include <sys/types.h>
27 #include <sys/stat.h>
28 #include <fcntl.h>
29 #include <errno.h>
30 #include <string.h>
31 #include <ctype.h>
32
33
34
35
write_hl_file_c(ARGUMENTS * args,GWEN_XMLNODE * node)36 int write_hl_file_c(ARGUMENTS *args, GWEN_XMLNODE *node)
37 {
38 int rv;
39 const char *f;
40 GWEN_BUFFER *fname;
41 GWEN_BUFFER *hbuf;
42 const char *s;
43 const char *nacc;
44 const char *constAcc;
45 const char *constName;
46 const char *fromDbAcc;
47 const char *fromDbName;
48 const char *dupAcc;
49 const char *dupName;
50 GWEN_SYNCIO *sio;
51 int err;
52 GWEN_XMLNODE *n;
53 const char *id;
54 const char *prefix;
55
56 id=get_struct_property(node, "id", 0);
57 if (!id) {
58 DBG_ERROR(0, "No id for struct");
59 return -1;
60 }
61
62 prefix=get_struct_property(node, "prefix", 0);
63 if (!prefix) {
64 DBG_ERROR(0, "No prefix for struct");
65 return -1;
66 }
67
68 f=get_struct_property(node, "filename", 0);
69 if (!f) {
70 DBG_ERROR(0, "No filename given");
71 return -1;
72 }
73
74 nacc=get_struct_property(node, "access", "public");
75 constAcc=get_struct_property(node, "constructor-access", nacc);
76 constName=get_struct_property(node, "constructor-name", 0);
77 fromDbAcc=get_struct_property(node, "fromdb-access", nacc);
78 fromDbName=get_struct_property(node, "fromdb-name", 0);
79 dupAcc=get_struct_property(node, "dup-access", nacc);
80 dupName=get_struct_property(node, "fromdb-name", 0);
81
82 fname=GWEN_Buffer_new(0, 256, 0, 1);
83 GWEN_Buffer_AppendString(fname, f);
84 GWEN_Buffer_AppendString(fname, "_l.h");
85
86 sio=GWEN_SyncIo_File_new(GWEN_Buffer_GetStart(fname),
87 GWEN_SyncIo_File_CreationMode_CreateAlways);
88 GWEN_SyncIo_AddFlags(sio,
89 GWEN_SYNCIO_FILE_FLAGS_READ |
90 GWEN_SYNCIO_FILE_FLAGS_WRITE |
91 GWEN_SYNCIO_FILE_FLAGS_UREAD |
92 GWEN_SYNCIO_FILE_FLAGS_UWRITE |
93 GWEN_SYNCIO_FILE_FLAGS_GREAD |
94 GWEN_SYNCIO_FILE_FLAGS_GWRITE);
95 rv=GWEN_SyncIo_Connect(sio);
96 if (rv<0) {
97 DBG_ERROR(0, "open(%s): %s",
98 GWEN_Buffer_GetStart(fname),
99 strerror(errno));
100 GWEN_Buffer_free(fname);
101 GWEN_SyncIo_free(sio);
102 return -1;
103 }
104 GWEN_Buffer_free(fname);
105
106 /* Insert the auto-generation warning */
107 GWEN_SyncIo_WriteString(sio, "/* This file is auto-generated from \"");
108 GWEN_SyncIo_WriteString(sio, f);
109 GWEN_SyncIo_WriteLine(sio, ".xml\" by the typemaker");
110 GWEN_SyncIo_WriteLine(sio, " tool of Gwenhywfar. ");
111 GWEN_SyncIo_WriteLine(sio, " Do not edit this file -- all changes will be lost! */");
112
113 hbuf=GWEN_Buffer_new(0, 256, 0, 1);
114 s=f;
115 while (*s) {
116 GWEN_Buffer_AppendByte(hbuf, toupper(*s));
117 s++;
118 }
119 GWEN_Buffer_AppendString(hbuf, "_L_H");
120
121 GWEN_SyncIo_WriteString(sio, "#ifndef ");
122 GWEN_SyncIo_WriteLine(sio, GWEN_Buffer_GetStart(hbuf));
123 GWEN_SyncIo_WriteString(sio, "#define ");
124 GWEN_SyncIo_WriteLine(sio, GWEN_Buffer_GetStart(hbuf));
125 GWEN_SyncIo_WriteLine(sio, "");
126
127
128 rv=write_apidoc_c(args, node, sio, "lib");
129 if (rv)
130 return rv;
131
132 if (strcasecmp(nacc, "lib")==0) {
133 GWEN_SyncIo_WriteLine(sio, "#ifdef __cplusplus");
134 GWEN_SyncIo_WriteLine(sio, "extern \"C\" {");
135 GWEN_SyncIo_WriteLine(sio, "#endif");
136 GWEN_SyncIo_WriteLine(sio, "");
137 GWEN_SyncIo_WriteString(sio, "typedef struct ");
138 GWEN_SyncIo_WriteString(sio, id);
139 GWEN_SyncIo_WriteString(sio, " ");
140 GWEN_SyncIo_WriteString(sio, id);
141 GWEN_SyncIo_WriteLine(sio, ";");
142 GWEN_SyncIo_WriteLine(sio, "");
143 GWEN_SyncIo_WriteLine(sio, "#ifdef __cplusplus");
144 GWEN_SyncIo_WriteLine(sio, "} /* __cplusplus */");
145 GWEN_SyncIo_WriteLine(sio, "#endif");
146 GWEN_SyncIo_WriteLine(sio, "");
147
148 }
149
150
151 if (strcasecmp(get_struct_property(node, "inherit", ""),
152 "lib")==0) {
153 GWEN_SyncIo_WriteLine(sio, "#include <gwenhywfar/inherit.h>");
154 }
155
156 if (strcasecmp(get_struct_property(node, "list", ""),
157 "lib")==0) {
158 GWEN_SyncIo_WriteLine(sio, "#include <gwenhywfar/misc.h>");
159 }
160
161 if (strcasecmp(get_struct_property(node, "list2", ""),
162 "lib")==0) {
163 GWEN_SyncIo_WriteLine(sio, "#include <gwenhywfar/list2.h>");
164 }
165
166 if (strcasecmp(nacc, "public")==0) {
167 fname=GWEN_Buffer_new(0, 256, 0, 1);
168 GWEN_Buffer_AppendString(fname, f);
169 GWEN_Buffer_AppendString(fname, ".h");
170 GWEN_SyncIo_WriteString(sio, "#include \"");
171 GWEN_SyncIo_WriteString(sio, GWEN_Buffer_GetStart(fname));
172 GWEN_SyncIo_WriteLine(sio, "\"");
173 GWEN_Buffer_free(fname);
174 }
175
176 if (strcasecmp(get_struct_property(node, "list", ""),
177 "lib")==0) {
178 GWEN_SyncIo_WriteLine(sio, "#include <gwenhywfar/misc.h>");
179 }
180
181
182 if (strcasecmp(nacc, "lib")==0) {
183 GWEN_SyncIo_WriteLine(sio, "#include <gwenhywfar/db.h>");
184
185 n=GWEN_XMLNode_FindFirstTag(node, "pre-headers", 0, 0);
186 if (n) {
187 GWEN_XMLNODE *nn;
188
189 nn=GWEN_XMLNode_GetFirstTag(n);
190 while (nn) {
191 rv=write_hp_group_c(args, nn, sio);
192 if (rv) {
193 GWEN_Buffer_free(hbuf);
194 return -1;
195 }
196 nn=GWEN_XMLNode_GetNextTag(nn);
197 } /* while */
198 }
199
200 n=GWEN_XMLNode_FindFirstTag(node, "headers", 0, 0);
201 if (n) {
202 GWEN_XMLNODE *nn;
203
204 nn=GWEN_XMLNode_GetFirstTag(n);
205 while (nn) {
206 rv=write_hp_group_c(args, nn, sio);
207 if (rv) {
208 GWEN_Buffer_free(hbuf);
209 return -1;
210 }
211 nn=GWEN_XMLNode_GetNextTag(nn);
212 } /* while */
213 }
214
215 n=GWEN_XMLNode_FindFirstTag(node, "post-headers", 0, 0);
216 if (n) {
217 GWEN_XMLNODE *nn;
218
219 nn=GWEN_XMLNode_GetFirstTag(n);
220 while (nn) {
221 rv=write_hp_group_c(args, nn, sio);
222 if (rv) {
223 GWEN_Buffer_free(hbuf);
224 return -1;
225 }
226 nn=GWEN_XMLNode_GetNextTag(nn);
227 } /* while */
228 }
229
230 }
231 GWEN_SyncIo_WriteLine(sio, "");
232 GWEN_SyncIo_WriteLine(sio, "#ifdef __cplusplus");
233 GWEN_SyncIo_WriteLine(sio, "extern \"C\" {");
234 GWEN_SyncIo_WriteLine(sio, "#endif");
235 GWEN_SyncIo_WriteLine(sio, "");
236
237 if (write_h_enums(args, node, sio, "lib")) {
238 DBG_ERROR(0, "Error writing enum types");
239 return -1;
240 }
241
242 if (write_h_funcs(args, node, sio, "lib")) {
243 DBG_ERROR(0, "Error writing function types");
244 return -1;
245 }
246
247 if (strcasecmp(get_struct_property(node, "inherit", ""),
248 "lib")==0) {
249 GWEN_SyncIo_WriteString(sio, "GWEN_INHERIT_FUNCTION_DEFS(");
250 GWEN_SyncIo_WriteString(sio, id);
251 GWEN_SyncIo_WriteLine(sio, ")");
252 }
253
254 if (strcasecmp(get_struct_property(node, "list", ""),
255 "lib")==0) {
256 GWEN_SyncIo_WriteString(sio, "GWEN_LIST_FUNCTION_DEFS(");
257 GWEN_SyncIo_WriteString(sio, id);
258 GWEN_SyncIo_WriteString(sio, ", ");
259 GWEN_SyncIo_WriteString(sio, prefix);
260 GWEN_SyncIo_WriteLine(sio, ")");
261
262 if (dupAcc && strcasecmp(dupAcc, "none")!=0) {
263 GWEN_SyncIo_WriteString(sio, id);
264 GWEN_SyncIo_WriteString(sio, "_LIST *");
265 GWEN_SyncIo_WriteString(sio, prefix);
266 GWEN_SyncIo_WriteString(sio, "_List_dup(const ");
267 GWEN_SyncIo_WriteString(sio, id);
268 GWEN_SyncIo_WriteLine(sio, "_LIST *stl);");
269 GWEN_SyncIo_WriteLine(sio, "");
270 }
271 }
272
273 if (strcasecmp(get_struct_property(node, "list2", ""),
274 "lib")==0) {
275 GWEN_SyncIo_WriteString(sio, "GWEN_LIST2_FUNCTION_DEFS(");
276 GWEN_SyncIo_WriteString(sio, id);
277 GWEN_SyncIo_WriteString(sio, ", ");
278 GWEN_SyncIo_WriteString(sio, prefix);
279 GWEN_SyncIo_WriteLine(sio, ")");
280
281 GWEN_SyncIo_WriteLine(sio, "");
282 GWEN_SyncIo_WriteString(sio, "void ");
283 GWEN_SyncIo_WriteString(sio, prefix);
284 GWEN_SyncIo_WriteString(sio, "_List2_freeAll(");
285 GWEN_SyncIo_WriteString(sio, id);
286 GWEN_SyncIo_WriteLine(sio, "_LIST2 *stl);");
287
288 GWEN_SyncIo_WriteLine(sio, "");
289 }
290
291 if (strcasecmp(constAcc, "lib")==0) {
292 GWEN_SyncIo_WriteString(sio, id);
293 GWEN_SyncIo_WriteString(sio, " *");
294 GWEN_SyncIo_WriteString(sio, prefix);
295 if (constName)
296 GWEN_SyncIo_WriteString(sio, constName);
297 else
298 GWEN_SyncIo_WriteString(sio, "_new");
299 GWEN_SyncIo_WriteLine(sio, "(void);");
300 }
301
302 /* FromDb */
303 if (strcasecmp(fromDbAcc, "lib")==0) {
304 GWEN_SyncIo_WriteString(sio, id);
305 GWEN_SyncIo_WriteString(sio, " *");
306 GWEN_SyncIo_WriteString(sio, prefix);
307 if (fromDbName)
308 GWEN_SyncIo_WriteString(sio, fromDbName);
309 else
310 GWEN_SyncIo_WriteString(sio, "_fromDb");
311 GWEN_SyncIo_WriteLine(sio, "(GWEN_DB_NODE *db);");
312 }
313
314 /* dup */
315 if (strcasecmp(dupAcc, "lib")==0) {
316 GWEN_SyncIo_WriteString(sio, id);
317 GWEN_SyncIo_WriteString(sio, " *");
318 GWEN_SyncIo_WriteString(sio, prefix);
319 if (dupName)
320 GWEN_SyncIo_WriteString(sio, dupName);
321 else
322 GWEN_SyncIo_WriteString(sio, "_dup");
323 GWEN_SyncIo_WriteString(sio, "(const ");
324 GWEN_SyncIo_WriteString(sio, id);
325 GWEN_SyncIo_WriteLine(sio, "*st);");
326 }
327
328 if (strcasecmp(nacc, "lib")==0) {
329 GWEN_SyncIo_WriteString(sio, "void ");
330 GWEN_SyncIo_WriteString(sio, prefix);
331 GWEN_SyncIo_WriteString(sio, "_free(");
332 GWEN_SyncIo_WriteString(sio, id);
333 GWEN_SyncIo_WriteLine(sio, " *st);");
334
335 GWEN_SyncIo_WriteString(sio, "void ");
336 GWEN_SyncIo_WriteString(sio, prefix);
337 GWEN_SyncIo_WriteString(sio, "_Attach(");
338 GWEN_SyncIo_WriteString(sio, id);
339 GWEN_SyncIo_WriteLine(sio, " *st);");
340
341 /* ReadDb */
342 GWEN_SyncIo_WriteString(sio, "int ");
343 GWEN_SyncIo_WriteString(sio, prefix);
344 GWEN_SyncIo_WriteString(sio, "_ReadDb(");
345 GWEN_SyncIo_WriteString(sio, id);
346 GWEN_SyncIo_WriteLine(sio, " *st, GWEN_DB_NODE *db);");
347
348 /* ToDb */
349 GWEN_SyncIo_WriteString(sio, "int ");
350 GWEN_SyncIo_WriteString(sio, prefix);
351 GWEN_SyncIo_WriteString(sio, "_toDb(const ");
352 GWEN_SyncIo_WriteString(sio, id);
353 GWEN_SyncIo_WriteLine(sio, "*st, GWEN_DB_NODE *db);");
354
355 GWEN_SyncIo_WriteString(sio, "int ");
356 GWEN_SyncIo_WriteString(sio, prefix);
357 GWEN_SyncIo_WriteString(sio, "_IsModified(const ");
358 GWEN_SyncIo_WriteString(sio, id);
359 GWEN_SyncIo_WriteLine(sio, " *st);");
360
361 GWEN_SyncIo_WriteString(sio, "void ");
362 GWEN_SyncIo_WriteString(sio, prefix);
363 GWEN_SyncIo_WriteString(sio, "_SetModified(");
364 GWEN_SyncIo_WriteString(sio, id);
365 GWEN_SyncIo_WriteLine(sio, " *st, int i);");
366 }
367
368 rv=write_h_setget_c(args, node, sio, "lib");
369 if (rv) {
370 GWEN_Buffer_free(hbuf);
371 GWEN_SyncIo_Disconnect(sio);
372 GWEN_SyncIo_free(sio);
373 return rv;
374 }
375
376 GWEN_SyncIo_WriteLine(sio, "");
377 GWEN_SyncIo_WriteLine(sio, "#ifdef __cplusplus");
378 GWEN_SyncIo_WriteLine(sio, "} /* __cplusplus */");
379 GWEN_SyncIo_WriteLine(sio, "#endif");
380 GWEN_SyncIo_WriteLine(sio, "");
381
382 /* write trailing endif */
383 GWEN_SyncIo_WriteLine(sio, "");
384
385 GWEN_SyncIo_WriteString(sio, "#endif /* ");
386 GWEN_SyncIo_WriteString(sio, GWEN_Buffer_GetStart(hbuf));
387 GWEN_SyncIo_WriteLine(sio, " */");
388
389 err=GWEN_SyncIo_Disconnect(sio);
390 if (err) {
391 DBG_ERROR_ERR(0, err);
392 GWEN_SyncIo_free(sio);
393 GWEN_Buffer_free(hbuf);
394 return -1;
395 }
396
397 GWEN_Buffer_free(hbuf);
398 return 0;
399 }
400
401
402
write_hl_files_c(ARGUMENTS * args,GWEN_XMLNODE * node)403 int write_hl_files_c(ARGUMENTS *args, GWEN_XMLNODE *node)
404 {
405 GWEN_XMLNODE *n;
406 int rv;
407
408 n=GWEN_XMLNode_FindFirstTag(node, "type", 0, 0);
409 while (n) {
410 rv=write_hl_file_c(args, n);
411 if (rv)
412 return rv;
413 n=GWEN_XMLNode_FindNextTag(n, "type", 0, 0);
414 }
415 return 0;
416 }
417
418
419
420
421
422
423
424
425