OS X's sed doesn't understand the 'i' flag. And commas and spaces don't
[AROS.git] / tools / genmodule / functionhead.c
blob7abf822fe2c8ded9844421ad3151c13a8a5544a3
1 /*
2 Copyright © 1995-2009, The AROS Development Team. All rights reserved.
3 $Id$
5 The code for storing information of functions present in the module
6 */
7 #include <string.h>
8 #include <assert.h>
9 #include "functionhead.h"
10 #include "config.h"
12 struct functionhead *newfunctionhead(const char *name, enum libcall libcall)
14 struct functionhead *funchead = malloc(sizeof(struct functionhead));
16 if (funchead != NULL)
18 funchead->next = NULL;
19 funchead->internalname = funchead->name = strdup(name);
20 funchead->type = NULL;
21 funchead->libcall = libcall;
22 funchead->lvo = 0;
23 funchead->argcount = 0;
24 funchead->arguments = NULL;
25 funchead->aliases = NULL;
26 funchead->interface = NULL;
27 funchead->method = NULL;
28 funchead->novararg = 0;
29 funchead->priv= 0;
31 else
33 puts("Out of memory !");
34 exit(20);
37 return funchead;
40 struct functionarg *funcaddarg
42 struct functionhead *funchead,
43 const char *arg, const char *reg
46 struct functionarg **argptr = &funchead->arguments;
48 while ((*argptr) != NULL) argptr = &(*argptr)->next;
50 *argptr = malloc(sizeof(struct functionarg));
51 if (*argptr != NULL)
53 (*argptr)->next = NULL;
54 (*argptr)->arg = (arg == NULL) ? NULL : strdup(arg);
55 (*argptr)->reg = (reg == NULL) ? NULL : strdup(reg);
57 funchead->argcount++;
59 else
61 puts("Out of memory !");
62 exit(20);
65 return *argptr;
68 struct stringlist *funcaddalias(struct functionhead *funchead, const char *alias)
70 return slist_append(&funchead->aliases, alias);
73 void funcsetinternalname(struct functionhead *funchead, const char *internalname)
75 if (funchead->name != funchead->internalname)
76 free(funchead->internalname);
77 funchead->internalname = strdup(internalname);
80 void writefuncdefs(FILE *out, struct config *cfg, struct functionhead *funclist)
82 struct functionhead *funclistit;
83 struct functionarg *arglistit;
84 char *type, *name;
85 int first;
87 for(funclistit = funclist; funclistit != NULL; funclistit = funclistit->next)
89 switch (funclistit->libcall)
91 case STACK:
92 fprintf(out, "%s %s(", funclistit->type, funclistit->internalname);
94 for(arglistit = funclistit->arguments, first = 1;
95 arglistit != NULL;
96 arglistit = arglistit->next, first = 0
99 if (!first)
100 fprintf(out, ", ");
102 fprintf(out, "%s", arglistit->arg);
104 fprintf(out, ");\n");
105 break;
107 case REGISTER:
108 assert(cfg);
109 fprintf(out, "%s %s(", funclistit->type, funclistit->internalname);
110 for (arglistit = funclistit->arguments, first = 1;
111 arglistit!=NULL;
112 arglistit = arglistit->next, first = 0
115 if (!first)
116 fprintf(out, ", ");
117 fprintf(out, "%s", arglistit->arg);
119 fprintf(out,
120 ");\nAROS_LH%d(%s, %s,\n",
121 funclistit->argcount, funclistit->type, funclistit->internalname
123 for (arglistit = funclistit->arguments;
124 arglistit!=NULL;
125 arglistit = arglistit->next
128 type = getargtype(arglistit);
129 name = getargname(arglistit);
130 assert(name != NULL && type != NULL);
132 fprintf(out,
133 " AROS_LHA(%s, %s, %s),\n",
134 type, name, arglistit->reg
136 free(type);
137 free(name);
139 fprintf(out,
140 " %s, %s, %u, %s)\n"
141 "{\n"
142 " AROS_LIBFUNC_INIT\n\n"
143 " return %s(",
144 cfg->libbasetypeptrextern, cfg->libbase, funclistit->lvo, cfg->basename,
145 funclistit->internalname
147 for (arglistit = funclistit->arguments, first = 1;
148 arglistit!=NULL;
149 arglistit = arglistit->next, first = 0
152 name = getargname(arglistit);
153 assert(name != NULL);
155 if (!first)
156 fprintf(out, ", ");
157 fprintf(out, "%s", name);
158 free(name);
160 fprintf(out,
161 ");\n\n"
162 " AROS_LIBFUNC_EXIT\n"
163 "}\n\n");
164 break;
166 case REGISTERMACRO:
167 assert(cfg);
168 if (funclistit->arguments == NULL
169 || strchr(funclistit->arguments->reg, '/') == NULL)
171 fprintf(out,
172 "AROS_LD%d(%s, %s,\n",
173 funclistit->argcount, funclistit->type, funclistit->internalname
175 for (arglistit = funclistit->arguments;
176 arglistit!=NULL;
177 arglistit = arglistit->next
180 type = getargtype(arglistit);
181 name = getargname(arglistit);
182 assert(type != NULL && name != NULL);
184 fprintf(out,
185 " AROS_LDA(%s, %s, %s),\n",
186 type, name, arglistit->reg
188 free(type);
189 free(name);
191 fprintf(out,
192 " LIBBASETYPEPTR, %s, %u, %s\n"
193 ");\n",
194 cfg->libbase, funclistit->lvo, cfg->basename
197 else
199 fprintf(out,
200 "AROS_LDQUAD%d(%s, %s,\n",
201 funclistit->argcount, funclistit->type, funclistit->internalname
203 for (arglistit = funclistit->arguments;
204 arglistit != NULL;
205 arglistit = arglistit->next
208 if (strlen(arglistit->reg) != 5)
210 fprintf(stderr, "Internal error: ../.. register format expected\n");
211 exit(20);
213 arglistit->reg[2] = 0;
215 type = getargtype(arglistit);
216 name = getargname(arglistit);
217 assert(type != NULL && name != NULL);
219 fprintf(out,
220 " AROS_LDAQUAD(%s, %s, %s, %s),\n",
221 type, name, arglistit->reg, arglistit->reg+3
223 arglistit->reg[2] = '/';
224 free(type);
225 free(name);
227 fprintf(out,
228 " LIBBASETYPEPTR, %s, %u, %s\n"
229 ");\n",
230 cfg->libbase, funclistit->lvo, cfg->basename
233 break;
235 default:
236 fprintf(stderr, "Internal error: unhandled libcall in writefuncdefs\n");
237 exit(20);
238 break;
243 void writefuncprotos(FILE *out, struct config *cfg, struct functionhead *funclist)
245 struct functionhead *funclistit;
246 struct functionarg *arglistit;
247 char *type, *name;
248 int first;
250 for(funclistit = funclist; funclistit != NULL; funclistit = funclistit->next)
252 fprintf(out,
253 "\n"
254 "#if !defined(__%s_LIBAPI__) || (%d <= __%s_LIBAPI__)"
255 "\n",
256 cfg->modulenameupper,
257 funclistit->version,
258 cfg->modulenameupper
261 switch (funclistit->libcall)
263 case STACK:
264 fprintf(out, "%s %s(", funclistit->type, funclistit->name);
266 for(arglistit = funclistit->arguments, first = 1;
267 arglistit != NULL;
268 arglistit = arglistit->next, first = 0
271 if (!first)
272 fprintf(out, ", ");
274 fprintf(out, "%s", arglistit->arg);
276 fprintf(out, ");\n");
277 break;
279 case REGISTER:
280 case REGISTERMACRO:
281 assert(cfg);
282 if (funclistit->priv || funclistit->lvo < cfg->firstlvo) {
283 fprintf(out, "/* private */\n");
284 break;
287 if (funclistit->arguments == NULL
288 || strchr(funclistit->arguments->reg, '/') == NULL
291 fprintf(out,
292 "AROS_LP%d(%s, %s,\n",
293 funclistit->argcount, funclistit->type, funclistit->name
295 for (arglistit = funclistit->arguments;
296 arglistit!=NULL;
297 arglistit = arglistit->next
300 type = getargtype(arglistit);
301 name = getargname(arglistit);
302 assert(type != NULL && name != NULL);
304 fprintf(out,
305 " AROS_LPA(%s, %s, %s),\n",
306 type, name, arglistit->reg
308 free(type);
309 free(name);
311 fprintf(out,
312 " LIBBASETYPEPTR, %s, %u, %s\n"
313 ");\n",
314 cfg->libbase, funclistit->lvo, cfg->basename
317 else
319 fprintf(out,
320 "AROS_LPQUAD%d(%s, %s,\n",
321 funclistit->argcount, funclistit->type, funclistit->name
323 for (arglistit = funclistit->arguments;
324 arglistit != NULL;
325 arglistit = arglistit->next
328 if (strlen(arglistit->reg) != 5)
330 fprintf(stderr, "Internal error: ../.. register format expected\n");
331 exit(20);
333 arglistit->reg[2] = 0;
335 type = getargtype(arglistit);
336 name = getargname(arglistit);
337 assert(type != NULL && name != NULL);
339 fprintf(out,
340 " AROS_LPAQUAD(%s, %s, %s, %s),\n",
341 type, name, arglistit->reg, arglistit->reg+3
343 arglistit->reg[2] = '/';
344 free(type);
345 free(name);
347 fprintf(out,
348 " LIBBASETYPEPTR, %s, %u, %s\n"
349 ");\n",
350 cfg->libbase, funclistit->lvo, cfg->basename
353 break;
355 default:
356 fprintf(stderr, "Internal error: unhandled libcall in writefuncdefs\n");
357 exit(20);
358 break;
361 fprintf(out,
362 "\n"
363 "#endif /* !defined(__%s_LIBAPI__) || (%d <= __%s_LIBAPI__) */"
364 "\n",
365 cfg->modulenameupper,
366 funclistit->version,
367 cfg->modulenameupper
372 char *getargtype(const struct functionarg *funcarg)
374 char *s, *begin, *end;
375 unsigned int brackets = 0, i;
377 begin = s = strdup(funcarg->arg);
379 /* Count the [] at the end of the argument */
380 end = begin+strlen(begin);
381 while (isspace(*(end-1))) end--;
382 while (*(end-1)==']')
384 brackets++;
385 end--;
386 while (isspace(*(end-1)) || isdigit(*(end-1))) end--;
387 if (*(end-1)!='[')
389 free(s);
390 return NULL;
392 end--;
393 while (isspace(*(end-1))) end--;
396 /* Skip over the argument name */
397 while (!isspace(*(end-1)) && *(end-1)!='*')
399 if (begin == end)
401 free(s);
402 fprintf(stderr, "no argument type or name found for arg: %s\n", funcarg->arg);
403 exit(20);
405 end--;
408 /* Add * for the brackets */
409 while (isspace(*(end-1))) end--;
410 for (i=0; i<brackets; i++)
412 *end='*';
413 end++;
415 *end='\0';
417 return s;
420 char *getargname(const struct functionarg *funcarg)
422 char *s, *begin, *end;
423 int len;
425 /* Count the [] at the end of the argument */
426 end = funcarg->arg+strlen(funcarg->arg);
427 while (isspace(*(end-1))) end--;
428 while (*(end-1)==']')
430 end--;
431 while (isspace(*(end-1))) end--;
432 if (*(end-1)!='[')
433 return NULL;
434 end--;
435 while (isspace(*(end-1))) end--;
438 /* Go to the beginning of the argument name */
439 begin = end;
440 while (!isspace(*(begin-1)) && *(begin-1)!='*') begin--;
442 /* Copy the name */
443 len = end - begin;
444 s = malloc(len+1);
445 strncpy(s, begin, len);
446 s[len] = '\0';
448 return s;