2 Copyright © 1995-2012, The AROS Development Team. All rights reserved.
5 The code for storing information of functions present in the module
9 #include "functionhead.h"
12 struct functionhead
*newfunctionhead(const char *name
, enum libcall libcall
)
14 struct functionhead
*funchead
= malloc(sizeof(struct functionhead
));
18 funchead
->next
= NULL
;
19 funchead
->internalname
= funchead
->name
= strdup(name
);
20 funchead
->type
= NULL
;
21 funchead
->libcall
= libcall
;
23 funchead
->argcount
= 0;
24 funchead
->arguments
= NULL
;
25 funchead
->aliases
= NULL
;
26 funchead
->interface
= NULL
;
27 funchead
->method
= NULL
;
28 funchead
->novararg
= 0;
30 funchead
->unusedlibbase
= 0;
34 puts("Out of memory !");
41 struct functionarg
*funcaddarg
43 struct functionhead
*funchead
,
44 const char *arg
, const char *reg
47 struct functionarg
**argptr
= &funchead
->arguments
;
49 while ((*argptr
) != NULL
) argptr
= &(*argptr
)->next
;
51 *argptr
= malloc(sizeof(struct functionarg
));
54 (*argptr
)->next
= NULL
;
55 (*argptr
)->arg
= (arg
== NULL
) ? NULL
: strdup(arg
);
56 (*argptr
)->reg
= (reg
== NULL
) ? NULL
: strdup(reg
);
62 puts("Out of memory !");
69 struct stringlist
*funcaddalias(struct functionhead
*funchead
, const char *alias
)
71 return slist_append(&funchead
->aliases
, alias
);
74 void funcsetinternalname(struct functionhead
*funchead
, const char *internalname
)
76 if (funchead
->name
!= funchead
->internalname
)
77 free(funchead
->internalname
);
78 funchead
->internalname
= strdup(internalname
);
81 void writefuncdefs(FILE *out
, struct config
*cfg
, struct functionhead
*funclist
)
83 struct functionhead
*funclistit
;
84 struct functionarg
*arglistit
;
88 for(funclistit
= funclist
; funclistit
!= NULL
; funclistit
= funclistit
->next
)
90 switch (funclistit
->libcall
)
93 fprintf(out
, "%s %s(", funclistit
->type
, funclistit
->internalname
);
95 for(arglistit
= funclistit
->arguments
, first
= 1;
97 arglistit
= arglistit
->next
, first
= 0
103 fprintf(out
, "%s", arglistit
->arg
);
105 fprintf(out
, ");\n");
110 fprintf(out
, "%s %s(", funclistit
->type
, funclistit
->internalname
);
111 for (arglistit
= funclistit
->arguments
, first
= 1;
113 arglistit
= arglistit
->next
, first
= 0
118 fprintf(out
, "%s", arglistit
->arg
);
121 ");\nAROS_LH%d%s(%s, %s,\n",
122 funclistit
->argcount
, funclistit
->unusedlibbase
? "I" : "",
123 funclistit
->type
, funclistit
->internalname
125 for (arglistit
= funclistit
->arguments
;
127 arglistit
= arglistit
->next
130 type
= getargtype(arglistit
);
131 name
= getargname(arglistit
);
132 assert(name
!= NULL
&& type
!= NULL
);
135 " AROS_LHA(%s, %s, %s),\n",
136 type
, name
, arglistit
->reg
144 " AROS_LIBFUNC_INIT\n\n"
146 cfg
->libbasetypeptrextern
, cfg
->libbase
, funclistit
->lvo
, cfg
->basename
,
147 funclistit
->internalname
149 for (arglistit
= funclistit
->arguments
, first
= 1;
151 arglistit
= arglistit
->next
, first
= 0
154 name
= getargname(arglistit
);
155 assert(name
!= NULL
);
159 fprintf(out
, "%s", name
);
164 " AROS_LIBFUNC_EXIT\n"
170 if (funclistit
->arguments
== NULL
171 || strchr(funclistit
->arguments
->reg
, '/') == NULL
)
174 "AROS_LD%d%s(%s, %s,\n",
175 funclistit
->argcount
, funclistit
->unusedlibbase
? "I" : "",
176 funclistit
->type
, funclistit
->internalname
178 for (arglistit
= funclistit
->arguments
;
180 arglistit
= arglistit
->next
183 type
= getargtype(arglistit
);
184 name
= getargname(arglistit
);
185 assert(type
!= NULL
&& name
!= NULL
);
188 " AROS_LDA(%s, %s, %s),\n",
189 type
, name
, arglistit
->reg
195 " LIBBASETYPEPTR, %s, %u, %s\n"
197 cfg
->libbase
, funclistit
->lvo
, cfg
->basename
203 "AROS_LDQUAD%d(%s, %s,\n",
204 funclistit
->argcount
, funclistit
->type
, funclistit
->internalname
206 for (arglistit
= funclistit
->arguments
;
208 arglistit
= arglistit
->next
211 if (strlen(arglistit
->reg
) != 5)
213 fprintf(stderr
, "Internal error: ../.. register format expected\n");
216 arglistit
->reg
[2] = 0;
218 type
= getargtype(arglistit
);
219 name
= getargname(arglistit
);
220 assert(type
!= NULL
&& name
!= NULL
);
223 " AROS_LDAQUAD(%s, %s, %s, %s),\n",
224 type
, name
, arglistit
->reg
, arglistit
->reg
+3
226 arglistit
->reg
[2] = '/';
231 " LIBBASETYPEPTR, %s, %u, %s\n"
233 cfg
->libbase
, funclistit
->lvo
, cfg
->basename
239 fprintf(stderr
, "Internal error: unhandled libcall in writefuncdefs\n");
246 void writefuncprotos(FILE *out
, struct config
*cfg
, struct functionhead
*funclist
)
248 struct functionhead
*funclistit
;
249 struct functionarg
*arglistit
;
253 for(funclistit
= funclist
; funclistit
!= NULL
; funclistit
= funclistit
->next
)
257 "#if !defined(__%s_LIBAPI__) || (%d <= __%s_LIBAPI__)"
259 cfg
->modulenameupper
,
264 switch (funclistit
->libcall
)
267 fprintf(out
, "%s %s(", funclistit
->type
, funclistit
->name
);
269 for(arglistit
= funclistit
->arguments
, first
= 1;
271 arglistit
= arglistit
->next
, first
= 0
277 fprintf(out
, "%s", arglistit
->arg
);
279 fprintf(out
, ");\n");
285 if (funclistit
->priv
|| funclistit
->lvo
< cfg
->firstlvo
) {
286 fprintf(out
, "/* private */\n");
290 if (funclistit
->arguments
== NULL
291 || strchr(funclistit
->arguments
->reg
, '/') == NULL
295 "AROS_LP%d%s(%s, %s,\n",
296 funclistit
->argcount
, funclistit
->unusedlibbase
? "I" : "",
297 funclistit
->type
, funclistit
->name
299 for (arglistit
= funclistit
->arguments
;
301 arglistit
= arglistit
->next
304 type
= getargtype(arglistit
);
305 name
= getargname(arglistit
);
306 assert(type
!= NULL
&& name
!= NULL
);
309 " AROS_LPA(%s, %s, %s),\n",
310 type
, name
, arglistit
->reg
316 " LIBBASETYPEPTR, %s, %u, %s\n"
318 cfg
->libbase
, funclistit
->lvo
, cfg
->basename
324 "AROS_LPQUAD%d(%s, %s,\n",
325 funclistit
->argcount
, funclistit
->type
, funclistit
->name
327 for (arglistit
= funclistit
->arguments
;
329 arglistit
= arglistit
->next
332 if (strlen(arglistit
->reg
) != 5)
334 fprintf(stderr
, "Internal error: ../.. register format expected\n");
337 arglistit
->reg
[2] = 0;
339 type
= getargtype(arglistit
);
340 name
= getargname(arglistit
);
341 assert(type
!= NULL
&& name
!= NULL
);
344 " AROS_LPAQUAD(%s, %s, %s, %s),\n",
345 type
, name
, arglistit
->reg
, arglistit
->reg
+3
347 arglistit
->reg
[2] = '/';
352 " LIBBASETYPEPTR, %s, %u, %s\n"
354 cfg
->libbase
, funclistit
->lvo
, cfg
->basename
360 fprintf(stderr
, "Internal error: unhandled libcall in writefuncdefs\n");
367 "#endif /* !defined(__%s_LIBAPI__) || (%d <= __%s_LIBAPI__) */"
369 cfg
->modulenameupper
,
376 void writefuncinternalstubs(FILE *out
, struct config
*cfg
, struct functionhead
*funclist
)
378 struct functionhead
*funclistit
;
379 struct functionarg
*arglistit
;
383 for(funclistit
= funclist
; funclistit
!= NULL
; funclistit
= funclistit
->next
)
385 switch (funclistit
->libcall
)
388 if ((cfg
->options
& OPTION_DUPBASE
)
389 && !funclistit
->unusedlibbase
393 "AROS_GM_STACKCALL(%s,%s,%d);\n"
402 "AROS_GM_STACKALIAS(%s,%s,%d);\n"
416 fprintf(stderr
, "Internal error: unhandled libcall in writefuncdefs\n");
423 char *getargtype(const struct functionarg
*funcarg
)
425 char *s
, *begin
, *end
;
426 unsigned int brackets
= 0, i
;
428 begin
= s
= strdup(funcarg
->arg
);
430 /* Count the [] at the end of the argument */
431 end
= begin
+strlen(begin
);
432 while (isspace(*(end
-1))) end
--;
433 while (*(end
-1)==']')
437 while (isspace(*(end
-1)) || isdigit(*(end
-1))) end
--;
444 while (isspace(*(end
-1))) end
--;
447 /* Skip over the argument name */
448 while (!isspace(*(end
-1)) && *(end
-1)!='*')
453 fprintf(stderr
, "no argument type or name found for arg: %s\n", funcarg
->arg
);
459 /* Add * for the brackets */
460 while (isspace(*(end
-1))) end
--;
461 for (i
=0; i
<brackets
; i
++)
471 char *getargname(const struct functionarg
*funcarg
)
473 char *s
, *begin
, *end
;
476 /* Count the [] at the end of the argument */
477 end
= funcarg
->arg
+strlen(funcarg
->arg
);
478 while (isspace(*(end
-1))) end
--;
479 while (*(end
-1)==']')
482 while (isspace(*(end
-1))) end
--;
486 while (isspace(*(end
-1))) end
--;
489 /* Go to the beginning of the argument name */
491 while (!isspace(*(begin
-1)) && *(begin
-1)!='*') begin
--;
496 strncpy(s
, begin
, len
);