# create separate cflags/dflags for the binary and linklib. if the binary uses autoin...
[AROS.git] / tools / genmodule / writeincdefines.c
blobf093b1916ea028c0ca521c241ad2a9711478520e
1 /*
2 Copyright © 1995-2017, 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 *, char);
10 static void writedefinevararg(FILE *, struct functionhead *, struct config *, char, char *);
11 static void writealiases(FILE *, struct functionhead *, struct config *);
13 void writeincdefines(struct config *cfg)
15 FILE *out;
16 char line[256], *banner;
17 struct functionhead *funclistit;
19 snprintf(line, 255, "%s/defines/%s.h", cfg->gendir, cfg->includename);
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 "#if !defined(__%s_LIBBASE)\n"
45 "# if !defined(__NOLIBBASE__) && !defined(__%s_NOLIBBASE__)\n"
46 "# define __%s_LIBBASE __aros_getbase_%s()\n"
47 "# else\n"
48 "# define __%s_LIBBASE %s\n"
49 "# endif\n"
50 "#endif\n"
51 "\n"
52 "__BEGIN_DECLS\n"
53 "\n",
54 cfg->includenameupper, cfg->includenameupper, banner, cfg->modulename,
55 cfg->includenameupper, cfg->includenameupper,
56 cfg->includenameupper, cfg->libbase,
57 cfg->includenameupper, cfg->libbase
59 freeBanner(banner);
61 for (funclistit = cfg->funclist; funclistit!=NULL; funclistit = funclistit->next)
63 if (!funclistit->priv && (funclistit->lvo >= cfg->firstlvo) && funclistit->libcall != STACK)
65 char isvararg = 0, *varargname = NULL, *lastname;
67 fprintf(out,
68 "\n"
69 "#if !defined(__%s_LIBAPI__) || (%d <= __%s_LIBAPI__)"
70 "\n",
71 cfg->includenameupper,
72 funclistit->version,
73 cfg->includenameupper
76 if ((!funclistit->novararg) && (funclistit->arguments))
78 struct functionarg *arglistit = funclistit->arguments;
80 while (arglistit->next != NULL) arglistit = arglistit->next;
82 lastname = getargname(arglistit);
83 assert(lastname != NULL);
85 if (*(funclistit->name + strlen(funclistit->name) - 1) == 'A')
87 isvararg = 1;
88 varargname = strdup(funclistit->name);
89 varargname[strlen(funclistit->name)-1] = '\0';
90 if (arglistit && strncmp(arglistit->arg, "RAWARG",6) == 0)
91 isvararg = 3;
93 else if (strcmp(funclistit->name + strlen(funclistit->name) - 7, "TagList") == 0)
95 isvararg = 1;
96 /* TagList has to be changed to Tags at the end of the functionname */
97 varargname = strdup(funclistit->name);
98 varargname[strlen(funclistit->name)-4] = 's';
99 varargname[strlen(funclistit->name)-3] = '\0';
101 else if (strcmp(funclistit->name + strlen(funclistit->name) - 4, "Args") == 0
102 && (strcasecmp(lastname, "args") == 0 || strcasecmp(lastname, "arglist") == 0)
105 isvararg = 1;
106 varargname = strdup(funclistit->name);
107 varargname[strlen(funclistit->name)-4] = '\0';
109 else if ((funclistit->name[0] == 'V') && (strncmp(arglistit->arg, "va_list", 7) == 0))
111 isvararg = 2;
112 varargname = malloc(strlen(funclistit->name));
113 strcpy(varargname, &funclistit->name[1]);
115 else if ((funclistit->name[0] == 'V') && (strncmp(arglistit->arg, "RAWARG", 6) == 0))
117 isvararg = 3;
118 varargname = malloc(strlen(funclistit->name));
119 strcpy(varargname, &funclistit->name[1]);
121 else
123 char *p;
125 if (strncmp(arglistit->arg, "const", 5) == 0) {
126 p = arglistit->arg + 5;
127 while (isspace(*p)) p++;
128 } else
129 p = arglistit->arg;
130 if (strncmp(p, "struct", 6)==0)
132 p += 6;
133 while (isspace(*p)) p++;
134 if (strncmp(p, "TagItem", 7) == 0)
136 p += 7;
137 while (isspace(*p)) p++;
139 if (*p == '*')
141 isvararg = 1;
142 varargname = malloc(strlen(funclistit->name) + 5);
143 strcpy(varargname, funclistit->name);
144 strcat(varargname, "Tags");
151 writedefineregister(out, funclistit, cfg, isvararg);
152 if (!funclistit->novararg && isvararg)
154 writedefinevararg(out, funclistit, cfg, isvararg, varargname);
155 free(varargname);
157 writealiases(out, funclistit, cfg);
159 fprintf(out,
160 "\n"
161 "#endif /* !defined(__%s_LIBAPI__) || (%d <= __%s_LIBAPI__) */"
162 "\n",
163 cfg->includenameupper,
164 funclistit->version,
165 cfg->includenameupper
170 fprintf(out,
171 "\n"
172 "__END_DECLS\n"
173 "\n"
174 "#endif /* DEFINES_%s_H*/\n",
175 cfg->includenameupper
177 fclose(out);
180 void
181 writedefineregister(FILE *out, struct functionhead *funclistit, struct config *cfg, char isvararg)
183 struct functionarg *arglistit;
184 int count, isvoid, nquad = 0, narg = 0;
185 char *type;
187 isvoid = strcmp(funclistit->type, "void") == 0
188 || strcmp(funclistit->type, "VOID") == 0;
190 fprintf(out,
191 "\n"
192 "#define __%s_WB(__%s",
193 funclistit->name, cfg->libbase
195 for (arglistit = funclistit->arguments, count = 1;
196 arglistit!=NULL;
197 arglistit = arglistit->next, count++
200 fprintf(out, ", __arg%d", count);
201 if (strchr(arglistit->reg, '/') != NULL) {
202 nquad++;
203 } else {
204 narg++;
207 fprintf(out,
208 ") ({\\\n"
210 fprintf(out,
211 " AROS_LIBREQ(%s,%d)\\\n",
212 cfg->libbase, funclistit->version
214 if (nquad == 0)
216 fprintf(out,
217 " AROS_LC%d%s%s(%s, %s, \\\n",
218 funclistit->argcount, funclistit->unusedlibbase ? "I" : "",
219 (isvoid) ? "NR" : "",
220 funclistit->type, funclistit->name
223 for (arglistit = funclistit->arguments, count = 1;
224 arglistit!=NULL;
225 arglistit = arglistit->next, count++
228 type = getargtype(arglistit);
229 assert(type != NULL);
230 fprintf(out,
231 " AROS_LCA(%s,(__arg%d),%s), \\\n",
232 type, count, arglistit->reg
234 free(type);
237 else
239 if (narg) {
240 fprintf(out,
241 " AROS_LC%dQUAD%d%s(%s, %s,\\\n",
242 narg, nquad, (isvoid) ? "NR" : "",
243 funclistit->type, funclistit->name
245 } else {
246 fprintf(out,
247 " AROS_LCQUAD%d%s(%s, %s,\\\n",
248 nquad, (isvoid) ? "NR" : "",
249 funclistit->type, funclistit->name
253 for (arglistit = funclistit->arguments, count = 1;
254 arglistit != NULL;
255 arglistit = arglistit->next, count++
258 char *quad2 = strchr(arglistit->reg, '/');
260 arglistit->reg[2] = 0;
261 type = getargtype(arglistit);
262 assert(type != NULL);
264 if (quad2 != NULL) {
265 *quad2 = 0;
266 fprintf(out,
267 " AROS_LCAQUAD(%s, (__arg%d), %s, %s), \\\n",
268 type, count, arglistit->reg, quad2+1
270 *quad2 = '/';
271 } else {
272 fprintf(out,
273 " AROS_LCA(%s, (__arg%d), %s), \\\n",
274 type, count, arglistit->reg
277 free(type);
280 fprintf(out,
281 " %s, (__%s), %u, %s);\\\n})\n\n",
282 cfg->libbasetypeptrextern, cfg->libbase, funclistit->lvo, cfg->basename
285 fprintf(out, "#define %s(", funclistit->name);
286 for (arglistit = funclistit->arguments, count = 1;
287 arglistit != NULL;
288 arglistit = arglistit->next, count++
291 if (arglistit != funclistit->arguments)
292 fprintf(out, ", ");
293 fprintf(out, "arg%d", count);
295 fprintf(out, ") \\\n __%s_WB(__%s_LIBBASE",
296 funclistit->name, cfg->includenameupper
298 for (arglistit = funclistit->arguments, count = 1;
299 arglistit != NULL;
300 arglistit = arglistit->next, count++
302 fprintf(out, ", (arg%d)", count);
303 fprintf(out, ")\n");
306 void
307 writedefinevararg(FILE *out, struct functionhead *funclistit, struct config *cfg, char isvararg, char *varargname)
309 struct functionarg *arglistit = funclistit->arguments;
310 int isvoid;
312 isvoid = strcmp(funclistit->type, "void") == 0
313 || strcmp(funclistit->type, "VOID") == 0;
315 if (isvararg == 1)
317 int count;
318 char *type;
320 fprintf(out,
321 "\n#if !defined(NO_INLINE_STDARG) && !defined(%s_NO_INLINE_STDARG)\n"
322 "#define %s(",
323 cfg->includenameupper, varargname
325 for (arglistit = funclistit->arguments, count = 1;
326 arglistit != NULL && arglistit->next != NULL;
327 arglistit = arglistit->next, count++
330 fprintf(out, "arg%d, ", count);
332 fprintf(out,
333 "...) \\\n"
334 "({ \\\n"
335 " %s(",
336 funclistit->name
338 for (arglistit = funclistit->arguments, count = 1;
339 arglistit != NULL;
340 arglistit = arglistit->next, count++
343 if (arglistit != funclistit->arguments)
344 fprintf(out, ", ");
346 if (arglistit->next == NULL)
348 type = getargtype(arglistit);
349 assert(type != NULL);
350 fprintf(out, "(%s)(const IPTR []){ AROS_PP_VARIADIC_CAST2IPTR(__VA_ARGS__) }", type);
351 free(type);
353 else
354 fprintf(out, "(arg%d)", count);
356 fprintf(out,
357 "); \\\n"
358 "})\n"
359 "#endif /* !NO_INLINE_STDARG */\n"
362 else if (isvararg == 2)
364 int count;
365 struct functionarg *lastarg;
367 fprintf(out,
368 "\n#if !defined(NO_INLINE_STDARG) && !defined(%s_NO_INLINE_STDARG)\n"
369 "static inline %s __%s_WB(%s __%s",
370 cfg->includenameupper,
371 funclistit->type, varargname, cfg->libbasetypeptrextern, cfg->libbase
373 for (arglistit = funclistit->arguments;
374 arglistit != NULL && arglistit->next != NULL;
375 arglistit = arglistit->next
378 fprintf(out, ", %s", arglistit->arg);
379 lastarg = arglistit;
381 fprintf(out, ", ...)\n");
383 fprintf(out,
384 "{\n"
385 " %s retval;\n"
386 " va_list args;\n"
387 "\n"
388 " va_start(args, %s);\n"
389 " retval = __%s_WB(__%s, ",
390 funclistit->type,
391 getargname(lastarg),
392 funclistit->name, cfg->libbase
394 for (arglistit = funclistit->arguments;
395 arglistit != NULL && arglistit->next != NULL;
396 arglistit = arglistit->next
399 fprintf(out, "%s, ", getargname(arglistit));
401 fprintf(out,
402 "args);\n"
403 " va_end(args);\n"
404 " return retval;\n"
405 "}\n"
406 "#define %s(",
407 varargname
409 for (arglistit = funclistit->arguments, count = 1;
410 arglistit != NULL && arglistit->next != NULL && arglistit->next->next != NULL;
411 arglistit = arglistit->next, count++
414 fprintf(out, "arg%d, ", count);
416 fprintf(out,
417 "...) __%s_WB(",
418 varargname, cfg->libbase
420 fprintf(out, "(%s)__%s_LIBBASE, ",
421 cfg->libbasetypeptrextern,
422 cfg->includenameupper);
423 for (arglistit = funclistit->arguments, count = 1;
424 arglistit != NULL && arglistit->next != NULL && arglistit->next->next != NULL;
425 arglistit = arglistit->next, count++
428 fprintf(out, "(arg%d), ", count);
430 fprintf(out,
431 "__VA_ARGS__)\n"
432 "#endif /* !NO_INLINE_STDARG */\n"
435 else if (isvararg == 3)
437 int count;
439 fprintf(out,
440 "\n#if !defined(NO_INLINE_STDARG) && !defined(%s_NO_INLINE_STDARG)\n"
441 "static inline %s __inline_%s_%s(%s __%s",
442 cfg->includenameupper,
443 funclistit->type, cfg->basename, varargname, cfg->libbasetypeptrextern, cfg->libbase
445 for (arglistit = funclistit->arguments, count = 0;
446 arglistit != NULL && arglistit->next != NULL;
447 arglistit = arglistit->next
450 char *type = getargtype(arglistit);
452 fprintf(out, ", %s __arg%d", type, ++count);
454 fprintf(out, ", ...)\n");
456 fprintf(out,"{\n");
457 if (!isvoid)
458 fprintf(out, " %s retval;\n\n", funclistit->type);
460 fprintf(out,
461 " AROS_SLOWSTACKFORMAT_PRE(__arg%d);\n"
462 " %s__%s_WB(__%s",
463 count,
464 isvoid ? "" : "retval = ",
465 funclistit->name,
466 cfg->libbase
468 for (arglistit = funclistit->arguments, count = 1;
469 arglistit != NULL && arglistit->next != NULL;
470 arglistit = arglistit->next, count++
473 fprintf(out, ", __arg%d", count);
475 count--;
476 fprintf(out,
477 ", AROS_SLOWSTACKFORMAT_ARG(__arg%d));\n"
478 " AROS_SLOWSTACKFORMAT_POST(__arg%d);\n"
479 " return%s;\n"
480 "}\n"
481 "\n"
482 "#define %s(",
483 count,
484 count,
485 isvoid ? "" : " retval",
486 varargname
488 for (arglistit = funclistit->arguments, count = 1;
489 arglistit != NULL && arglistit->next != NULL && arglistit->next->next != NULL;
490 arglistit = arglistit->next, count++
493 fprintf(out, "arg%d, ", count);
495 fprintf(out,
496 "...) \\\n"
497 " __inline_%s_%s(",
498 cfg->basename, varargname
500 fprintf(out, "(%s)__%s_LIBBASE, ",
501 cfg->libbasetypeptrextern,
502 cfg->includenameupper);
503 for (arglistit = funclistit->arguments, count = 1;
504 arglistit != NULL && arglistit->next != NULL && arglistit->next->next != NULL;
505 arglistit = arglistit->next, count++
508 fprintf(out, "(arg%d), ", count);
510 fprintf(out,
511 "__VA_ARGS__)\n"
512 "#endif /* !NO_INLINE_STDARG */\n"
517 void
518 writealiases(FILE *out, struct functionhead *funclistit, struct config *cfg)
520 struct stringlist *aliasesit;
522 for (aliasesit = funclistit->aliases;
523 aliasesit != NULL;
524 aliasesit = aliasesit->next
527 fprintf(out, "#define %s %s\n", aliasesit->s, funclistit->name);