- Set a default PCM volume so that something can be heard when driver is
[AROS.git] / tools / genmodule / functionhead.c
blob43d59aebb9438964f85c1034fc54df4f1e57e203
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 switch (funclistit->libcall)
254 case STACK:
255 fprintf(out, "%s %s(", funclistit->type, funclistit->name);
257 for(arglistit = funclistit->arguments, first = 1;
258 arglistit != NULL;
259 arglistit = arglistit->next, first = 0
262 if (!first)
263 fprintf(out, ", ");
265 fprintf(out, "%s", arglistit->arg);
267 fprintf(out, ");\n");
268 break;
270 case REGISTER:
271 case REGISTERMACRO:
272 assert(cfg);
273 if (funclistit->priv || funclistit->lvo < cfg->firstlvo)
274 continue;
276 if (funclistit->arguments == NULL
277 || strchr(funclistit->arguments->reg, '/') == NULL
280 fprintf(out,
281 "AROS_LP%d(%s, %s,\n",
282 funclistit->argcount, funclistit->type, funclistit->name
284 for (arglistit = funclistit->arguments;
285 arglistit!=NULL;
286 arglistit = arglistit->next
289 type = getargtype(arglistit);
290 name = getargname(arglistit);
291 assert(type != NULL && name != NULL);
293 fprintf(out,
294 " AROS_LPA(%s, %s, %s),\n",
295 type, name, arglistit->reg
297 free(type);
298 free(name);
300 fprintf(out,
301 " LIBBASETYPEPTR, %s, %u, %s\n"
302 ");\n",
303 cfg->libbase, funclistit->lvo, cfg->basename
306 else
308 fprintf(out,
309 "AROS_LPQUAD%d(%s, %s,\n",
310 funclistit->argcount, funclistit->type, funclistit->name
312 for (arglistit = funclistit->arguments;
313 arglistit != NULL;
314 arglistit = arglistit->next
317 if (strlen(arglistit->reg) != 5)
319 fprintf(stderr, "Internal error: ../.. register format expected\n");
320 exit(20);
322 arglistit->reg[2] = 0;
324 type = getargtype(arglistit);
325 name = getargname(arglistit);
326 assert(type != NULL && name != NULL);
328 fprintf(out,
329 " AROS_LPAQUAD(%s, %s, %s, %s),\n",
330 type, name, arglistit->reg, arglistit->reg+3
332 arglistit->reg[2] = '/';
333 free(type);
334 free(name);
336 fprintf(out,
337 " LIBBASETYPEPTR, %s, %u, %s\n"
338 ");\n",
339 cfg->libbase, funclistit->lvo, cfg->basename
342 break;
344 default:
345 fprintf(stderr, "Internal error: unhandled libcall in writefuncdefs\n");
346 exit(20);
347 break;
352 char *getargtype(const struct functionarg *funcarg)
354 char *s, *begin, *end;
355 unsigned int brackets = 0, i;
357 begin = s = strdup(funcarg->arg);
359 /* Count the [] at the end of the argument */
360 end = begin+strlen(begin);
361 while (isspace(*(end-1))) end--;
362 while (*(end-1)==']')
364 brackets++;
365 end--;
366 while (isspace(*(end-1))) end--;
367 if (*(end-1)!='[')
369 free(s);
370 return NULL;
372 end--;
373 while (isspace(*(end-1))) end--;
376 /* Skip over the argument name */
377 while (!isspace(*(end-1)) && *(end-1)!='*')
379 if (begin == end)
381 free(s);
382 fprintf(stderr, "no argument type or name found for arg: %s\n", funcarg->arg);
383 exit(20);
385 end--;
388 /* Add * for the brackets */
389 while (isspace(*(end-1))) end--;
390 for (i=0; i<brackets; i++)
392 *end='*';
393 end++;
395 *end='\0';
397 return s;
400 char *getargname(const struct functionarg *funcarg)
402 char *s, *begin, *end;
403 int len;
405 /* Count the [] at the end of the argument */
406 end = funcarg->arg+strlen(funcarg->arg);
407 while (isspace(*(end-1))) end--;
408 while (*(end-1)==']')
410 end--;
411 while (isspace(*(end-1))) end--;
412 if (*(end-1)!='[')
413 return NULL;
414 end--;
415 while (isspace(*(end-1))) end--;
418 /* Go to the beginning of the argument name */
419 begin = end;
420 while (!isspace(*(begin-1)) && *(begin-1)!='*') begin--;
422 /* Copy the name */
423 len = end - begin;
424 s = malloc(len+1);
425 strncpy(s, begin, len);
426 s[len] = '\0';
428 return s;