Datatype descriptor for D64/T64 files added.
[cake.git] / tools / genmodule / functionhead.c
blob32259675562c78d15749cf07cfd3915e18d3a404
1 /*
2 Copyright © 1995-2005, 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->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 writefuncdefs(FILE *out, struct config *cfg, struct functionhead *funclist)
75 struct functionhead *funclistit;
76 struct functionarg *arglistit;
77 char *type, *name;
78 int first;
80 for(funclistit = funclist; funclistit != NULL; funclistit = funclistit->next)
82 switch (funclistit->libcall)
84 case STACK:
85 fprintf(out, "%s %s(", funclistit->type, funclistit->name);
87 for(arglistit = funclistit->arguments, first = 1;
88 arglistit != NULL;
89 arglistit = arglistit->next, first = 0
92 if (!first)
93 fprintf(out, ", ");
95 fprintf(out, "%s", arglistit->arg);
97 fprintf(out, ");\n");
98 break;
100 case REGISTER:
101 assert(cfg);
102 fprintf(out, "%s %s(", funclistit->type, funclistit->name);
103 for (arglistit = funclistit->arguments, first = 1;
104 arglistit!=NULL;
105 arglistit = arglistit->next, first = 0
108 if (!first)
109 fprintf(out, ", ");
110 fprintf(out, "%s", arglistit->arg);
112 fprintf(out,
113 ");\nAROS_LH%d(%s, %s,\n",
114 funclistit->argcount, funclistit->type, funclistit->name
116 for (arglistit = funclistit->arguments;
117 arglistit!=NULL;
118 arglistit = arglistit->next
121 type = getargtype(arglistit);
122 name = getargname(arglistit);
123 assert(name != NULL && type != NULL);
125 fprintf(out,
126 " AROS_LHA(%s, %s, %s),\n",
127 type, name, arglistit->reg
129 free(type);
130 free(name);
132 fprintf(out,
133 " %s, %s, %u, %s)\n"
134 "{\n"
135 " AROS_LIBFUNC_INIT\n\n"
136 " return %s(",
137 cfg->libbasetypeptrextern, cfg->libbase, funclistit->lvo, cfg->basename,
138 funclistit->name
140 for (arglistit = funclistit->arguments, first = 1;
141 arglistit!=NULL;
142 arglistit = arglistit->next, first = 0
145 name = getargname(arglistit);
146 assert(name != NULL);
148 if (!first)
149 fprintf(out, ", ");
150 fprintf(out, "%s", name);
151 free(name);
153 fprintf(out,
154 ");\n\n"
155 " AROS_LIBFUNC_EXIT\n"
156 "}\n\n");
157 break;
159 case REGISTERMACRO:
160 assert(cfg);
161 if (funclistit->arguments == NULL
162 || strchr(funclistit->arguments->reg, '/') == NULL)
164 fprintf(out,
165 "AROS_LD%d(%s, %s,\n",
166 funclistit->argcount, funclistit->type, funclistit->name
168 for (arglistit = funclistit->arguments;
169 arglistit!=NULL;
170 arglistit = arglistit->next
173 type = getargtype(arglistit);
174 name = getargname(arglistit);
175 assert(type != NULL && name != NULL);
177 fprintf(out,
178 " AROS_LDA(%s, %s, %s),\n",
179 type, name, arglistit->reg
181 free(type);
182 free(name);
184 fprintf(out,
185 " LIBBASETYPEPTR, %s, %u, %s\n"
186 ");\n",
187 cfg->libbase, funclistit->lvo, cfg->basename
190 else
192 fprintf(out,
193 "AROS_LDQUAD%d(%s, %s,\n",
194 funclistit->argcount, funclistit->type, funclistit->name
196 for (arglistit = funclistit->arguments;
197 arglistit != NULL;
198 arglistit = arglistit->next
201 if (strlen(arglistit->reg) != 5)
203 fprintf(stderr, "Internal error: ../.. register format expected\n");
204 exit(20);
206 arglistit->reg[2] = 0;
208 type = getargtype(arglistit);
209 name = getargname(arglistit);
210 assert(type != NULL && name != NULL);
212 fprintf(out,
213 " AROS_LDAQUAD(%s, %s, %s, %s),\n",
214 type, name, arglistit->reg, arglistit->reg+3
216 arglistit->reg[2] = '/';
217 free(type);
218 free(name);
220 fprintf(out,
221 " LIBBASETYPEPTR, %s, %u, %s\n"
222 ");\n",
223 cfg->libbase, funclistit->lvo, cfg->basename
226 break;
228 default:
229 fprintf(stderr, "Internal error: unhandled libcall in writefuncdefs\n");
230 exit(20);
231 break;
236 void writefuncprotos(FILE *out, struct config *cfg, struct functionhead *funclist)
238 struct functionhead *funclistit;
239 struct functionarg *arglistit;
240 char *type, *name;
241 int first;
243 for(funclistit = funclist; funclistit != NULL; funclistit = funclistit->next)
245 switch (funclistit->libcall)
247 case STACK:
248 fprintf(out, "%s %s(", funclistit->type, funclistit->name);
250 for(arglistit = funclistit->arguments, first = 1;
251 arglistit != NULL;
252 arglistit = arglistit->next, first = 0
255 if (!first)
256 fprintf(out, ", ");
258 fprintf(out, "%s", arglistit->arg);
260 fprintf(out, ");\n");
261 break;
263 case REGISTER:
264 case REGISTERMACRO:
265 assert(cfg);
266 if (funclistit->priv || funclistit->lvo < cfg->firstlvo)
267 continue;
269 if (funclistit->arguments == NULL
270 || strchr(funclistit->arguments->reg, '/') == NULL
273 fprintf(out,
274 "AROS_LP%d(%s, %s,\n",
275 funclistit->argcount, funclistit->type, funclistit->name
277 for (arglistit = funclistit->arguments;
278 arglistit!=NULL;
279 arglistit = arglistit->next
282 type = getargtype(arglistit);
283 name = getargname(arglistit);
284 assert(type != NULL && name != NULL);
286 fprintf(out,
287 " AROS_LPA(%s, %s, %s),\n",
288 type, name, arglistit->reg
290 free(type);
291 free(name);
293 fprintf(out,
294 " LIBBASETYPEPTR, %s, %u, %s\n"
295 ");\n",
296 cfg->libbase, funclistit->lvo, cfg->basename
299 else
301 fprintf(out,
302 "AROS_LPQUAD%d(%s, %s,\n",
303 funclistit->argcount, funclistit->type, funclistit->name
305 for (arglistit = funclistit->arguments;
306 arglistit != NULL;
307 arglistit = arglistit->next
310 if (strlen(arglistit->reg) != 5)
312 fprintf(stderr, "Internal error: ../.. register format expected\n");
313 exit(20);
315 arglistit->reg[2] = 0;
317 type = getargtype(arglistit);
318 name = getargname(arglistit);
319 assert(type != NULL && name != NULL);
321 fprintf(out,
322 " AROS_LPAQUAD(%s, %s, %s, %s),\n",
323 type, name, arglistit->reg, arglistit->reg+3
325 arglistit->reg[2] = '/';
326 free(type);
327 free(name);
329 fprintf(out,
330 " LIBBASETYPEPTR, %s, %u, %s\n"
331 ");\n",
332 cfg->libbase, funclistit->lvo, cfg->basename
335 break;
337 default:
338 fprintf(stderr, "Internal error: unhandled libcall in writefuncdefs\n");
339 exit(20);
340 break;
345 char *getargtype(const struct functionarg *funcarg)
347 char *s, *begin, *end;
348 unsigned int brackets = 0, i;
350 begin = s = strdup(funcarg->arg);
352 /* Count the [] at the end of the argument */
353 end = begin+strlen(begin);
354 while (isspace(*(end-1))) end--;
355 while (*(end-1)==']')
357 brackets++;
358 end--;
359 while (isspace(*(end-1))) end--;
360 if (*(end-1)!='[')
362 free(s);
363 return NULL;
365 end--;
366 while (isspace(*(end-1))) end--;
369 /* Skip over the argument name */
370 while (!isspace(*(end-1)) && *(end-1)!='*') end--;
372 /* Add * for the brackets */
373 while (isspace(*(end-1))) end--;
374 for (i=0; i<brackets; i++)
376 *end='*';
377 end++;
379 *end='\0';
381 return s;
384 char *getargname(const struct functionarg *funcarg)
386 char *s, *begin, *end;
387 int len;
389 /* Count the [] at the end of the argument */
390 end = funcarg->arg+strlen(funcarg->arg);
391 while (isspace(*(end-1))) end--;
392 while (*(end-1)==']')
394 end--;
395 while (isspace(*(end-1))) end--;
396 if (*(end-1)!='[')
397 return NULL;
398 end--;
399 while (isspace(*(end-1))) end--;
402 /* Go to the beginning of the argument name */
403 begin = end;
404 while (!isspace(*(begin-1)) && *(begin-1)!='*') begin--;
406 /* Copy the name */
407 len = end - begin;
408 s = malloc(len+1);
409 strncpy(s, begin, len);
410 s[len] = '\0';
412 return s;