genmodule: Allow the use of __LIBNAME_LIBAPI__=NN defines
[AROS.git] / tools / genmodule / writeincdefines.c
blob68e77953be20b3a6e1d253ea6024ab8ed65d0800
1 /*
2 Copyright © 1995-2011, The AROS Development Team. All rights reserved.
3 $Id$
5 Function to write defines/modulename.h. Part of genmodule.
6 */
7 #include "genmodule.h"
9 static void writedefineregister(FILE *, struct functionhead *, struct config *);
10 static void writedefinevararg(FILE *, struct functionhead *, struct config *);
11 static void writealiases(FILE *, struct functionhead *, struct config *);
13 void writeincdefines(struct config *cfg)
15 FILE *out;
16 char line[256], *banner;
17 struct functionhead *funclistit;
19 snprintf(line, 255, "%s/defines/%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 DEFINES_%s_H\n"
31 "#define DEFINES_%s_H\n"
32 "\n"
33 "%s"
34 "\n"
35 "/*\n"
36 " Desc: Defines 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 "__BEGIN_DECLS\n"
45 "\n",
46 cfg->modulenameupper, cfg->modulenameupper, banner, cfg->modulename
48 freeBanner(banner);
50 for (funclistit = cfg->funclist; funclistit!=NULL; funclistit = funclistit->next)
52 if (!funclistit->priv && (funclistit->lvo >= cfg->firstlvo))
54 fprintf(out,
55 "\n"
56 "#if !defined(__%s_LIBAPI__) || (%d <= __%s_LIBAPI__)"
57 "\n",
58 cfg->modulenameupper,
59 funclistit->version,
60 cfg->modulenameupper
63 if (funclistit->libcall != STACK)
65 writedefineregister(out, funclistit, cfg);
66 if (!funclistit->novararg)
67 writedefinevararg(out, funclistit, cfg);
69 else /* libcall == STACK */
71 writedefinestack(out, funclistit, cfg);
74 writealiases(out, funclistit, cfg);
76 fprintf(out,
77 "\n"
78 "#endif /* !defined(__%s_LIBAPI__) || (%d <= __%s_LIBAPI__) */"
79 "\n",
80 cfg->modulenameupper,
81 funclistit->version,
82 cfg->modulenameupper
87 fprintf(out,
88 "\n"
89 "__END_DECLS\n"
90 "\n"
91 "#endif /* DEFINES_%s_H*/\n",
92 cfg->modulenameupper
94 fclose(out);
98 void
99 writedefineregister(FILE *out, struct functionhead *funclistit, struct config *cfg)
101 struct functionarg *arglistit;
102 int count, isvoid;
103 char *type;
105 isvoid = strcmp(funclistit->type, "void") == 0
106 || strcmp(funclistit->type, "VOID") == 0;
108 fprintf(out,
109 "\n"
110 "#define __%s_WB(__%s",
111 funclistit->name, cfg->libbase
113 for (arglistit = funclistit->arguments, count = 1;
114 arglistit!=NULL;
115 arglistit = arglistit->next, count++
118 fprintf(out, ", __arg%d", count);
120 fprintf(out,
121 ") ({\\\n"
123 if (cfg->options & OPTION_AUTOINIT) {
124 fprintf(out,
125 " AROS_LIBREQ(%s,%d)\\\n",
126 cfg->libbase, funclistit->version
129 if (funclistit->arguments == NULL
130 || strchr(funclistit->arguments->reg, '/') == NULL
133 fprintf(out,
134 " AROS_LC%d%s(%s, %s, \\\n",
135 funclistit->argcount, (isvoid) ? "NR" : "",
136 funclistit->type, funclistit->name
139 for (arglistit = funclistit->arguments, count = 1;
140 arglistit!=NULL;
141 arglistit = arglistit->next, count++
144 type = getargtype(arglistit);
145 assert(type != NULL);
146 fprintf(out,
147 " AROS_LCA(%s,(__arg%d),%s), \\\n",
148 type, count, arglistit->reg
150 free(type);
153 else
155 fprintf(out,
156 " AROS_LCQUAD%d%s(%s, %s, \\\n",
157 funclistit->argcount, (isvoid) ? "NR" : "",
158 funclistit->type, funclistit->name
161 for (arglistit = funclistit->arguments, count = 1;
162 arglistit != NULL;
163 arglistit = arglistit->next, count++
166 if (strlen(arglistit->reg) != 5)
168 fprintf(stderr, "Internal error: ../.. register format expected\n");
169 exit(20);
171 arglistit->reg[2] = 0;
173 type = getargtype(arglistit);
174 assert(type != NULL);
176 fprintf(out,
177 " AROS_LCAQUAD(%s, (__arg%d), %s, %s), \\\n",
178 type, count, arglistit->reg, arglistit->reg+3
180 arglistit->reg[2] = '/';
181 free(type);
184 fprintf(out,
185 " %s, (__%s), %u, %s);\\\n})\n\n",
186 cfg->libbasetypeptrextern, cfg->libbase, funclistit->lvo, cfg->basename
189 fprintf(out, "#define %s(", funclistit->name);
190 for (arglistit = funclistit->arguments, count = 1;
191 arglistit != NULL;
192 arglistit = arglistit->next, count++
195 if (arglistit != funclistit->arguments)
196 fprintf(out, ", ");
197 fprintf(out, "arg%d", count);
199 fprintf(out, ") \\\n __%s_WB(%s", funclistit->name, cfg->libbase);
200 for (arglistit = funclistit->arguments, count = 1;
201 arglistit != NULL;
202 arglistit = arglistit->next, count++
204 fprintf(out, ", (arg%d)", count);
205 fprintf(out, ")\n");
208 void
209 writedefinevararg(FILE *out, struct functionhead *funclistit, struct config *cfg)
211 struct functionarg *arglistit = funclistit->arguments;
212 char isvararg = 0, *varargname, *lastname;
214 /* Go to last argument */
215 if (arglistit == NULL)
216 return;
218 while (arglistit->next != NULL) arglistit = arglistit->next;
220 lastname = getargname(arglistit);
221 assert(lastname != NULL);
223 if (*(funclistit->name + strlen(funclistit->name) - 1) == 'A')
225 isvararg = 1;
226 varargname = strdup(funclistit->name);
227 varargname[strlen(funclistit->name)-1] = '\0';
229 else if (strcmp(funclistit->name + strlen(funclistit->name) - 7, "TagList") == 0)
231 isvararg = 1;
232 /* TagList has to be changed in Tags at the end of the functionname */
233 varargname = strdup(funclistit->name);
234 varargname[strlen(funclistit->name)-4] = 's';
235 varargname[strlen(funclistit->name)-3] = '\0';
237 else if (strcmp(funclistit->name + strlen(funclistit->name) - 4, "Args") == 0
238 && (strcasecmp(lastname, "args") == 0 || strcasecmp(lastname, "arglist") == 0)
241 isvararg = 1;
242 varargname = strdup(funclistit->name);
243 varargname[strlen(funclistit->name)-4] = '\0';
245 else if ((funclistit->name[0] == 'V') && (strncmp(arglistit->arg, "va_list", 7) == 0))
247 isvararg = 2;
248 varargname = malloc(strlen(funclistit->name));
249 strcpy(varargname, &funclistit->name[1]);
251 else
253 char *p;
255 if (strncmp(arglistit->arg, "const", 5) == 0) {
256 p = arglistit->arg + 5;
257 while (isspace(*p)) p++;
258 } else
259 p = arglistit->arg;
260 if (strncmp(p, "struct", 6)==0)
262 p += 6;
263 while (isspace(*p)) p++;
264 if (strncmp(p, "TagItem", 7) == 0)
266 p += 7;
267 while (isspace(*p)) p++;
269 if (*p == '*')
271 isvararg = 1;
272 varargname = malloc(strlen(funclistit->name) + 5);
273 strcpy(varargname, funclistit->name);
274 strcat(varargname, "Tags");
280 if (isvararg == 1)
282 int count;
283 char *type;
285 fprintf(out,
286 "\n#if !defined(NO_INLINE_STDARG) && !defined(%s_NO_INLINE_STDARG)\n"
287 "#define %s(",
288 cfg->modulenameupper, varargname
290 for (arglistit = funclistit->arguments, count = 1;
291 arglistit != NULL && arglistit->next != NULL;
292 arglistit = arglistit->next, count++
295 fprintf(out, "arg%d, ", count);
297 fprintf(out,
298 "...) \\\n"
299 "({ \\\n"
300 " IPTR __args[] = { AROS_PP_VARIADIC_CAST2IPTR(__VA_ARGS__) }; \\\n"
301 " %s(",
302 funclistit->name
304 for (arglistit = funclistit->arguments, count = 1;
305 arglistit != NULL;
306 arglistit = arglistit->next, count++
309 if (arglistit != funclistit->arguments)
310 fprintf(out, ", ");
312 if (arglistit->next == NULL)
314 type = getargtype(arglistit);
315 assert(type != NULL);
316 fprintf(out, "(%s)__args", type);
317 free(type);
319 else
320 fprintf(out, "(arg%d)", count);
322 fprintf(out,
323 "); \\\n"
324 "})\n"
325 "#endif /* !NO_INLINE_STDARG */\n"
328 free(varargname);
330 else if (isvararg == 2)
332 int count;
333 struct functionarg *lastarg;
335 fprintf(out,
336 "\n#if !defined(NO_INLINE_STDARG) && !defined(%s_NO_INLINE_STDARG)\n"
337 "static inline %s __%s_WB(%s __%s",
338 cfg->modulenameupper,
339 funclistit->type, varargname, cfg->libbasetypeptrextern, cfg->libbase
341 for (arglistit = funclistit->arguments;
342 arglistit != NULL && arglistit->next != NULL;
343 arglistit = arglistit->next
346 fprintf(out, ", %s", arglistit->arg);
347 lastarg = arglistit;
349 fprintf(out, ", ...)\n");
351 fprintf(out,
352 "{\n"
353 " %s retval;\n"
354 " va_list args;\n"
355 "\n"
356 " va_start(args, %s);\n"
357 " retval = __%s_WB(__%s, ",
358 funclistit->type,
359 getargname(lastarg),
360 funclistit->name, cfg->libbase
362 for (arglistit = funclistit->arguments;
363 arglistit != NULL && arglistit->next != NULL;
364 arglistit = arglistit->next
367 fprintf(out, "%s, ", getargname(arglistit));
369 fprintf(out,
370 "args);\n"
371 " va_end(args);\n"
372 " return retval;\n"
373 "}\n"
374 "#define %s(",
375 varargname
377 for (arglistit = funclistit->arguments, count = 1;
378 arglistit != NULL && arglistit->next != NULL;
379 arglistit = arglistit->next, count++
382 fprintf(out, "arg%d, ", count);
384 fprintf(out,
385 "...) __%s_WB(%s, ",
386 varargname, cfg->libbase
388 for (arglistit = funclistit->arguments, count = 1;
389 arglistit != NULL && arglistit->next != NULL;
390 arglistit = arglistit->next, count++
393 fprintf(out, "(arg%d), ", count);
395 fprintf(out,
396 "__VA_ARGS__)\n"
397 "#endif /* !NO_INLINE_STDARG */\n"
400 free(varargname);
404 void
405 writedefinestack(FILE *out, struct functionhead *funclistit, struct config *cfg)
407 struct functionarg *arglistit;
409 /* Only if no peropener or pertask base */
410 if (cfg->options & OPTION_DUPBASE)
411 return;
413 fprintf(out, "#define %s ((%s (*)(", funclistit->name, funclistit->type);
414 for (arglistit = funclistit->arguments;
415 arglistit != NULL;
416 arglistit = arglistit->next
419 fprintf(out, "%s", arglistit->arg);
420 if (arglistit->next != NULL)
421 fprintf(out, ", ");
423 fprintf(out, "))__AROS_GETVECADDR(%s,%d))\n", cfg->libbase, funclistit->lvo);
426 void
427 writealiases(FILE *out, struct functionhead *funclistit, struct config *cfg)
429 struct stringlist *aliasesit;
431 for (aliasesit = funclistit->aliases;
432 aliasesit != NULL;
433 aliasesit = aliasesit->next
436 fprintf(out, "#define %s %s\n", aliasesit->s, funclistit->name);