tools/genmodule: Added .unusedlibbase option
[AROS.git] / tools / genmodule / writeincdefines.c
blob03c7441847c0873588693498d81bf6be1a58c3ea
1 /*
2 Copyright © 1995-2012, The AROS Development Team. All rights reserved.
3 $Id$
5 Function to write defines/modulename.h. Part of genmodule.
6 */
7 #include "genmodule.h"
9 static void writedefineregister(FILE *, struct functionhead *, struct config *, int is_rel);
10 static void writedefinevararg(FILE *, struct functionhead *, struct config *);
11 static void writealiases(FILE *, struct functionhead *, struct config *);
13 void writeincdefines(struct config *cfg, int is_rel)
15 FILE *out;
16 char line[256], *banner;
17 struct functionhead *funclistit;
19 snprintf(line, 255, "%s/defines/%s%s.h", cfg->gendir, cfg->modulename, is_rel ? "_rel" : "");
20 out = fopen(line, "w");
22 if (out == NULL)
24 perror(line);
25 exit(20);
28 banner = getBanner(cfg);
29 fprintf(out,
30 "#ifndef DEFINES_%s_H\n"
31 "#define DEFINES_%s_H\n"
32 "\n"
33 "%s"
34 "\n"
35 "/*\n"
36 " Desc: Defines for %s\n"
37 "*/\n"
38 "\n"
39 "#include <aros/libcall.h>\n"
40 "#include <exec/types.h>\n"
41 "#include <aros/symbolsets.h>\n"
42 "#include <aros/preprocessor/variadic/cast2iptr.hpp>\n"
43 "\n"
44 "__BEGIN_DECLS\n"
45 "\n",
46 cfg->modulenameupper, cfg->modulenameupper, banner, cfg->modulename
48 freeBanner(banner);
50 for (funclistit = cfg->funclist; funclistit!=NULL; funclistit = funclistit->next)
52 if (!funclistit->priv && (funclistit->lvo >= cfg->firstlvo))
54 fprintf(out,
55 "\n"
56 "#if !defined(__%s_LIBAPI__) || (%d <= __%s_LIBAPI__)"
57 "\n",
58 cfg->modulenameupper,
59 funclistit->version,
60 cfg->modulenameupper
63 if (funclistit->libcall != STACK)
65 writedefineregister(out, funclistit, cfg, is_rel);
66 if (!funclistit->novararg)
67 writedefinevararg(out, funclistit, cfg);
69 else /* libcall == STACK */
71 writedefinestack(out, funclistit, cfg, is_rel);
74 writealiases(out, funclistit, cfg);
76 fprintf(out,
77 "\n"
78 "#endif /* !defined(__%s_LIBAPI__) || (%d <= __%s_LIBAPI__) */"
79 "\n",
80 cfg->modulenameupper,
81 funclistit->version,
82 cfg->modulenameupper
87 fprintf(out,
88 "\n"
89 "__END_DECLS\n"
90 "\n"
91 "#endif /* DEFINES_%s_H*/\n",
92 cfg->modulenameupper
94 fclose(out);
98 void
99 writedefineregister(FILE *out, struct functionhead *funclistit, struct config *cfg, int is_rel)
101 struct functionarg *arglistit;
102 int count, isvoid, nquad = 0, narg = 0;
103 char *type;
105 isvoid = strcmp(funclistit->type, "void") == 0
106 || strcmp(funclistit->type, "VOID") == 0;
108 fprintf(out,
109 "\n"
110 "#define __%s_WB(__%s",
111 funclistit->name, cfg->libbase
113 for (arglistit = funclistit->arguments, count = 1;
114 arglistit!=NULL;
115 arglistit = arglistit->next, count++
118 fprintf(out, ", __arg%d", count);
119 if (strchr(arglistit->reg, '/') != NULL) {
120 nquad++;
121 } else {
122 narg++;
125 fprintf(out,
126 ") ({\\\n"
128 fprintf(out,
129 " AROS_LIBREQ(%s,%d)\\\n",
130 cfg->libbase, funclistit->version
132 if (nquad == 0)
134 fprintf(out,
135 " AROS_LC%d%s%s(%s, %s, \\\n",
136 funclistit->argcount, funclistit->unusedlibbase ? "I" : "",
137 (isvoid) ? "NR" : "",
138 funclistit->type, funclistit->name
141 for (arglistit = funclistit->arguments, count = 1;
142 arglistit!=NULL;
143 arglistit = arglistit->next, count++
146 type = getargtype(arglistit);
147 assert(type != NULL);
148 fprintf(out,
149 " AROS_LCA(%s,(__arg%d),%s), \\\n",
150 type, count, arglistit->reg
152 free(type);
155 else
157 if (narg) {
158 fprintf(out,
159 " AROS_LC%dQUAD%d%s(%s, %s,\\\n",
160 narg, nquad, (isvoid) ? "NR" : "",
161 funclistit->type, funclistit->name
163 } else {
164 fprintf(out,
165 " AROS_LCQUAD%d%s(%s, %s,\\\n",
166 nquad, (isvoid) ? "NR" : "",
167 funclistit->type, funclistit->name
171 for (arglistit = funclistit->arguments, count = 1;
172 arglistit != NULL;
173 arglistit = arglistit->next, count++
176 char *quad2 = strchr(arglistit->reg, '/');
178 arglistit->reg[2] = 0;
179 type = getargtype(arglistit);
180 assert(type != NULL);
182 if (quad2 != NULL) {
183 *quad2 = 0;
184 fprintf(out,
185 " AROS_LCAQUAD(%s, (__arg%d), %s, %s), \\\n",
186 type, count, arglistit->reg, quad2+1
188 *quad2 = '/';
189 } else {
190 fprintf(out,
191 " AROS_LCA(%s, (__arg%d), %s), \\\n",
192 type, count, arglistit->reg
195 free(type);
198 fprintf(out,
199 " %s, (__%s), %u, %s);\\\n})\n\n",
200 cfg->libbasetypeptrextern, cfg->libbase, funclistit->lvo, cfg->basename
203 fprintf(out, "#define %s(", funclistit->name);
204 for (arglistit = funclistit->arguments, count = 1;
205 arglistit != NULL;
206 arglistit = arglistit->next, count++
209 if (arglistit != funclistit->arguments)
210 fprintf(out, ", ");
211 fprintf(out, "arg%d", count);
213 fprintf(out, ") \\\n __%s_WB(%s%s%s", funclistit->name,
214 is_rel ? "*(void **)((void *)__aros_getbase() + __aros_rellib_offset_" : ""
215 , cfg->libbase
216 , is_rel ? ")" : "");
217 for (arglistit = funclistit->arguments, count = 1;
218 arglistit != NULL;
219 arglistit = arglistit->next, count++
221 fprintf(out, ", (arg%d)", count);
222 fprintf(out, ")\n");
225 void
226 writedefinevararg(FILE *out, struct functionhead *funclistit, struct config *cfg)
228 struct functionarg *arglistit = funclistit->arguments;
229 char isvararg = 0, *varargname, *lastname;
231 /* Go to last argument */
232 if (arglistit == NULL)
233 return;
235 while (arglistit->next != NULL) arglistit = arglistit->next;
237 lastname = getargname(arglistit);
238 assert(lastname != NULL);
240 if (*(funclistit->name + strlen(funclistit->name) - 1) == 'A')
242 isvararg = 1;
243 varargname = strdup(funclistit->name);
244 varargname[strlen(funclistit->name)-1] = '\0';
246 else if (strcmp(funclistit->name + strlen(funclistit->name) - 7, "TagList") == 0)
248 isvararg = 1;
249 /* TagList has to be changed in Tags at the end of the functionname */
250 varargname = strdup(funclistit->name);
251 varargname[strlen(funclistit->name)-4] = 's';
252 varargname[strlen(funclistit->name)-3] = '\0';
254 else if (strcmp(funclistit->name + strlen(funclistit->name) - 4, "Args") == 0
255 && (strcasecmp(lastname, "args") == 0 || strcasecmp(lastname, "arglist") == 0)
258 isvararg = 1;
259 varargname = strdup(funclistit->name);
260 varargname[strlen(funclistit->name)-4] = '\0';
262 else if ((funclistit->name[0] == 'V') && (strncmp(arglistit->arg, "va_list", 7) == 0))
264 isvararg = 2;
265 varargname = malloc(strlen(funclistit->name));
266 strcpy(varargname, &funclistit->name[1]);
268 else
270 char *p;
272 if (strncmp(arglistit->arg, "const", 5) == 0) {
273 p = arglistit->arg + 5;
274 while (isspace(*p)) p++;
275 } else
276 p = arglistit->arg;
277 if (strncmp(p, "struct", 6)==0)
279 p += 6;
280 while (isspace(*p)) p++;
281 if (strncmp(p, "TagItem", 7) == 0)
283 p += 7;
284 while (isspace(*p)) p++;
286 if (*p == '*')
288 isvararg = 1;
289 varargname = malloc(strlen(funclistit->name) + 5);
290 strcpy(varargname, funclistit->name);
291 strcat(varargname, "Tags");
297 if (isvararg == 1)
299 int count;
300 char *type;
302 fprintf(out,
303 "\n#if !defined(NO_INLINE_STDARG) && !defined(%s_NO_INLINE_STDARG)\n"
304 "#define %s(",
305 cfg->modulenameupper, varargname
307 for (arglistit = funclistit->arguments, count = 1;
308 arglistit != NULL && arglistit->next != NULL;
309 arglistit = arglistit->next, count++
312 fprintf(out, "arg%d, ", count);
314 fprintf(out,
315 "...) \\\n"
316 "({ \\\n"
317 " %s(",
318 funclistit->name
320 for (arglistit = funclistit->arguments, count = 1;
321 arglistit != NULL;
322 arglistit = arglistit->next, count++
325 if (arglistit != funclistit->arguments)
326 fprintf(out, ", ");
328 if (arglistit->next == NULL)
330 type = getargtype(arglistit);
331 assert(type != NULL);
332 fprintf(out, "(%s)(IPTR []){ AROS_PP_VARIADIC_CAST2IPTR(__VA_ARGS__) }", type);
333 free(type);
335 else
336 fprintf(out, "(arg%d)", count);
338 fprintf(out,
339 "); \\\n"
340 "})\n"
341 "#endif /* !NO_INLINE_STDARG */\n"
344 free(varargname);
346 else if (isvararg == 2)
348 int count;
349 struct functionarg *lastarg;
351 fprintf(out,
352 "\n#if !defined(NO_INLINE_STDARG) && !defined(%s_NO_INLINE_STDARG)\n"
353 "static inline %s __%s_WB(%s __%s",
354 cfg->modulenameupper,
355 funclistit->type, varargname, cfg->libbasetypeptrextern, cfg->libbase
357 for (arglistit = funclistit->arguments;
358 arglistit != NULL && arglistit->next != NULL;
359 arglistit = arglistit->next
362 fprintf(out, ", %s", arglistit->arg);
363 lastarg = arglistit;
365 fprintf(out, ", ...)\n");
367 fprintf(out,
368 "{\n"
369 " %s retval;\n"
370 " va_list args;\n"
371 "\n"
372 " va_start(args, %s);\n"
373 " retval = __%s_WB(__%s, ",
374 funclistit->type,
375 getargname(lastarg),
376 funclistit->name, cfg->libbase
378 for (arglistit = funclistit->arguments;
379 arglistit != NULL && arglistit->next != NULL;
380 arglistit = arglistit->next
383 fprintf(out, "%s, ", getargname(arglistit));
385 fprintf(out,
386 "args);\n"
387 " va_end(args);\n"
388 " return retval;\n"
389 "}\n"
390 "#define %s(",
391 varargname
393 for (arglistit = funclistit->arguments, count = 1;
394 arglistit != NULL && arglistit->next != NULL && arglistit->next->next != NULL;
395 arglistit = arglistit->next, count++
398 fprintf(out, "arg%d, ", count);
400 fprintf(out,
401 "...) __%s_WB(%s, ",
402 varargname, cfg->libbase
404 for (arglistit = funclistit->arguments, count = 1;
405 arglistit != NULL && arglistit->next != NULL && arglistit->next->next != NULL;
406 arglistit = arglistit->next, count++
409 fprintf(out, "(arg%d), ", count);
411 fprintf(out,
412 "__VA_ARGS__)\n"
413 "#endif /* !NO_INLINE_STDARG */\n"
416 free(varargname);
420 void
421 writedefinestack(FILE *out, struct functionhead *funclistit, struct config *cfg, int is_rel)
423 struct functionarg *arglistit;
425 /* Only if no peropener or pertask base */
426 if (cfg->options & OPTION_DUPBASE)
427 return;
429 fprintf(out, "#define %s ((%s (*)(", funclistit->name, funclistit->type);
430 for (arglistit = funclistit->arguments;
431 arglistit != NULL;
432 arglistit = arglistit->next
435 fprintf(out, "%s", arglistit->arg);
436 if (arglistit->next != NULL)
437 fprintf(out, ", ");
439 fprintf(out, "))__AROS_GETVECADDR(%s%s%s,%d))\n",
440 is_rel ? "*(void **)((void *)__aros_getbase() + __aros_rellib_offset_" : "",
441 cfg->libbase,
442 is_rel ? ")" : "",
443 funclistit->lvo);
446 void
447 writealiases(FILE *out, struct functionhead *funclistit, struct config *cfg)
449 struct stringlist *aliasesit;
451 for (aliasesit = funclistit->aliases;
452 aliasesit != NULL;
453 aliasesit = aliasesit->next
456 fprintf(out, "#define %s %s\n", aliasesit->s, funclistit->name);