make.tmpl: add missing compiler attribute to build_progs
[AROS.git] / tools / genmodule / writeincinline.c
blobb5de8bac1b156b1ed9702798644bb1151798b310
1 /*
2 Copyright © 1995-2011, 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 in 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%s __arg%d, ",
190 ((isvararg) && (!arglistit->next)) ? "const " : "",
191 type, count);
192 if (strchr(arglistit->reg, '/') != NULL) {
193 nquad++;
194 } else {
195 narg++;
198 fprintf(out,
199 "APTR __%s)\n"
200 "{\n",
201 cfg->libbase
203 fprintf(out,
204 " AROS_LIBREQ(%s, %d)\n",
205 cfg->libbase, funclistit->version
207 if (nquad==0)
209 fprintf(out,
210 " %sAROS_LC%d%s(%s, %s,\n",
211 (isvoid) ? "" : "return ",
212 funclistit->argcount, (isvoid) ? "NR" : "",
213 funclistit->type, funclistit->name
216 for (arglistit = funclistit->arguments, count = 1;
217 arglistit!=NULL;
218 arglistit = arglistit->next, count++
221 type = getargtype(arglistit);
222 assert(type != NULL);
223 fprintf(out,
224 " AROS_LCA(%s%s,(__arg%d),%s),\n",
225 ((isvararg) && (!arglistit->next)) ? "const " : "",
226 type, count, arglistit->reg
228 free(type);
231 else /* nquad != 0 */
233 if (narg) {
234 fprintf(out,
235 " %sAROS_LC%dQUAD%d%s(%s, %s,\n",
236 (isvoid) ? "" : "return ", narg,
237 nquad, (isvoid) ? "NR" : "",
238 funclistit->type, funclistit->name
240 } else {
241 fprintf(out,
242 " %sAROS_LCQUAD%d%s(%s, %s,\n",
243 (isvoid) ? "" : "return ",
244 nquad, (isvoid) ? "NR" : "",
245 funclistit->type, funclistit->name
249 for (arglistit = funclistit->arguments, count = 1;
250 arglistit != NULL;
251 arglistit = arglistit->next, count++
254 char *quad2 = strchr(arglistit->reg, '/');
256 arglistit->reg[2] = 0;
257 type = getargtype(arglistit);
258 assert(type != NULL);
260 if (quad2 != NULL) {
261 *quad2 = 0;
262 fprintf(out,
263 " AROS_LCAQUAD(%s%s, (__arg%d), %s, %s), \\\n",
264 ((isvararg) && (!arglistit->next)) ? "const " : "",
265 type, count, arglistit->reg, quad2+1
267 *quad2 = '/';
268 } else {
269 fprintf(out,
270 " AROS_LCA(%s%s, (__arg%d), %s), \\\n",
271 ((isvararg) && (!arglistit->next)) ? "const " : "",
272 type, count, arglistit->reg
275 free(type);
278 fprintf(out,
279 " %s, (__%s), %u, %s"
280 " );\n"
281 "}\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 __inline_%s_%s(", cfg->basename, funclistit->name);
296 for (arglistit = funclistit->arguments, count = 1;
297 arglistit != NULL;
298 arglistit = arglistit->next, count++
300 fprintf(out, "(arg%d), ", count);
301 fprintf(out, "__aros_getbase_%s())\n", cfg->libbase);
304 void
305 writeinlinevararg(FILE *out, struct functionhead *funclistit, struct config *cfg, char isvararg, char *varargname)
307 struct functionarg *arglistit = funclistit->arguments;
308 int isvoid;
310 isvoid = strcmp(funclistit->type, "void") == 0
311 || strcmp(funclistit->type, "VOID") == 0;
313 if (isvararg == 1)
315 int count;
316 char *type;
318 fprintf(out,
319 "\n#if !defined(NO_INLINE_STDARG) && !defined(%s_NO_INLINE_STDARG)\n"
320 "#define %s(",
321 cfg->includenameupper, varargname
323 for (arglistit = funclistit->arguments, count = 1;
324 arglistit != NULL && arglistit->next != NULL;
325 arglistit = arglistit->next, count++
328 fprintf(out, "arg%d, ", count);
330 fprintf(out,
331 "...) \\\n"
332 "({ \\\n"
334 for (arglistit = funclistit->arguments, count = 1;
335 arglistit != NULL;
336 arglistit = arglistit->next, count++
339 if (arglistit->next == NULL)
341 fprintf(out, " const IPTR %s_args[] = { AROS_PP_VARIADIC_CAST2IPTR(__VA_ARGS__) };\\\n", funclistit->name);
344 fprintf(out,
345 " %s(",
346 funclistit->name
348 for (arglistit = funclistit->arguments, count = 1;
349 arglistit != NULL;
350 arglistit = arglistit->next, count++
353 if (arglistit != funclistit->arguments)
354 fprintf(out, ", ");
356 if (arglistit->next == NULL)
358 type = getargtype(arglistit);
359 assert(type != NULL);
360 fprintf(out, "(const %s)(%s_args)", type, funclistit->name);
361 free(type);
363 else
364 fprintf(out, "(arg%d)", count);
366 fprintf(out,
367 "); \\\n"
368 "})\n"
369 "#endif /* !NO_INLINE_STDARG */\n"
372 else if (isvararg == 2)
374 int count;
376 fprintf(out,
377 "\n#if !defined(NO_INLINE_STDARG) && !defined(%s_NO_INLINE_STDARG)\n"
378 "static inline %s __inline_%s_%s(%s __%s",
379 cfg->includenameupper,
380 funclistit->type, cfg->basename, varargname, cfg->libbasetypeptrextern, cfg->libbase
382 for (arglistit = funclistit->arguments, count = 0;
383 arglistit != NULL && arglistit->next != NULL;
384 arglistit = arglistit->next
387 char *type = getargtype(arglistit);
389 fprintf(out, ", %s __arg%d", type, ++count);
391 fprintf(out, ", ...)\n");
393 fprintf(out,
394 "{\n"
395 " %s retval;\n"
396 " va_list __args;\n"
397 "\n"
398 " va_start(__args, __arg%d);\n"
399 " retval = __inline_%s_%s(",
400 funclistit->type,
401 count,
402 cfg->basename, funclistit->name
404 for (arglistit = funclistit->arguments, count = 1;
405 arglistit != NULL && arglistit->next != NULL;
406 arglistit = arglistit->next, count++
409 fprintf(out, "__arg%d, ", count);
411 fprintf(out,
412 "__args, __%s);\n"
413 " va_end(__args);\n"
414 " return retval;\n"
415 "}\n"
416 "\n"
417 "#define %s(",
418 cfg->libbase,
419 varargname
421 for (arglistit = funclistit->arguments, count = 1;
422 arglistit != NULL && arglistit->next != NULL && arglistit->next->next != NULL;
423 arglistit = arglistit->next, count++
426 fprintf(out, "arg%d, ", count);
428 fprintf(out,
429 "...) \\\n"
430 " __inline_%s_%s(%s, ",
431 cfg->basename, varargname, cfg->libbase
433 for (arglistit = funclistit->arguments, count = 1;
434 arglistit != NULL && arglistit->next != NULL && arglistit->next->next != NULL;
435 arglistit = arglistit->next, count++
438 fprintf(out, "(arg%d), ", count);
440 fprintf(out,
441 "__VA_ARGS__)\n"
442 "#endif /* !NO_INLINE_STDARG */\n"
445 else if (isvararg == 3)
447 int count;
449 fprintf(out,
450 "\n#if !defined(NO_INLINE_STDARG) && !defined(%s_NO_INLINE_STDARG)\n"
451 "static inline %s __inline_%s_%s(%s __%s",
452 cfg->includenameupper,
453 funclistit->type, cfg->basename, varargname, cfg->libbasetypeptrextern, cfg->libbase
455 for (arglistit = funclistit->arguments, count = 0;
456 arglistit != NULL && arglistit->next != NULL;
457 arglistit = arglistit->next
460 char *type = getargtype(arglistit);
462 fprintf(out, ", %s __arg%d", type, ++count);
464 fprintf(out, ", ...)\n");
466 fprintf(out,"{\n");
467 if (!isvoid)
468 fprintf(out, " %s retval;\n", funclistit->type);
470 fprintf(out,
471 "\n"
472 " AROS_SLOWSTACKFORMAT_PRE(__arg%d);\n"
473 " %s__inline_%s_%s(",
474 count,
475 isvoid ? "" : "retval = ",
476 cfg->basename, funclistit->name
478 for (arglistit = funclistit->arguments, count = 1;
479 arglistit != NULL && arglistit->next != NULL;
480 arglistit = arglistit->next, count++
483 fprintf(out, "__arg%d, ", count);
485 count--;
486 fprintf(out,
487 "AROS_SLOWSTACKFORMAT_ARG(__arg%d), __%s);\n"
488 " AROS_SLOWSTACKFORMAT_POST(__arg%d);\n"
489 " return%s;\n"
490 "}\n"
491 "\n"
492 "#define %s(",
493 count,
494 cfg->libbase,
495 count,
496 isvoid ? "" : " retval",
497 varargname
499 for (arglistit = funclistit->arguments, count = 1;
500 arglistit != NULL && arglistit->next != NULL && arglistit->next->next != NULL;
501 arglistit = arglistit->next, count++
504 fprintf(out, "arg%d, ", count);
506 fprintf(out,
507 "...) \\\n"
508 " __inline_%s_%s((%s)(%s), ",
509 cfg->basename, varargname,
510 cfg->libbasetypeptrextern,
511 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);