only bring in as many sdl things as are strictly necessary
[tangerine.git] / tools / genmodule / readref.c
blobc6c4ef34b9125d76e870ee5fc906b0456513bc2f
1 /*
2 Copyright © 1995-2005, The AROS Development Team. All rights reserved.
3 $Id$
5 Function to read in the function reference file. Part of genmodule.
6 */
7 #include "genmodule.h"
8 #include "fileread.h"
9 #include <assert.h>
11 /* A structure for storing parse state information during scanning of the ref file */
12 struct _parseinfo
14 char infunction;
15 struct stringlist *currreg;
16 struct functionhead *currentfunc;
19 /* Prototypes of static functions */
20 static int parsemethodname(char *name,
21 struct _parseinfo *parseinfo,
22 struct config *cfg
24 static int parsemacroname(char *name,
25 struct _parseinfo *parseinfo,
26 struct config *cfg
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);
40 exit(20);
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
47 * are parsed.
49 parseinfo.infunction = 0;
50 while ((line=readline())!=NULL)
52 if (strlen(line)>0)
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
63 ) &&
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);
71 exit(20);
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,':');
89 if (begin==NULL)
91 fprintf(stderr, "Syntax error in reffile %s\n", cfg->reffile);
92 exit(20);
94 begin++;
95 while (isspace(*begin)) begin++;
96 end = strchr(begin, '[');
97 if (end==NULL)
99 fprintf(stderr, "Syntax error in reffile %s\n", cfg->reffile);
100 exit(20);
102 while (isspace(*(end-1))) end--;
103 *end = '\0';
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)
117 int i, brackets=0;
118 char *name;
120 begin = strchr(line, ':');
121 if (begin==NULL)
123 fprintf(stderr, "Syntax error in reffile %s\n", cfg->reffile);
124 exit(20);
126 begin++;
127 while (isspace(*begin)) begin++;
129 /* for libcall == STACK the whole argument is the type
130 * otherwise split the argument in type and name
132 #if 0
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)==']')
140 brackets++;
141 end--;
142 while (isspace(*(end-1))) end--;
143 if (*(end-1)!='[')
145 fprintf(stderr,
146 "Argument \"%s\" not understood for function %s\n",
147 begin, parseinfo.currentfunc->name
149 exit(20);
151 end--;
152 while (isspace(*(end-1))) end--;
154 *end='\0';
156 /* Skip over the argument name and duplicate it */
157 while (!isspace(*(end-1)) && *(end-1)!='*') end--;
158 name = strdup(end);
160 /* Add * for the brackets */
161 while (isspace(*(end-1))) end--;
162 for (i=0; i<brackets; i++)
164 *end='*';
165 end++;
167 *end='\0';
169 #endif
170 if (strcasecmp(begin, "void")!=0)
172 switch (parseinfo.currentfunc->libcall)
174 case STACK:
175 funcaddarg(parseinfo.currentfunc, begin, NULL);
176 break;
177 case REGISTER:
178 if (parseinfo.currreg == NULL)
180 fprintf(stderr,
181 "Error: argument count mismatch for funtion \"%s\"\n",
182 parseinfo.currentfunc->name
184 exit(20);
186 funcaddarg(parseinfo.currentfunc, begin, parseinfo.currreg->s);
187 parseinfo.currreg = parseinfo.currreg->next;
188 break;
189 case REGISTERMACRO:
191 char *reg = begin + strlen(begin) - 1;
192 while (reg != begin && *reg != '_') reg--;
194 assert(reg > begin);
196 *reg = '\0';
197 reg++;
199 funcaddarg(parseinfo.currentfunc, begin, reg);
201 break;
202 default:
203 fprintf(stderr,
204 "Internal error: Unhandled modtype in readref\n"
206 break;
210 else if (strncmp(line, "Type", 4)==0)
212 begin = strchr(line, ':');
213 if (begin==NULL)
215 fprintf(stderr, "Syntax error in reffile %s\n", cfg->reffile);
216 exit(20);
218 begin++;
219 while (isspace(*begin)) begin++;
220 end = begin+strlen(begin)-funcnamelength;
221 while (isspace(*(end-1))) end--;
222 *end = '\0';
223 parseinfo.currentfunc->type = strdup(begin);
228 fileclose();
230 /* Checking to see if every function has a prototype */
231 for
233 funclistit = cfg->funclist;
234 funclistit != NULL;
235 funclistit = funclistit->next
238 if (funclistit->type==NULL)
240 fprintf
242 stderr, "Did not find function %s in reffile %s\n",
243 funclistit->name, cfg->reffile
245 exit(20);
251 static int parsemethodname(char *name,
252 struct _parseinfo *parseinfo,
253 struct config *cfg
256 int ok = 0;
257 struct classinfo *cl;
259 for (cl = cfg->classlist; cl != NULL; cl = cl->next)
261 char *sep = NULL;
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);
277 prefixptr++;
282 sep != NULL
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;
292 else
294 it = cl->methlist;
296 while (it->next != NULL) it = it->next;
298 it->next = method;
301 parseinfo->currentfunc = method;
302 ok = 1;
306 return ok;
310 static int parsemacroname(char *name,
311 struct _parseinfo *parseinfo,
312 struct config *cfg
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;
325 unsigned int lvo;
327 if (strncmp(name, "AROS_LH_", 8) == 0)
329 begin = name+8;
331 else
332 if (strncmp(name, "AROS_PLH_", 9) == 0)
334 begin = name+9;
335 priv = 1;
337 else
339 begin = name+10;
340 novararg = 1;
343 if (strncmp(begin, cfg->basename, strlen(cfg->basename)) != 0
344 || begin[strlen(cfg->basename)] != '_'
346 return 0;
348 begin = begin + strlen(cfg->basename) + 1;
349 end = begin + strlen(begin) - 1;
351 while(end != begin && *end != '_') end--;
352 *end = '\0';
353 funcname = begin;
355 begin = end+1;
356 sscanf(begin, "%d", &lvo);
358 func = newfunctionhead(funcname, REGISTERMACRO);
359 func->lvo = lvo;
360 func->novararg = novararg;
361 func->priv = priv;
363 if (cfg->funclist == NULL || cfg->funclist->lvo > func->lvo)
365 func->next = cfg->funclist;
366 cfg->funclist = func;
368 else
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)
380 fprintf(stderr,
381 "Function '%s' and '%s' have the same LVO number\n",
382 funclistit->next->name, func->name
384 exit(20);
387 func->next = funclistit->next;
388 funclistit->next = func;
391 parseinfo->currentfunc = func;
393 return 1;
395 else
396 return 0;