make sure the bases are cast to the expected types.
[AROS.git] / tools / genmodule / writeincinline.c
bloba73355b0ec7eb184ac548fee6e66879e7a4fc72c
1 /*
2 Copyright © 1995-2017, The AROS Development Team. All rights reserved.
3 $Id$
5 Function to write inline/modulename.h. Part of genmodule.
6 */
7 #include "genmodule.h"
9 static void writeinlineregister(FILE *, struct functionhead *, struct config *, char);
10 static void writeinlinevararg(FILE *, struct functionhead *, struct config *, char, char *);
11 static void writealiases(FILE *, struct functionhead *, struct config *);
13 void writeincinline(struct config *cfg)
15 FILE *out;
16 char line[256], *banner;
17 struct functionhead *funclistit;
19 snprintf(line, 255, "%s/inline/%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 INLINE_%s_H\n"
31 "#define INLINE_%s_H\n"
32 "\n"
33 "%s"
34 "\n"
35 "/*\n"
36 " Desc: Inline function(s) 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 cfg->includenameupper, cfg->includenameupper, banner, cfg->modulename
46 freeBanner(banner);
48 for (funclistit = cfg->funclist; funclistit!=NULL; funclistit = funclistit->next)
50 if (!funclistit->priv && (funclistit->lvo >= cfg->firstlvo) && funclistit->libcall != STACK)
52 char isvararg = 0, *varargname = NULL, *lastname;
54 fprintf(out,
55 "\n"
56 "#if !defined(__%s_LIBAPI__) || (%d <= __%s_LIBAPI__)"
57 "\n",
58 cfg->includenameupper,
59 funclistit->version,
60 cfg->includenameupper
63 if ((!funclistit->novararg) && (funclistit->arguments))
65 struct functionarg *arglistit = funclistit->arguments;
67 while (arglistit->next != NULL) arglistit = arglistit->next;
69 lastname = getargname(arglistit);
70 assert(lastname != NULL);
72 if (*(funclistit->name + strlen(funclistit->name) - 1) == 'A')
74 isvararg = 1;
75 varargname = strdup(funclistit->name);
76 varargname[strlen(funclistit->name)-1] = '\0';
77 if (arglistit && strncmp(arglistit->arg, "RAWARG", 6) == 0)
78 isvararg = 3;
80 else if (strcmp(funclistit->name + strlen(funclistit->name) - 7, "TagList") == 0)
82 isvararg = 1;
83 /* TagList has to be changed to Tags at the end of the functionname */
84 varargname = strdup(funclistit->name);
85 varargname[strlen(funclistit->name)-4] = 's';
86 varargname[strlen(funclistit->name)-3] = '\0';
88 else if (strcmp(funclistit->name + strlen(funclistit->name) - 4, "Args") == 0
89 && (strcasecmp(lastname, "args") == 0 || strcasecmp(lastname, "arglist") == 0)
92 isvararg = 1;
93 varargname = strdup(funclistit->name);
94 varargname[strlen(funclistit->name)-4] = '\0';
96 else if ((funclistit->name[0] == 'V') && (strncmp(arglistit->arg, "va_list", 7) == 0))
98 isvararg = 2;
99 varargname = malloc(strlen(funclistit->name));
100 strcpy(varargname, &funclistit->name[1]);
102 else if ((funclistit->name[0] == 'V') && (strncmp(arglistit->arg, "RAWARG", 6) == 0))
104 isvararg = 3;
105 varargname = malloc(strlen(funclistit->name));
106 strcpy(varargname, &funclistit->name[1]);
108 else
110 char *p;
113 if (strncmp(arglistit->arg, "const", 5) == 0) {
114 p = arglistit->arg + 5;
115 while (isspace(*p)) p++;
116 } else
117 p = arglistit->arg;
118 if (strncmp(p, "struct", 6)==0)
120 p += 6;
121 while (isspace(*p)) p++;
122 if (strncmp(p, "TagItem", 7) == 0)
124 p += 7;
125 while (isspace(*p)) p++;
127 if (*p == '*')
129 isvararg = 1;
130 varargname = malloc(strlen(funclistit->name) + 5);
131 strcpy(varargname, funclistit->name);
132 strcat(varargname, "Tags");
139 writeinlineregister(out, funclistit, cfg, isvararg);
140 if (!funclistit->novararg && isvararg)
142 writeinlinevararg(out, funclistit, cfg, isvararg, varargname);
143 free(varargname);
146 writealiases(out, funclistit, cfg);
148 fprintf(out,
149 "\n"
150 "#endif /* !defined(__%s_LIBAPI__) || (%d <= __%s_LIBAPI__) */"
151 "\n",
152 cfg->includenameupper,
153 funclistit->version,
154 cfg->includenameupper
159 fprintf(out,
160 "\n"
161 "#endif /* INLINE_%s_H*/\n",
162 cfg->includenameupper
164 fclose(out);
167 void
168 writeinlineregister(FILE *out, struct functionhead *funclistit, struct config *cfg, char isvararg)
170 struct functionarg *arglistit;
171 int count, isvoid;
172 int narg=0,nquad=0;
173 char *type;
175 isvoid = strcmp(funclistit->type, "void") == 0
176 || strcmp(funclistit->type, "VOID") == 0;
178 fprintf(out,
179 "\n"
180 "static inline %s __inline_%s_%s(",
181 funclistit->type, cfg->basename, funclistit->name
183 for (arglistit = funclistit->arguments, count = 1;
184 arglistit != NULL;
185 arglistit = arglistit->next, count++
188 type = getargtype(arglistit);
189 fprintf(out, "%s __arg%d, ",
190 type, count);
191 if (strchr(arglistit->reg, '/') != NULL) {
192 nquad++;
193 } else {
194 narg++;
197 fprintf(out,
198 "APTR __%s)\n"
199 "{\n",
200 cfg->libbase
202 fprintf(out,
203 " AROS_LIBREQ(%s, %d)\n",
204 cfg->libbase, funclistit->version
206 if (nquad==0)
208 fprintf(out,
209 " %sAROS_LC%d%s(%s, %s,\n",
210 (isvoid) ? "" : "return ",
211 funclistit->argcount, (isvoid) ? "NR" : "",
212 funclistit->type, funclistit->name
215 for (arglistit = funclistit->arguments, count = 1;
216 arglistit!=NULL;
217 arglistit = arglistit->next, count++
220 type = getargtype(arglistit);
221 assert(type != NULL);
222 fprintf(out,
223 " AROS_LCA(%s,(__arg%d),%s),\n",
224 type, count, arglistit->reg
226 free(type);
229 else /* nquad != 0 */
231 if (narg) {
232 fprintf(out,
233 " %sAROS_LC%dQUAD%d%s(%s, %s,\n",
234 (isvoid) ? "" : "return ", narg,
235 nquad, (isvoid) ? "NR" : "",
236 funclistit->type, funclistit->name
238 } else {
239 fprintf(out,
240 " %sAROS_LCQUAD%d%s(%s, %s,\n",
241 (isvoid) ? "" : "return ",
242 nquad, (isvoid) ? "NR" : "",
243 funclistit->type, funclistit->name
247 for (arglistit = funclistit->arguments, count = 1;
248 arglistit != NULL;
249 arglistit = arglistit->next, count++
252 char *quad2 = strchr(arglistit->reg, '/');
254 arglistit->reg[2] = 0;
255 type = getargtype(arglistit);
256 assert(type != NULL);
258 if (quad2 != NULL) {
259 *quad2 = 0;
260 fprintf(out,
261 " AROS_LCAQUAD(%s, (__arg%d), %s, %s), \\\n",
262 type, count, arglistit->reg, quad2+1
264 *quad2 = '/';
265 } else {
266 fprintf(out,
267 " AROS_LCA(%s, (__arg%d), %s), \\\n",
268 type, count, arglistit->reg
271 free(type);
274 fprintf(out,
275 " %s, (__%s), %u, %s"
276 " );\n"
277 "}\n\n",
278 cfg->libbasetypeptrextern, cfg->libbase, funclistit->lvo, cfg->basename
281 fprintf(out, "#define %s(", funclistit->name);
282 for (arglistit = funclistit->arguments, count = 1;
283 arglistit != NULL;
284 arglistit = arglistit->next, count++
287 if (arglistit != funclistit->arguments)
288 fprintf(out, ", ");
289 fprintf(out, "arg%d", count);
291 fprintf(out, ") \\\n __inline_%s_%s(", cfg->basename, funclistit->name);
292 for (arglistit = funclistit->arguments, count = 1;
293 arglistit != NULL;
294 arglistit = arglistit->next, count++
296 fprintf(out, "(arg%d), ", count);
297 fprintf(out, "__aros_getbase_%s())\n", cfg->libbase);
300 void
301 writeinlinevararg(FILE *out, struct functionhead *funclistit, struct config *cfg, char isvararg, char *varargname)
303 struct functionarg *arglistit = funclistit->arguments;
304 int isvoid;
306 isvoid = strcmp(funclistit->type, "void") == 0
307 || strcmp(funclistit->type, "VOID") == 0;
309 if (isvararg == 1)
311 int count;
312 char *type;
314 fprintf(out,
315 "\n#if !defined(NO_INLINE_STDARG) && !defined(%s_NO_INLINE_STDARG)\n"
316 "#define %s(",
317 cfg->includenameupper, varargname
319 for (arglistit = funclistit->arguments, count = 1;
320 arglistit != NULL && arglistit->next != NULL;
321 arglistit = arglistit->next, count++
324 fprintf(out, "arg%d, ", count);
326 fprintf(out,
327 "...) \\\n"
328 "({ \\\n"
330 for (arglistit = funclistit->arguments, count = 1;
331 arglistit != NULL;
332 arglistit = arglistit->next, count++
335 if (arglistit->next == NULL)
337 fprintf(out, " const IPTR %s_args[] = { AROS_PP_VARIADIC_CAST2IPTR(__VA_ARGS__) };\\\n", funclistit->name);
340 fprintf(out,
341 " %s(",
342 funclistit->name
344 for (arglistit = funclistit->arguments, count = 1;
345 arglistit != NULL;
346 arglistit = arglistit->next, count++
349 if (arglistit != funclistit->arguments)
350 fprintf(out, ", ");
352 if (arglistit->next == NULL)
354 type = getargtype(arglistit);
355 assert(type != NULL);
356 fprintf(out, "(%s)(%s_args)", type, funclistit->name);
357 free(type);
359 else
360 fprintf(out, "(arg%d)", count);
362 fprintf(out,
363 "); \\\n"
364 "})\n"
365 "#endif /* !NO_INLINE_STDARG */\n"
368 else if (isvararg == 2)
370 int count;
372 fprintf(out,
373 "\n#if !defined(NO_INLINE_STDARG) && !defined(%s_NO_INLINE_STDARG)\n"
374 "static inline %s __inline_%s_%s(%s __%s",
375 cfg->includenameupper,
376 funclistit->type, cfg->basename, varargname, cfg->libbasetypeptrextern, cfg->libbase
378 for (arglistit = funclistit->arguments, count = 0;
379 arglistit != NULL && arglistit->next != NULL;
380 arglistit = arglistit->next
383 char *type = getargtype(arglistit);
385 fprintf(out, ", %s __arg%d", type, ++count);
387 fprintf(out, ", ...)\n");
389 fprintf(out,
390 "{\n"
391 " %s retval;\n"
392 " va_list __args;\n"
393 "\n"
394 " va_start(__args, __arg%d);\n"
395 " retval = __inline_%s_%s(",
396 funclistit->type,
397 count,
398 cfg->basename, funclistit->name
400 for (arglistit = funclistit->arguments, count = 1;
401 arglistit != NULL && arglistit->next != NULL;
402 arglistit = arglistit->next, count++
405 fprintf(out, "__arg%d, ", count);
407 fprintf(out,
408 "__args, __%s);\n"
409 " va_end(__args);\n"
410 " return retval;\n"
411 "}\n"
412 "\n"
413 "#define %s(",
414 cfg->libbase,
415 varargname
417 for (arglistit = funclistit->arguments, count = 1;
418 arglistit != NULL && arglistit->next != NULL && arglistit->next->next != NULL;
419 arglistit = arglistit->next, count++
422 fprintf(out, "arg%d, ", count);
424 fprintf(out,
425 "...) \\\n"
426 " __inline_%s_%s(",
427 cfg->basename, varargname
429 fprintf(out, "(%s)__aros_getbase_%s(), ",
430 cfg->libbasetypeptrextern,
431 cfg->libbase);
432 for (arglistit = funclistit->arguments, count = 1;
433 arglistit != NULL && arglistit->next != NULL && arglistit->next->next != NULL;
434 arglistit = arglistit->next, count++
437 fprintf(out, "(arg%d), ", count);
439 fprintf(out,
440 "__VA_ARGS__)\n"
441 "#endif /* !NO_INLINE_STDARG */\n"
444 else if (isvararg == 3)
446 int count;
448 fprintf(out,
449 "\n#if !defined(NO_INLINE_STDARG) && !defined(%s_NO_INLINE_STDARG)\n"
450 "static inline %s __inline_%s_%s(%s __%s",
451 cfg->includenameupper,
452 funclistit->type, cfg->basename, varargname, cfg->libbasetypeptrextern, cfg->libbase
454 for (arglistit = funclistit->arguments, count = 0;
455 arglistit != NULL && arglistit->next != NULL;
456 arglistit = arglistit->next
459 char *type = getargtype(arglistit);
461 fprintf(out, ", %s __arg%d", type, ++count);
463 fprintf(out, ", ...)\n");
465 fprintf(out,"{\n");
466 if (!isvoid)
467 fprintf(out, " %s retval;\n", funclistit->type);
469 fprintf(out,
470 "\n"
471 " AROS_SLOWSTACKFORMAT_PRE(__arg%d);\n"
472 " %s__inline_%s_%s(",
473 count,
474 isvoid ? "" : "retval = ",
475 cfg->basename, funclistit->name
477 for (arglistit = funclistit->arguments, count = 1;
478 arglistit != NULL && arglistit->next != NULL;
479 arglistit = arglistit->next, count++
482 fprintf(out, "__arg%d, ", count);
484 count--;
485 fprintf(out,
486 "AROS_SLOWSTACKFORMAT_ARG(__arg%d), __%s);\n"
487 " AROS_SLOWSTACKFORMAT_POST(__arg%d);\n"
488 " return%s;\n"
489 "}\n"
490 "\n"
491 "#define %s(",
492 count,
493 cfg->libbase,
494 count,
495 isvoid ? "" : " retval",
496 varargname
498 for (arglistit = funclistit->arguments, count = 1;
499 arglistit != NULL && arglistit->next != NULL && arglistit->next->next != NULL;
500 arglistit = arglistit->next, count++
503 fprintf(out, "arg%d, ", count);
505 fprintf(out,
506 "...) \\\n"
507 " __inline_%s_%s(",
508 cfg->basename, varargname
510 fprintf(out, "(%s)__aros_getbase_%s(), ",
511 cfg->libbasetypeptrextern,
512 cfg->libbase);
513 for (arglistit = funclistit->arguments, count = 1;
514 arglistit != NULL && arglistit->next != NULL && arglistit->next->next != NULL;
515 arglistit = arglistit->next, count++
518 fprintf(out, "(arg%d), ", count);
520 fprintf(out,
521 "__VA_ARGS__)\n"
522 "#endif /* !NO_INLINE_STDARG */\n"
527 void
528 writealiases(FILE *out, struct functionhead *funclistit, struct config *cfg)
530 struct stringlist *aliasesit;
532 for (aliasesit = funclistit->aliases;
533 aliasesit != NULL;
534 aliasesit = aliasesit->next
537 fprintf(out, "#define %s %s\n", aliasesit->s, funclistit->name);