2 Copyright © 1995-2015, 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 (strcasecmp(funclistit
->type
, "void") == 0) ? "" : "return ",
148 funclistit
->internalname
150 for (arglistit
= funclistit
->arguments
, first
= 1;
152 arglistit
= arglistit
->next
, first
= 0
155 name
= getargname(arglistit
);
156 assert(name
!= NULL
);
160 fprintf(out
, "%s", name
);
165 " AROS_LIBFUNC_EXIT\n"
171 if (funclistit
->arguments
== NULL
172 || strchr(funclistit
->arguments
->reg
, '/') == NULL
)
175 "AROS_LD%d%s(%s, %s,\n",
176 funclistit
->argcount
, funclistit
->unusedlibbase
? "I" : "",
177 funclistit
->type
, funclistit
->internalname
179 for (arglistit
= funclistit
->arguments
;
181 arglistit
= arglistit
->next
184 type
= getargtype(arglistit
);
185 name
= getargname(arglistit
);
186 assert(type
!= NULL
&& name
!= NULL
);
189 " AROS_LDA(%s, %s, %s),\n",
190 type
, name
, arglistit
->reg
196 " LIBBASETYPEPTR, %s, %u, %s\n"
198 cfg
->libbase
, funclistit
->lvo
, cfg
->basename
204 "AROS_LDQUAD%d(%s, %s,\n",
205 funclistit
->argcount
, funclistit
->type
, funclistit
->internalname
207 for (arglistit
= funclistit
->arguments
;
209 arglistit
= arglistit
->next
212 if (strlen(arglistit
->reg
) != 5)
214 fprintf(stderr
, "Internal error: ../.. register format expected\n");
217 arglistit
->reg
[2] = 0;
219 type
= getargtype(arglistit
);
220 name
= getargname(arglistit
);
221 assert(type
!= NULL
&& name
!= NULL
);
224 " AROS_LDAQUAD(%s, %s, %s, %s),\n",
225 type
, name
, arglistit
->reg
, arglistit
->reg
+3
227 arglistit
->reg
[2] = '/';
232 " LIBBASETYPEPTR, %s, %u, %s\n"
234 cfg
->libbase
, funclistit
->lvo
, cfg
->basename
240 fprintf(stderr
, "Internal error: unhandled libcall in writefuncdefs\n");
247 void writefuncprotos(FILE *out
, struct config
*cfg
, struct functionhead
*funclist
)
249 struct functionhead
*funclistit
;
250 struct functionarg
*arglistit
;
254 for(funclistit
= funclist
; funclistit
!= NULL
; funclistit
= funclistit
->next
)
258 "#if !defined(__%s_LIBAPI__) || (%d <= __%s_LIBAPI__)"
260 cfg
->includenameupper
,
262 cfg
->includenameupper
265 switch (funclistit
->libcall
)
273 funclistit
->type
, funclistit
->name
276 for(arglistit
= funclistit
->arguments
, first
= 1;
278 arglistit
= arglistit
->next
, first
= 0
284 fprintf(out
, "%s", arglistit
->arg
);
286 fprintf(out
, ");\n#endif\n");
292 if (funclistit
->priv
|| funclistit
->lvo
< cfg
->firstlvo
) {
293 fprintf(out
, "/* private */\n");
297 if (funclistit
->arguments
== NULL
298 || strchr(funclistit
->arguments
->reg
, '/') == NULL
302 "AROS_LP%d%s(%s, %s,\n",
303 funclistit
->argcount
, funclistit
->unusedlibbase
? "I" : "",
304 funclistit
->type
, funclistit
->name
306 for (arglistit
= funclistit
->arguments
;
308 arglistit
= arglistit
->next
311 type
= getargtype(arglistit
);
312 name
= getargname(arglistit
);
313 assert(type
!= NULL
&& name
!= NULL
);
316 " AROS_LPA(%s, %s, %s),\n",
317 type
, name
, arglistit
->reg
323 " LIBBASETYPEPTR, %s, %u, %s\n"
325 cfg
->libbase
, funclistit
->lvo
, cfg
->basename
331 "AROS_LPQUAD%d(%s, %s,\n",
332 funclistit
->argcount
, funclistit
->type
, funclistit
->name
334 for (arglistit
= funclistit
->arguments
;
336 arglistit
= arglistit
->next
339 if (strlen(arglistit
->reg
) != 5)
341 fprintf(stderr
, "Internal error: ../.. register format expected\n");
344 arglistit
->reg
[2] = 0;
346 type
= getargtype(arglistit
);
347 name
= getargname(arglistit
);
348 assert(type
!= NULL
&& name
!= NULL
);
351 " AROS_LPAQUAD(%s, %s, %s, %s),\n",
352 type
, name
, arglistit
->reg
, arglistit
->reg
+3
354 arglistit
->reg
[2] = '/';
359 " LIBBASETYPEPTR, %s, %u, %s\n"
361 cfg
->libbase
, funclistit
->lvo
, cfg
->basename
367 fprintf(stderr
, "Internal error:"
368 " unhandled libcall in writefuncprotos\n");
375 "#endif /* !defined(__%s_LIBAPI__) || (%d <= __%s_LIBAPI__) */"
377 cfg
->includenameupper
,
379 cfg
->includenameupper
384 void writefuncinternalstubs(FILE *out
, struct config
*cfg
, struct functionhead
*funclist
)
386 struct functionhead
*funclistit
;
387 struct functionarg
*arglistit
;
391 for(funclistit
= funclist
; funclistit
!= NULL
; funclistit
= funclistit
->next
)
393 switch (funclistit
->libcall
)
396 if ((cfg
->options
& OPTION_DUPBASE
)
397 && !funclistit
->unusedlibbase
401 "AROS_GM_STACKCALL(%s,%s,%d);\n"
402 , funclistit
->internalname
410 "AROS_GM_STACKALIAS(%s,%s,%d);\n"
411 , funclistit
->internalname
424 fprintf(stderr
, "Internal error: "
425 "unhandled libcall in writefuncinternalstubs\n");
432 char *getargtype(const struct functionarg
*funcarg
)
434 char *s
, *begin
, *end
;
435 unsigned int brackets
= 0, i
;
437 begin
= s
= strdup(funcarg
->arg
);
439 /* Count the [] at the end of the argument */
440 end
= begin
+strlen(begin
);
441 while (isspace(*(end
-1))) end
--;
442 while (*(end
-1)==']')
446 while (isspace(*(end
-1)) || isdigit(*(end
-1))) end
--;
453 while (isspace(*(end
-1))) end
--;
456 /* Skip over the argument name */
457 while (!isspace(*(end
-1)) && *(end
-1)!='*')
462 fprintf(stderr
, "no argument type or name found for arg: %s\n", funcarg
->arg
);
468 /* Add * for the brackets */
469 while (isspace(*(end
-1))) end
--;
470 for (i
=0; i
<brackets
; i
++)
480 char *getargname(const struct functionarg
*funcarg
)
482 char *s
, *begin
, *end
;
485 /* Count the [] at the end of the argument */
486 end
= funcarg
->arg
+strlen(funcarg
->arg
);
487 while (isspace(*(end
-1))) end
--;
488 while (*(end
-1)==']')
491 while (isspace(*(end
-1))) end
--;
495 while (isspace(*(end
-1))) end
--;
498 /* Go to the beginning of the argument name */
500 while (!isspace(*(begin
-1)) && *(begin
-1)!='*') begin
--;
505 strncpy(s
, begin
, len
);