added concrete implementations of putc(), getc(), getchar() and gets()
[tangerine.git] / tools / genmodule / functionhead.c
blob7ac404b514be107efec48e4ac511f6acc110f1ed
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 continue;
250 case REGISTER:
251 case REGISTERMACRO:
252 assert(cfg);
253 if (funclistit->priv || funclistit->lvo < cfg->firstlvo)
254 continue;
256 if (funclistit->arguments == NULL
257 || strchr(funclistit->arguments->reg, '/') == NULL
260 fprintf(out,
261 "AROS_LP%d(%s, %s,\n",
262 funclistit->argcount, funclistit->type, funclistit->name
264 for (arglistit = funclistit->arguments;
265 arglistit!=NULL;
266 arglistit = arglistit->next
269 type = getargtype(arglistit);
270 name = getargname(arglistit);
271 assert(type != NULL && name != NULL);
273 fprintf(out,
274 " AROS_LPA(%s, %s, %s),\n",
275 type, name, arglistit->reg
277 free(type);
278 free(name);
280 fprintf(out,
281 " LIBBASETYPEPTR, %s, %u, %s\n"
282 ");\n",
283 cfg->libbase, funclistit->lvo, cfg->basename
286 else
288 fprintf(out,
289 "AROS_LPQUAD%d(%s, %s,\n",
290 funclistit->argcount, funclistit->type, funclistit->name
292 for (arglistit = funclistit->arguments;
293 arglistit != NULL;
294 arglistit = arglistit->next
297 if (strlen(arglistit->reg) != 5)
299 fprintf(stderr, "Internal error: ../.. register format expected\n");
300 exit(20);
302 arglistit->reg[2] = 0;
304 type = getargtype(arglistit);
305 name = getargname(arglistit);
306 assert(type != NULL && name != NULL);
308 fprintf(out,
309 " AROS_LPAQUAD(%s, %s, %s, %s),\n",
310 type, name, arglistit->reg, arglistit->reg+3
312 arglistit->reg[2] = '/';
313 free(type);
314 free(name);
316 fprintf(out,
317 " LIBBASETYPEPTR, %s, %u, %s\n"
318 ");\n",
319 cfg->libbase, funclistit->lvo, cfg->basename
322 break;
324 default:
325 fprintf(stderr, "Internal error: unhandled libcall in writefuncdefs\n");
326 exit(20);
327 break;
332 char *getargtype(const struct functionarg *funcarg)
334 char *s, *begin, *end;
335 unsigned int brackets = 0, i;
337 begin = s = strdup(funcarg->arg);
339 /* Count the [] at the end of the argument */
340 end = begin+strlen(begin);
341 while (isspace(*(end-1))) end--;
342 while (*(end-1)==']')
344 brackets++;
345 end--;
346 while (isspace(*(end-1))) end--;
347 if (*(end-1)!='[')
349 free(s);
350 return NULL;
352 end--;
353 while (isspace(*(end-1))) end--;
356 /* Skip over the argument name */
357 while (!isspace(*(end-1)) && *(end-1)!='*') end--;
359 /* Add * for the brackets */
360 while (isspace(*(end-1))) end--;
361 for (i=0; i<brackets; i++)
363 *end='*';
364 end++;
366 *end='\0';
368 return s;
371 char *getargname(const struct functionarg *funcarg)
373 char *s, *begin, *end;
374 int len;
376 /* Count the [] at the end of the argument */
377 end = funcarg->arg+strlen(funcarg->arg);
378 while (isspace(*(end-1))) end--;
379 while (*(end-1)==']')
381 end--;
382 while (isspace(*(end-1))) end--;
383 if (*(end-1)!='[')
384 return NULL;
385 end--;
386 while (isspace(*(end-1))) end--;
389 /* Go to the beginning of the argument name */
390 begin = end;
391 while (!isspace(*(begin-1)) && *(begin-1)!='*') begin--;
393 /* Copy the name */
394 len = end - begin;
395 s = malloc(len+1);
396 strncpy(s, begin, len);
397 s[len] = '\0';
399 return s;