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_ha_file_c(ARGUMENTS * args,GWEN_XMLNODE * node)36 int write_ha_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, ".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, "_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 rv=write_apidoc_c(args, node, sio, "public");
128 if (rv) {
129 DBG_INFO(0, "here (%d)", rv);
130 return rv;
131 }
132
133 if (strcasecmp(nacc, "public")==0) {
134 GWEN_SyncIo_WriteLine(sio, "#ifdef __cplusplus");
135 GWEN_SyncIo_WriteLine(sio, "extern \"C\" {");
136 GWEN_SyncIo_WriteLine(sio, "#endif");
137 GWEN_SyncIo_WriteLine(sio, "");
138 GWEN_SyncIo_WriteString(sio, "typedef struct ");
139 GWEN_SyncIo_WriteString(sio, id);
140 GWEN_SyncIo_WriteString(sio, " ");
141 GWEN_SyncIo_WriteString(sio, id);
142 GWEN_SyncIo_WriteLine(sio, ";");
143 GWEN_SyncIo_WriteLine(sio, "");
144 GWEN_SyncIo_WriteLine(sio, "#ifdef __cplusplus");
145 GWEN_SyncIo_WriteLine(sio, "} /* __cplusplus */");
146 GWEN_SyncIo_WriteLine(sio, "#endif");
147 GWEN_SyncIo_WriteLine(sio, "");
148 }
149
150 GWEN_SyncIo_WriteLine(sio, "#include <gwenhywfar/db.h>");
151
152 if (strcasecmp(get_struct_property(node, "inherit", ""),
153 "public")==0) {
154 GWEN_SyncIo_WriteLine(sio, "#include <gwenhywfar/inherit.h>");
155 }
156
157 if (strcasecmp(get_struct_property(node, "list", ""),
158 "public")==0) {
159 GWEN_SyncIo_WriteLine(sio, "#include <gwenhywfar/misc.h>");
160 }
161
162 if (strcasecmp(get_struct_property(node, "list2", ""),
163 "public")==0) {
164 GWEN_SyncIo_WriteLine(sio, "#include <gwenhywfar/list2.h>");
165 }
166
167 n=GWEN_XMLNode_FindFirstTag(node, "pre-headers", 0, 0);
168 if (n) {
169 GWEN_XMLNODE *nn;
170
171 GWEN_SyncIo_WriteLine(sio, "/* pre-headers */");
172 nn=GWEN_XMLNode_GetFirstTag(n);
173 while (nn) {
174 rv=write_hp_group_c(args, nn, sio);
175 if (rv) {
176 GWEN_Buffer_free(hbuf);
177 return -1;
178 }
179 nn=GWEN_XMLNode_GetNextTag(nn);
180 } /* while */
181 GWEN_SyncIo_WriteLine(sio, "");
182 }
183
184 n=GWEN_XMLNode_FindFirstTag(node, "headers", 0, 0);
185 if (n) {
186 GWEN_XMLNODE *nn;
187
188 GWEN_SyncIo_WriteLine(sio, "/* headers */");
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 DBG_INFO(0, "here (%d)", rv);
195 return -1;
196 }
197 nn=GWEN_XMLNode_GetNextTag(nn);
198 } /* while */
199 GWEN_SyncIo_WriteLine(sio, "");
200 }
201
202 GWEN_SyncIo_WriteLine(sio, "#ifdef __cplusplus");
203 GWEN_SyncIo_WriteLine(sio, "extern \"C\" {");
204 GWEN_SyncIo_WriteLine(sio, "#endif");
205 GWEN_SyncIo_WriteLine(sio, "");
206
207 if (write_h_enums(args, node, sio, "public")) {
208 DBG_ERROR(0, "Error writing enum types");
209 return -1;
210 }
211
212 if (write_h_funcs(args, node, sio, "public")) {
213 DBG_ERROR(0, "Error writing function types");
214 return -1;
215 }
216
217 if (strcasecmp(get_struct_property(node, "inherit", ""),
218 "public")==0) {
219 if (args->domain)
220 GWEN_SyncIo_WriteString(sio, "GWEN_INHERIT_FUNCTION_LIB_DEFS(");
221 else
222 GWEN_SyncIo_WriteString(sio, "GWEN_INHERIT_FUNCTION_DEFS(");
223 GWEN_SyncIo_WriteString(sio, id);
224 if (args->domain) {
225 GWEN_SyncIo_WriteString(sio, ", ");
226 GWEN_SyncIo_WriteString(sio, args->domain);
227 }
228 GWEN_SyncIo_WriteLine(sio, ")");
229 }
230
231 if (strcasecmp(get_struct_property(node, "list", ""),
232 "public")==0) {
233 if (args->domain)
234 GWEN_SyncIo_WriteString(sio, "GWEN_LIST_FUNCTION_LIB_DEFS(");
235 else
236 GWEN_SyncIo_WriteString(sio, "GWEN_LIST_FUNCTION_DEFS(");
237 GWEN_SyncIo_WriteString(sio, id);
238 GWEN_SyncIo_WriteString(sio, ", ");
239 GWEN_SyncIo_WriteString(sio, prefix);
240 if (args->domain) {
241 GWEN_SyncIo_WriteString(sio, ", ");
242 GWEN_SyncIo_WriteString(sio, args->domain);
243 }
244 GWEN_SyncIo_WriteLine(sio, ")");
245
246 if (dupAcc && strcasecmp(dupAcc, "none")!=0) {
247 if (args->domain) {
248 GWEN_SyncIo_WriteString(sio, args->domain);
249 GWEN_SyncIo_WriteString(sio, " ");
250 }
251 GWEN_SyncIo_WriteString(sio, id);
252 GWEN_SyncIo_WriteString(sio, "_LIST *");
253 GWEN_SyncIo_WriteString(sio, prefix);
254 GWEN_SyncIo_WriteString(sio, "_List_dup(const ");
255 GWEN_SyncIo_WriteString(sio, id);
256 GWEN_SyncIo_WriteLine(sio, "_LIST *stl);");
257 GWEN_SyncIo_WriteLine(sio, "");
258 }
259 }
260
261 if (strcasecmp(get_struct_property(node, "list2", ""),
262 "public")==0) {
263 if (args->domain)
264 GWEN_SyncIo_WriteString(sio, "GWEN_LIST2_FUNCTION_LIB_DEFS(");
265 else
266 GWEN_SyncIo_WriteString(sio, "GWEN_LIST2_FUNCTION_DEFS(");
267 GWEN_SyncIo_WriteString(sio, id);
268 GWEN_SyncIo_WriteString(sio, ", ");
269 GWEN_SyncIo_WriteString(sio, prefix);
270 if (args->domain) {
271 GWEN_SyncIo_WriteString(sio, ", ");
272 GWEN_SyncIo_WriteString(sio, args->domain);
273 }
274 GWEN_SyncIo_WriteLine(sio, ")");
275 GWEN_SyncIo_WriteLine(sio, "");
276
277 GWEN_SyncIo_WriteLine(sio,
278 "/** Destroys all objects stored in the given "
279 "LIST2 and the list itself");
280 GWEN_SyncIo_WriteLine(sio, "*/");
281 if (args->domain) {
282 GWEN_SyncIo_WriteString(sio, args->domain);
283 GWEN_SyncIo_WriteString(sio, " ");
284 }
285 GWEN_SyncIo_WriteString(sio, "void ");
286 GWEN_SyncIo_WriteString(sio, prefix);
287 GWEN_SyncIo_WriteString(sio, "_List2_freeAll(");
288 GWEN_SyncIo_WriteString(sio, id);
289 GWEN_SyncIo_WriteLine(sio, "_LIST2 *stl);");
290
291 GWEN_SyncIo_WriteLine(sio, "");
292 }
293
294 n=GWEN_XMLNode_FindFirstTag(node, "post-headers", 0, 0);
295 if (n) {
296 GWEN_XMLNODE *nn;
297
298 GWEN_SyncIo_WriteLine(sio, "/* post-headers */");
299 nn=GWEN_XMLNode_GetFirstTag(n);
300 while (nn) {
301 rv=write_hp_group_c(args, nn, sio);
302 if (rv) {
303 GWEN_Buffer_free(hbuf);
304 DBG_INFO(0, "here (%d)", rv);
305 return -1;
306 }
307 nn=GWEN_XMLNode_GetNextTag(nn);
308 } /* while */
309 GWEN_SyncIo_WriteLine(sio, "");
310 }
311
312
313 if (strcasecmp(constAcc, "public")==0) {
314 GWEN_SyncIo_WriteLine(sio,
315 "/** Creates a new object.");
316 GWEN_SyncIo_WriteLine(sio, "*/");
317 if (args->domain) {
318 GWEN_SyncIo_WriteString(sio, args->domain);
319 GWEN_SyncIo_WriteString(sio, " ");
320 }
321 GWEN_SyncIo_WriteString(sio, id);
322 GWEN_SyncIo_WriteString(sio, " *");
323 GWEN_SyncIo_WriteString(sio, prefix);
324 if (constName)
325 GWEN_SyncIo_WriteString(sio, constName);
326 else
327 GWEN_SyncIo_WriteString(sio, "_new");
328 GWEN_SyncIo_WriteLine(sio, "(void);");
329 }
330
331 /* FromDb */
332 if (strcasecmp(fromDbAcc, "public")==0) {
333 GWEN_SyncIo_WriteLine(sio,
334 "/** Creates an object from the data in the"
335 " given GWEN_DB_NODE");
336 GWEN_SyncIo_WriteLine(sio, "*/");
337 if (args->domain) {
338 GWEN_SyncIo_WriteString(sio, args->domain);
339 GWEN_SyncIo_WriteString(sio, " ");
340 }
341 GWEN_SyncIo_WriteString(sio, id);
342 GWEN_SyncIo_WriteString(sio, " *");
343 GWEN_SyncIo_WriteString(sio, prefix);
344 if (fromDbName)
345 GWEN_SyncIo_WriteString(sio, fromDbName);
346 else
347 GWEN_SyncIo_WriteString(sio, "_fromDb");
348 GWEN_SyncIo_WriteLine(sio, "(GWEN_DB_NODE *db);");
349 }
350
351 /* dup */
352 if (strcasecmp(dupAcc, "public")==0) {
353 GWEN_SyncIo_WriteLine(sio,
354 "/** Creates and returns a deep copy of the"
355 "given object.");
356 GWEN_SyncIo_WriteLine(sio, "*/");
357 if (args->domain) {
358 GWEN_SyncIo_WriteString(sio, args->domain);
359 GWEN_SyncIo_WriteString(sio, " ");
360 }
361 GWEN_SyncIo_WriteString(sio, id);
362 GWEN_SyncIo_WriteString(sio, " *");
363 GWEN_SyncIo_WriteString(sio, prefix);
364 if (dupName)
365 GWEN_SyncIo_WriteString(sio, dupName);
366 else
367 GWEN_SyncIo_WriteString(sio, "_dup");
368 GWEN_SyncIo_WriteString(sio, "(const ");
369 GWEN_SyncIo_WriteString(sio, id);
370 GWEN_SyncIo_WriteLine(sio, "*st);");
371 }
372
373 if (strcasecmp(nacc, "public")==0) {
374 GWEN_SyncIo_WriteLine(sio,
375 "/** Destroys the given object.");
376 GWEN_SyncIo_WriteLine(sio, "*/");
377 if (args->domain) {
378 GWEN_SyncIo_WriteString(sio, args->domain);
379 GWEN_SyncIo_WriteString(sio, " ");
380 }
381 GWEN_SyncIo_WriteString(sio, "void ");
382 GWEN_SyncIo_WriteString(sio, prefix);
383 GWEN_SyncIo_WriteString(sio, "_free(");
384 GWEN_SyncIo_WriteString(sio, id);
385 GWEN_SyncIo_WriteLine(sio, " *st);");
386
387 GWEN_SyncIo_WriteLine(sio,
388 "/** Increments the usage counter of the "
389 "given object, so an additional free() is"
390 " needed to destroy the object.");
391 GWEN_SyncIo_WriteLine(sio, "*/");
392 if (args->domain) {
393 GWEN_SyncIo_WriteString(sio, args->domain);
394 GWEN_SyncIo_WriteString(sio, " ");
395 }
396 GWEN_SyncIo_WriteString(sio, "void ");
397 GWEN_SyncIo_WriteString(sio, prefix);
398 GWEN_SyncIo_WriteString(sio, "_Attach(");
399 GWEN_SyncIo_WriteString(sio, id);
400 GWEN_SyncIo_WriteLine(sio, " *st);");
401
402 /* ReadDb */
403 GWEN_SyncIo_WriteLine(sio, "/** Reads data from a GWEN_DB.");
404 GWEN_SyncIo_WriteLine(sio, "*/");
405 if (args->domain) {
406 GWEN_SyncIo_WriteString(sio, args->domain);
407 GWEN_SyncIo_WriteString(sio, " ");
408 }
409 GWEN_SyncIo_WriteString(sio, "int ");
410 GWEN_SyncIo_WriteString(sio, prefix);
411 GWEN_SyncIo_WriteString(sio, "_ReadDb(");
412 GWEN_SyncIo_WriteString(sio, id);
413 GWEN_SyncIo_WriteLine(sio, " *st, GWEN_DB_NODE *db);");
414
415 /* ToDb */
416 GWEN_SyncIo_WriteLine(sio,
417 "/** Stores an object in the"
418 " given GWEN_DB_NODE");
419 GWEN_SyncIo_WriteLine(sio, "*/");
420 if (args->domain) {
421 GWEN_SyncIo_WriteString(sio, args->domain);
422 GWEN_SyncIo_WriteString(sio, " ");
423 }
424 GWEN_SyncIo_WriteString(sio, "int ");
425 GWEN_SyncIo_WriteString(sio, prefix);
426 GWEN_SyncIo_WriteString(sio, "_toDb(const ");
427 GWEN_SyncIo_WriteString(sio, id);
428 GWEN_SyncIo_WriteLine(sio, "*st, GWEN_DB_NODE *db);");
429
430 GWEN_SyncIo_WriteLine(sio,
431 "/** Returns 0 if this object has not been"
432 " modified, !=0 otherwise");
433 GWEN_SyncIo_WriteLine(sio, "*/");
434 if (args->domain) {
435 GWEN_SyncIo_WriteString(sio, args->domain);
436 GWEN_SyncIo_WriteString(sio, " ");
437 }
438 GWEN_SyncIo_WriteString(sio, "int ");
439 GWEN_SyncIo_WriteString(sio, prefix);
440 GWEN_SyncIo_WriteString(sio, "_IsModified(const ");
441 GWEN_SyncIo_WriteString(sio, id);
442 GWEN_SyncIo_WriteLine(sio, " *st);");
443
444 GWEN_SyncIo_WriteLine(sio,
445 "/** Sets the modified state of the given "
446 "object");
447 GWEN_SyncIo_WriteLine(sio, "*/");
448 if (args->domain) {
449 GWEN_SyncIo_WriteString(sio, args->domain);
450 GWEN_SyncIo_WriteString(sio, " ");
451 }
452 GWEN_SyncIo_WriteString(sio, "void ");
453 GWEN_SyncIo_WriteString(sio, prefix);
454 GWEN_SyncIo_WriteString(sio, "_SetModified(");
455 GWEN_SyncIo_WriteString(sio, id);
456 GWEN_SyncIo_WriteLine(sio, " *st, int i);");
457 }
458
459 rv=write_h_setget_c(args, node, sio, "public");
460 if (rv) {
461 GWEN_Buffer_free(hbuf);
462 GWEN_SyncIo_Disconnect(sio);
463 GWEN_SyncIo_free(sio);
464 DBG_INFO(0, "here (%d)", rv);
465 return rv;
466 }
467
468 err=GWEN_SyncIo_WriteLine(sio, "");
469 if (err) {
470 DBG_ERROR_ERR(0, err);
471 GWEN_Buffer_free(hbuf);
472 return -1;
473 }
474
475 err=GWEN_SyncIo_WriteLine(sio, "#ifdef __cplusplus");
476 if (err) {
477 DBG_ERROR_ERR(0, err);
478 GWEN_Buffer_free(hbuf);
479 return -1;
480 }
481 err=GWEN_SyncIo_WriteLine(sio, "} /* __cplusplus */");
482 if (err) {
483 DBG_ERROR_ERR(0, err);
484 GWEN_Buffer_free(hbuf);
485 return -1;
486 }
487 err=GWEN_SyncIo_WriteLine(sio, "#endif");
488 if (err) {
489 DBG_ERROR_ERR(0, err);
490 GWEN_Buffer_free(hbuf);
491 return -1;
492 }
493 err=GWEN_SyncIo_WriteLine(sio, "");
494 if (err) {
495 DBG_ERROR_ERR(0, err);
496 GWEN_Buffer_free(hbuf);
497 return -1;
498 }
499
500 /* write trailing endif */
501 err=GWEN_SyncIo_WriteLine(sio, "");
502 if (err) {
503 DBG_ERROR_ERR(0, err);
504 GWEN_Buffer_free(hbuf);
505 return -1;
506 }
507
508 err=GWEN_SyncIo_WriteString(sio, "#endif /* ");
509 if (err) {
510 DBG_ERROR_ERR(0, err);
511 GWEN_Buffer_free(hbuf);
512 return -1;
513 }
514 err=GWEN_SyncIo_WriteString(sio, GWEN_Buffer_GetStart(hbuf));
515 if (err) {
516 DBG_ERROR_ERR(0, err);
517 GWEN_Buffer_free(hbuf);
518 return -1;
519 }
520 err=GWEN_SyncIo_WriteLine(sio, " */");
521 if (err) {
522 DBG_ERROR_ERR(0, err);
523 GWEN_Buffer_free(hbuf);
524 return -1;
525 }
526
527 err=GWEN_SyncIo_Disconnect(sio);
528 if (err) {
529 DBG_ERROR_ERR(0, err);
530 GWEN_SyncIo_free(sio);
531 GWEN_Buffer_free(hbuf);
532 return -1;
533 }
534
535 GWEN_Buffer_free(hbuf);
536 return 0;
537 }
538
539
540
write_ha_files_c(ARGUMENTS * args,GWEN_XMLNODE * node)541 int write_ha_files_c(ARGUMENTS *args, GWEN_XMLNODE *node)
542 {
543 GWEN_XMLNODE *n;
544 int rv;
545
546 n=GWEN_XMLNode_FindFirstTag(node, "type", 0, 0);
547 while (n) {
548 const char *nacc;
549
550 nacc=get_struct_property(n, "access", "public");
551 if (strcasecmp(nacc, "public")==0) {
552 rv=write_ha_file_c(args, n);
553 if (rv) {
554 DBG_INFO(0, "here (%d)", rv);
555 return rv;
556 }
557 }
558 n=GWEN_XMLNode_FindNextTag(n, "type", 0, 0);
559 }
560 return 0;
561 }
562
563
564
565
566
567
568
569
570