Import SB128-v5.24 to main branch
[AROS.git] / tools / genmodule / writeincinline.c
blobd9b7651054f424dcb99e40e82e56f0d380d9aca8
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 *);
10 static void writeinlinevararg(FILE *, struct functionhead *, struct config *);
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->modulename);
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 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->modulenameupper, cfg->modulenameupper, banner, cfg->modulename
46 freeBanner(banner);
48 for (funclistit = cfg->funclist; funclistit!=NULL; funclistit = funclistit->next)
50 if (!funclistit->priv && (funclistit->lvo >= cfg->firstlvo))
52 if (funclistit->libcall != STACK)
54 writeinlineregister(out, funclistit, cfg);
55 if (!funclistit->novararg)
56 writeinlinevararg(out, funclistit, cfg);
58 else /* libcall == STACK */
60 /* NOP: nothing to be written for stack argument passing.
61 The stubs in sthe link library will be used */
64 writealiases(out, funclistit, cfg);
68 fprintf(out,
69 "\n"
70 "#endif /* INLINE_%s_H*/\n",
71 cfg->modulenameupper
73 fclose(out);
77 void
78 writeinlineregister(FILE *out, struct functionhead *funclistit, struct config *cfg)
80 struct functionarg *arglistit;
81 int count, isvoid;
82 int narg=0,nquad=0;
83 char *type;
85 isvoid = strcmp(funclistit->type, "void") == 0
86 || strcmp(funclistit->type, "VOID") == 0;
88 fprintf(out,
89 "\n"
90 "static inline %s __inline_%s_%s(",
91 funclistit->type, cfg->basename, funclistit->name
93 for (arglistit = funclistit->arguments, count = 1;
94 arglistit!=NULL;
95 arglistit = arglistit->next, count++
98 type = getargtype(arglistit);
99 fprintf(out, "%s __arg%d, ", type, count);
100 if (strchr(arglistit->reg, '/') != NULL) {
101 nquad++;
102 } else {
103 narg++;
106 fprintf(out,
107 "APTR __%s)\n"
108 "{\n",
109 cfg->libbase
111 if (cfg->options & OPTION_AUTOINIT) {
112 fprintf(out,
113 " AROS_LIBREQ(%s, %d)\n",
114 cfg->libbase, funclistit->version
117 if (nquad==0)
119 fprintf(out,
120 " %sAROS_LC%d%s(%s, %s,\n",
121 (isvoid) ? "" : "return ",
122 funclistit->argcount, (isvoid) ? "NR" : "",
123 funclistit->type, funclistit->name
126 for (arglistit = funclistit->arguments, count = 1;
127 arglistit!=NULL;
128 arglistit = arglistit->next, count++
131 type = getargtype(arglistit);
132 assert(type != NULL);
133 fprintf(out,
134 " AROS_LCA(%s,(__arg%d),%s),\n",
135 type, count, arglistit->reg
137 free(type);
140 else /* nquad != 0 */
142 if (narg) {
143 fprintf(out,
144 " %sAROS_LC%dQUAD%d%s(%s, %s,\n",
145 (isvoid) ? "" : "return ", narg,
146 nquad, (isvoid) ? "NR" : "",
147 funclistit->type, funclistit->name
149 } else {
150 fprintf(out,
151 " %sAROS_LCQUAD%d%s(%s, %s,\n",
152 (isvoid) ? "" : "return ",
153 nquad, (isvoid) ? "NR" : "",
154 funclistit->type, funclistit->name
158 for (arglistit = funclistit->arguments, count = 1;
159 arglistit != NULL;
160 arglistit = arglistit->next, count++
163 char *quad2 = strchr(arglistit->reg, '/');
165 arglistit->reg[2] = 0;
166 type = getargtype(arglistit);
167 assert(type != NULL);
169 if (quad2 != NULL) {
170 *quad2 = 0;
171 fprintf(out,
172 " AROS_LCAQUAD(%s, (__arg%d), %s, %s), \\\n",
173 type, count, arglistit->reg, quad2+1
175 *quad2 = '/';
176 } else {
177 fprintf(out,
178 " AROS_LCA(%s, (__arg%d), %s), \\\n",
179 type, count, arglistit->reg
182 free(type);
185 fprintf(out,
186 " %s, (__%s), %u, %s"
187 " );\n"
188 "}\n\n",
189 cfg->libbasetypeptrextern, cfg->libbase, funclistit->lvo, cfg->basename
192 fprintf(out, "#define %s(", funclistit->name);
193 for (arglistit = funclistit->arguments, count = 1;
194 arglistit != NULL;
195 arglistit = arglistit->next, count++
198 if (arglistit != funclistit->arguments)
199 fprintf(out, ", ");
200 fprintf(out, "arg%d", count);
202 fprintf(out, ") \\\n __inline_%s_%s(", cfg->basename, funclistit->name);
203 for (arglistit = funclistit->arguments, count = 1;
204 arglistit != NULL;
205 arglistit = arglistit->next, count++
207 fprintf(out, "(arg%d), ", count);
208 fprintf(out, "(APTR)%s)\n", cfg->libbase);
211 void
212 writeinlinevararg(FILE *out, struct functionhead *funclistit, struct config *cfg)
214 struct functionarg *arglistit = funclistit->arguments;
215 char isvararg = 0, *varargname, *lastname;
217 /* Go to last argument */
218 if (arglistit == NULL)
219 return;
221 while (arglistit->next != NULL) arglistit = arglistit->next;
223 lastname = getargname(arglistit);
224 assert(lastname != NULL);
226 if (*(funclistit->name + strlen(funclistit->name) - 1) == 'A')
228 isvararg = 1;
229 varargname = strdup(funclistit->name);
230 varargname[strlen(funclistit->name)-1] = '\0';
232 else if (strcmp(funclistit->name + strlen(funclistit->name) - 7, "TagList") == 0)
234 isvararg = 1;
235 /* TagList has to be changed in Tags at the end of the functionname */
236 varargname = strdup(funclistit->name);
237 varargname[strlen(funclistit->name)-4] = 's';
238 varargname[strlen(funclistit->name)-3] = '\0';
240 else if (strcmp(funclistit->name + strlen(funclistit->name) - 4, "Args") == 0
241 && (strcasecmp(lastname, "args") == 0 || strcasecmp(lastname, "arglist") == 0)
244 isvararg = 1;
245 varargname = strdup(funclistit->name);
246 varargname[strlen(funclistit->name)-4] = '\0';
248 else if ((funclistit->name[0] == 'V') && (strncmp(arglistit->arg, "va_list", 7) == 0))
250 isvararg = 2;
251 varargname = malloc(strlen(funclistit->name));
252 strcpy(varargname, &funclistit->name[1]);
254 else
256 char *p;
259 if (strncmp(arglistit->arg, "const", 5) == 0) {
260 p = arglistit->arg + 5;
261 while (isspace(*p)) p++;
262 } else
263 p = arglistit->arg;
264 if (strncmp(p, "struct", 6)==0)
266 p += 6;
267 while (isspace(*p)) p++;
268 if (strncmp(p, "TagItem", 7) == 0)
270 p += 7;
271 while (isspace(*p)) p++;
273 if (*p == '*')
275 isvararg = 1;
276 varargname = malloc(strlen(funclistit->name) + 5);
277 strcpy(varargname, funclistit->name);
278 strcat(varargname, "Tags");
283 if (isvararg == 1)
285 int count;
286 char *type;
288 fprintf(out,
289 "\n#if !defined(NO_INLINE_STDARG) && !defined(%s_NO_INLINE_STDARG)\n"
290 "#define %s(",
291 cfg->modulenameupper, varargname
293 for (arglistit = funclistit->arguments, count = 1;
294 arglistit != NULL && arglistit->next != NULL;
295 arglistit = arglistit->next, count++
298 fprintf(out, "arg%d, ", count);
300 fprintf(out,
301 "...) \\\n"
302 "({ \\\n"
303 " IPTR __args[] = { AROS_PP_VARIADIC_CAST2IPTR(__VA_ARGS__) }; \\\n"
304 " %s(",
305 funclistit->name
307 for (arglistit = funclistit->arguments, count = 1;
308 arglistit != NULL;
309 arglistit = arglistit->next, count++
312 if (arglistit != funclistit->arguments)
313 fprintf(out, ", ");
315 if (arglistit->next == NULL)
317 type = getargtype(arglistit);
318 assert(type != NULL);
319 fprintf(out, "(%s)__args", type);
320 free(type);
322 else
323 fprintf(out, "(arg%d)", count);
325 fprintf(out,
326 "); \\\n"
327 "})\n"
328 "#endif /* !NO_INLINE_STDARG */\n"
331 free(varargname);
333 else if (isvararg == 2)
335 int count;
337 fprintf(out,
338 "\n#if !defined(NO_INLINE_STDARG) && !defined(%s_NO_INLINE_STDARG)\n"
339 "static inline %s __inline_%s_%s(%s __%s",
340 cfg->modulenameupper,
341 funclistit->type, cfg->basename, varargname, cfg->libbasetypeptrextern, cfg->libbase
343 for (arglistit = funclistit->arguments, count = 0;
344 arglistit != NULL && arglistit->next != NULL;
345 arglistit = arglistit->next
348 char *type = getargtype(arglistit);
350 fprintf(out, ", %s __arg%d", type, ++count);
352 fprintf(out, ", ...)\n");
354 fprintf(out,
355 "{\n"
356 " %s retval;\n"
357 " va_list __args;\n"
358 "\n"
359 " va_start(__args, __arg%d);\n"
360 " retval = __inline_%s_%s(",
361 funclistit->type,
362 count,
363 cfg->basename, funclistit->name
365 for (arglistit = funclistit->arguments, count = 1;
366 arglistit != NULL && arglistit->next != NULL;
367 arglistit = arglistit->next, count++
370 fprintf(out, "__arg%d, ", count);
372 fprintf(out,
373 "__args, __%s);\n"
374 " va_end(__args);\n"
375 " return retval;\n"
376 "}\n"
377 "\n"
378 "#define %s(",
379 cfg->libbase,
380 varargname
382 for (arglistit = funclistit->arguments, count = 1;
383 arglistit != NULL && arglistit->next != NULL && arglistit->next->next != NULL;
384 arglistit = arglistit->next, count++
387 fprintf(out, "arg%d, ", count);
389 fprintf(out,
390 "...) \\\n"
391 " __inline_%s_%s(%s, ",
392 cfg->basename, varargname, cfg->libbase
394 for (arglistit = funclistit->arguments, count = 1;
395 arglistit != NULL && arglistit->next != NULL && arglistit->next->next != NULL;
396 arglistit = arglistit->next, count++
399 fprintf(out, "(arg%d), ", count);
401 fprintf(out,
402 "__VA_ARGS__)\n"
403 "#endif /* !NO_INLINE_STDARG */\n"
406 free(varargname);
410 void
411 writealiases(FILE *out, struct functionhead *funclistit, struct config *cfg)
413 struct stringlist *aliasesit;
415 for (aliasesit = funclistit->aliases;
416 aliasesit != NULL;
417 aliasesit = aliasesit->next
420 fprintf(out, "#define %s %s\n", aliasesit->s, funclistit->name);