tools/genmodule/writestart.c: Proper use of AROS_LDx macro's
[AROS.git] / tools / genmodule / writestart.c
blob33a3508aca202ccf1ec2c935711d8d3d44435c57
1 /*
2 Copyright © 1995-2011, The AROS Development Team. All rights reserved.
3 $Id$
5 Print the library magic and init code in the file modname_start.c.
6 This code is partly based on code in CLib37x.lha from Andreas R. Kleinert
7 */
8 #include "genmodule.h"
9 #include "oopsupport.h"
10 #include "muisupport.h"
11 #include "dtsupport.h"
12 #include "boopsisupport.h"
14 static void writedecl(FILE *, struct config *);
15 static void writedeclsets(FILE *, struct config *);
16 static void writeresident(FILE *, struct config *);
17 static void writeinitlib(FILE *, struct config *);
18 static void writehandler(FILE *, struct config *);
19 static void writeopenlib(FILE *, struct config *);
20 static void writecloselib(FILE *, struct config *);
21 static void writeexpungelib(FILE *, struct config *);
22 static void writeextfunclib(FILE *, struct config *);
23 static void writefunctable(FILE *, struct config *);
24 static void writesets(FILE *, struct config *);
26 void writestart(struct config *cfg)
28 FILE *out;
29 char line[256], *banner;
30 struct classinfo *cl;
32 snprintf(line, 255, "%s/%s_start.c", cfg->gendir, cfg->modulename);
33 out = fopen(line, "w");
35 if (out == NULL)
37 perror(line);
38 exit(20);
41 banner = getBanner(cfg);
42 fprintf(out, "%s", banner);
43 freeBanner(banner);
45 writedecl(out, cfg);
46 if (!(cfg->options & OPTION_NORESIDENT))
48 writeresident(out, cfg);
49 writedeclsets(out, cfg);
50 writeinitlib(out, cfg);
51 if (cfg->modtype != RESOURCE && cfg->modtype != HANDLER)
53 writeopenlib(out, cfg);
54 writecloselib(out, cfg);
55 writeexpungelib(out, cfg);
56 writeextfunclib(out, cfg);
57 if (cfg->modtype == MCC || cfg->modtype == MUI || cfg->modtype == MCP)
58 writemccquery(out, cfg);
59 else if (cfg->modtype == DATATYPE)
60 writeobtainengine(out, cfg);
62 writesets(out, cfg);
65 if (cfg->modtype != HANDLER)
66 writefunctable(out, cfg);
68 for (cl = cfg->classlist; cl != NULL; cl = cl->next)
70 switch (cl->classtype)
72 case MCC:
73 case MUI:
74 case MCP:
75 /* Second argument to next call: the class is not the main class if it is not
76 * the first class or the modtype is not a MUI class
78 writemccinit(out, cl != cfg->classlist || cfg->modtype != cl->classtype, cl);
79 break;
80 case GADGET:
81 case DATATYPE:
82 case CLASS:
83 case IMAGE:
84 writeclassinit(out, cl);
85 break;
86 case HIDD:
87 writeoopinit(out, cl);
88 break;
89 default:
90 fprintf(stdout, "Internal error: unsupported classtype in writestart\n");
91 exit(20);
95 fclose(out);
99 static void writedecl(FILE *out, struct config *cfg)
101 struct stringlist *linelistit;
102 int boopsiinc=0, muiinc=0, oopinc=0;
103 struct functionhead *funclistit;
104 struct functionarg *arglistit;
105 struct classinfo *classlistit;
106 char *type, *name;
108 if (cfg->modtype == DEVICE)
110 fprintf(out,
111 "#include <exec/io.h>\n"
112 "#include <exec/errors.h>\n"
115 fprintf(out,
116 "#include <exec/types.h>\n"
117 "#include <exec/libraries.h>\n"
118 "#include <exec/resident.h>\n"
119 "#include <aros/libcall.h>\n"
120 "#include <aros/asmcall.h>\n"
121 "#include <aros/symbolsets.h>\n"
122 "#include <dos/dos.h>\n"
123 "\n"
124 "#include \"%s_libdefs.h\"\n"
125 "\n"
126 "#ifdef SysBase\n"
127 "#undef SysBase\n"
128 "#endif\n"
129 "\n"
130 "#include <proto/exec.h>\n"
131 "#include <proto/alib.h>\n"
132 "#ifndef __AROS__\n"
133 "struct ExecBase *SysBase = NULL;\n"
134 "#endif\n"
135 "\n",
136 cfg->modulename
139 /* Write out declaration section provided in the config file */
140 for (linelistit = cfg->cdeflines; linelistit != NULL; linelistit = linelistit->next)
142 fprintf(out, "%s\n", linelistit->s);
145 /* Is there a variable for storing the segList ? */
146 if (!(cfg->options & OPTION_NOEXPUNGE) && cfg->modtype!=RESOURCE && cfg->modtype != HANDLER)
148 fprintf(out,
149 "#ifndef GM_SEGLIST_FIELD\n"
150 "static BPTR __attribute__((unused)) GM_UNIQUENAME(seglist);\n"
151 "#define GM_SEGLIST_FIELD(lh) (GM_UNIQUENAME(seglist))\n"
152 "#endif\n"
155 if (cfg->options & OPTION_DUPBASE)
156 fprintf(out,
157 "#ifndef GM_ROOTBASE_FIELD\n"
158 "static LIBBASETYPEPTR GM_UNIQUENAME(rootbase);\n"
159 "#define GM_ROOTBASE_FIELD(lh) (GM_UNIQUENAME(rootbase))\n"
160 "#endif\n"
161 "static int __baseslot;\n"
162 "LIBBASETYPEPTR __GM_GetBase(void)\n"
163 "{\n"
164 " return (LIBBASETYPEPTR)SysBase->ThisTask->tc_UnionETask.tc_TaskStorage[__baseslot];\n"
165 "}\n"
166 /* On AMD64 don't clobber registers used for argument passing,
167 * only clobber rax, r10 and r11
169 "#if defined __x86_64__\n"
170 "asm(\".global __comp_get_relbase\\n\"\n"
171 " \"__comp_get_relbase :\\n\"\n"
172 " \"\\tmovq SysBase(%%rip), %%rax\\n\"\n"
173 " \"\\tmovq 552(%%rax), %%rax\\n\"\n"
174 " \"\\tmovq 56(%%rax), %%r10\\n\"\n"
175 " \"\\tmovslq __baseslot(%%rip),%%r11\\n\"\n"
176 " \"\\tmovq (%%r10,%%r11,8), %%rax\\n\"\n"
177 " \"\\tret\\n\"\n"
178 ");\n"
179 "#else\n"
180 "AROS_MAKE_ALIAS(__GM_GetBase, __comp_get_relbase);\n"
181 "#endif\n"
182 "static __used void __GM_SetBase(LIBBASETYPEPTR base)\n"
183 "{\n"
184 " SysBase->ThisTask->tc_UnionETask.tc_TaskStorage[__baseslot] = (IPTR)base;\n"
185 "}\n"
186 "#if defined __i386__\n"
187 "#define GM_INTERNALFUNCSTUB(fname)\\\n"
188 " asm(#fname \"_stub :\\n\"\\\n"
189 " \"\\tpushl %%edx\\n\"\\\n"
190 " \"\\tcall __GM_SetBase\\n\"\\\n"
191 " \"\\tpopl %%edx\\n\"\\\n"
192 " \"\\tjmp \" #fname \"\\n\"\\\n"
193 " )\n"
194 "#elif defined __x86_64__\n"
195 /* On AMD64 we can't call __GM_SetBase() as it will mess
196 * up with the parameters passed in registers
198 "#define GM_INTERNALFUNCSTUB(fname)\\\n"
199 /* On x86_64 we can use r10 and r11 in between function call and entry
200 r11 contains libbase */
201 " asm(#fname \"_stub :\\n\"\\\n"
202 " \"\\tpushq %%rax\\n\"\\\n"
203 " \"\\tmovq SysBase(%%rip), %%rax\\n\"\\\n"
204 " \"\\tmovslq __baseslot(%%rip),%%r10\\n\"\\\n"
205 " \"\\tmovq 552(%%rax), %%rax\\n\"\\\n"
206 " \"\\tmovq 56(%%rax), %%rax\\n\"\\\n"
207 " \"\\tmovq %%r11,(%%rax,%%r10,8)\\n\"\\\n"
208 " \"\\tpopq %%rax\\n\"\\\n"
209 " \"\\tjmp \" #fname \"\\n\"\\\n"
210 " )\n"
211 "#elif defined __mc68000__\n"
212 "#define GM_INTERNALFUNCSTUB(fname)\\\n"
213 " asm(#fname \"_stub :\\n\"\\\n"
214 " \"\\tmove.l %%a1,%%sp@-\\n\"\\\n"
215 " \"\\tjsr __GM_SetBase\\n\"\\\n"
216 " \"\\tmove.l %%sp@+,%%a1\\n\"\\\n"
217 " \"\\tjmp \" #fname \"\\n\"\\\n"
218 " )\n"
219 "#elif defined __powerpc__\n"
220 /* FIXME: struct offsets are from i386,
221 need to be checked ! */
222 "#define GM_INTERNALFUNCSTUB(fname)\\\n"
223 /* On PPC we can use r0, r11, r12 in between function call and entry
224 * r12 contains libbase
226 " asm(#fname \"_stub :\\n\"\\\n"
227 /* r0 = SysBase->ThisTask->tc_UnionETask.tc_TaskStorage */
228 " \"\\tlis 11, SysBase@ha\\n\"\\\n"
229 " \"\\tlwz 11, SysBase@l(11)\\n\"\\\n"
230 " \"\\tlwz 11, 284(11)\\n\"\\\n"
231 " \"\\tlwz 0, 36(11)\\n\"\\\n"
232 /* r11 = r0 + __baseslot */
233 " \"\\tlis 11, __baseslot@ha\\n\"\\\n"
234 " \"\\tlwz 11, __baseslot@l(11)\\n\"\\\n"
235 " \"\\tadd 11,0,11\\n\"\\\n"
236 /* *r11 = r12 (== libbase) */
237 " \"\\tstw 12, 0(11)\\n\"\\\n"
238 " \"\\tb \" #fname \"\\n\"\\\n"
239 " )\n"
240 "#elif defined __arm__\n"
241 "#define GM_INTERNALFUNCSTUB(fname)\\\n"
242 " asm(#fname \"_stub :\\n\"\\\n"
243 " \"\\tpush {r0, r1, r2, r3, lr}\\n\"\\\n"
244 " \"\\tmov r0, r12\\n\"\\\n"
245 " \"\\tbl __GM_SetBase\\n\"\\\n" /* r12 may be scratched */
246 " \"\\tpop {r0, r1, r2, r3, lr}\\n\"\\\n"
247 " \"\\tb \" #fname \"\\n\"\\\n" /* call function */
248 " )\n"
249 "#else\n"
250 "# error unsupported CPU type\n"
251 "#endif\n"
254 if (cfg->options & OPTION_PERTASKBASE)
255 fprintf(out,
256 "struct __GM_PerTaskBase {\n"
257 " LIBBASETYPE base;\n"
258 " ULONG taskopencount;\n"
259 " struct Task *task;\n"
260 " APTR retaddr;\n"
261 " LIBBASETYPEPTR oldbase;\n"
262 "};\n"
263 "#define LIBBASESIZE sizeof(struct __GM_PerTaskBase)\n"
264 "static int __pertaskslot;\n"
265 "LIBBASETYPEPTR __GM_GetBaseParent(LIBBASETYPEPTR base)\n"
266 "{\n"
267 " return ((struct __GM_PerTaskBase *)base)->oldbase;\n"
268 "}\n"
269 "static inline LIBBASETYPEPTR __GM_GetPerTaskBase(void)\n"
270 "{\n"
271 " return (LIBBASETYPEPTR)SysBase->ThisTask->tc_UnionETask.tc_TaskStorage[__pertaskslot];\n"
272 "}\n"
273 "static inline void __GM_SetPerTaskBase(LIBBASETYPEPTR base)\n"
274 "{\n"
275 " SysBase->ThisTask->tc_UnionETask.tc_TaskStorage[__pertaskslot] = (IPTR)base;\n"
276 "}\n"
278 else
279 fprintf(out, "#define LIBBASESIZE sizeof(LIBBASETYPE)\n");
281 for (classlistit = cfg->classlist; classlistit != NULL; classlistit = classlistit->next)
283 /* For the main class basename is the same as the module basename */
284 if (strcmp(classlistit->basename, cfg->basename) == 0)
286 if (classlistit->classptr_var == NULL)
288 fprintf(out,
289 "#if !defined(GM_CLASSPTR_FIELD) && !defined(%s_CLASSPTR_FIELD)\n"
290 "static APTR GM_UNIQUENAME(%sClass);\n"
291 "#define GM_CLASSPTR_FIELD(lh) (GM_UNIQUENAME(%sClass))\n"
292 "#define %s_CLASSPTR_FIELD(lh) (GM_UNIQUENAME(%sClass))\n"
293 "#define %s_STORE_CLASSPTR 1\n"
294 "#elif defined(GM_CLASSPTR_FIELD) && !defined(%s_CLASSPTR_FIELD)\n"
295 "#define %s_CLASSPTR_FIELD(lh) (GM_CLASSPTR_FIELD(lh))\n"
296 "#elif !defined(GM_CLASSPTR_FIELD) && defined(%s_CLASSPTR_FIELD)\n"
297 "#define GM_CLASSPTR_FIELD(lh) (%s_CLASSPTR_FIELD(lh))\n"
298 "#endif\n",
299 classlistit->basename,
300 classlistit->basename,
301 classlistit->basename,
302 classlistit->basename, classlistit->basename,
303 classlistit->basename,
304 classlistit->basename,
305 classlistit->basename,
306 classlistit->basename,
307 classlistit->basename
310 else
312 fprintf(out,
313 "#define GM_CLASSPTR_FIELD(lh) (%s)\n"
314 "#define %s_CLASSPTR_FIELD(lh) (%s)\n"
315 "#define %s_STORE_CLASSPTR 1\n",
316 classlistit->classptr_var,
317 classlistit->basename, classlistit->classptr_var,
318 classlistit->basename
322 else
324 if (classlistit->classptr_var == NULL)
326 fprintf(out,
327 "#if !defined(%s_CLASSPTR_FIELD)\n"
328 "static APTR GM_UNIQUENAME(%sClass);\n"
329 "#define %s_CLASSPTR_FIELD(lh) (GM_UNIQUENAME(%sClass))\n"
330 "#define %s_STORE_CLASSPTR 1\n"
331 "#endif\n",
332 classlistit->basename,
333 classlistit->basename,
334 classlistit->basename, classlistit->basename,
335 classlistit->basename
338 else
340 fprintf(out,
341 "#define %s_CLASSPTR_FIELD(lh) (%s)\n"
342 "#define %s_STORE_CLASSPTR 1\n",
343 classlistit->basename, classlistit->classptr_var,
344 classlistit->basename
350 /* Write out the defines for the functions of the function table */
351 writefuncdefs(out, cfg, cfg->funclist);
352 /* Write internal stubs */
353 writefuncinternalstubs(out, cfg, cfg->funclist);
354 fprintf(out, "\n");
357 /* Write out the includes needed for the classes */
358 if (cfg->classlist != NULL)
359 writeboopsiincludes(out);
361 for (classlistit = cfg->classlist; classlistit != NULL; classlistit = classlistit->next)
363 switch (classlistit->classtype)
365 case MUI:
366 case MCC:
367 case MCP:
368 if (!muiinc)
370 writemuiincludes(out);
371 muiinc = 1;
373 /* Fall through: also write boopsi includes */
374 case GADGET:
375 case DATATYPE:
376 case CLASS:
377 case IMAGE:
378 if (!boopsiinc)
380 writeboopsiincludes(out);
381 boopsiinc = 1;
383 break;
384 case HIDD:
385 if (!oopinc)
387 writeoopincludes(out);
388 oopinc = 1;
390 break;
391 default:
392 fprintf(stderr, "Internal error: unhandled classtype in writedecl\n");
393 exit(20);
399 static void writedeclsets(FILE *out, struct config *cfg)
401 fprintf(out,
402 "THIS_PROGRAM_HANDLES_SYMBOLSETS\n"
403 "DECLARESET(INIT)\n"
404 "DECLARESET(EXIT)\n"
405 "DECLARESET(CTORS)\n"
406 "DECLARESET(DTORS)\n"
407 "DECLARESET(INITLIB)\n"
408 "DECLARESET(EXPUNGELIB)\n"
410 if (!(cfg->options & OPTION_NOOPENCLOSE))
411 fprintf(out,
412 "DECLARESET(OPENLIB)\n"
413 "DECLARESET(CLOSELIB)\n"
415 if (cfg->modtype == DEVICE)
416 fprintf(out,
417 "DECLARESET(OPENDEV)\n"
418 "DECLARESET(CLOSEDEV)\n"
420 if (cfg->classlist != NULL)
421 fprintf(out,
422 "DECLARESET(CLASSESINIT)\n"
423 "DECLARESET(CLASSESEXPUNGE)\n"
424 "#define ADD2INITCLASSES(symbol, pri) ADD2SET(symbol, classesinit, pri)\n"
425 "#define ADD2EXPUNGECLASSES(symbol, pri) ADD2SET(symbol, classesexpunge, pri)\n"
427 fprintf(out, "\n");
431 static void writeresident(FILE *out, struct config *cfg)
433 char *rt_skip = cfg->addromtag;
435 if (rt_skip)
436 fprintf(out, "extern const struct Resident %s;\n", rt_skip);
437 else
439 rt_skip = "GM_UNIQUENAME(End)";
440 fprintf(out, "extern const int %s;\n", rt_skip);
442 fprintf(out,
443 "extern const APTR GM_UNIQUENAME(FuncTable)[];\n"
445 if (cfg->options & OPTION_RESAUTOINIT)
446 fprintf(out, "static const struct InitTable GM_UNIQUENAME(InitTable);\n");
447 fprintf(out,
448 "\n"
449 "extern const char GM_UNIQUENAME(LibName)[];\n"
450 "extern const char GM_UNIQUENAME(LibID)[];\n"
451 "extern const char GM_UNIQUENAME(Copyright)[];\n"
452 "\n"
455 if (cfg->options & OPTION_RESAUTOINIT)
457 fprintf(out,
458 "#define __freebase(lh)\\\n"
459 "do {\\\n"
460 " UWORD negsize, possize;\\\n"
461 " UBYTE *negptr = (UBYTE *)lh;\\\n"
462 " negsize = ((struct Library *)lh)->lib_NegSize;\\\n"
463 " negptr -= negsize;\\\n"
464 " possize = ((struct Library *)lh)->lib_PosSize;\\\n"
465 " FreeMem (negptr, negsize+possize);\\\n"
466 "} while(0)\n"
467 "\n");
470 fprintf(out,
471 "AROS_UFP3 (LIBBASETYPEPTR, GM_UNIQUENAME(InitLib),\n"
472 " AROS_UFPA(LIBBASETYPEPTR, lh, D0),\n"
473 " AROS_UFPA(BPTR, segList, A0),\n"
474 " AROS_UFPA(struct ExecBase *, sysBase, A6)\n"
475 ");\n"
477 if (cfg->modtype != RESOURCE && cfg->modtype != HANDLER)
479 fprintf(out,
480 "AROS_LD1(BPTR, GM_UNIQUENAME(ExpungeLib),\n"
481 " AROS_LDA(LIBBASETYPEPTR, extralh, D0),\n"
482 " LIBBASETYPEPTR, lh, 3, %s\n"
483 ");\n"
484 "\n",
485 cfg->basename
488 fprintf(out,
489 "struct Resident const GM_UNIQUENAME(ROMTag) =\n"
490 "{\n"
491 " RTC_MATCHWORD,\n"
492 " (struct Resident *)&GM_UNIQUENAME(ROMTag),\n"
493 " (APTR)&%s,\n"
494 " RESIDENTFLAGS,\n"
495 " VERSION_NUMBER,\n",
496 rt_skip
498 switch (cfg->modtype)
500 case LIBRARY:
501 case MUI:
502 case MCC:
503 case MCP:
504 case GADGET:
505 case DATATYPE:
506 case USBCLASS:
507 case HIDD:
508 fprintf(out, " NT_LIBRARY,\n");
509 break;
510 case DEVICE:
511 fprintf(out, " NT_DEVICE,\n");
512 break;
513 case RESOURCE:
514 case HANDLER:
515 fprintf(out, " NT_RESOURCE,\n");
516 break;
517 default:
518 fprintf(stderr, "Internal error: unsupported modtype for NT_...\n");
519 exit(20);
520 break;
522 fprintf(out,
523 " RESIDENTPRI,\n"
524 " (CONST_STRPTR)&GM_UNIQUENAME(LibName)[0],\n"
525 " (CONST_STRPTR)&GM_UNIQUENAME(LibID)[6],\n"
527 if (cfg->options & OPTION_RESAUTOINIT)
529 fprintf(out,
530 " (APTR)&GM_UNIQUENAME(InitTable)\n"
531 "};\n"
532 "\n"
533 "static struct InitTable\n"
534 "{\n"
535 " IPTR Size;\n"
536 " const APTR *FuncTable;\n"
537 " struct DataTable *DataTable;\n"
538 " APTR InitLibTable;\n"
539 "}\n"
540 "const GM_UNIQUENAME(InitTable) =\n"
541 "{\n"
542 " LIBBASESIZE,\n"
543 " &GM_UNIQUENAME(FuncTable)[0],\n"
544 " NULL,\n"
545 " (APTR)GM_UNIQUENAME(InitLib)\n"
546 "};\n"
549 else
550 fprintf(out, " (APTR)GM_UNIQUENAME(InitLib)\n};\n");
552 fprintf(out,
553 "\n"
554 "const char GM_UNIQUENAME(LibName)[] = MOD_NAME_STRING;\n"
555 "const char GM_UNIQUENAME(LibID)[] = VERSION_STRING;\n"
556 "const char GM_UNIQUENAME(Copyright)[] = COPYRIGHT_STRING;\n"
557 "\n"
561 static void writehandler(FILE *out, struct config *cfg)
563 int i;
564 struct handlerinfo *hl;
566 fprintf(out,
567 "\n"
568 "#include <resources/filesysres.h>\n"
569 "#include <aros/system.h>\n"
570 "#include <proto/arossupport.h>\n"
571 "#include <proto/dos.h>\n"
572 "\n"
575 for (hl = cfg->handlerlist; hl != NULL; hl = hl->next) {
576 fprintf(out,
577 "extern void %s(void);\n",
578 hl->handler);
581 fprintf(out,
582 "\n"
583 "void GM_UNIQUENAME(InitHandler)(void)\n"
584 "{\n"
585 " struct FileSysResource *fsr;\n"
586 " int i;\n"
587 " const struct {\n"
588 " ULONG id;\n"
589 " BSTR name;\n"
590 " BYTE autodetect;\n"
591 " BYTE priority;\n"
592 " ULONG stacksize;\n"
593 " void (*handler)(void);\n"
594 " } const __handler[] = { \n");
595 for (hl = cfg->handlerlist; hl != NULL; hl = hl->next)
597 switch (hl->type)
599 case HANDLER_RESIDENT:
600 fprintf(out,
601 " { .id = 0, .name = AROS_CONST_BSTR(\"%s\"), .handler = %s }, \n",
602 hl->name, hl->handler);
603 break;
604 case HANDLER_DOSTYPE:
605 fprintf(out,
606 " { .id = 0x%08x, .name = AROS_CONST_BSTR(MOD_NAME_STRING), .handler = %s, .autodetect = %d, .priority = %d, .stacksize = %d*sizeof(IPTR) }, \n",
607 hl->id, hl->handler, hl->autodetect, hl->priority, hl->stacksize);
608 break;
611 fprintf(out,
612 " };\n"
613 " BPTR seg[sizeof(__handler)/sizeof(__handler[0])] = { };\n"
614 "\n"
615 " fsr = (struct FileSysResource *)OpenResource(\"FileSystem.resource\");\n"
616 " if (fsr == NULL)\n"
617 " return;\n"
618 "\n"
619 " for (i = 0; i < sizeof(__handler)/sizeof(__handler[0]); i++) {\n"
620 " struct FileSysEntry *fse;\n"
621 " int j;\n"
622 "\n"
623 " /* Check to see if we can allocate the memory for the fse */\n"
624 " fse = AllocMem(sizeof(*fse), MEMF_CLEAR);\n"
625 " if (!fse)\n"
626 " return;\n"
627 "\n"
628 " /* Did we already make a segment for this handler? */\n"
629 " for (j = 0; j < i; j++)\n"
630 " if (__handler[i].handler == __handler[j].handler)\n"
631 " break;\n"
632 " if (seg[j] == (BPTR)0)\n"
633 " seg[j] = CreateSegList(__handler[j].handler);\n"
634 " if (seg[j] == BNULL) {\n"
635 " FreeMem(fse, sizeof(*fse));\n"
636 " return;\n"
637 " }\n"
638 " \n"
639 " /* DOS ID based handlers\n"
640 " * NOTE: fse_DosType == 0 is a special flag use in\n"
641 " * dos.library's init to add the handler to the\n"
642 " * resident segment list\n"
643 " */\n"
644 " fse->fse_Node.ln_Name = VERSION_STRING;\n"
645 " fse->fse_Node.ln_Pri = __handler[i].autodetect;\n"
646 " fse->fse_DosType = __handler[i].id;\n"
647 " fse->fse_Version = (MAJOR_VERSION << 16) | MINOR_VERSION;\n"
648 " fse->fse_PatchFlags = FSEF_SEGLIST | FSEF_GLOBALVEC | FSEF_HANDLER | FSEF_PRIORITY;\n"
649 " if (__handler[i].stacksize) {\n"
650 " fse->fse_PatchFlags |= FSEF_STACKSIZE;\n"
651 " fse->fse_StackSize = __handler[i].stacksize;\n"
652 " }\n"
653 " fse->fse_Handler = __handler[i].name;\n"
654 " fse->fse_Priority = __handler[i].priority;\n"
655 " fse->fse_SegList = seg[j];\n"
656 " fse->fse_GlobalVec = (BPTR)(SIPTR)-1;\n"
657 " \n"
658 " /* Add to the list. I know forbid and permit are\n"
659 " * a little unnecessary for the pre-multitasking state\n"
660 " * we should be in at this point, but you never know\n"
661 " * who's going to blindly copy this code as an example.\n"
662 " */\n"
663 " Forbid();\n"
664 " Enqueue(&fsr->fsr_FileSysEntries, (struct Node *)fse);\n"
665 " Permit();\n"
666 " }\n"
667 "}\n");
670 static void writeinitlib(FILE *out, struct config *cfg)
672 if (cfg->handlerlist)
673 writehandler(out, cfg);
675 fprintf(out,
676 "AROS_UFH3 (LIBBASETYPEPTR, GM_UNIQUENAME(InitLib),\n"
677 " AROS_UFHA(LIBBASETYPEPTR, lh, D0),\n"
678 " AROS_UFHA(BPTR, segList, A0),\n"
679 " AROS_UFHA(struct ExecBase *, sysBase, A6)\n"
680 ")\n"
681 "{\n"
682 " AROS_USERFUNC_INIT\n"
683 "\n"
684 " int ok;\n"
686 if (cfg->modtype != HANDLER)
687 fprintf(out,
688 " int initcalled = 0;\n"
690 fprintf(out,
691 "\n"
694 if (cfg->options & OPTION_RESAUTOINIT) {
695 fprintf(out,
696 "#ifndef __AROS__\n"
697 " SysBase = sysBase;\n"
698 "#endif\n"
699 "#ifdef GM_SYSBASE_FIELD\n"
700 " GM_SYSBASE_FIELD(lh) = (APTR)sysBase;\n"
701 "#endif\n"
702 "#ifdef GM_OOPBASE_FIELD\n"
703 " GM_OOPBASE_FIELD(lh) = OpenLibrary(\"oop.library\",0);\n"
704 " if (GM_OOPBASE_FIELD(lh) == NULL)\n"
705 " return NULL;\n"
706 "#endif\n"
710 if (cfg->modtype != HANDLER)
712 if (!(cfg->options & OPTION_RESAUTOINIT))
714 fprintf(out,
715 " int vecsize;\n"
716 " struct Node *n;\n"
717 " char *mem;\n"
718 "\n"
719 " vecsize = FUNCTIONS_COUNT * LIB_VECTSIZE;\n"
720 " if (vecsize > 0)\n"
721 " vecsize = ((vecsize-1)/sizeof(IPTR) + 1)*sizeof(IPTR);\n"
722 " mem = AllocMem(vecsize+sizeof(LIBBASETYPE), MEMF_PUBLIC|MEMF_CLEAR);\n"
723 " if (mem == NULL)\n"
724 " return NULL;\n"
725 " lh = (LIBBASETYPEPTR)(mem + vecsize);\n"
726 " n = (struct Node *)lh;\n"
727 " n->ln_Type = NT_RESOURCE;\n"
728 " n->ln_Pri = RESIDENTPRI;\n"
729 " n->ln_Name = (char *)GM_UNIQUENAME(LibName);\n"
730 " MakeFunctions(lh, (APTR)GM_UNIQUENAME(FuncTable), NULL);\n"
732 if ((cfg->modtype != RESOURCE) && (cfg->options & OPTION_SELFINIT))
734 fprintf(out,
735 " ((struct Library*)lh)->lib_NegSize = vecsize;\n"
736 " ((struct Library*)lh)->lib_PosSize = sizeof(LIBBASETYPE);\n"
741 else
743 fprintf(out,
744 " ((struct Library *)lh)->lib_Revision = REVISION_NUMBER;\n"
749 if (cfg->options & OPTION_DUPBASE)
750 fprintf(out,
751 " __baseslot = AllocTaskStorageSlot();\n"
752 " __GM_SetBase(lh);\n"
754 if (cfg->options & OPTION_PERTASKBASE)
755 fprintf(out,
756 " __pertaskslot = AllocTaskStorageSlot();\n"
759 if (!(cfg->options & OPTION_NOEXPUNGE) && cfg->modtype!=RESOURCE && cfg->modtype != HANDLER)
760 fprintf(out, " GM_SEGLIST_FIELD(lh) = segList;\n");
761 if (cfg->options & OPTION_DUPBASE)
762 fprintf(out, " GM_ROOTBASE_FIELD(lh) = (LIBBASETYPEPTR)lh;\n");
763 fprintf(out, " if (");
764 if (!(cfg->options & OPTION_NOAUTOLIB))
765 fprintf(out, "set_open_libraries() && ");
766 if (cfg->classlist != NULL)
767 fprintf(out, "set_call_libfuncs(SETNAME(CLASSESINIT), 1, 1, lh) && ");
768 fprintf(out,
769 "set_call_funcs(SETNAME(INIT), 1, 1) )\n"
770 " {\n"
771 " set_call_funcs(SETNAME(CTORS), -1, 0);\n"
772 "\n"
775 if (cfg->modtype == HANDLER)
776 fprintf(out,
777 " ok = 1;\n");
778 else
779 fprintf(out,
780 " initcalled = 1;\n"
781 " ok = set_call_libfuncs(SETNAME(INITLIB), 1, 1, lh);\n");
782 fprintf(out,
783 " }\n"
784 " else\n"
785 " ok = 0;\n"
786 "\n"
787 " if (!ok)\n"
788 " {\n"
791 if (cfg->modtype != HANDLER)
792 fprintf(out,
793 " if (initcalled)\n"
794 " set_call_libfuncs(SETNAME(EXPUNGELIB), -1, 0, lh);\n");
796 fprintf(out,
797 " set_call_funcs(SETNAME(DTORS), 1, 0);\n"
798 " set_call_funcs(SETNAME(EXIT), -1, 0);\n"
800 if (cfg->classlist != NULL)
801 fprintf(out, " set_call_libfuncs(SETNAME(CLASSESEXPUNGE), -1, 0, lh);\n");
802 if (!(cfg->options & OPTION_NOAUTOLIB))
803 fprintf(out, " set_close_libraries();\n");
805 if (cfg->modtype != HANDLER)
807 if (cfg->options & OPTION_RESAUTOINIT)
809 fprintf(out,
810 "\n"
811 " __freebase(lh);\n"
814 else
816 fprintf(out,
817 "\n"
818 " FreeMem(mem, vecsize+LIBBASESIZE);\n"
822 fprintf(out,
823 " return NULL;\n"
824 " }\n"
825 " else\n"
826 " {\n"
829 if (!(cfg->options & OPTION_RESAUTOINIT) && !(cfg->options & OPTION_SELFINIT))
831 switch (cfg->modtype)
833 case RESOURCE:
834 fprintf(out, " AddResource(lh);\n");
835 break;
837 case DEVICE:
838 fprintf(out, " AddDevice(lh);\n");
840 case HANDLER:
841 /* Bare handlers don't require adding at all */
842 break;
844 default:
845 /* Everything else is library */
846 fprintf(out, " AddLibrary(lh);\n");
847 break;
851 if (cfg->handlerlist)
852 fprintf(out, " GM_UNIQUENAME(InitHandler)();\n");
854 fprintf(out,
855 " return lh;\n"
856 " }\n"
857 "\n"
858 " AROS_USERFUNC_EXIT\n"
859 "}\n"
860 "\n"
864 static void writeopenlib(FILE *out, struct config *cfg)
866 switch (cfg->modtype)
868 case RESOURCE:
869 fprintf(stderr, "Internal error: writeopenlib called for a resource\n");
870 break;
871 case HANDLER:
872 fprintf(stderr, "Internal error: writeopenlib called for a handler\n");
873 break;
874 case DEVICE:
875 if (cfg->options & OPTION_NOOPENCLOSE)
876 fprintf(out,
877 "AROS_LD3 (void, GM_UNIQUENAME(OpenLib),\n"
878 " AROS_LDA(struct IORequest *, ioreq, A1),\n"
879 " AROS_LDA(ULONG, unitnum, D0),\n"
880 " AROS_LDA(ULONG, flags, D1),\n"
881 " LIBBASETYPEPTR, lh, 1, %s\n"
882 ");\n",
883 cfg->basename
885 else
887 fprintf(out,
888 "AROS_LH3 (void, GM_UNIQUENAME(OpenLib),\n"
889 " AROS_LHA(struct IORequest *, ioreq, A1),\n"
890 " AROS_LHA(IPTR, unitnum, D0),\n"
891 " AROS_LHA(ULONG, flags, D1),\n"
892 " LIBBASETYPEPTR, lh, 1, %s\n"
893 ")\n",
894 cfg->basename
896 fprintf(out,
897 "{\n"
898 " AROS_LIBFUNC_INIT\n"
899 "\n"
900 " if ( set_call_libfuncs(SETNAME(OPENLIB), 1, 1, lh)\n"
901 " && set_call_devfuncs(SETNAME(OPENDEV), 1, 1, lh, ioreq, unitnum, flags)\n"
902 " )\n"
903 " {\n"
904 " ((struct Library *)lh)->lib_OpenCnt++;\n"
905 " ((struct Library *)lh)->lib_Flags &= ~LIBF_DELEXP;\n"
906 "\n"
907 " ioreq->io_Message.mn_Node.ln_Type = NT_REPLYMSG;\n"
908 " }\n"
909 " else\n"
910 " {\n"
911 " if (ioreq->io_Error >= 0)\n"
912 " ioreq->io_Error = IOERR_OPENFAIL;\n"
913 " }\n"
914 "\n"
915 " return;\n"
916 "\n"
917 " AROS_LIBFUNC_EXIT\n"
918 "}\n"
919 "\n"
922 break;
923 default:
924 if (cfg->options & OPTION_NOOPENCLOSE)
926 fprintf(out,
927 "AROS_LD1 (LIBBASETYPEPTR, GM_UNIQUENAME(OpenLib),\n"
928 " AROS_LDA (ULONG, version, D0),\n"
929 " LIBBASETYPEPTR, lh, 1, %s\n"
930 ");\n",
931 cfg->basename
933 return;
935 fprintf(out,
936 "AROS_LH1 (LIBBASETYPEPTR, GM_UNIQUENAME(OpenLib),\n"
937 " AROS_LHA (ULONG, version, D0),\n"
938 " LIBBASETYPEPTR, lh, 1, %s\n"
939 ")\n"
940 "{\n"
941 " AROS_LIBFUNC_INIT\n"
942 "\n",
943 cfg->basename
945 if (!(cfg->options & OPTION_DUPBASE))
947 fprintf(out,
948 " if ( set_call_libfuncs(SETNAME(OPENLIB), 1, 1, lh) )\n"
949 " {\n"
950 " ((struct Library *)lh)->lib_OpenCnt++;\n"
951 " ((struct Library *)lh)->lib_Flags &= ~LIBF_DELEXP;\n"
952 "\n"
953 " return lh;\n"
954 " }\n"
955 "\n"
956 " return NULL;\n"
957 "\n"
958 " AROS_LIBFUNC_EXIT\n"
959 "}\n"
960 "\n"
963 else /* OPTION_DUPBASE */
965 fprintf(out,
966 " struct Library *newlib = NULL;\n"
967 " UWORD possize = ((struct Library *)lh)->lib_PosSize;\n"
969 if (cfg->options & OPTION_PERTASKBASE)
970 fprintf(out,
971 " struct Task *thistask = FindTask(NULL);\n"
972 " LIBBASETYPEPTR oldbase = __GM_GetPerTaskBase();\n"
973 " newlib = (struct Library *)oldbase;\n"
974 " if (newlib)\n"
975 " {\n"
976 " struct __GM_PerTaskBase *pertaskbase = (struct __GM_PerTaskBase *)newlib;\n"
977 " if (pertaskbase->task != thistask)\n"
978 " newlib = NULL;\n"
979 " else if (thistask->tc_Node.ln_Type == NT_PROCESS\n"
980 " && pertaskbase->retaddr != ((struct Process *)thistask)->pr_ReturnAddr\n"
981 " )\n"
982 " newlib = NULL;\n"
983 " else\n"
984 " pertaskbase->taskopencount++;\n"
985 " }\n"
988 fprintf(out,
989 "\n"
990 " if (newlib == NULL)\n"
991 " {\n"
992 " newlib = MakeLibrary(GM_UNIQUENAME(InitTable).FuncTable,\n"
993 " GM_UNIQUENAME(InitTable).DataTable,\n"
994 " NULL,\n"
995 " GM_UNIQUENAME(InitTable).Size,\n"
996 " (BPTR)NULL\n"
997 " );\n"
998 " if (newlib == NULL)\n"
999 " return NULL;\n"
1000 "\n"
1001 " CopyMem(lh, newlib, possize);\n"
1002 " __GM_SetBase((LIBBASETYPEPTR)newlib);\n"
1004 if (cfg->options & OPTION_PERTASKBASE)
1005 fprintf(out,
1006 " struct __GM_PerTaskBase *pertaskbase = (struct __GM_PerTaskBase *)newlib;\n"
1007 " pertaskbase->task = thistask;\n"
1008 " if (thistask->tc_Node.ln_Type == NT_PROCESS)\n"
1009 " pertaskbase->retaddr = ((struct Process *)thistask)->pr_ReturnAddr;\n"
1010 " pertaskbase->oldbase = oldbase;\n"
1011 " pertaskbase->taskopencount = 1;\n"
1012 " __GM_SetPerTaskBase((LIBBASETYPEPTR)newlib);\n"
1014 fprintf(out,
1015 "\n"
1016 " if (!(set_open_rellibraries(newlib)\n"
1017 " && set_call_libfuncs(SETNAME(OPENLIB), 1, 1, newlib)\n"
1018 " )\n"
1019 " )\n"
1020 " {\n");
1021 if (cfg->options & OPTION_PERTASKBASE)
1022 fprintf(out,
1023 " __GM_SetPerTaskBase(oldbase);\n");
1024 fprintf(out,
1025 " __freebase(newlib);\n"
1026 " return NULL;\n"
1027 " }\n"
1028 "\n"
1029 " ((struct Library *)lh)->lib_OpenCnt++;\n"
1030 " ((struct Library *)lh)->lib_Flags &= ~LIBF_DELEXP;\n"
1031 " }\n"
1032 "\n"
1033 " return (LIBBASETYPEPTR)newlib;\n"
1034 "\n"
1035 " AROS_LIBFUNC_EXIT\n"
1036 "}\n"
1037 "\n"
1044 static void writecloselib(FILE *out, struct config *cfg)
1046 if (cfg->options & OPTION_NOOPENCLOSE)
1048 if (cfg->modtype != DEVICE)
1049 fprintf(out,
1050 "AROS_LD0 (BPTR, GM_UNIQUENAME(CloseLib),\n"
1051 " LIBBASETYPEPTR, lh, 2, %s\n"
1052 ");\n",
1053 cfg->basename
1055 else
1056 fprintf(out,
1057 "AROS_LD1(BPTR, GM_UNIQUENAME(CloseLib),\n"
1058 " AROS_LDA(struct IORequest *, ioreq, A1),\n"
1059 " LIBBASETYPEPTR, lh, 2, %s\n"
1060 ");\n",
1061 cfg->basename
1063 return;
1065 if (cfg->modtype != DEVICE)
1066 fprintf(out,
1067 "AROS_LH0 (BPTR, GM_UNIQUENAME(CloseLib),\n"
1068 " LIBBASETYPEPTR, lh, 2, %s\n"
1069 ")\n",
1070 cfg->basename
1072 else
1073 fprintf(out,
1074 "AROS_LH1(BPTR, GM_UNIQUENAME(CloseLib),\n"
1075 " AROS_LHA(struct IORequest *, ioreq, A1),\n"
1076 " LIBBASETYPEPTR, lh, 2, %s\n"
1077 ")\n",
1078 cfg->basename
1081 fprintf(out,
1082 "{\n"
1083 " AROS_LIBFUNC_INIT\n"
1084 "\n"
1086 if (cfg->modtype == DEVICE)
1087 fprintf(out,
1088 " if (!set_call_devfuncs(SETNAME(CLOSEDEV), -1, 1, lh, ioreq, 0, 0))\n"
1089 " {\n"
1090 " return BNULL;\n"
1091 " }\n"
1093 if (!(cfg->options & OPTION_DUPBASE))
1095 fprintf(out,
1096 " ((struct Library *)lh)->lib_OpenCnt--;\n"
1097 " set_call_libfuncs(SETNAME(CLOSELIB), -1, 0, lh);\n"
1100 else
1102 fprintf(out,
1103 " LIBBASETYPEPTR rootbase = GM_ROOTBASE_FIELD(lh);\n"
1105 if (cfg->options & OPTION_PERTASKBASE)
1106 fprintf(out,
1107 " struct __GM_PerTaskBase *pertaskbase = (struct __GM_PerTaskBase *)lh;\n"
1108 " pertaskbase->taskopencount--;\n"
1109 " if (pertaskbase->taskopencount != 0)\n"
1110 " return BNULL;\n"
1112 fprintf(out,
1113 "\n"
1114 " set_call_libfuncs(SETNAME(CLOSELIB), -1, 0, lh);\n"
1115 " set_close_rellibraries(lh);\n");
1116 if (cfg->options & OPTION_PERTASKBASE)
1117 fprintf(out,
1118 " __GM_SetPerTaskBase(((struct __GM_PerTaskBase *)lh)->oldbase);\n");
1119 fprintf(out,
1120 " __freebase(lh);\n"
1121 " lh = rootbase;\n"
1122 " ((struct Library *)lh)->lib_OpenCnt--;\n"
1123 "\n"
1126 if (!(cfg->options & OPTION_NOEXPUNGE))
1127 fprintf(out,
1128 " if\n"
1129 " (\n"
1130 " (((struct Library *)lh)->lib_OpenCnt == 0)\n"
1131 " && (((struct Library *)lh)->lib_Flags & LIBF_DELEXP)\n"
1132 " )\n"
1133 " {\n"
1134 " return AROS_LC1(BPTR, GM_UNIQUENAME(ExpungeLib),\n"
1135 " AROS_LCA(LIBBASETYPEPTR, lh, D0),\n"
1136 " LIBBASETYPEPTR, lh, 3, %s\n"
1137 " );\n"
1138 " }\n",
1139 cfg->basename
1141 fprintf(out,
1142 "\n"
1143 " return BNULL;\n"
1144 "\n"
1145 " AROS_LIBFUNC_EXIT\n"
1146 "}\n"
1147 "\n"
1152 static void writeexpungelib(FILE *out, struct config *cfg)
1154 fprintf(out,
1155 "AROS_LH1 (BPTR, GM_UNIQUENAME(ExpungeLib),\n"
1156 " AROS_LHA(LIBBASETYPEPTR, extralh, D0),\n"
1157 " LIBBASETYPEPTR, lh, 3, %s\n"
1158 ")\n",
1159 cfg->basename
1161 fprintf(out,
1162 "{\n"
1163 " AROS_LIBFUNC_INIT\n"
1164 "\n"
1166 if (!(cfg->options & OPTION_NOEXPUNGE))
1168 fprintf(out,
1169 "\n"
1170 " if ( ((struct Library *)lh)->lib_OpenCnt == 0 )\n"
1171 " {\n"
1172 " BPTR seglist = GM_SEGLIST_FIELD(lh);\n"
1173 "\n"
1174 " if(!set_call_libfuncs(SETNAME(EXPUNGELIB), -1, 1, lh))\n"
1175 " {\n"
1176 " ((struct Library *)lh)->lib_Flags |= LIBF_DELEXP;\n"
1177 " return BNULL;\n"
1178 " }\n"
1179 "\n"
1180 " Remove((struct Node *)lh);\n"
1181 "\n"
1182 " set_call_funcs(SETNAME(DTORS), 1, 0);\n"
1183 " set_call_funcs(SETNAME(EXIT), -1, 0);\n"
1185 if (cfg->classlist != NULL)
1186 fprintf(out, " set_call_libfuncs(SETNAME(CLASSESEXPUNGE), -1, 0, lh);\n");
1187 if (!(cfg->options & OPTION_NOAUTOLIB))
1188 fprintf(out, " set_close_libraries();\n"
1189 "#ifdef GM_OOPBASE_FIELD\n"
1190 " CloseLibrary((struct Library *)GM_OOPBASE_FIELD(lh));\n"
1191 "#endif\n"
1193 if (cfg->options & OPTION_PERTASKBASE)
1194 fprintf(out,
1195 " FreeTaskStorageSlot(__pertaskslot);\n"
1196 " __pertaskslot = 0;\n"
1198 fprintf(out,
1199 "\n"
1200 " __freebase(lh);\n"
1201 "\n"
1202 " return seglist;\n"
1203 " }\n"
1204 "\n"
1205 " ((struct Library *)lh)->lib_Flags |= LIBF_DELEXP;\n"
1208 fprintf(out,
1209 "\n"
1210 " return BNULL;\n"
1211 "\n"
1212 " AROS_LIBFUNC_EXIT\n"
1213 "}\n"
1214 "\n"
1219 static void writeextfunclib(FILE *out, struct config *cfg)
1221 fprintf(out,
1222 "AROS_LH0 (LIBBASETYPEPTR, GM_UNIQUENAME(ExtFuncLib),\n"
1223 " LIBBASETYPEPTR, lh, 4, %s\n"
1224 ")\n"
1225 "{\n"
1226 " AROS_LIBFUNC_INIT\n"
1227 " return NULL;\n"
1228 " AROS_LIBFUNC_EXIT\n"
1229 "}\n"
1230 "\n",
1231 cfg->basename
1236 static void
1237 writefunctable(FILE *out,
1238 struct config *cfg
1241 struct functionhead *funclistit = cfg->funclist;
1242 struct functionarg *arglistit;
1243 unsigned int lvo;
1244 int i;
1245 char *name, *type;
1246 int lastversion = 0;
1248 /* lvo contains the number of functions already printed in the functable */
1249 lvo = 0;
1251 if (!(cfg->options & OPTION_NORESIDENT))
1253 fprintf(out,
1254 "\n"
1255 "const APTR GM_UNIQUENAME(FuncTable)[]=\n"
1256 "{\n"
1258 if (cfg->modtype != RESOURCE && cfg->modtype != HANDLER)
1260 fprintf(out,
1261 " &AROS_SLIB_ENTRY(GM_UNIQUENAME(OpenLib),%s,1),\n"
1262 " &AROS_SLIB_ENTRY(GM_UNIQUENAME(CloseLib),%s,2),\n"
1263 " &AROS_SLIB_ENTRY(GM_UNIQUENAME(ExpungeLib),%s,3),\n"
1264 " &AROS_SLIB_ENTRY(GM_UNIQUENAME(ExtFuncLib),%s,4),\n",
1265 cfg->basename, cfg->basename, cfg->basename, cfg->basename
1267 lvo += 4;
1269 if (cfg->modtype == MCC || cfg->modtype == MUI || cfg->modtype == MCP)
1271 lvo++;
1272 fprintf(out,
1273 " &AROS_SLIB_ENTRY(MCC_Query,%s,%d),\n",
1274 cfg->basename, lvo
1277 else if (cfg->modtype == DATATYPE)
1279 lvo++;
1280 fprintf(out,
1281 " &AROS_SLIB_ENTRY(ObtainEngine,%s,%d),\n",
1282 cfg->basename, lvo
1286 else /* NORESIDENT */
1288 if (cfg->modtype != RESOURCE && cfg->modtype != HANDLER)
1290 int neednull = 0;
1291 struct functionhead *funclistit2;
1293 if (funclistit->lvo != 1)
1295 fprintf(stderr, "Module without a generated resident structure has to provide the Open function (LVO==1)\n");
1296 exit(20);
1298 else
1299 funclistit = funclistit->next;
1301 if (funclistit->lvo != 2)
1303 fprintf(stderr, "Module without a generated resident structure has to provide the Close function (LVO==2)\n");
1304 exit(20);
1306 else
1307 funclistit = funclistit->next;
1309 if (funclistit->lvo == 3)
1310 funclistit = funclistit->next;
1311 else
1312 neednull = 1;
1314 if (funclistit->lvo == 4)
1315 funclistit = funclistit->next;
1316 else
1317 neednull = 1;
1319 if (neednull)
1320 fprintf(out,
1321 "\n"
1322 "AROS_UFH1S(int, %s_null,\n"
1323 " AROS_UFHA(struct Library *, libbase, A6)\n"
1324 ")\n"
1325 "{\n"
1326 " AROS_USERFUNC_INIT\n"
1327 " return 0;\n"
1328 " AROS_USERFUNC_EXIT\n"
1329 "}\n",
1330 cfg->modulename
1333 funclistit = cfg->funclist;
1334 funclistit2 = funclistit->next;
1335 fprintf(out,
1336 "\n"
1337 "const APTR GM_UNIQUENAME(FuncTable)[]=\n"
1338 "{\n"
1339 " &AROS_SLIB_ENTRY(%s,%s,%d),\n"
1340 " &AROS_SLIB_ENTRY(%s,%s,%d),\n",
1341 funclistit->internalname, cfg->basename, lvo+1,
1342 funclistit2->internalname, cfg->basename, lvo+2
1344 lvo += 2;
1345 funclistit = funclistit2->next;
1347 if (funclistit->lvo == 3)
1349 fprintf(out, " &AROS_SLIB_ENTRY(%s,%s,%d),\n",
1350 funclistit->internalname, cfg->basename, lvo+1
1352 funclistit = funclistit->next;
1354 else
1355 fprintf(out, " &%s_null,\n", cfg->modulename);
1356 lvo++;
1358 if (funclistit->lvo == 4)
1360 fprintf(out, " &AROS_SLIB_ENTRY(%s,%s,%d),\n",
1361 funclistit->internalname, cfg->basename, lvo+1
1363 funclistit = funclistit->next;
1365 else
1366 fprintf(out, " &%s_null,\n", cfg->modulename);
1367 lvo++;
1369 else
1371 fprintf(out,
1372 "\n"
1373 "const APTR GM_UNIQUENAME(FuncTable)[]=\n"
1374 "{\n");
1378 while (funclistit != NULL)
1380 for (i = lvo+1; i<funclistit->lvo; i++)
1381 fprintf(out, " NULL,\n");
1382 lvo = funclistit->lvo;
1384 switch (funclistit->libcall)
1386 case STACK:
1387 fprintf(out, " &%s%s,\n", funclistit->internalname,
1388 cfg->options & OPTION_DUPBASE ? "_stub" : ""
1390 break;
1392 case REGISTER:
1393 case REGISTERMACRO:
1394 if (funclistit->version != lastversion) {
1395 lastversion = funclistit->version;
1396 fprintf(out, " /* Version %d */\n", lastversion);
1398 fprintf(out, " &AROS_SLIB_ENTRY(%s,%s,%d),\n", funclistit->internalname, cfg->basename, lvo);
1399 break;
1401 default:
1402 fprintf(stderr, "Internal error: unhandled libcall type in writestart\n");
1403 exit(20);
1404 break;
1407 funclistit = funclistit->next;
1410 fprintf(out, " (void *)-1\n};\n");
1414 static void writesets(FILE *out, struct config *cfg)
1416 fprintf(out,
1417 "DEFINESET(INIT)\n"
1418 "DEFINESET(EXIT)\n"
1419 "DEFINESET(CTORS)\n"
1420 "DEFINESET(DTORS)\n"
1422 if (cfg->modtype != HANDLER)
1423 fprintf(out,
1424 "DEFINESET(INITLIB)\n"
1425 "DEFINESET(EXPUNGELIB)\n"
1427 if (!(cfg->options & OPTION_NOOPENCLOSE))
1428 fprintf(out,
1429 "DEFINESET(OPENLIB)\n"
1430 "DEFINESET(CLOSELIB)\n"
1432 if (cfg->modtype == DEVICE)
1433 fprintf(out,
1434 "DEFINESET(OPENDEV)\n"
1435 "DEFINESET(CLOSEDEV)\n"
1437 if (cfg->classlist != NULL)
1438 fprintf(out,
1439 "DEFINESET(CLASSESINIT)\n"
1440 "DEFINESET(CLASSESEXPUNGE)\n"
1442 fprintf(out, "\n");