Added support for building datatypes with genmodule and
[AROS.git] / tools / genmodule / boopsisupport.c
blobbe2832b3a17d631a84334e0922b2c9d132553ced
1 /*
2 Copyright © 1995-2005, The AROS Development Team. All rights reserved.
3 $Id$
5 Support function for generating code for BOOPSI classes. Part of genmodule.
6 */
7 #include "config.h"
8 #include "functionhead.h"
10 /* gettype remove the variable name from a variable definition and leave return
11 * the type of the variable
12 * [] at the end will be added as * in the variable type
13 * e.g. char *var[] => type: char **, name: var
14 * This is a destructive function and will change to string pointed to by def
15 * to only contain the type afterwards.
16 * Function return 0 when it did not understand the input, 1 otherwise
18 static int gettype(char *def);
20 void writeboopsidispatcher(FILE *out, struct config *cfg, struct functions *functions)
22 struct functionhead *methlistit;
23 struct functionarg *arglistit;
24 int i;
26 if (!cfg->customdispatcher)
28 fprintf
30 out,
31 "\n"
32 "\n"
33 "/*** Dispatcher *************************************************************/\n"
34 "BOOPSI_DISPATCHER(IPTR, %s_Dispatcher, CLASS, self, message)\n"
35 "{\n"
36 " switch (message->MethodID)\n"
37 " {\n",
38 cfg->basename
41 for
43 methlistit = functions->methlist;
44 methlistit != NULL;
45 methlistit = methlistit->next
48 char *type;
50 fprintf(out, " case %s: ", methlistit->name);
51 if (strcmp(methlistit->type, "void") != 0)
52 fprintf(out, "return (IPTR)");
53 fprintf(out,"%s__%s(", cfg->basename, methlistit->name);
55 if (methlistit->argcount != 3)
57 fprintf(stderr, "Method \"%s\" has wrong number of arguments\n", methlistit->name);
58 exit(20);
61 arglistit = methlistit->arguments;
62 fprintf(out, "CLASS, ");
64 arglistit = arglistit->next;
65 type = strdup(arglistit->type);
66 if (!gettype(type))
68 fprintf(stderr,
69 "Argument \"%s\" not understood for function %s\n",
70 arglistit->type, methlistit->name
72 exit(20);
74 fprintf(out, "(%s)self, ", type);
75 free(type);
77 arglistit = arglistit->next;
78 type = strdup(arglistit->type);
79 if (!gettype(type))
81 fprintf(stderr,
82 "Argument \"%s\" not understood for function %s\n",
83 arglistit->type, methlistit->name
85 exit(20);
87 fprintf(out, "(%s) message);", type);
88 free(type);
90 if (strcmp(methlistit->type, "void") == 0)
91 fprintf(out, " break;");
93 fprintf(out, "\n");
96 fprintf
98 out,
99 " default: return DoSuperMethodA(CLASS, self, message);\n"
100 " }\n"
101 " \n"
102 " return (IPTR) NULL;\n"
103 "}\n"
104 "BOOPSI_DISPATCHER_END\n"
107 else
109 fprintf
111 out,
112 "\n"
113 "\n"
114 "/*** Custom dispatcher prototype ********************************************/\n"
115 "BOOPSI_DISPATCHER_PROTO(IPTR, %s_Dispatcher, CLASS, object, message);\n",
116 cfg->basename
121 void writeclassinit(FILE *out, struct config *cfg, struct functions *functions)
123 struct functionhead *methlistit;
124 struct functionarg *arglistit;
125 struct stringlist *linelistit;
126 unsigned int lvo;
128 fprintf
130 out,
131 "/* Initialisation routines for a BOOPSI class */\n"
132 "/* ===========================================*/\n"
133 "\n"
134 "#include <intuition/classes.h>\n"
135 "#include <intuition/classusr.h>\n"
136 "\n"
137 "#include <proto/exec.h>\n"
138 "#include <proto/utility.h>\n"
139 "#include <proto/dos.h>\n"
140 "#include <proto/graphics.h>\n"
141 "#include <proto/intuition.h>\n"
142 "#include <proto/muimaster.h>\n"
143 "\n"
144 "#include <aros/symbolsets.h>\n"
145 "\n",
146 cfg->modulename
149 for(linelistit = cfg->cdeflines; linelistit != NULL; linelistit = linelistit->next)
151 fprintf(out, "%s\n", linelistit->s);
154 fprintf
156 out,
157 "/*** Prototypes *************************************************************/\n"
160 for
162 methlistit = functions->methlist;
163 methlistit != NULL;
164 methlistit = methlistit->next
167 int first = 1;
169 fprintf(out, "%s %s__%s(", methlistit->type, cfg->basename, methlistit->name);
171 for
173 arglistit = methlistit->arguments;
174 arglistit != NULL;
175 arglistit = arglistit->next
178 if (!first)
179 fprintf(out, ", ");
180 else
181 first = 0;
183 fprintf(out, "%s", arglistit->type);
186 fprintf(out, ");\n");
189 writeboopsidispatcher(out, cfg, functions);
191 if (cfg->classdatatype == NULL)
192 fprintf(out, "#define %s_DATA_SIZE (0)\n", cfg->basename);
193 else
194 fprintf(out,
195 "#define %s_DATA_SIZE (sizeof(%s))\n",
196 cfg->basename, cfg->classdatatype
199 fprintf
201 out,
202 "\n"
203 "\n"
204 "/*** Library startup and shutdown *******************************************/\n"
205 "AROS_SET_LIBFUNC(BOOPSI_Startup, LIBBASETYPE, LIBBASE)\n"
206 "{\n"
207 " AROS_SET_LIBFUNC_INIT\n"
208 "\n"
209 " struct IClass *cl = NULL;\n"
210 " \n"
211 " cl = MakeClass(\"%s\", \"%s\", NULL, %s_DATA_SIZE, 0);\n"
212 " if (cl != NULL)\n"
213 " {\n"
214 " GM_CLASSPTR_FIELD(LIBBASE) = cl;\n"
215 " cl->cl_Dispatcher.h_Entry = (APTR)%s_Dispatcher;\n"
216 " cl->cl_Dispatcher.h_SubEntry = NULL;\n"
217 " cl->cl_UserData = (IPTR)LIBBASE\n;"
218 "\n"
219 " AddClass(cl);\n"
220 "\n"
221 " return TRUE;\n"
222 " }\n"
223 " else\n"
224 " return FALSE;\n"
225 " \n"
226 " AROS_SET_LIBFUNC_EXIT\n"
227 "}\n"
228 "\n"
229 "AROS_SET_LIBFUNC(BOOPSI_Shutdown, LIBBASETYPE, LIBBASE)\n"
230 "{\n"
231 " AROS_SET_LIBFUNC_INIT\n"
232 " \n"
233 " if (GM_CLASSPTR_FIELD(LIBBASE) != NULL)\n"
234 " {\n"
235 " RemoveClass(GM_CLASSPTR_FIELD(LIBBASE));\n"
236 " FreeClass(GM_CLASSPTR_FIELD(LIBBASE));\n"
237 " GM_CLASSPTR_FIELD(LIBBASE) = NULL;\n"
238 " }\n"
239 "\n"
240 " return TRUE;\n"
241 "\n"
242 " AROS_SET_LIBFUNC_EXIT\n"
243 "}\n"
244 "\n"
245 "ADD2INITLIB(BOOPSI_Startup, 1);\n"
246 "ADD2EXPUNGELIB(BOOPSI_Shutdown, 1);\n",
247 cfg->classname, cfg->superclass, cfg->basename, cfg->basename
251 static int gettype(char *def)
253 char *begin = def, *end;
254 unsigned int brackets = 0, i;
256 /* Count the [] at the end of the argument */
257 end = begin+strlen(begin);
258 while (isspace(*(end-1))) end--;
259 while (*(end-1)==']')
261 brackets++;
262 end--;
263 while (isspace(*(end-1))) end--;
264 if (*(end-1)!='[')
265 return 0;
266 end--;
267 while (isspace(*(end-1))) end--;
270 /* Skip over the argument name */
271 while (!isspace(*(end-1)) && *(end-1)!='*') end--;
273 /* Add * for the brackets */
274 while (isspace(*(end-1))) end--;
275 for (i=0; i<brackets; i++)
277 *end='*';
278 end++;
280 *end='\0';
282 return 1;