tools/genmodule: include aros/relbase.h in _start.c file when it is a relbase shared...
[AROS.git] / tools / genmodule / writestart.c
blobfc5b257ca94276f9e5a55608b24810168d71192d
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
138 if (cfg->options & OPTION_BASEREL)
139 fprintf(out, "#include <aros/relbase.h>\n");
141 /* Write out declaration section provided in the config file */
142 for (linelistit = cfg->cdeflines; linelistit != NULL; linelistit = linelistit->next)
144 fprintf(out, "%s\n", linelistit->s);
147 /* Is there a variable for storing the segList ? */
148 if (!(cfg->options & OPTION_NOEXPUNGE) && cfg->modtype!=RESOURCE && cfg->modtype != HANDLER)
150 fprintf(out,
151 "#ifndef GM_SEGLIST_FIELD\n"
152 "static BPTR __attribute__((unused)) GM_UNIQUENAME(seglist);\n"
153 "#define GM_SEGLIST_FIELD(lh) (GM_UNIQUENAME(seglist))\n"
154 "#endif\n"
157 if (cfg->options & OPTION_DUPBASE)
158 fprintf(out,
159 "#ifndef GM_ROOTBASE_FIELD\n"
160 "static LIBBASETYPEPTR GM_UNIQUENAME(rootbase);\n"
161 "#define GM_ROOTBASE_FIELD(lh) (GM_UNIQUENAME(rootbase))\n"
162 "#endif\n"
164 if (cfg->options & OPTION_DUPPERID)
165 fprintf(out,
166 "#ifdef __GM_OWNGETID\n"
167 "#include <dos/dosextens.h>\n"
168 "IPTR __GM_Id2(void)\n"
169 "{\n"
170 " struct Process *process = (struct Process *)FindTask(NULL);\n"
171 "\n"
172 " if (process->pr_Task.tc_Node.ln_Type == NT_PROCESS)\n"
173 " return (IPTR)process->pr_ReturnAddr;\n"
174 "\n"
175 " return (IPTR)NULL;\n"
176 "}\n"
177 "#endif\n"
178 "\n"
179 "#ifdef GM_GETID2\n"
180 "struct __GM_ID2Node\n"
181 "{\n"
182 " struct MinNode node;\n"
183 " IPTR id2;\n"
184 " struct Library *lh;\n"
185 " ULONG dupopencount;\n"
186 "};\n"
187 "#endif\n"
188 "\n"
189 "struct __GM_AVLNode {\n"
190 " struct AVLNode node;\n"
191 " IPTR id;\n"
192 "#ifndef GM_GETID2\n"
193 " struct Library *lh;\n"
194 " ULONG dupopencount;\n"
195 "#else\n"
196 " struct MinList id2nodes;\n"
197 "#endif\n"
198 "};\n"
199 "struct __GM_BaseAVL {\n"
200 " LIBBASETYPE base;\n"
201 " struct __GM_AVLNode *avlnode, _avlnode;\n"
202 "#ifdef GM_GETID2\n"
203 " struct __GM_ID2Node *id2node, _id2node;\n"
204 "#endif\n"
205 "};\n"
206 "static AROS_UFH2(LONG, __GM_CompKey,\n"
207 " AROS_UFHA(const struct __GM_AVLNode *, gm_avlnode, A0),\n"
208 " AROS_UFHA(AVLKey, _key, A1)\n"
209 ")\n"
210 "{\n"
211 " AROS_USERFUNC_INIT\n"
212 "\n"
213 " IPTR id = (IPTR)_key;\n"
214 " if (gm_avlnode->id == id)\n"
215 " return (LONG) 0;\n"
216 " else if (gm_avlnode->id < id)\n"
217 " return (LONG)-1;\n"
218 " else\n"
219 " return (LONG)1;\n"
220 "\n"
221 " AROS_USERFUNC_EXIT\n"
222 "}\n"
223 "static AROS_UFH2(LONG, __GM_CompNode,\n"
224 " AROS_UFHA(const struct __GM_AVLNode *, gm_avlnode1, A0),\n"
225 " AROS_UFHA(const struct __GM_AVLNode *, gm_avlnode2, A1)\n"
226 ")\n"
227 "{\n"
228 " AROS_USERFUNC_INIT\n"
229 "\n"
230 " return AROS_UFC2(LONG, __GM_CompKey,\n"
231 " AROS_UFPA(const struct __GM_AVLNode *, gm_avlnode1, A0),\n"
232 " AROS_UFPA(AVLKey, (AVLKey)gm_avlnode2->id, A1)\n"
233 " );\n"
234 "\n"
235 " AROS_USERFUNC_EXIT\n"
236 "}\n"
237 "#define LIBBASESIZE sizeof(struct __GM_BaseAVL)\n"
238 "struct AVLNode *__GM_AVLRoot = NULL;\n"
239 "\n"
240 "#ifdef __GM_OWNPARENTBASEID2\n"
241 "LIBBASETYPEPTR GM_UNIQUENAME(__GetParentLibbase)(LIBBASETYPEPTR lh)\n"
242 "{\n"
243 " struct __GM_ID2Node *id2node = ((struct __GM_BaseAVL *)lh)->id2node;\n"
244 "\n"
245 " id2node = (struct __GM_ID2Node *)GetSucc(id2node);\n"
246 "\n"
247 " if (id2node != NULL)\n"
248 " return (LIBBASETYPEPTR)id2node->lh;\n"
249 " else\n"
250 " return (LIBBASETYPEPTR)NULL;\n"
251 "}\n"
252 "#endif\n"
253 "\n"
255 else
256 fprintf(out, "#define LIBBASESIZE sizeof(LIBBASETYPE)\n");
258 for (classlistit = cfg->classlist; classlistit != NULL; classlistit = classlistit->next)
260 /* For the main class basename is the same as the module basename */
261 if (strcmp(classlistit->basename, cfg->basename) == 0)
263 if (classlistit->classptr_var == NULL)
265 fprintf(out,
266 "#if !defined(GM_CLASSPTR_FIELD) && !defined(%s_CLASSPTR_FIELD)\n"
267 "static APTR GM_UNIQUENAME(%sClass);\n"
268 "#define GM_CLASSPTR_FIELD(lh) (GM_UNIQUENAME(%sClass))\n"
269 "#define %s_CLASSPTR_FIELD(lh) (GM_UNIQUENAME(%sClass))\n"
270 "#define %s_STORE_CLASSPTR 1\n"
271 "#elif defined(GM_CLASSPTR_FIELD) && !defined(%s_CLASSPTR_FIELD)\n"
272 "#define %s_CLASSPTR_FIELD(lh) (GM_CLASSPTR_FIELD(lh))\n"
273 "#elif !defined(GM_CLASSPTR_FIELD) && defined(%s_CLASSPTR_FIELD)\n"
274 "#define GM_CLASSPTR_FIELD(lh) (%s_CLASSPTR_FIELD(lh))\n"
275 "#endif\n",
276 classlistit->basename,
277 classlistit->basename,
278 classlistit->basename,
279 classlistit->basename, classlistit->basename,
280 classlistit->basename,
281 classlistit->basename,
282 classlistit->basename,
283 classlistit->basename,
284 classlistit->basename
287 else
289 fprintf(out,
290 "#define GM_CLASSPTR_FIELD(lh) (%s)\n"
291 "#define %s_CLASSPTR_FIELD(lh) (%s)\n"
292 "#define %s_STORE_CLASSPTR 1\n",
293 classlistit->classptr_var,
294 classlistit->basename, classlistit->classptr_var,
295 classlistit->basename
299 else
301 if (classlistit->classptr_var == NULL)
303 fprintf(out,
304 "#if !defined(%s_CLASSPTR_FIELD)\n"
305 "static APTR GM_UNIQUENAME(%sClass);\n"
306 "#define %s_CLASSPTR_FIELD(lh) (GM_UNIQUENAME(%sClass))\n"
307 "#define %s_STORE_CLASSPTR 1\n"
308 "#endif\n",
309 classlistit->basename,
310 classlistit->basename,
311 classlistit->basename, classlistit->basename,
312 classlistit->basename
315 else
317 fprintf(out,
318 "#define %s_CLASSPTR_FIELD(lh) (%s)\n"
319 "#define %s_STORE_CLASSPTR 1\n",
320 classlistit->basename, classlistit->classptr_var,
321 classlistit->basename
327 /* Write out the defines for the functions of the function table */
328 writefuncdefs(out, cfg, cfg->funclist);
329 fprintf(out, "\n");
331 /* Write out the includes needed for the classes */
332 if (cfg->classlist != NULL)
333 writeboopsiincludes(out);
335 for (classlistit = cfg->classlist; classlistit != NULL; classlistit = classlistit->next)
337 switch (classlistit->classtype)
339 case MUI:
340 case MCC:
341 case MCP:
342 if (!muiinc)
344 writemuiincludes(out);
345 muiinc = 1;
347 /* Fall through: also write boopsi includes */
348 case GADGET:
349 case DATATYPE:
350 case CLASS:
351 case IMAGE:
352 if (!boopsiinc)
354 writeboopsiincludes(out);
355 boopsiinc = 1;
357 break;
358 case HIDD:
359 if (!oopinc)
361 writeoopincludes(out);
362 oopinc = 1;
364 break;
365 default:
366 fprintf(stderr, "Internal error: unhandled classtype in writedecl\n");
367 exit(20);
373 static void writedeclsets(FILE *out, struct config *cfg)
375 fprintf(out,
376 "THIS_PROGRAM_HANDLES_SYMBOLSETS\n"
377 "DECLARESET(INIT)\n"
378 "DECLARESET(EXIT)\n"
379 "DECLARESET(CTORS)\n"
380 "DECLARESET(DTORS)\n"
381 "DECLARESET(INITLIB)\n"
382 "DECLARESET(EXPUNGELIB)\n"
384 if (!(cfg->options & OPTION_NOOPENCLOSE))
385 fprintf(out,
386 "DECLARESET(OPENLIB)\n"
387 "DECLARESET(CLOSELIB)\n"
389 if (cfg->modtype == DEVICE)
390 fprintf(out,
391 "DECLARESET(OPENDEV)\n"
392 "DECLARESET(CLOSEDEV)\n"
394 if (cfg->classlist != NULL)
395 fprintf(out,
396 "DECLARESET(CLASSESINIT)\n"
397 "DECLARESET(CLASSESEXPUNGE)\n"
398 "#define ADD2INITCLASSES(symbol, pri) ADD2SET(symbol, classesinit, pri)\n"
399 "#define ADD2EXPUNGECLASSES(symbol, pri) ADD2SET(symbol, classesexpunge, pri)\n"
401 fprintf(out, "\n");
405 static void writeresident(FILE *out, struct config *cfg)
407 char *rt_skip = cfg->addromtag;
409 if (rt_skip)
410 fprintf(out, "extern const struct Resident %s;\n", rt_skip);
411 else
413 rt_skip = "GM_UNIQUENAME(End)";
414 fprintf(out, "extern const int %s;\n", rt_skip);
416 fprintf(out,
417 "extern const APTR GM_UNIQUENAME(FuncTable)[];\n"
419 if (cfg->options & OPTION_RESAUTOINIT)
420 fprintf(out, "static const struct InitTable GM_UNIQUENAME(InitTable);\n");
421 fprintf(out,
422 "\n"
423 "extern const char GM_UNIQUENAME(LibName)[];\n"
424 "extern const char GM_UNIQUENAME(LibID)[];\n"
425 "extern const char GM_UNIQUENAME(Copyright)[];\n"
426 "\n"
429 if (cfg->options & OPTION_RESAUTOINIT)
431 if (!(cfg->options & OPTION_DUPPERID))
433 fprintf(out,
434 "#define __freebase(lh)\\\n"
435 "do {\\\n"
436 " UWORD negsize, possize;\\\n"
437 " UBYTE *negptr = (UBYTE *)lh;\\\n"
438 " negsize = ((struct Library *)lh)->lib_NegSize;\\\n"
439 " negptr -= negsize;\\\n"
440 " possize = ((struct Library *)lh)->lib_PosSize;\\\n"
441 " FreeMem (negptr, negsize+possize);\\\n"
442 "} while(0)\n"
443 "\n"
446 else
448 fprintf(out,
449 "#ifndef GM_GETID2\n"
450 "#define __freebase(lh)\\\n"
451 "do {\\\n"
452 " UWORD negsize, possize;\\\n"
453 " UBYTE *negptr = (UBYTE *)lh;\\\n"
454 " struct __GM_AVLNode *avlnode = ((struct __GM_BaseAVL *)lh)->avlnode;\\\n"
455 " AVL_RemNodeByAddress(&__GM_AVLRoot, (struct AVLNode *)avlnode);\\\n"
456 " negsize = ((struct Library *)lh)->lib_NegSize;\\\n"
457 " negptr -= negsize;\\\n"
458 " possize = ((struct Library *)lh)->lib_PosSize;\\\n"
459 " FreeMem (negptr, negsize+possize);\\\n"
460 "} while(0)\n"
461 "#else\n"
462 "#define __freebase(lh)\\\n"
463 "do {\\\n"
464 " UWORD negsize, possize;\\\n"
465 " UBYTE *negptr = (UBYTE *)lh;\\\n"
466 " struct __GM_AVLNode *avlnode = ((struct __GM_BaseAVL *)lh)->avlnode;\\\n"
467 " struct __GM_ID2Node *id2node = ((struct __GM_BaseAVL *)lh)->id2node;\\\n"
468 " BOOL remnode;\\\n"
469 " /* avlnode == NULL for original libbase provided to LibInit */\\\n"
470 " if (avlnode)\\\n"
471 " {\\\n"
472 " Remove((struct Node *)id2node);\\\n"
473 " remnode = GetHead((struct List *)&avlnode->id2nodes) == NULL;\\\n"
474 " if (remnode)\\\n"
475 " AVL_RemNodeByAddress(&__GM_AVLRoot, (struct AVLNode *)avlnode);\\\n"
476 " else if (avlnode == &((struct __GM_BaseAVL *)lh)->_avlnode)\\\n"
477 " /* Do not free as avlnode is still in the AVL Tree\\\n"
478 " This is causing a memory leak because sublibrary is not closed */\\\n"
479 " break;\\\n"
480 " }\\\n"
481 " negsize = ((struct Library *)lh)->lib_NegSize;\\\n"
482 " negptr -= negsize;\\\n"
483 " possize = ((struct Library *)lh)->lib_PosSize;\\\n"
484 " FreeMem (negptr, negsize+possize);\\\n"
485 "} while(0)\n"
486 "#endif\n"
491 fprintf(out,
492 "AROS_UFP3 (LIBBASETYPEPTR, GM_UNIQUENAME(InitLib),\n"
493 " AROS_UFPA(LIBBASETYPEPTR, lh, D0),\n"
494 " AROS_UFPA(BPTR, segList, A0),\n"
495 " AROS_UFPA(struct ExecBase *, sysBase, A6)\n"
496 ");\n"
498 if (cfg->modtype != RESOURCE && cfg->modtype != HANDLER)
500 fprintf(out,
501 "AROS_LP1(BPTR, GM_UNIQUENAME(ExpungeLib),\n"
502 " AROS_LPA(LIBBASETYPEPTR, extralh, D0),\n"
503 " LIBBASETYPEPTR, lh, 3, %s\n"
504 ");\n"
505 "\n",
506 cfg->basename
509 fprintf(out,
510 "struct Resident const GM_UNIQUENAME(ROMTag) =\n"
511 "{\n"
512 " RTC_MATCHWORD,\n"
513 " (struct Resident *)&GM_UNIQUENAME(ROMTag),\n"
514 " (APTR)&%s,\n"
515 " RESIDENTFLAGS,\n"
516 " VERSION_NUMBER,\n",
517 rt_skip
519 switch (cfg->modtype)
521 case LIBRARY:
522 case MUI:
523 case MCC:
524 case MCP:
525 case GADGET:
526 case DATATYPE:
527 case USBCLASS:
528 case HIDD:
529 fprintf(out, " NT_LIBRARY,\n");
530 break;
531 case DEVICE:
532 fprintf(out, " NT_DEVICE,\n");
533 break;
534 case RESOURCE:
535 case HANDLER:
536 fprintf(out, " NT_RESOURCE,\n");
537 break;
538 default:
539 fprintf(stderr, "Internal error: unsupported modtype for NT_...\n");
540 exit(20);
541 break;
543 fprintf(out,
544 " RESIDENTPRI,\n"
545 " (CONST_STRPTR)&GM_UNIQUENAME(LibName)[0],\n"
546 " (CONST_STRPTR)&GM_UNIQUENAME(LibID)[6],\n"
548 if (cfg->options & OPTION_RESAUTOINIT)
550 fprintf(out,
551 " (APTR)&GM_UNIQUENAME(InitTable)\n"
552 "};\n"
553 "\n"
554 "static struct InitTable\n"
555 "{\n"
556 " IPTR Size;\n"
557 " const APTR *FuncTable;\n"
558 " struct DataTable *DataTable;\n"
559 " APTR InitLibTable;\n"
560 "}\n"
561 "const GM_UNIQUENAME(InitTable) =\n"
562 "{\n"
563 " LIBBASESIZE,\n"
564 " &GM_UNIQUENAME(FuncTable)[0],\n"
565 " NULL,\n"
566 " (APTR)GM_UNIQUENAME(InitLib)\n"
567 "};\n"
570 else
571 fprintf(out, " (APTR)GM_UNIQUENAME(InitLib)\n};\n");
573 fprintf(out,
574 "\n"
575 "const char GM_UNIQUENAME(LibName)[] = MOD_NAME_STRING;\n"
576 "const char GM_UNIQUENAME(LibID)[] = VERSION_STRING;\n"
577 "const char GM_UNIQUENAME(Copyright)[] = COPYRIGHT_STRING;\n"
578 "\n"
582 static void writehandler(FILE *out, struct config *cfg)
584 int i;
585 struct handlerinfo *hl;
587 fprintf(out,
588 "\n"
589 "#include <resources/filesysres.h>\n"
590 "#include <aros/system.h>\n"
591 "#include <proto/arossupport.h>\n"
592 "#include <proto/dos.h>\n"
593 "\n"
596 for (hl = cfg->handlerlist; hl != NULL; hl = hl->next) {
597 fprintf(out,
598 "extern void %s(void);\n",
599 hl->handler);
602 fprintf(out,
603 "\n"
604 "void GM_UNIQUENAME(InitHandler)(void)\n"
605 "{\n"
606 " struct FileSysResource *fsr;\n"
607 " int i;\n"
608 " const struct {\n"
609 " ULONG id;\n"
610 " BSTR name;\n"
611 " BYTE autodetect;\n"
612 " BYTE priority;\n"
613 " ULONG stacksize;\n"
614 " void (*handler)(void);\n"
615 " } const __handler[] = { \n");
616 for (hl = cfg->handlerlist; hl != NULL; hl = hl->next)
618 switch (hl->type)
620 case HANDLER_RESIDENT:
621 fprintf(out,
622 " { .id = 0, .name = AROS_CONST_BSTR(\"%s\"), .handler = %s }, \n",
623 hl->name, hl->handler);
624 break;
625 case HANDLER_DOSTYPE:
626 fprintf(out,
627 " { .id = 0x%08x, .name = AROS_CONST_BSTR(MOD_NAME_STRING), .handler = %s, .autodetect = %d, .priority = %d, .stacksize = %d*sizeof(IPTR) }, \n",
628 hl->id, hl->handler, hl->autodetect, hl->priority, hl->stacksize);
629 break;
632 fprintf(out,
633 " };\n"
634 " BPTR seg[sizeof(__handler)/sizeof(__handler[0])] = { };\n"
635 "\n"
636 " fsr = (struct FileSysResource *)OpenResource(\"FileSystem.resource\");\n"
637 " if (fsr == NULL)\n"
638 " return;\n"
639 "\n"
640 " for (i = 0; i < sizeof(__handler)/sizeof(__handler[0]); i++) {\n"
641 " struct FileSysEntry *fse;\n"
642 " int j;\n"
643 "\n"
644 " /* Check to see if we can allocate the memory for the fse */\n"
645 " fse = AllocMem(sizeof(*fse), MEMF_CLEAR);\n"
646 " if (!fse)\n"
647 " return;\n"
648 "\n"
649 " /* Did we already make a segment for this handler? */\n"
650 " for (j = 0; j < i; j++)\n"
651 " if (__handler[i].handler == __handler[j].handler)\n"
652 " break;\n"
653 " if (seg[j] == (BPTR)0)\n"
654 " seg[j] = CreateSegList(__handler[j].handler);\n"
655 " if (seg[j] == BNULL) {\n"
656 " FreeMem(fse, sizeof(*fse));\n"
657 " return;\n"
658 " }\n"
659 " \n"
660 " /* DOS ID based handlers\n"
661 " * NOTE: fse_DosType == 0 is a special flag use in\n"
662 " * dos.library's init to add the handler to the\n"
663 " * resident segment list\n"
664 " */\n"
665 " fse->fse_Node.ln_Name = VERSION_STRING;\n"
666 " fse->fse_Node.ln_Pri = __handler[i].autodetect;\n"
667 " fse->fse_DosType = __handler[i].id;\n"
668 " fse->fse_Version = (MAJOR_VERSION << 16) | MINOR_VERSION;\n"
669 " fse->fse_PatchFlags = FSEF_SEGLIST | FSEF_GLOBALVEC | FSEF_HANDLER | FSEF_PRIORITY;\n"
670 " if (__handler[i].stacksize) {\n"
671 " fse->fse_PatchFlags |= FSEF_STACKSIZE;\n"
672 " fse->fse_StackSize = __handler[i].stacksize;\n"
673 " }\n"
674 " fse->fse_Handler = __handler[i].name;\n"
675 " fse->fse_Priority = __handler[i].priority;\n"
676 " fse->fse_SegList = seg[j];\n"
677 " fse->fse_GlobalVec = (BPTR)(SIPTR)-1;\n"
678 " \n"
679 " /* Add to the list. I know forbid and permit are\n"
680 " * a little unnecessary for the pre-multitasking state\n"
681 " * we should be in at this point, but you never know\n"
682 " * who's going to blindly copy this code as an example.\n"
683 " */\n"
684 " Forbid();\n"
685 " Enqueue(&fsr->fsr_FileSysEntries, (struct Node *)fse);\n"
686 " Permit();\n"
687 " }\n"
688 "}\n");
691 static void writeinitlib(FILE *out, struct config *cfg)
693 if (cfg->handlerlist)
694 writehandler(out, cfg);
696 fprintf(out,
697 "AROS_UFH3 (LIBBASETYPEPTR, GM_UNIQUENAME(InitLib),\n"
698 " AROS_UFHA(LIBBASETYPEPTR, lh, D0),\n"
699 " AROS_UFHA(BPTR, segList, A0),\n"
700 " AROS_UFHA(struct ExecBase *, sysBase, A6)\n"
701 ")\n"
702 "{\n"
703 " AROS_USERFUNC_INIT\n"
704 "\n"
705 " int ok;\n"
706 "\n"
709 if (cfg->options & OPTION_RESAUTOINIT) {
710 fprintf(out,
711 "#ifndef __AROS__\n"
712 " SysBase = sysBase;\n"
713 "#endif\n"
714 "#ifdef GM_SYSBASE_FIELD\n"
715 " GM_SYSBASE_FIELD(lh) = (APTR)sysBase;\n"
716 "#endif\n"
720 if (cfg->modtype != HANDLER)
722 if (!(cfg->options & OPTION_RESAUTOINIT))
724 fprintf(out,
725 " int vecsize;\n"
726 " struct Node *n;\n"
727 " char *mem;\n"
728 "\n"
729 " vecsize = FUNCTIONS_COUNT * LIB_VECTSIZE;\n"
730 " if (vecsize > 0)\n"
731 " vecsize = ((vecsize-1)/sizeof(IPTR) + 1)*sizeof(IPTR);\n"
732 " mem = AllocMem(vecsize+sizeof(LIBBASETYPE), MEMF_PUBLIC|MEMF_CLEAR);\n"
733 " if (mem == NULL)\n"
734 " return NULL;\n"
735 " lh = (LIBBASETYPEPTR)(mem + vecsize);\n"
736 " n = (struct Node *)lh;\n"
737 " n->ln_Type = NT_RESOURCE;\n"
738 " n->ln_Pri = RESIDENTPRI;\n"
739 " n->ln_Name = (char *)GM_UNIQUENAME(LibName);\n"
740 " MakeFunctions(lh, (APTR)GM_UNIQUENAME(FuncTable), NULL);\n"
742 if ((cfg->modtype != RESOURCE) && (cfg->options & OPTION_SELFINIT))
744 fprintf(out,
745 " ((struct Library*)lh)->lib_NegSize = vecsize;\n"
746 " ((struct Library*)lh)->lib_PosSize = sizeof(LIBBASETYPE);\n"
751 else
753 fprintf(out,
754 " ((struct Library *)lh)->lib_Revision = REVISION_NUMBER;\n"
759 if (cfg->options & OPTION_BASEREL)
760 fprintf(out,
761 " void *oldbase = AROS_SET_LIBBASE(lh);\n");
763 if (!(cfg->options & OPTION_NOEXPUNGE) && cfg->modtype!=RESOURCE && cfg->modtype != HANDLER)
764 fprintf(out, " GM_SEGLIST_FIELD(lh) = segList;\n");
765 if (cfg->options & OPTION_DUPBASE)
766 fprintf(out, " GM_ROOTBASE_FIELD(lh) = (LIBBASETYPEPTR)lh;\n");
767 fprintf(out, " if (");
768 if (!(cfg->options & OPTION_NOAUTOLIB))
769 fprintf(out, "set_open_libraries() && ");
770 if (cfg->classlist != NULL)
771 fprintf(out, "set_call_libfuncs(SETNAME(CLASSESINIT), 1, 1, lh) && ");
772 fprintf(out,
773 "set_call_funcs(SETNAME(INIT), 1, 1) )\n"
774 " {\n"
775 " set_call_funcs(SETNAME(CTORS), -1, 0);\n"
776 "\n"
779 if (cfg->modtype == HANDLER)
780 fprintf(out,
781 " ok = 1;\n");
782 else
783 fprintf(out,
784 " ok = set_call_libfuncs(SETNAME(INITLIB), 1, 1, lh);\n");
785 fprintf(out,
786 " }\n"
787 " else\n"
788 " ok = 0;\n"
789 "\n"
790 " if (!ok)\n"
791 " {\n"
794 if (cfg->modtype != HANDLER)
795 fprintf(out,
796 " set_call_libfuncs(SETNAME(EXPUNGELIB), -1, 0, lh);\n");
798 fprintf(out,
799 " set_call_funcs(SETNAME(DTORS), 1, 0);\n"
800 " set_call_funcs(SETNAME(EXIT), -1, 0);\n"
802 if (cfg->classlist != NULL)
803 fprintf(out, " set_call_libfuncs(SETNAME(CLASSESEXPUNGE), -1, 0, lh);\n");
804 if (!(cfg->options & OPTION_NOAUTOLIB))
805 fprintf(out, " set_close_libraries();\n");
806 if (cfg->options & OPTION_BASEREL)
807 fprintf(out, " (void)AROS_SET_LIBBASE(oldbase);\n");
809 if (cfg->modtype != HANDLER)
811 if (cfg->options & OPTION_RESAUTOINIT)
813 fprintf(out,
814 "\n"
815 " __freebase(lh);\n"
818 else
820 fprintf(out,
821 "\n"
822 " FreeMem(mem, vecsize+LIBBASESIZE);\n"
826 fprintf(out,
827 " return NULL;\n"
828 " }\n"
829 " else\n"
830 " {\n"
833 if (!(cfg->options & OPTION_RESAUTOINIT) && !(cfg->options & OPTION_SELFINIT))
835 switch (cfg->modtype)
837 case RESOURCE:
838 fprintf(out, " AddResource(lh);\n");
839 break;
841 case DEVICE:
842 fprintf(out, " AddDevice(lh);\n");
844 case HANDLER:
845 /* Bare handlers don't require adding at all */
846 break;
848 default:
849 /* Everything else is library */
850 fprintf(out, " AddLibrary(lh);\n");
851 break;
855 if (cfg->handlerlist)
856 fprintf(out, " GM_UNIQUENAME(InitHandler)();\n");
858 if (cfg->options & OPTION_BASEREL)
859 fprintf(out,
860 " (void)AROS_SET_LIBBASE(oldbase);\n");
861 fprintf(out,
862 " return lh;\n"
863 " }\n"
864 "\n"
865 " AROS_USERFUNC_EXIT\n"
866 "}\n"
867 "\n"
871 static void writeopenlib(FILE *out, struct config *cfg)
873 switch (cfg->modtype)
875 case RESOURCE:
876 fprintf(stderr, "Internal error: writeopenlib called for a resource\n");
877 break;
878 case HANDLER:
879 fprintf(stderr, "Internal error: writeopenlib called for a handler\n");
880 break;
881 case DEVICE:
882 if (cfg->options & OPTION_NOOPENCLOSE)
883 fprintf(out,
884 "AROS_LD3 (void, GM_UNIQUENAME(OpenLib),\n"
885 " AROS_LHA(struct IORequest *, ioreq, A1),\n"
886 " AROS_LHA(ULONG, unitnum, D0),\n"
887 " AROS_LHA(ULONG, flags, D1),\n"
888 " LIBBASETYPEPTR, lh, 1, %s\n"
889 ");\n",
890 cfg->basename
892 else
894 fprintf(out,
895 "AROS_LH3 (void, GM_UNIQUENAME(OpenLib),\n"
896 " AROS_LHA(struct IORequest *, ioreq, A1),\n"
897 " AROS_LHA(IPTR, unitnum, D0),\n"
898 " AROS_LHA(ULONG, flags, D1),\n"
899 " LIBBASETYPEPTR, lh, 1, %s\n"
900 ")\n",
901 cfg->basename
903 fprintf(out,
904 "{\n"
905 " AROS_LIBFUNC_INIT\n"
906 "\n"
907 " if ( set_call_libfuncs(SETNAME(OPENLIB), 1, 1, lh)\n"
908 " && set_call_devfuncs(SETNAME(OPENDEV), 1, 1, lh, ioreq, unitnum, flags)\n"
909 " )\n"
910 " {\n"
911 " ((struct Library *)lh)->lib_OpenCnt++;\n"
912 " ((struct Library *)lh)->lib_Flags &= ~LIBF_DELEXP;\n"
913 "\n"
914 " ioreq->io_Message.mn_Node.ln_Type = NT_REPLYMSG;\n"
915 " }\n"
916 " else\n"
917 " {\n"
918 " if (ioreq->io_Error >= 0)\n"
919 " ioreq->io_Error = IOERR_OPENFAIL;\n"
920 " }\n"
921 "\n"
922 " return;\n"
923 "\n"
924 " AROS_LIBFUNC_EXIT\n"
925 "}\n"
926 "\n"
929 break;
930 default:
931 if (cfg->options & OPTION_NOOPENCLOSE)
933 fprintf(out,
934 "AROS_LD1 (LIBBASETYPEPTR, GM_UNIQUENAME(OpenLib),\n"
935 " AROS_LHA (ULONG, version, D0),\n"
936 " LIBBASETYPEPTR, lh, 1, %s\n"
937 ");\n",
938 cfg->basename
940 return;
942 fprintf(out,
943 "AROS_LH1 (LIBBASETYPEPTR, GM_UNIQUENAME(OpenLib),\n"
944 " AROS_LHA (ULONG, version, D0),\n"
945 " LIBBASETYPEPTR, lh, 1, %s\n"
946 ")\n"
947 "{\n"
948 " AROS_LIBFUNC_INIT\n"
949 "\n",
950 cfg->basename
952 if (!(cfg->options & OPTION_DUPBASE))
954 fprintf(out,
955 " if ( set_call_libfuncs(SETNAME(OPENLIB), 1, 1, lh) )\n"
956 " {\n"
957 " ((struct Library *)lh)->lib_OpenCnt++;\n"
958 " ((struct Library *)lh)->lib_Flags &= ~LIBF_DELEXP;\n"
959 "\n"
960 " return lh;\n"
961 " }\n"
962 "\n"
963 " return NULL;\n"
964 "\n"
965 " AROS_LIBFUNC_EXIT\n"
966 "}\n"
967 "\n"
970 else /* OPTION_DUPBASE */
972 fprintf(out,
973 " struct Library *newlib = NULL;\n"
974 " UWORD possize = ((struct Library *)lh)->lib_PosSize;\n"
976 if (cfg->options & OPTION_DUPPERID)
977 fprintf(out,
978 " struct __GM_AVLNode *avlnode = NULL;\n"
979 " IPTR id = GM_GETID;\n"
980 "#ifdef GM_GETID2\n"
981 " struct __GM_ID2Node *id2node = NULL, *id2node_it;\n"
982 " IPTR id2 = GM_GETID2;\n"
983 "#endif\n"
984 "\n"
985 " avlnode = (struct __GM_AVLNode *)AVL_FindNode(__GM_AVLRoot, (AVLKey)id, (AVLKEYCOMP)__GM_CompKey);\n"
986 "#ifndef GM_GETID2\n"
987 " if (avlnode != NULL)\n"
988 " {\n"
989 " avlnode->dupopencount++;\n"
990 " newlib = avlnode->lh;\n"
991 " }\n"
992 "#else\n"
993 " if (avlnode != NULL)\n"
994 " {\n"
995 " ForeachNode(&avlnode->id2nodes, id2node_it)\n"
996 " {\n"
997 " if (id2node_it->id2 == id2)\n"
998 " id2node = id2node_it;\n"
999 " break;\n"
1000 " }\n"
1001 " }\n"
1002 " if (id2node != NULL)\n"
1003 " {\n"
1004 " id2node->dupopencount++;\n"
1005 " newlib = id2node->lh;\n"
1006 " }\n"
1007 "#endif\n"
1008 "\n"
1010 fprintf(out,
1011 "\n"
1012 " if (newlib == NULL)\n"
1013 " {\n"
1014 " newlib = MakeLibrary(GM_UNIQUENAME(InitTable).FuncTable,\n"
1015 " GM_UNIQUENAME(InitTable).DataTable,\n"
1016 " NULL,\n"
1017 " GM_UNIQUENAME(InitTable).Size,\n"
1018 " (BPTR)NULL\n"
1019 " );\n"
1020 " if (newlib == NULL)\n"
1021 " return NULL;\n"
1022 "\n"
1023 " CopyMem(lh, newlib, possize);\n"
1025 if (cfg->options & OPTION_DUPPERID)
1026 fprintf(out,
1027 "#ifndef GM_GETID2\n"
1028 " avlnode\n"
1029 " = ((struct __GM_BaseAVL *)newlib)->avlnode\n"
1030 " = &((struct __GM_BaseAVL *)newlib)->_avlnode;\n"
1031 " avlnode->id = id;\n"
1032 " avlnode->lh = newlib;\n"
1033 " avlnode->dupopencount = 1;\n"
1034 " AVL_AddNode((struct AVLNode **)&__GM_AVLRoot, (struct AVLNode *)avlnode, (AVLNODECOMP)__GM_CompNode);\n"
1035 "#else\n"
1036 " if(avlnode == NULL)\n"
1037 " {\n"
1038 " /* avlnode does not exists yet, use the one in the allocated libbase */\n"
1039 " avlnode\n"
1040 " = ((struct __GM_BaseAVL *)newlib)->avlnode\n"
1041 " = &((struct __GM_BaseAVL *)newlib)->_avlnode;\n"
1042 " avlnode->id = id;\n"
1043 " NEWLIST(&avlnode->id2nodes);\n"
1044 " AVL_AddNode((struct AVLNode **)&__GM_AVLRoot, (struct AVLNode *)avlnode, (AVLNODECOMP)__GM_CompNode);\n"
1045 " }\n"
1046 " else\n"
1047 " /* avlnode already in AVL tree, let avlnode pointer in libbase point to it */\n"
1048 " ((struct __GM_BaseAVL *)newlib)->avlnode = avlnode;\n"
1049 "\n"
1050 " id2node\n"
1051 " = ((struct __GM_BaseAVL *)newlib)->id2node\n"
1052 " = &((struct __GM_BaseAVL *)newlib)->_id2node;\n"
1053 " id2node->id2 = id2;\n"
1054 " id2node->lh = newlib;\n"
1055 " id2node->dupopencount = 1;\n"
1056 " AddHead((struct List *)&avlnode->id2nodes, (struct Node *)id2node);\n"
1057 "#endif\n"
1060 if (cfg->options & OPTION_BASEREL)
1061 fprintf(out,
1062 "\n"
1063 " void *oldbase = AROS_SET_LIBBASE(newlib);");
1064 fprintf(out,
1065 "\n"
1066 " if (!(set_open_rellibraries(newlib)\n"
1067 " && set_call_libfuncs(SETNAME(OPENLIB), 1, 1, newlib)\n"
1068 " )\n"
1069 " )\n"
1070 " {\n");
1071 if (cfg->options & OPTION_BASEREL)
1072 fprintf(out,
1073 " (void)AROS_SET_LIBBASE(oldbase);\n");
1074 fprintf(out,
1075 " __freebase(newlib);\n"
1076 " return NULL;\n"
1077 " }\n");
1078 if (cfg->options & OPTION_BASEREL)
1079 fprintf(out,
1080 " (void)AROS_SET_LIBBASE(oldbase);\n");
1081 fprintf(out,
1082 "\n"
1083 " ((struct Library *)lh)->lib_OpenCnt++;\n"
1084 " ((struct Library *)lh)->lib_Flags &= ~LIBF_DELEXP;\n"
1085 " }\n"
1086 "\n"
1087 " return (LIBBASETYPEPTR)newlib;\n"
1088 "\n"
1089 " AROS_LIBFUNC_EXIT\n"
1090 "}\n"
1091 "\n"
1098 static void writecloselib(FILE *out, struct config *cfg)
1100 if (cfg->options & OPTION_NOOPENCLOSE)
1102 if (cfg->modtype != DEVICE)
1103 fprintf(out,
1104 "AROS_LD0 (BPTR, GM_UNIQUENAME(CloseLib),\n"
1105 " LIBBASETYPEPTR, lh, 2, %s\n"
1106 ");\n",
1107 cfg->basename
1109 else
1110 fprintf(out,
1111 "AROS_LD1(BPTR, GM_UNIQUENAME(CloseLib),\n"
1112 " AROS_LHA(struct IORequest *, ioreq, A1),\n"
1113 " LIBBASETYPEPTR, lh, 2, %s\n"
1114 ");\n",
1115 cfg->basename
1117 return;
1119 if (cfg->modtype != DEVICE)
1120 fprintf(out,
1121 "AROS_LH0 (BPTR, GM_UNIQUENAME(CloseLib),\n"
1122 " LIBBASETYPEPTR, lh, 2, %s\n"
1123 ")\n",
1124 cfg->basename
1126 else
1127 fprintf(out,
1128 "AROS_LH1(BPTR, GM_UNIQUENAME(CloseLib),\n"
1129 " AROS_LHA(struct IORequest *, ioreq, A1),\n"
1130 " LIBBASETYPEPTR, lh, 2, %s\n"
1131 ")\n",
1132 cfg->basename
1135 fprintf(out,
1136 "{\n"
1137 " AROS_LIBFUNC_INIT\n"
1138 "\n"
1140 if (cfg->options & OPTION_BASEREL)
1141 fprintf(out,
1142 " void *oldbase = AROS_SET_LIBBASE(lh);\n"
1143 "\n"
1145 if (cfg->modtype == DEVICE)
1147 fprintf(out,
1148 " if (!set_call_devfuncs(SETNAME(CLOSEDEV), -1, 1, lh, ioreq, 0, 0))\n"
1149 " {\n");
1150 if (cfg->options & OPTION_BASEREL)
1151 fprintf(out,
1152 " (void)AROS_SET_LIBBASE(oldbase);\n");
1153 fprintf(out,
1154 " return BNULL;\n"
1155 " }\n"
1158 if (!(cfg->options & OPTION_DUPBASE))
1160 fprintf(out,
1161 " ((struct Library *)lh)->lib_OpenCnt--;\n"
1162 " set_call_libfuncs(SETNAME(CLOSELIB), -1, 0, lh);\n"
1165 else
1167 fprintf(out,
1168 " LIBBASETYPEPTR rootbase = GM_ROOTBASE_FIELD(lh);\n"
1170 if (cfg->options & OPTION_DUPPERID)
1171 fprintf(out,
1172 "#ifndef GM_GETID2\n"
1173 " struct __GM_AVLNode *avlnode = ((struct __GM_BaseAVL *)lh)->avlnode;\n"
1174 " avlnode->dupopencount--;\n"
1175 " if (avlnode->dupopencount != 0)\n"
1176 " return BNULL;\n"
1177 "#else\n"
1178 " struct __GM_ID2Node *id2node = ((struct __GM_BaseAVL *)lh)->id2node;\n"
1179 " id2node->dupopencount--;\n"
1180 " if (id2node->dupopencount != 0)\n"
1181 " return BNULL;\n"
1182 "#endif\n"
1184 fprintf(out,
1185 "\n"
1186 " set_call_libfuncs(SETNAME(CLOSELIB), -1, 0, lh);\n"
1187 " set_close_rellibraries(lh);\n"
1188 " __freebase(lh);\n"
1189 " lh = rootbase;\n"
1190 " ((struct Library *)lh)->lib_OpenCnt--;\n"
1191 "\n"
1194 if (!(cfg->options & OPTION_NOEXPUNGE))
1196 fprintf(out,
1197 " if\n"
1198 " (\n"
1199 " (((struct Library *)lh)->lib_OpenCnt == 0)\n"
1200 " && (((struct Library *)lh)->lib_Flags & LIBF_DELEXP)\n"
1201 " )\n"
1202 " {\n");
1203 if (cfg->options & OPTION_BASEREL)
1204 fprintf(out,
1205 " (void)AROS_SET_LIBBASE(oldbase);\n");
1206 fprintf(out,
1207 " return AROS_LC1(BPTR, GM_UNIQUENAME(ExpungeLib),\n"
1208 " AROS_LCA(LIBBASETYPEPTR, lh, D0),\n"
1209 " LIBBASETYPEPTR, lh, 3, %s\n"
1210 " );\n"
1211 " }\n",
1212 cfg->basename
1215 if (cfg->options & OPTION_BASEREL)
1216 fprintf(out,
1217 "\n"
1218 " (void)AROS_SET_LIBBASE(oldbase);");
1219 fprintf(out,
1220 "\n"
1221 " return BNULL;\n"
1222 "\n"
1223 " AROS_LIBFUNC_EXIT\n"
1224 "}\n"
1225 "\n"
1230 static void writeexpungelib(FILE *out, struct config *cfg)
1232 fprintf(out,
1233 "AROS_LH1 (BPTR, GM_UNIQUENAME(ExpungeLib),\n"
1234 " AROS_LHA(LIBBASETYPEPTR, extralh, D0),\n"
1235 " LIBBASETYPEPTR, lh, 3, %s\n"
1236 ")\n",
1237 cfg->basename
1239 fprintf(out,
1240 "{\n"
1241 " AROS_LIBFUNC_INIT\n"
1242 "\n"
1244 if (!(cfg->options & OPTION_NOEXPUNGE))
1246 fprintf(out,
1247 "\n"
1248 " if ( ((struct Library *)lh)->lib_OpenCnt == 0 )\n"
1249 " {\n"
1250 " BPTR seglist = GM_SEGLIST_FIELD(lh);\n"
1251 "\n");
1252 if (cfg->options & OPTION_BASEREL)
1253 fprintf(out,
1254 " void *oldbase = AROS_SET_LIBBASE(lh);\n"
1255 "\n");
1256 fprintf(out,
1257 " if(!set_call_libfuncs(SETNAME(EXPUNGELIB), -1, 1, lh))\n"
1258 " {\n"
1259 " ((struct Library *)lh)->lib_Flags |= LIBF_DELEXP;\n"
1260 " return BNULL;\n"
1261 " }\n"
1262 "\n"
1263 " Remove((struct Node *)lh);\n"
1264 "\n"
1265 " set_call_funcs(SETNAME(DTORS), 1, 0);\n"
1266 " set_call_funcs(SETNAME(EXIT), -1, 0);\n"
1268 if (cfg->classlist != NULL)
1269 fprintf(out, " set_call_libfuncs(SETNAME(CLASSESEXPUNGE), -1, 0, lh);\n");
1270 if (!(cfg->options & OPTION_NOAUTOLIB))
1271 fprintf(out, " set_close_libraries();\n");
1272 if (cfg->options & OPTION_BASEREL)
1273 fprintf(out,
1274 "\n"
1275 " (void)AROS_SET_LIBBASE(oldbase);");
1276 fprintf(out,
1277 "\n"
1278 " __freebase(lh);\n"
1279 "\n"
1280 " return seglist;\n"
1281 " }\n"
1282 "\n"
1283 " ((struct Library *)lh)->lib_Flags |= LIBF_DELEXP;\n"
1286 fprintf(out,
1287 "\n"
1288 " return BNULL;\n"
1289 "\n"
1290 " AROS_LIBFUNC_EXIT\n"
1291 "}\n"
1292 "\n"
1297 static void writeextfunclib(FILE *out, struct config *cfg)
1299 fprintf(out,
1300 "AROS_LH0 (LIBBASETYPEPTR, GM_UNIQUENAME(ExtFuncLib),\n"
1301 " LIBBASETYPEPTR, lh, 4, %s\n"
1302 ")\n"
1303 "{\n"
1304 " AROS_LIBFUNC_INIT\n"
1305 " return NULL;\n"
1306 " AROS_LIBFUNC_EXIT\n"
1307 "}\n"
1308 "\n",
1309 cfg->basename
1314 static void
1315 writefunctable(FILE *out,
1316 struct config *cfg
1319 struct functionhead *funclistit = cfg->funclist;
1320 struct functionarg *arglistit;
1321 unsigned int lvo;
1322 int i;
1323 char *name, *type;
1324 int lastversion = 0;
1326 /* lvo contains the number of functions already printed in the functable */
1327 lvo = 0;
1329 if (!(cfg->options & OPTION_NORESIDENT))
1331 fprintf(out,
1332 "\n"
1333 "const APTR GM_UNIQUENAME(FuncTable)[]=\n"
1334 "{\n"
1336 if (cfg->modtype != RESOURCE && cfg->modtype != HANDLER)
1338 fprintf(out,
1339 " &AROS_SLIB_ENTRY(GM_UNIQUENAME(OpenLib),%s,1),\n"
1340 " &AROS_SLIB_ENTRY(GM_UNIQUENAME(CloseLib),%s,2),\n"
1341 " &AROS_SLIB_ENTRY(GM_UNIQUENAME(ExpungeLib),%s,3),\n"
1342 " &AROS_SLIB_ENTRY(GM_UNIQUENAME(ExtFuncLib),%s,4),\n",
1343 cfg->basename, cfg->basename, cfg->basename, cfg->basename
1345 lvo += 4;
1347 if (cfg->modtype == MCC || cfg->modtype == MUI || cfg->modtype == MCP)
1349 lvo++;
1350 fprintf(out,
1351 " &AROS_SLIB_ENTRY(MCC_Query,%s,%d),\n",
1352 cfg->basename, lvo
1355 else if (cfg->modtype == DATATYPE)
1357 lvo++;
1358 fprintf(out,
1359 " &AROS_SLIB_ENTRY(ObtainEngine,%s,%d),\n",
1360 cfg->basename, lvo
1364 else /* NORESIDENT */
1366 if (cfg->modtype != RESOURCE && cfg->modtype != HANDLER)
1368 int neednull = 0;
1369 struct functionhead *funclistit2;
1371 if (funclistit->lvo != 1)
1373 fprintf(stderr, "Module without a generated resident structure has to provide the Open function (LVO==1)\n");
1374 exit(20);
1376 else
1377 funclistit = funclistit->next;
1379 if (funclistit->lvo != 2)
1381 fprintf(stderr, "Module without a generated resident structure has to provide the Close function (LVO==2)\n");
1382 exit(20);
1384 else
1385 funclistit = funclistit->next;
1387 if (funclistit->lvo == 3)
1388 funclistit = funclistit->next;
1389 else
1390 neednull = 1;
1392 if (funclistit->lvo == 4)
1393 funclistit = funclistit->next;
1394 else
1395 neednull = 1;
1397 if (neednull)
1398 fprintf(out,
1399 "\n"
1400 "AROS_UFH1S(int, %s_null,\n"
1401 " AROS_UFHA(struct Library *, libbase, A6)\n"
1402 ")\n"
1403 "{\n"
1404 " AROS_USERFUNC_INIT\n"
1405 " return 0;\n"
1406 " AROS_USERFUNC_EXIT\n"
1407 "}\n",
1408 cfg->modulename
1411 funclistit = cfg->funclist;
1412 funclistit2 = funclistit->next;
1413 fprintf(out,
1414 "\n"
1415 "const APTR GM_UNIQUENAME(FuncTable)[]=\n"
1416 "{\n"
1417 " &AROS_SLIB_ENTRY(%s,%s,%d),\n"
1418 " &AROS_SLIB_ENTRY(%s,%s,%d),\n",
1419 funclistit->internalname, cfg->basename, lvo+1,
1420 funclistit2->internalname, cfg->basename, lvo+2
1422 lvo += 2;
1423 funclistit = funclistit2->next;
1425 if (funclistit->lvo == 3)
1427 fprintf(out, " &AROS_SLIB_ENTRY(%s,%s,%d),\n",
1428 funclistit->internalname, cfg->basename, lvo+1
1430 funclistit = funclistit->next;
1432 else
1433 fprintf(out, " &%s_null,\n", cfg->modulename);
1434 lvo++;
1436 if (funclistit->lvo == 4)
1438 fprintf(out, " &AROS_SLIB_ENTRY(%s,%s,%d),\n",
1439 funclistit->internalname, cfg->basename, lvo+1
1441 funclistit = funclistit->next;
1443 else
1444 fprintf(out, " &%s_null,\n", cfg->modulename);
1445 lvo++;
1447 else
1449 fprintf(out,
1450 "\n"
1451 "const APTR GM_UNIQUENAME(FuncTable)[]=\n"
1452 "{\n");
1456 while (funclistit != NULL)
1458 for (i = lvo+1; i<funclistit->lvo; i++)
1459 fprintf(out, " NULL,\n");
1460 lvo = funclistit->lvo;
1462 switch (funclistit->libcall)
1464 case STACK:
1465 fprintf(out, " &%s,\n", funclistit->internalname);
1466 break;
1468 case REGISTER:
1469 case REGISTERMACRO:
1470 if (funclistit->version != lastversion) {
1471 lastversion = funclistit->version;
1472 fprintf(out, " /* Version %d */\n", lastversion);
1474 fprintf(out, " &AROS_SLIB_ENTRY(%s,%s,%d),\n", funclistit->internalname, cfg->basename, lvo);
1475 break;
1477 default:
1478 fprintf(stderr, "Internal error: unhandled libcall type in writestart\n");
1479 exit(20);
1480 break;
1483 funclistit = funclistit->next;
1486 fprintf(out, " (void *)-1\n};\n");
1490 static void writesets(FILE *out, struct config *cfg)
1492 fprintf(out,
1493 "DEFINESET(INIT)\n"
1494 "DEFINESET(EXIT)\n"
1495 "DEFINESET(CTORS)\n"
1496 "DEFINESET(DTORS)\n"
1498 if (cfg->modtype != HANDLER)
1499 fprintf(out,
1500 "DEFINESET(INITLIB)\n"
1501 "DEFINESET(EXPUNGELIB)\n"
1503 if (!(cfg->options & OPTION_NOOPENCLOSE))
1504 fprintf(out,
1505 "DEFINESET(OPENLIB)\n"
1506 "DEFINESET(CLOSELIB)\n"
1508 if (cfg->modtype == DEVICE)
1509 fprintf(out,
1510 "DEFINESET(OPENDEV)\n"
1511 "DEFINESET(CLOSEDEV)\n"
1513 if (cfg->classlist != NULL)
1514 fprintf(out,
1515 "DEFINESET(CLASSESINIT)\n"
1516 "DEFINESET(CLASSESEXPUNGE)\n"
1518 fprintf(out, "\n");