# create separate cflags/dflags for the binary and linklib. if the binary uses autoin...
[AROS.git] / tools / genmodule / writeincinline.c
blob7e70793c37b209c8ca445db8db7d53f5f9f2cd79
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 "#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 cfg->includenameupper, cfg->includenameupper, banner, cfg->modulename,
53 cfg->includenameupper, cfg->includenameupper,
54 cfg->includenameupper, cfg->libbase,
55 cfg->includenameupper, cfg->libbase
57 freeBanner(banner);
59 for (funclistit = cfg->funclist; funclistit!=NULL; funclistit = funclistit->next)
61 if (!funclistit->priv && (funclistit->lvo >= cfg->firstlvo) && funclistit->libcall != STACK)
63 char isvararg = 0, *varargname = NULL, *lastname;
65 fprintf(out,
66 "\n"
67 "#if !defined(__%s_LIBAPI__) || (%d <= __%s_LIBAPI__)"
68 "\n",
69 cfg->includenameupper,
70 funclistit->version,
71 cfg->includenameupper
74 if ((!funclistit->novararg) && (funclistit->arguments))
76 struct functionarg *arglistit = funclistit->arguments;
78 while (arglistit->next != NULL) arglistit = arglistit->next;
80 lastname = getargname(arglistit);
81 assert(lastname != NULL);
83 if (*(funclistit->name + strlen(funclistit->name) - 1) == 'A')
85 isvararg = 1;
86 varargname = strdup(funclistit->name);
87 varargname[strlen(funclistit->name)-1] = '\0';
88 if (arglistit && strncmp(arglistit->arg, "RAWARG", 6) == 0)
89 isvararg = 3;
91 else if (strcmp(funclistit->name + strlen(funclistit->name) - 7, "TagList") == 0)
93 isvararg = 1;
94 /* TagList has to be changed to Tags at the end of the functionname */
95 varargname = strdup(funclistit->name);
96 varargname[strlen(funclistit->name)-4] = 's';
97 varargname[strlen(funclistit->name)-3] = '\0';
99 else if (strcmp(funclistit->name + strlen(funclistit->name) - 4, "Args") == 0
100 && (strcasecmp(lastname, "args") == 0 || strcasecmp(lastname, "arglist") == 0)
103 isvararg = 1;
104 varargname = strdup(funclistit->name);
105 varargname[strlen(funclistit->name)-4] = '\0';
107 else if ((funclistit->name[0] == 'V') && (strncmp(arglistit->arg, "va_list", 7) == 0))
109 isvararg = 2;
110 varargname = malloc(strlen(funclistit->name));
111 strcpy(varargname, &funclistit->name[1]);
113 else if ((funclistit->name[0] == 'V') && (strncmp(arglistit->arg, "RAWARG", 6) == 0))
115 isvararg = 3;
116 varargname = malloc(strlen(funclistit->name));
117 strcpy(varargname, &funclistit->name[1]);
119 else
121 char *p;
124 if (strncmp(arglistit->arg, "const", 5) == 0) {
125 p = arglistit->arg + 5;
126 while (isspace(*p)) p++;
127 } else
128 p = arglistit->arg;
129 if (strncmp(p, "struct", 6)==0)
131 p += 6;
132 while (isspace(*p)) p++;
133 if (strncmp(p, "TagItem", 7) == 0)
135 p += 7;
136 while (isspace(*p)) p++;
138 if (*p == '*')
140 isvararg = 1;
141 varargname = malloc(strlen(funclistit->name) + 5);
142 strcpy(varargname, funclistit->name);
143 strcat(varargname, "Tags");
150 writeinlineregister(out, funclistit, cfg, isvararg);
151 if (!funclistit->novararg && isvararg)
153 writeinlinevararg(out, funclistit, cfg, isvararg, varargname);
154 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 "#endif /* INLINE_%s_H*/\n",
173 cfg->includenameupper
175 fclose(out);
178 void
179 writeinlineregister(FILE *out, struct functionhead *funclistit, struct config *cfg, char isvararg)
181 struct functionarg *arglistit;
182 int count, isvoid;
183 int narg=0,nquad=0;
184 char *type;
186 isvoid = strcmp(funclistit->type, "void") == 0
187 || strcmp(funclistit->type, "VOID") == 0;
189 fprintf(out,
190 "\n"
191 "static inline %s __inline_%s_%s(",
192 funclistit->type, cfg->basename, funclistit->name
194 for (arglistit = funclistit->arguments, count = 1;
195 arglistit != NULL;
196 arglistit = arglistit->next, count++
199 type = getargtype(arglistit);
200 fprintf(out, "%s __arg%d, ",
201 type, count);
202 if (strchr(arglistit->reg, '/') != NULL) {
203 nquad++;
204 } else {
205 narg++;
208 fprintf(out,
209 "APTR __%s)\n"
210 "{\n",
211 cfg->libbase
213 fprintf(out,
214 " AROS_LIBREQ(%s, %d)\n",
215 cfg->libbase, funclistit->version
217 if (nquad==0)
219 fprintf(out,
220 " %sAROS_LC%d%s(%s, %s,\n",
221 (isvoid) ? "" : "return ",
222 funclistit->argcount, (isvoid) ? "NR" : "",
223 funclistit->type, funclistit->name
226 for (arglistit = funclistit->arguments, count = 1;
227 arglistit!=NULL;
228 arglistit = arglistit->next, count++
231 type = getargtype(arglistit);
232 assert(type != NULL);
233 fprintf(out,
234 " AROS_LCA(%s,(__arg%d),%s),\n",
235 type, count, arglistit->reg
237 free(type);
240 else /* nquad != 0 */
242 if (narg) {
243 fprintf(out,
244 " %sAROS_LC%dQUAD%d%s(%s, %s,\n",
245 (isvoid) ? "" : "return ", narg,
246 nquad, (isvoid) ? "NR" : "",
247 funclistit->type, funclistit->name
249 } else {
250 fprintf(out,
251 " %sAROS_LCQUAD%d%s(%s, %s,\n",
252 (isvoid) ? "" : "return ",
253 nquad, (isvoid) ? "NR" : "",
254 funclistit->type, funclistit->name
258 for (arglistit = funclistit->arguments, count = 1;
259 arglistit != NULL;
260 arglistit = arglistit->next, count++
263 char *quad2 = strchr(arglistit->reg, '/');
265 arglistit->reg[2] = 0;
266 type = getargtype(arglistit);
267 assert(type != NULL);
269 if (quad2 != NULL) {
270 *quad2 = 0;
271 fprintf(out,
272 " AROS_LCAQUAD(%s, (__arg%d), %s, %s), \\\n",
273 type, count, arglistit->reg, quad2+1
275 *quad2 = '/';
276 } else {
277 fprintf(out,
278 " AROS_LCA(%s, (__arg%d), %s), \\\n",
279 type, count, arglistit->reg
282 free(type);
285 fprintf(out,
286 " %s, (__%s), %u, %s"
287 " );\n"
288 "}\n\n",
289 cfg->libbasetypeptrextern, cfg->libbase, funclistit->lvo, cfg->basename
292 fprintf(out, "#define %s(", funclistit->name);
293 for (arglistit = funclistit->arguments, count = 1;
294 arglistit != NULL;
295 arglistit = arglistit->next, count++
298 if (arglistit != funclistit->arguments)
299 fprintf(out, ", ");
300 fprintf(out, "arg%d", count);
302 fprintf(out, ") \\\n __inline_%s_%s(", cfg->basename, funclistit->name);
303 for (arglistit = funclistit->arguments, count = 1;
304 arglistit != NULL;
305 arglistit = arglistit->next, count++
307 fprintf(out, "(arg%d), ", count);
308 fprintf(out, "__%s_LIBBASE)\n", cfg->includenameupper);
311 void
312 writeinlinevararg(FILE *out, struct functionhead *funclistit, struct config *cfg, char isvararg, char *varargname)
314 struct functionarg *arglistit = funclistit->arguments;
315 int isvoid;
317 isvoid = strcmp(funclistit->type, "void") == 0
318 || strcmp(funclistit->type, "VOID") == 0;
320 if (isvararg == 1)
322 int count;
323 char *type;
325 fprintf(out,
326 "\n#if !defined(NO_INLINE_STDARG) && !defined(%s_NO_INLINE_STDARG)\n"
327 "#define %s(",
328 cfg->includenameupper, varargname
330 for (arglistit = funclistit->arguments, count = 1;
331 arglistit != NULL && arglistit->next != NULL;
332 arglistit = arglistit->next, count++
335 fprintf(out, "arg%d, ", count);
337 fprintf(out,
338 "...) \\\n"
339 "({ \\\n"
341 for (arglistit = funclistit->arguments, count = 1;
342 arglistit != NULL;
343 arglistit = arglistit->next, count++
346 if (arglistit->next == NULL)
348 fprintf(out, " const IPTR %s_args[] = { AROS_PP_VARIADIC_CAST2IPTR(__VA_ARGS__) };\\\n", funclistit->name);
351 fprintf(out,
352 " %s(",
353 funclistit->name
355 for (arglistit = funclistit->arguments, count = 1;
356 arglistit != NULL;
357 arglistit = arglistit->next, count++
360 if (arglistit != funclistit->arguments)
361 fprintf(out, ", ");
363 if (arglistit->next == NULL)
365 type = getargtype(arglistit);
366 assert(type != NULL);
367 fprintf(out, "(%s)(%s_args)", type, funclistit->name);
368 free(type);
370 else
371 fprintf(out, "(arg%d)", count);
373 fprintf(out,
374 "); \\\n"
375 "})\n"
376 "#endif /* !NO_INLINE_STDARG */\n"
379 else if (isvararg == 2)
381 int count;
383 fprintf(out,
384 "\n#if !defined(NO_INLINE_STDARG) && !defined(%s_NO_INLINE_STDARG)\n"
385 "static inline %s __inline_%s_%s(%s __%s",
386 cfg->includenameupper,
387 funclistit->type, cfg->basename, varargname, cfg->libbasetypeptrextern, cfg->libbase
389 for (arglistit = funclistit->arguments, count = 0;
390 arglistit != NULL && arglistit->next != NULL;
391 arglistit = arglistit->next
394 char *type = getargtype(arglistit);
396 fprintf(out, ", %s __arg%d", type, ++count);
398 fprintf(out, ", ...)\n");
400 fprintf(out,
401 "{\n"
402 " %s retval;\n"
403 " va_list __args;\n"
404 "\n"
405 " va_start(__args, __arg%d);\n"
406 " retval = __inline_%s_%s(",
407 funclistit->type,
408 count,
409 cfg->basename, funclistit->name
411 for (arglistit = funclistit->arguments, count = 1;
412 arglistit != NULL && arglistit->next != NULL;
413 arglistit = arglistit->next, count++
416 fprintf(out, "__arg%d, ", count);
418 fprintf(out,
419 "__args, __%s);\n"
420 " va_end(__args);\n"
421 " return retval;\n"
422 "}\n"
423 "\n"
424 "#define %s(",
425 cfg->libbase,
426 varargname
428 for (arglistit = funclistit->arguments, count = 1;
429 arglistit != NULL && arglistit->next != NULL && arglistit->next->next != NULL;
430 arglistit = arglistit->next, count++
433 fprintf(out, "arg%d, ", count);
435 fprintf(out,
436 "...) \\\n"
437 " __inline_%s_%s(",
438 cfg->basename, varargname
440 fprintf(out, "(%s)__%s_LIBBASE, ",
441 cfg->libbasetypeptrextern,
442 cfg->includenameupper);
443 for (arglistit = funclistit->arguments, count = 1;
444 arglistit != NULL && arglistit->next != NULL && arglistit->next->next != NULL;
445 arglistit = arglistit->next, count++
448 fprintf(out, "(arg%d), ", count);
450 fprintf(out,
451 "__VA_ARGS__)\n"
452 "#endif /* !NO_INLINE_STDARG */\n"
455 else if (isvararg == 3)
457 int count;
459 fprintf(out,
460 "\n#if !defined(NO_INLINE_STDARG) && !defined(%s_NO_INLINE_STDARG)\n"
461 "static inline %s __inline_%s_%s(%s __%s",
462 cfg->includenameupper,
463 funclistit->type, cfg->basename, varargname, cfg->libbasetypeptrextern, cfg->libbase
465 for (arglistit = funclistit->arguments, count = 0;
466 arglistit != NULL && arglistit->next != NULL;
467 arglistit = arglistit->next
470 char *type = getargtype(arglistit);
472 fprintf(out, ", %s __arg%d", type, ++count);
474 fprintf(out, ", ...)\n");
476 fprintf(out,"{\n");
477 if (!isvoid)
478 fprintf(out, " %s retval;\n", funclistit->type);
480 fprintf(out,
481 "\n"
482 " AROS_SLOWSTACKFORMAT_PRE(__arg%d);\n"
483 " %s__inline_%s_%s(",
484 count,
485 isvoid ? "" : "retval = ",
486 cfg->basename, funclistit->name
488 for (arglistit = funclistit->arguments, count = 1;
489 arglistit != NULL && arglistit->next != NULL;
490 arglistit = arglistit->next, count++
493 fprintf(out, "__arg%d, ", count);
495 count--;
496 fprintf(out,
497 "AROS_SLOWSTACKFORMAT_ARG(__arg%d), __%s);\n"
498 " AROS_SLOWSTACKFORMAT_POST(__arg%d);\n"
499 " return%s;\n"
500 "}\n"
501 "\n"
502 "#define %s(",
503 count,
504 cfg->libbase,
505 count,
506 isvoid ? "" : " retval",
507 varargname
509 for (arglistit = funclistit->arguments, count = 1;
510 arglistit != NULL && arglistit->next != NULL && arglistit->next->next != NULL;
511 arglistit = arglistit->next, count++
514 fprintf(out, "arg%d, ", count);
516 fprintf(out,
517 "...) \\\n"
518 " __inline_%s_%s(",
519 cfg->basename, varargname
521 fprintf(out, "(%s)__%s_LIBBASE, ",
522 cfg->libbasetypeptrextern,
523 cfg->includenameupper);
524 for (arglistit = funclistit->arguments, count = 1;
525 arglistit != NULL && arglistit->next != NULL && arglistit->next->next != NULL;
526 arglistit = arglistit->next, count++
529 fprintf(out, "(arg%d), ", count);
531 fprintf(out,
532 "__VA_ARGS__)\n"
533 "#endif /* !NO_INLINE_STDARG */\n"
538 void
539 writealiases(FILE *out, struct functionhead *funclistit, struct config *cfg)
541 struct stringlist *aliasesit;
543 for (aliasesit = funclistit->aliases;
544 aliasesit != NULL;
545 aliasesit = aliasesit->next
548 fprintf(out, "#define %s %s\n", aliasesit->s, funclistit->name);