Added very useful and convenient macro for parsing attribute IDs
[AROS.git] / tools / genmodule / writeincinline.c
blob08a7c26431c786e4f4e573adacd3a8f498f93910
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 fprintf(out,
53 "\n"
54 "#if !defined(__%s_LIBAPI__) || (%d <= __%s_LIBAPI__)"
55 "\n",
56 cfg->modulenameupper,
57 funclistit->version,
58 cfg->modulenameupper
61 if (funclistit->libcall != STACK)
63 writeinlineregister(out, funclistit, cfg);
64 if (!funclistit->novararg)
65 writeinlinevararg(out, funclistit, cfg);
67 else /* libcall == STACK */
69 /* This is the same as in defines */
70 writedefinestack(out, funclistit, cfg);
73 writealiases(out, funclistit, cfg);
75 fprintf(out,
76 "\n"
77 "#endif /* !defined(__%s_LIBAPI__) || (%d <= __%s_LIBAPI__) */"
78 "\n",
79 cfg->modulenameupper,
80 funclistit->version,
81 cfg->modulenameupper
86 fprintf(out,
87 "\n"
88 "#endif /* INLINE_%s_H*/\n",
89 cfg->modulenameupper
91 fclose(out);
95 void
96 writeinlineregister(FILE *out, struct functionhead *funclistit, struct config *cfg)
98 struct functionarg *arglistit;
99 int count, isvoid;
100 int narg=0,nquad=0;
101 char *type;
103 isvoid = strcmp(funclistit->type, "void") == 0
104 || strcmp(funclistit->type, "VOID") == 0;
106 fprintf(out,
107 "\n"
108 "static inline %s __inline_%s_%s(",
109 funclistit->type, cfg->basename, funclistit->name
111 for (arglistit = funclistit->arguments, count = 1;
112 arglistit!=NULL;
113 arglistit = arglistit->next, count++
116 type = getargtype(arglistit);
117 fprintf(out, "%s __arg%d, ", type, count);
118 if (strchr(arglistit->reg, '/') != NULL) {
119 nquad++;
120 } else {
121 narg++;
124 fprintf(out,
125 "APTR __%s)\n"
126 "{\n",
127 cfg->libbase
129 fprintf(out,
130 " AROS_LIBREQ(%s, %d)\n",
131 cfg->libbase, funclistit->version
133 if (nquad==0)
135 fprintf(out,
136 " %sAROS_LC%d%s(%s, %s,\n",
137 (isvoid) ? "" : "return ",
138 funclistit->argcount, (isvoid) ? "NR" : "",
139 funclistit->type, funclistit->name
142 for (arglistit = funclistit->arguments, count = 1;
143 arglistit!=NULL;
144 arglistit = arglistit->next, count++
147 type = getargtype(arglistit);
148 assert(type != NULL);
149 fprintf(out,
150 " AROS_LCA(%s,(__arg%d),%s),\n",
151 type, count, arglistit->reg
153 free(type);
156 else /* nquad != 0 */
158 if (narg) {
159 fprintf(out,
160 " %sAROS_LC%dQUAD%d%s(%s, %s,\n",
161 (isvoid) ? "" : "return ", narg,
162 nquad, (isvoid) ? "NR" : "",
163 funclistit->type, funclistit->name
165 } else {
166 fprintf(out,
167 " %sAROS_LCQUAD%d%s(%s, %s,\n",
168 (isvoid) ? "" : "return ",
169 nquad, (isvoid) ? "NR" : "",
170 funclistit->type, funclistit->name
174 for (arglistit = funclistit->arguments, count = 1;
175 arglistit != NULL;
176 arglistit = arglistit->next, count++
179 char *quad2 = strchr(arglistit->reg, '/');
181 arglistit->reg[2] = 0;
182 type = getargtype(arglistit);
183 assert(type != NULL);
185 if (quad2 != NULL) {
186 *quad2 = 0;
187 fprintf(out,
188 " AROS_LCAQUAD(%s, (__arg%d), %s, %s), \\\n",
189 type, count, arglistit->reg, quad2+1
191 *quad2 = '/';
192 } else {
193 fprintf(out,
194 " AROS_LCA(%s, (__arg%d), %s), \\\n",
195 type, count, arglistit->reg
198 free(type);
201 fprintf(out,
202 " %s, (__%s), %u, %s"
203 " );\n"
204 "}\n\n",
205 cfg->libbasetypeptrextern, cfg->libbase, funclistit->lvo, cfg->basename
208 fprintf(out, "#define %s(", funclistit->name);
209 for (arglistit = funclistit->arguments, count = 1;
210 arglistit != NULL;
211 arglistit = arglistit->next, count++
214 if (arglistit != funclistit->arguments)
215 fprintf(out, ", ");
216 fprintf(out, "arg%d", count);
218 fprintf(out, ") \\\n __inline_%s_%s(", cfg->basename, funclistit->name);
219 for (arglistit = funclistit->arguments, count = 1;
220 arglistit != NULL;
221 arglistit = arglistit->next, count++
223 fprintf(out, "(arg%d), ", count);
224 fprintf(out, "__aros_getbase_%s())\n", cfg->libbase);
227 void
228 writeinlinevararg(FILE *out, struct functionhead *funclistit, struct config *cfg)
230 struct functionarg *arglistit = funclistit->arguments;
231 char isvararg = 0, *varargname, *lastname;
233 /* Go to last argument */
234 if (arglistit == NULL)
235 return;
237 while (arglistit->next != NULL) arglistit = arglistit->next;
239 lastname = getargname(arglistit);
240 assert(lastname != NULL);
242 if (*(funclistit->name + strlen(funclistit->name) - 1) == 'A')
244 isvararg = 1;
245 varargname = strdup(funclistit->name);
246 varargname[strlen(funclistit->name)-1] = '\0';
248 else if (strcmp(funclistit->name + strlen(funclistit->name) - 7, "TagList") == 0)
250 isvararg = 1;
251 /* TagList has to be changed in Tags at the end of the functionname */
252 varargname = strdup(funclistit->name);
253 varargname[strlen(funclistit->name)-4] = 's';
254 varargname[strlen(funclistit->name)-3] = '\0';
256 else if (strcmp(funclistit->name + strlen(funclistit->name) - 4, "Args") == 0
257 && (strcasecmp(lastname, "args") == 0 || strcasecmp(lastname, "arglist") == 0)
260 isvararg = 1;
261 varargname = strdup(funclistit->name);
262 varargname[strlen(funclistit->name)-4] = '\0';
264 else if ((funclistit->name[0] == 'V') && (strncmp(arglistit->arg, "va_list", 7) == 0))
266 isvararg = 2;
267 varargname = malloc(strlen(funclistit->name));
268 strcpy(varargname, &funclistit->name[1]);
270 else
272 char *p;
275 if (strncmp(arglistit->arg, "const", 5) == 0) {
276 p = arglistit->arg + 5;
277 while (isspace(*p)) p++;
278 } else
279 p = arglistit->arg;
280 if (strncmp(p, "struct", 6)==0)
282 p += 6;
283 while (isspace(*p)) p++;
284 if (strncmp(p, "TagItem", 7) == 0)
286 p += 7;
287 while (isspace(*p)) p++;
289 if (*p == '*')
291 isvararg = 1;
292 varargname = malloc(strlen(funclistit->name) + 5);
293 strcpy(varargname, funclistit->name);
294 strcat(varargname, "Tags");
299 if (isvararg == 1)
301 int count;
302 char *type;
304 fprintf(out,
305 "\n#if !defined(NO_INLINE_STDARG) && !defined(%s_NO_INLINE_STDARG)\n"
306 "#define %s(",
307 cfg->modulenameupper, varargname
309 for (arglistit = funclistit->arguments, count = 1;
310 arglistit != NULL && arglistit->next != NULL;
311 arglistit = arglistit->next, count++
314 fprintf(out, "arg%d, ", count);
316 fprintf(out,
317 "...) \\\n"
318 "({ \\\n"
319 " %s(",
320 funclistit->name
322 for (arglistit = funclistit->arguments, count = 1;
323 arglistit != NULL;
324 arglistit = arglistit->next, count++
327 if (arglistit != funclistit->arguments)
328 fprintf(out, ", ");
330 if (arglistit->next == NULL)
332 type = getargtype(arglistit);
333 assert(type != NULL);
334 fprintf(out, "(%s)(IPTR []){ AROS_PP_VARIADIC_CAST2IPTR(__VA_ARGS__) }", type);
335 free(type);
337 else
338 fprintf(out, "(arg%d)", count);
340 fprintf(out,
341 "); \\\n"
342 "})\n"
343 "#endif /* !NO_INLINE_STDARG */\n"
346 free(varargname);
348 else if (isvararg == 2)
350 int count;
352 fprintf(out,
353 "\n#if !defined(NO_INLINE_STDARG) && !defined(%s_NO_INLINE_STDARG)\n"
354 "static inline %s __inline_%s_%s(%s __%s",
355 cfg->modulenameupper,
356 funclistit->type, cfg->basename, varargname, cfg->libbasetypeptrextern, cfg->libbase
358 for (arglistit = funclistit->arguments, count = 0;
359 arglistit != NULL && arglistit->next != NULL;
360 arglistit = arglistit->next
363 char *type = getargtype(arglistit);
365 fprintf(out, ", %s __arg%d", type, ++count);
367 fprintf(out, ", ...)\n");
369 fprintf(out,
370 "{\n"
371 " %s retval;\n"
372 " va_list __args;\n"
373 "\n"
374 " va_start(__args, __arg%d);\n"
375 " retval = __inline_%s_%s(",
376 funclistit->type,
377 count,
378 cfg->basename, funclistit->name
380 for (arglistit = funclistit->arguments, count = 1;
381 arglistit != NULL && arglistit->next != NULL;
382 arglistit = arglistit->next, count++
385 fprintf(out, "__arg%d, ", count);
387 fprintf(out,
388 "__args, __%s);\n"
389 " va_end(__args);\n"
390 " return retval;\n"
391 "}\n"
392 "\n"
393 "#define %s(",
394 cfg->libbase,
395 varargname
397 for (arglistit = funclistit->arguments, count = 1;
398 arglistit != NULL && arglistit->next != NULL && arglistit->next->next != NULL;
399 arglistit = arglistit->next, count++
402 fprintf(out, "arg%d, ", count);
404 fprintf(out,
405 "...) \\\n"
406 " __inline_%s_%s(%s, ",
407 cfg->basename, varargname, cfg->libbase
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 "__VA_ARGS__)\n"
418 "#endif /* !NO_INLINE_STDARG */\n"
421 free(varargname);
425 void
426 writealiases(FILE *out, struct functionhead *funclistit, struct config *cfg)
428 struct stringlist *aliasesit;
430 for (aliasesit = funclistit->aliases;
431 aliasesit != NULL;
432 aliasesit = aliasesit->next
435 fprintf(out, "#define %s %s\n", aliasesit->s, funclistit->name);