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