2 Copyright © 1995-2005, The AROS Development Team. All rights reserved.
5 Function to read in the function reference file. Part of genmodule.
11 /* A structure for storing parse state information during scanning of the ref file */
15 struct stringlist
*currreg
;
16 struct functionhead
*currentfunc
;
19 /* Prototypes of static functions */
20 static int parsemethodname(char *name
,
21 struct _parseinfo
*parseinfo
,
24 static int parsemacroname(char *name
,
25 struct _parseinfo
*parseinfo
,
29 void readref(struct config
*cfg
)
31 struct functionhead
*funclistit
= NULL
;
32 struct functionhead
*currentfunc
= NULL
; /* will be either funclistit or methlistit */
33 struct _parseinfo parseinfo
;
34 unsigned int funcnamelength
;
35 char *begin
, *end
, *line
;
37 if (!fileopen(cfg
->reffile
))
39 fprintf(stderr
, "In readref: Could not open %s\n", cfg
->reffile
);
43 /* Go over all the lines in the ref file and look for the functions and their
44 * arguments in the file. There are two states during parsing infunction==0 for
45 * outside a function header and then just look for the next function name.
46 * infunction==1 in a function header and then the arguments of this function
49 parseinfo
.infunction
= 0;
50 while ((line
=readline())!=NULL
)
54 /* When the registers are specified in the config file check if the number provided
55 * provided in the file corresponds with the number of arguments in the ref file
57 if (parseinfo
.infunction
&&
58 (strncmp(line
, "FILE", 4)==0 ||
59 strncmp(line
, "INCLUDES", 8)==0 ||
60 strncmp(line
, "DEFINES", 7)==0 ||
61 strncmp(line
, "VARIABLE", 8)==0 ||
62 strncmp(line
, "FUNCTION", 8)==0
64 parseinfo
.currentfunc
->libcall
==REGISTER
)
66 /* About to leave function */
67 if (parseinfo
.currreg
!=NULL
)
69 fprintf(stderr
, "Error: too many registers specified for function \"%s\"\n",
70 parseinfo
.currentfunc
->name
);
75 /* End of function header ? */
76 if (parseinfo
.infunction
77 && (strncmp(line
, "FILE", 4)==0
78 || strncmp(line
, "INCLUDES", 8)==0
79 || strncmp(line
, "DEFINES", 7)==0
80 || strncmp(line
, "VARIABLE", 8)==0
83 parseinfo
.infunction
= 0;
85 /* Start of a new function header ? */
86 if (strncmp(line
, "FUNCTION", 8)==0)
88 begin
= strchr(line
,':');
91 fprintf(stderr
, "Syntax error in reffile %s\n", cfg
->reffile
);
95 while (isspace(*begin
)) begin
++;
96 end
= strchr(begin
, '[');
99 fprintf(stderr
, "Syntax error in reffile %s\n", cfg
->reffile
);
102 while (isspace(*(end
-1))) end
--;
105 funcnamelength
= strlen(begin
);
107 parseinfo
.infunction
=
109 parsemethodname(begin
, &parseinfo
, cfg
)
110 || parsemacroname(begin
, &parseinfo
, cfg
)
113 else if (parseinfo
.infunction
)
115 if (strncmp(line
, "Arguments", 9)==0)
120 begin
= strchr(line
, ':');
123 fprintf(stderr
, "Syntax error in reffile %s\n", cfg
->reffile
);
127 while (isspace(*begin
)) begin
++;
129 /* for libcall == STACK the whole argument is the type
130 * otherwise split the argument in type and name
133 if (parseinfo
.currentfunc
->libcall
!= STACK
)
135 /* Count the [] specification at the end of the argument */
136 end
= begin
+strlen(begin
);
137 while (isspace(*(end
-1))) end
--;
138 while (*(end
-1)==']')
142 while (isspace(*(end
-1))) end
--;
146 "Argument \"%s\" not understood for function %s\n",
147 begin
, parseinfo
.currentfunc
->name
152 while (isspace(*(end
-1))) end
--;
156 /* Skip over the argument name and duplicate it */
157 while (!isspace(*(end
-1)) && *(end
-1)!='*') end
--;
160 /* Add * for the brackets */
161 while (isspace(*(end
-1))) end
--;
162 for (i
=0; i
<brackets
; i
++)
170 if (strcasecmp(begin
, "void")!=0)
172 switch (parseinfo
.currentfunc
->libcall
)
175 funcaddarg(parseinfo
.currentfunc
, begin
, NULL
);
178 if (parseinfo
.currreg
== NULL
)
181 "Error: argument count mismatch for funtion \"%s\"\n",
182 parseinfo
.currentfunc
->name
186 funcaddarg(parseinfo
.currentfunc
, begin
, parseinfo
.currreg
->s
);
187 parseinfo
.currreg
= parseinfo
.currreg
->next
;
191 char *reg
= begin
+ strlen(begin
) - 1;
192 while (reg
!= begin
&& *reg
!= '_') reg
--;
199 funcaddarg(parseinfo
.currentfunc
, begin
, reg
);
204 "Internal error: Unhandled modtype in readref\n"
210 else if (strncmp(line
, "Type", 4)==0)
212 begin
= strchr(line
, ':');
215 fprintf(stderr
, "Syntax error in reffile %s\n", cfg
->reffile
);
219 while (isspace(*begin
)) begin
++;
220 end
= begin
+strlen(begin
)-funcnamelength
;
221 while (isspace(*(end
-1))) end
--;
223 parseinfo
.currentfunc
->type
= strdup(begin
);
230 /* Checking to see if every function has a prototype */
233 funclistit
= cfg
->funclist
;
235 funclistit
= funclistit
->next
238 if (funclistit
->type
==NULL
)
242 stderr
, "Did not find function %s in reffile %s\n",
243 funclistit
->name
, cfg
->reffile
251 static int parsemethodname(char *name
,
252 struct _parseinfo
*parseinfo
,
257 struct classinfo
*cl
;
259 for (cl
= cfg
->classlist
; cl
!= NULL
; cl
= cl
->next
)
262 const char **prefixptr
= cl
->boopsimprefix
;
264 /* For a BOOPSI class a custom dispatcher has the name
265 * 'modulename_Dispatcher'
269 strncmp(name
, cl
->basename
, strlen(cl
->basename
)) == 0
270 && strcmp(name
+strlen(cl
->basename
), "_Dispatcher") == 0
272 cl
->dispatcher
= strdup(name
);
274 while (*prefixptr
!= NULL
&& sep
== NULL
)
276 sep
= strstr(name
, *prefixptr
);
283 && strncmp(cl
->basename
, name
, sep
- name
) == 0
286 struct functionhead
*method
, *it
;
288 method
= newfunctionhead(sep
+2, STACK
);
290 if (cl
->methlist
== NULL
)
291 cl
->methlist
= method
;
296 while (it
->next
!= NULL
) it
= it
->next
;
301 parseinfo
->currentfunc
= method
;
310 static int parsemacroname(char *name
,
311 struct _parseinfo
*parseinfo
,
317 strncmp(name
, "AROS_LH_", 8) == 0
318 || strncmp(name
, "AROS_PLH_", 9) == 0
319 || strncmp(name
, "AROS_NTLH_", 10) == 0
322 struct functionhead
*funclistit
, *func
;
323 char *begin
, *end
, *funcname
;
324 int novararg
= 0, priv
= 0;
327 if (strncmp(name
, "AROS_LH_", 8) == 0)
332 if (strncmp(name
, "AROS_PLH_", 9) == 0)
343 if (strncmp(begin
, cfg
->basename
, strlen(cfg
->basename
)) != 0
344 || begin
[strlen(cfg
->basename
)] != '_'
348 begin
= begin
+ strlen(cfg
->basename
) + 1;
349 end
= begin
+ strlen(begin
) - 1;
351 while(end
!= begin
&& *end
!= '_') end
--;
356 sscanf(begin
, "%d", &lvo
);
358 func
= newfunctionhead(funcname
, REGISTERMACRO
);
360 func
->novararg
= novararg
;
363 if (cfg
->funclist
== NULL
|| cfg
->funclist
->lvo
> func
->lvo
)
365 func
->next
= cfg
->funclist
;
366 cfg
->funclist
= func
;
372 funclistit
= cfg
->funclist
;
373 funclistit
->next
!= NULL
&& funclistit
->next
->lvo
< func
->lvo
;
374 funclistit
= funclistit
->next
378 if (funclistit
->next
!= NULL
&& funclistit
->next
->lvo
== func
->lvo
)
381 "Function '%s' and '%s' have the same LVO number\n",
382 funclistit
->next
->name
, func
->name
387 func
->next
= funclistit
->next
;
388 funclistit
->next
= func
;
391 parseinfo
->currentfunc
= func
;