2 Copyright © 1995-2009, The AROS Development Team. All rights reserved.
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
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 writeopenlib(FILE *, struct config
*);
19 static void writecloselib(FILE *, struct config
*);
20 static void writeexpungelib(FILE *, struct config
*);
21 static void writeextfunclib(FILE *, struct config
*);
22 static void writefunctable(FILE *, struct config
*);
23 static void writesets(FILE *, struct config
*);
25 void writestart(struct config
*cfg
)
28 char line
[256], *banner
;
31 snprintf(line
, 255, "%s/%s_start.c", cfg
->gendir
, cfg
->modulename
);
32 out
= fopen(line
, "w");
40 banner
= getBanner(cfg
);
45 if (!(cfg
->options
& OPTION_NORESIDENT
))
47 writeresident(out
, cfg
);
48 writedeclsets(out
, cfg
);
49 writeinitlib(out
, cfg
);
50 if (cfg
->modtype
!= RESOURCE
)
52 writeopenlib(out
, cfg
);
53 writecloselib(out
, cfg
);
54 writeexpungelib(out
, cfg
);
55 writeextfunclib(out
, cfg
);
56 if (cfg
->modtype
== MCC
|| cfg
->modtype
== MUI
|| cfg
->modtype
== MCP
)
57 writemccquery(out
, cfg
);
58 else if (cfg
->modtype
== DATATYPE
)
59 writeobtainengine(out
, cfg
);
63 writefunctable(out
, cfg
);
65 for (cl
= cfg
->classlist
; cl
!= NULL
; cl
= cl
->next
)
67 switch (cl
->classtype
)
72 /* Second argument to next call: the class is not the main class if it is not
73 * the first class or the modtype is not a MUI class
75 writemccinit(out
, cl
!= cfg
->classlist
|| cfg
->modtype
!= cl
->classtype
, cl
);
81 writeclassinit(out
, cl
);
84 writeoopinit(out
, cl
);
87 fprintf(stdout
, "Internal error: unsupported classtype in writestart\n");
96 static void writedecl(FILE *out
, struct config
*cfg
)
98 struct stringlist
*linelistit
;
99 int boopsiinc
=0, muiinc
=0, oopinc
=0;
100 struct functionhead
*funclistit
;
101 struct functionarg
*arglistit
;
102 struct classinfo
*classlistit
;
105 if (cfg
->modtype
== DEVICE
)
108 "#include <exec/io.h>\n"
109 "#include <exec/errors.h>\n"
113 "#include <exec/types.h>\n"
114 "#include <exec/libraries.h>\n"
115 "#include <exec/resident.h>\n"
116 "#include <aros/libcall.h>\n"
117 "#include <aros/asmcall.h>\n"
118 "#include <aros/symbolsets.h>\n"
119 "#include <dos/dos.h>\n"
121 "#include \"%s_libdefs.h\"\n"
127 "#include <proto/exec.h>\n"
128 "#include <proto/alib.h>\n"
130 "struct ExecBase *SysBase = NULL;\n"
136 /* Write out declaration section provided in the config file */
137 for (linelistit
= cfg
->cdeflines
; linelistit
!= NULL
; linelistit
= linelistit
->next
)
139 fprintf(out
, "%s\n", linelistit
->s
);
142 /* Is there a variable for storing the segList ? */
143 if (!(cfg
->options
& OPTION_NOEXPUNGE
) && cfg
->modtype
!=RESOURCE
)
146 "#ifndef GM_SEGLIST_FIELD\n"
147 "static BPTR GM_UNIQUENAME(seglist);\n"
148 "#define GM_SEGLIST_FIELD(lh) (GM_UNIQUENAME(seglist))\n"
152 if (cfg
->options
& OPTION_DUPBASE
)
154 "#ifndef GM_ROOTBASE_FIELD\n"
155 "static LIBBASETYPEPTR GM_UNIQUENAME(rootbase);\n"
156 "#define GM_ROOTBASE_FIELD(lh) (GM_UNIQUENAME(rootbase))\n"
159 if (cfg
->options
& OPTION_DUPPERID
)
161 "#ifdef __GM_OWNGETID\n"
162 "#include <dos/dosextens.h>\n"
163 "IPTR __GM_Id2(void)\n"
165 " struct Process *process = (struct Process *)FindTask(NULL);\n"
167 " if (process->pr_Task.tc_Node.ln_Type == NT_PROCESS)\n"
168 " return (IPTR)process->pr_ReturnAddr;\n"
170 " return (IPTR)NULL;\n"
175 "struct __GM_ID2Node\n"
177 " struct MinNode node;\n"
179 " struct Library *lh;\n"
180 " ULONG dupopencount;\n"
184 "struct __GM_AVLNode {\n"
185 " struct AVLNode node;\n"
187 "#ifndef GM_GETID2\n"
188 " struct Library *lh;\n"
189 " ULONG dupopencount;\n"
191 " struct MinList id2nodes;\n"
194 "struct __GM_BaseAVL {\n"
195 " LIBBASETYPE base;\n"
196 " struct __GM_AVLNode *avlnode, _avlnode;\n"
198 " struct __GM_ID2Node *id2node, _id2node;\n"
201 "static AROS_UFH2(LONG, __GM_CompKey,\n"
202 " AROS_UFHA(const struct __GM_AVLNode *, gm_avlnode, A0),\n"
203 " AROS_UFHA(AVLKey, _key, A1)\n"
206 " AROS_USERFUNC_INIT\n"
208 " IPTR id = (IPTR)_key;\n"
209 " if (gm_avlnode->id == id)\n"
210 " return (LONG) 0;\n"
211 " else if (gm_avlnode->id < id)\n"
212 " return (LONG)-1;\n"
216 " AROS_USERFUNC_EXIT\n"
218 "static AROS_UFH2(LONG, __GM_CompNode,\n"
219 " AROS_UFHA(const struct __GM_AVLNode *, gm_avlnode1, A0),\n"
220 " AROS_UFHA(const struct __GM_AVLNode *, gm_avlnode2, A1)\n"
223 " AROS_USERFUNC_INIT\n"
225 " return AROS_UFC2(LONG, __GM_CompKey,\n"
226 " AROS_UFPA(const struct __GM_AVLNode *, gm_avlnode1, A0),\n"
227 " AROS_UFPA(AVLKey, (AVLKey)gm_avlnode2->id, A1)\n"
230 " AROS_USERFUNC_EXIT\n"
232 "#define LIBBASESIZE sizeof(struct __GM_BaseAVL)\n"
233 "struct AVLNode *__GM_AVLRoot = NULL;\n"
235 "#ifdef __GM_OWNPARENTBASEID2\n"
236 "LIBBASETYPEPTR GM_UNIQUENAME(__GetParentLibbase)(LIBBASETYPEPTR lh)\n"
238 " struct __GM_ID2Node *id2node = ((struct __GM_BaseAVL *)lh)->id2node;\n"
240 " id2node = (struct __GM_ID2Node *)GetSucc(id2node);\n"
242 " if (id2node != NULL)\n"
243 " return (LIBBASETYPEPTR)id2node->lh;\n"
245 " return (LIBBASETYPEPTR)NULL;\n"
251 fprintf(out
, "#define LIBBASESIZE sizeof(LIBBASETYPE)\n");
253 for (classlistit
= cfg
->classlist
; classlistit
!= NULL
; classlistit
= classlistit
->next
)
255 /* For the main class basename is the same a the module basename */
256 if (strcmp(classlistit
->basename
, cfg
->basename
) == 0)
258 if (classlistit
->classptr_var
== NULL
)
261 "#if !defined(GM_CLASSPTR_FIELD) && !defined(%s_CLASSPTR_FIELD)\n"
262 "static APTR GM_UNIQUENAME(%sClass);\n"
263 "#define GM_CLASSPTR_FIELD(lh) (GM_UNIQUENAME(%sClass))\n"
264 "#define %s_CLASSPTR_FIELD(lh) (GM_UNIQUENAME(%sClass))\n"
265 "#define %s_STORE_CLASSPTR 1\n"
266 "#elif defined(GM_CLASSPTR_FIELD) && !defined(%s_CLASSPTR_FIELD)\n"
267 "#define %s_CLASSPTR_FIELD(lh) (GM_CLASSPTR_FIELD(lh))\n"
268 "#elif !defined(GM_CLASSPTR_FIELD) && defined(%s_CLASSPTR_FIELD)\n"
269 "#define GM_CLASSPTR_FIELD(lh) (%s_CLASSPTR_FIELD(lh))\n"
271 classlistit
->basename
,
272 classlistit
->basename
,
273 classlistit
->basename
,
274 classlistit
->basename
, classlistit
->basename
,
275 classlistit
->basename
,
276 classlistit
->basename
,
277 classlistit
->basename
,
278 classlistit
->basename
,
279 classlistit
->basename
285 "#define GM_CLASSPTR_FIELD(lh) (%s)\n"
286 "#define %s_CLASSPTR_FIELD(lh) (%s)\n"
287 "#define %s_STORE_CLASSPTR 1\n",
288 classlistit
->classptr_var
,
289 classlistit
->basename
, classlistit
->classptr_var
,
290 classlistit
->basename
296 if (classlistit
->classptr_var
== NULL
)
299 "#if !defined(%s_CLASSPTR_FIELD)\n"
300 "static APTR GM_UNIQUENAME(%sClass);\n"
301 "#define %s_CLASSPTR_FIELD(lh) (GM_UNIQUENAME(%sClass))\n"
302 "#define %s_STORE_CLASSPTR 1\n"
304 classlistit
->basename
,
305 classlistit
->basename
,
306 classlistit
->basename
, classlistit
->basename
,
307 classlistit
->basename
313 "#define %s_CLASSPTR_FIELD(lh) (%s)\n"
314 "#define %s_STORE_CLASSPTR 1\n",
315 classlistit
->basename
, classlistit
->classptr_var
,
316 classlistit
->basename
322 /* Write out the defines for the functions of the function table */
323 writefuncdefs(out
, cfg
, cfg
->funclist
);
326 /* Write out the includes needed for the classes */
327 if (cfg
->classlist
!= NULL
)
328 writeboopsiincludes(out
);
330 for (classlistit
= cfg
->classlist
; classlistit
!= NULL
; classlistit
= classlistit
->next
)
332 switch (classlistit
->classtype
)
339 writemuiincludes(out
);
342 /* Fall through: also write boopsi includes */
349 writeboopsiincludes(out
);
356 writeoopincludes(out
);
361 fprintf(stderr
, "Internal error: unhandled classtype in writedecl\n");
368 static void writedeclsets(FILE *out
, struct config
*cfg
)
371 "THIS_PROGRAM_HANDLES_SYMBOLSETS\n"
374 "DECLARESET(CTORS)\n"
375 "DECLARESET(DTORS)\n"
376 "DECLARESET(INITLIB)\n"
377 "DECLARESET(EXPUNGELIB)\n"
378 "DECLARESET(OPENLIB)\n"
379 "DECLARESET(CLOSELIB)\n"
380 "DECLARESET(OPENDEV)\n"
381 "DECLARESET(CLOSEDEV)\n"
383 if (cfg
->classlist
!= NULL
)
385 "DECLARESET(CLASSESINIT)\n"
386 "DECLARESET(CLASSESEXPUNGE)\n"
387 "#define ADD2INITCLASSES(symbol, pri) ADD2SET(symbol, classesinit, pri)\n"
388 "#define ADD2EXPUNGECLASSES(symbol, pri) ADD2SET(symbol, classesexpunge, pri)\n"
394 static void writeresident(FILE *out
, struct config
*cfg
)
397 "extern const int GM_UNIQUENAME(End);\n"
398 "extern const APTR GM_UNIQUENAME(FuncTable)[];\n"
400 if (cfg
->modtype
!= RESOURCE
)
401 fprintf(out
, "static const struct InitTable GM_UNIQUENAME(InitTable);\n");
404 "extern const char GM_UNIQUENAME(LibName)[];\n"
405 "extern const char GM_UNIQUENAME(LibID)[];\n"
406 "extern const char GM_UNIQUENAME(Copyright)[];\n"
410 if (cfg
->modtype
!= RESOURCE
)
412 if (!(cfg
->options
& OPTION_DUPPERID
))
415 "#define __freebase(lh)\\\n"
417 " UWORD negsize, possize;\\\n"
418 " UBYTE *negptr = (UBYTE *)lh;\\\n"
419 " negsize = ((struct Library *)lh)->lib_NegSize;\\\n"
420 " negptr -= negsize;\\\n"
421 " possize = ((struct Library *)lh)->lib_PosSize;\\\n"
422 " FreeMem (negptr, negsize+possize);\\\n"
430 "#ifndef GM_GETID2\n"
431 "#define __freebase(lh)\\\n"
433 " UWORD negsize, possize;\\\n"
434 " UBYTE *negptr = (UBYTE *)lh;\\\n"
435 " struct __GM_AVLNode *avlnode = ((struct __GM_BaseAVL *)lh)->avlnode;\\\n"
436 " AVL_RemNodeByAddress(&__GM_AVLRoot, (struct AVLNode *)avlnode);\\\n"
437 " negsize = ((struct Library *)lh)->lib_NegSize;\\\n"
438 " negptr -= negsize;\\\n"
439 " possize = ((struct Library *)lh)->lib_PosSize;\\\n"
440 " FreeMem (negptr, negsize+possize);\\\n"
443 "#define __freebase(lh)\\\n"
445 " UWORD negsize, possize;\\\n"
446 " UBYTE *negptr = (UBYTE *)lh;\\\n"
447 " struct __GM_AVLNode *avlnode = ((struct __GM_BaseAVL *)lh)->avlnode;\\\n"
448 " struct __GM_ID2Node *id2node = ((struct __GM_BaseAVL *)lh)->id2node;\\\n"
450 " /* avlnode == NULL for original libbase provided to LibInit */\\\n"
453 " Remove((struct Node *)id2node);\\\n"
454 " remnode = GetHead((struct List *)&avlnode->id2nodes) == NULL;\\\n"
456 " AVL_RemNodeByAddress(&__GM_AVLRoot, (struct AVLNode *)avlnode);\\\n"
457 " else if (avlnode == &((struct __GM_BaseAVL *)lh)->_avlnode)\\\n"
458 " /* Do not free as avlnode is still in the AVL Tree\\\n"
459 " This is causing a memory leak because sublibrary is not closed */\\\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"
473 "AROS_UFP3 (LIBBASETYPEPTR, GM_UNIQUENAME(InitLib),\n"
474 " AROS_UFPA(LIBBASETYPEPTR, lh, D0),\n"
475 " AROS_UFPA(BPTR, segList, A0),\n"
476 " AROS_UFPA(struct ExecBase *, sysBase, A6)\n"
479 if (cfg
->modtype
!= RESOURCE
)
482 "AROS_LP1(BPTR, GM_UNIQUENAME(ExpungeLib),\n"
483 " AROS_LPA(LIBBASETYPEPTR, extralh, D0),\n"
484 " LIBBASETYPEPTR, lh, 3, %s\n"
491 "struct Resident const GM_UNIQUENAME(ROMTag) =\n"
494 " (struct Resident *)&GM_UNIQUENAME(ROMTag),\n"
495 " (APTR)&GM_UNIQUENAME(End),\n"
499 switch (cfg
->modtype
)
509 fprintf(out
, " NT_LIBRARY,\n");
512 fprintf(out
, " NT_DEVICE,\n");
515 fprintf(out
, " NT_RESOURCE,\n");
518 fprintf(stderr
, "Internal error: unsupported modtype for NT_...\n");
524 " (CONST_STRPTR)&GM_UNIQUENAME(LibName)[0],\n"
525 " (CONST_STRPTR)&GM_UNIQUENAME(LibID)[6],\n"
527 if (cfg
->modtype
!= RESOURCE
)
530 " (APTR)&GM_UNIQUENAME(InitTable)\n"
533 "static struct InitTable\n"
536 " const APTR *FuncTable;\n"
537 " struct DataTable *DataTable;\n"
538 " APTR InitLibTable;\n"
540 "const GM_UNIQUENAME(InitTable) =\n"
543 " &GM_UNIQUENAME(FuncTable)[0],\n"
545 " (APTR)GM_UNIQUENAME(InitLib)\n"
550 fprintf(out
, " (APTR)GM_UNIQUENAME(InitLib)\n};\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"
561 static void writeinitlib(FILE *out
, struct config
*cfg
)
564 "AROS_UFH3 (LIBBASETYPEPTR, GM_UNIQUENAME(InitLib),\n"
565 " AROS_UFHA(LIBBASETYPEPTR, lh, D0),\n"
566 " AROS_UFHA(BPTR, segList, A0),\n"
567 " AROS_UFHA(struct ExecBase *, sysBase, A6)\n"
570 " AROS_USERFUNC_INIT\n"
578 " SysBase = sysBase;\n"
580 "#ifdef GM_SYSBASE_FIELD\n"
581 " GM_SYSBASE_FIELD(lh) = sysBase;\n"
585 if (cfg
->modtype
== RESOURCE
)
587 unsigned int funccount
;
588 struct functionhead
*funclistit
= cfg
->funclist
;
589 if (funclistit
== NULL
)
590 funccount
= cfg
->firstlvo
-1;
593 while (funclistit
->next
!= NULL
)
594 funclistit
= funclistit
->next
;
596 funccount
= funclistit
->lvo
;
603 " vecsize = %u*LIB_VECTSIZE;\n"
604 " if (vecsize > 0)\n"
605 " vecsize = ((vecsize-1)/sizeof(IPTR) + 1)*sizeof(IPTR);\n"
606 " mem = AllocMem(vecsize+sizeof(LIBBASETYPE), MEMF_PUBLIC|MEMF_CLEAR);\n"
607 " if (mem == NULL)\n"
609 " lh = (LIBBASETYPEPTR)(mem + vecsize);\n"
610 " n = (struct Node *)lh;\n"
611 " n->ln_Type = NT_RESOURCE;\n"
612 " n->ln_Pri = RESIDENTPRI;\n"
613 " n->ln_Name = (char *)GM_UNIQUENAME(LibName);\n"
614 " MakeFunctions(lh, (APTR)GM_UNIQUENAME(FuncTable), NULL);\n",
621 " ((struct Library *)lh)->lib_Revision = REVISION_NUMBER;\n"
625 if (!(cfg
->options
& OPTION_NOEXPUNGE
) && cfg
->modtype
!=RESOURCE
)
626 fprintf(out
, " GM_SEGLIST_FIELD(lh) = segList;\n");
627 if (cfg
->options
& OPTION_DUPBASE
)
628 fprintf(out
, " GM_ROOTBASE_FIELD(lh) = (LIBBASETYPEPTR)lh;\n");
629 fprintf(out
, " if (");
630 if (!(cfg
->options
& OPTION_NOAUTOLIB
))
631 fprintf(out
, "set_open_libraries() && ");
632 if (cfg
->classlist
!= NULL
)
633 fprintf(out
, "set_call_libfuncs(SETNAME(CLASSESINIT), 1, 1, lh) && ");
635 "set_call_funcs(SETNAME(INIT), 1, 1) )\n"
637 " set_call_funcs(SETNAME(CTORS), -1, 0);\n"
639 " ok = set_call_libfuncs(SETNAME(INITLIB), 1, 1, lh);\n"
646 " set_call_libfuncs(SETNAME(EXPUNGELIB), -1, 0, lh);\n"
647 " set_call_funcs(SETNAME(DTORS), 1, 0);\n"
648 " set_call_funcs(SETNAME(EXIT), -1, 0);\n"
650 if (cfg
->classlist
!= NULL
)
651 fprintf(out
, " set_call_libfuncs(SETNAME(CLASSESEXPUNGE), -1, 0, lh);\n");
652 if (!(cfg
->options
& OPTION_NOAUTOLIB
))
653 fprintf(out
, " set_close_libraries();\n");
654 if (cfg
->modtype
!= RESOURCE
)
665 " FreeMem(mem, vecsize+LIBBASESIZE);\n"
675 if (cfg
->modtype
== RESOURCE
)
678 " AddResource(lh);\n"
686 " AROS_USERFUNC_EXIT\n"
693 static void writeopenlib(FILE *out
, struct config
*cfg
)
695 switch (cfg
->modtype
)
698 fprintf(stderr
, "Internal error: writeopenlib called for a resource\n");
702 "AROS_LH3 (void, GM_UNIQUENAME(OpenLib),\n"
703 " AROS_LHA(struct IORequest *, ioreq, A1),\n"
704 " AROS_LHA(ULONG, unitnum, D0),\n"
705 " AROS_LHA(ULONG, flags, D1),\n"
706 " LIBBASETYPEPTR, lh, 1, %s\n"
712 " AROS_LIBFUNC_INIT\n"
714 " if ( set_call_libfuncs(SETNAME(OPENLIB), 1, 1, lh)\n"
715 " && set_call_devfuncs(SETNAME(OPENDEV), 1, 1, lh, ioreq, unitnum, flags)\n"
718 " ((struct Library *)lh)->lib_OpenCnt++;\n"
719 " ((struct Library *)lh)->lib_Flags &= ~LIBF_DELEXP;\n"
721 " ioreq->io_Message.mn_Node.ln_Type = NT_REPLYMSG;\n"
725 " if (ioreq->io_Error >= 0)\n"
726 " ioreq->io_Error = IOERR_OPENFAIL;\n"
731 " AROS_LIBFUNC_EXIT\n"
738 "AROS_LH1 (LIBBASETYPEPTR, GM_UNIQUENAME(OpenLib),\n"
739 " AROS_LHA (ULONG, version, D0),\n"
740 " LIBBASETYPEPTR, lh, 1, %s\n"
743 " AROS_LIBFUNC_INIT\n"
747 if (!(cfg
->options
& OPTION_DUPBASE
))
750 " if ( set_call_libfuncs(SETNAME(OPENLIB), 1, 1, lh) )\n"
752 " ((struct Library *)lh)->lib_OpenCnt++;\n"
753 " ((struct Library *)lh)->lib_Flags &= ~LIBF_DELEXP;\n"
760 " AROS_LIBFUNC_EXIT\n"
765 else /* OPTION_DUPBASE */
768 " struct Library *newlib = NULL;\n"
769 " UWORD possize = ((struct Library *)lh)->lib_PosSize;\n"
771 if (cfg
->options
& OPTION_DUPPERID
)
773 " struct __GM_AVLNode *avlnode = NULL;\n"
774 " IPTR id = GM_GETID;\n"
776 " struct __GM_ID2Node *id2node = NULL, *id2node_it;\n"
777 " IPTR id2 = GM_GETID2;\n"
780 " avlnode = (struct __GM_AVLNode *)AVL_FindNode(__GM_AVLRoot, (AVLKey)id, (AVLKEYCOMP)__GM_CompKey);\n"
781 "#ifndef GM_GETID2\n"
782 " if (avlnode != NULL)\n"
784 " avlnode->dupopencount++;\n"
785 " newlib = avlnode->lh;\n"
788 " if (avlnode != NULL)\n"
790 " ForeachNode(&avlnode->id2nodes, id2node_it)\n"
792 " if (id2node_it->id2 == id2)\n"
793 " id2node = id2node_it;\n"
797 " if (id2node != NULL)\n"
799 " id2node->dupopencount++;\n"
800 " newlib = id2node->lh;\n"
807 " if (newlib == NULL)\n"
809 " newlib = MakeLibrary(GM_UNIQUENAME(InitTable).FuncTable,\n"
810 " GM_UNIQUENAME(InitTable).DataTable,\n"
812 " GM_UNIQUENAME(InitTable).Size,\n"
815 " if (newlib == NULL)\n"
818 " CopyMem(lh, newlib, possize);\n"
820 if (cfg
->options
& OPTION_DUPPERID
)
822 "#ifndef GM_GETID2\n"
824 " = ((struct __GM_BaseAVL *)newlib)->avlnode\n"
825 " = &((struct __GM_BaseAVL *)newlib)->_avlnode;\n"
826 " avlnode->id = id;\n"
827 " avlnode->lh = newlib;\n"
828 " avlnode->dupopencount = 1;\n"
829 " AVL_AddNode((struct AVLNode **)&__GM_AVLRoot, (struct AVLNode *)avlnode, (AVLNODECOMP)__GM_CompNode);\n"
831 " if(avlnode == NULL)\n"
833 " /* avlnode does not exists yet, use the one in the allocated libbase */\n"
835 " = ((struct __GM_BaseAVL *)newlib)->avlnode\n"
836 " = &((struct __GM_BaseAVL *)newlib)->_avlnode;\n"
837 " avlnode->id = id;\n"
838 " NEWLIST(&avlnode->id2nodes);\n"
839 " AVL_AddNode((struct AVLNode **)&__GM_AVLRoot, (struct AVLNode *)avlnode, (AVLNODECOMP)__GM_CompNode);\n"
842 " /* avlnode already in AVL tree, let avlnode pointer in libbase point to it */\n"
843 " ((struct __GM_BaseAVL *)newlib)->avlnode = avlnode;\n"
846 " = ((struct __GM_BaseAVL *)newlib)->id2node\n"
847 " = &((struct __GM_BaseAVL *)newlib)->_id2node;\n"
848 " id2node->id2 = id2;\n"
849 " id2node->lh = newlib;\n"
850 " id2node->dupopencount = 1;\n"
851 " AddHead((struct List *)&avlnode->id2nodes, (struct Node *)id2node);\n"
856 " if (!set_call_libfuncs(SETNAME(OPENLIB), 1, 1, newlib))\n"
858 " __freebase(newlib);\n"
862 " ((struct Library *)lh)->lib_OpenCnt++;\n"
863 " ((struct Library *)lh)->lib_Flags &= ~LIBF_DELEXP;\n"
866 " return (LIBBASETYPEPTR)newlib;\n"
868 " AROS_LIBFUNC_EXIT\n"
877 static void writecloselib(FILE *out
, struct config
*cfg
)
879 if (cfg
->modtype
!= DEVICE
)
881 "AROS_LH0 (BPTR, GM_UNIQUENAME(CloseLib),\n"
882 " LIBBASETYPEPTR, lh, 2, %s\n"
888 "AROS_LH1(BPTR, GM_UNIQUENAME(CloseLib),\n"
889 " AROS_LHA(struct IORequest *, ioreq, A1),\n"
890 " LIBBASETYPEPTR, lh, 2, %s\n"
897 " AROS_LIBFUNC_INIT\n"
900 if (cfg
->modtype
== DEVICE
)
902 " if (!set_call_devfuncs(SETNAME(CLOSEDEV), -1, 1, lh, ioreq, 0, 0))\n"
907 if (!(cfg
->options
& OPTION_DUPBASE
))
910 " ((struct Library *)lh)->lib_OpenCnt--;\n"
911 " set_call_libfuncs(SETNAME(CLOSELIB), -1, 0, lh);\n"
917 " LIBBASETYPEPTR rootbase = GM_ROOTBASE_FIELD(lh);\n"
919 if (cfg
->options
& OPTION_DUPPERID
)
921 "#ifndef GM_GETID2\n"
922 " struct __GM_AVLNode *avlnode = ((struct __GM_BaseAVL *)lh)->avlnode;\n"
923 " avlnode->dupopencount--;\n"
924 " if (avlnode->dupopencount != 0)\n"
925 " return (BPTR)NULL;\n"
927 " struct __GM_ID2Node *id2node = ((struct __GM_BaseAVL *)lh)->id2node;\n"
928 " id2node->dupopencount--;\n"
929 " if (id2node->dupopencount != 0)\n"
930 " return (BPTR)NULL;\n"
935 " set_call_libfuncs(SETNAME(CLOSELIB), -1, 0, lh);\n"
938 " ((struct Library *)lh)->lib_OpenCnt--;\n"
942 if (!(cfg
->options
& OPTION_NOEXPUNGE
))
946 " (((struct Library *)lh)->lib_OpenCnt == 0)\n"
947 " && (((struct Library *)lh)->lib_Flags & LIBF_DELEXP)\n"
950 " return AROS_LC1(BPTR, GM_UNIQUENAME(ExpungeLib),\n"
951 " AROS_LCA(LIBBASETYPEPTR, lh, D0),\n"
952 " LIBBASETYPEPTR, lh, 3, %s\n"
961 " AROS_LIBFUNC_EXIT\n"
968 static void writeexpungelib(FILE *out
, struct config
*cfg
)
971 "AROS_LH1 (BPTR, GM_UNIQUENAME(ExpungeLib),\n"
972 " AROS_LHA(LIBBASETYPEPTR, extralh, D0),\n"
973 " LIBBASETYPEPTR, lh, 3, %s\n"
979 " AROS_LIBFUNC_INIT\n"
982 if (!(cfg
->options
& OPTION_NOEXPUNGE
))
986 " if ( ((struct Library *)lh)->lib_OpenCnt == 0 )\n"
988 " BPTR seglist = GM_SEGLIST_FIELD(lh);\n"
990 " if(!set_call_libfuncs(SETNAME(EXPUNGELIB), -1, 1, lh))\n"
992 " ((struct Library *)lh)->lib_Flags |= LIBF_DELEXP;\n"
996 " Remove((struct Node *)lh);\n"
998 " set_call_funcs(SETNAME(DTORS), 1, 0);\n"
999 " set_call_funcs(SETNAME(EXIT), -1, 0);\n"
1001 if (cfg
->classlist
!= NULL
)
1002 fprintf(out
, " set_call_libfuncs(SETNAME(CLASSESEXPUNGE), -1, 0, lh);\n");
1003 if (!(cfg
->options
& OPTION_NOAUTOLIB
))
1004 fprintf(out
, " set_close_libraries();\n");
1007 " __freebase(lh);\n"
1009 " return seglist;\n"
1012 " ((struct Library *)lh)->lib_Flags |= LIBF_DELEXP;\n"
1019 " AROS_LIBFUNC_EXIT\n"
1026 static void writeextfunclib(FILE *out
, struct config
*cfg
)
1029 "AROS_LH0 (LIBBASETYPEPTR, GM_UNIQUENAME(ExtFuncLib),\n"
1030 " LIBBASETYPEPTR, lh, 4, %s\n"
1033 " AROS_LIBFUNC_INIT\n"
1035 " AROS_LIBFUNC_EXIT\n"
1044 writefunctable(FILE *out
,
1048 struct functionhead
*funclistit
;
1049 struct functionarg
*arglistit
;
1054 /* lvo contains the number of functions already printed in the functable */
1057 if (!(cfg
->options
& OPTION_NORESIDENT
))
1061 "const APTR GM_UNIQUENAME(FuncTable)[]=\n"
1064 if (cfg
->modtype
!= RESOURCE
)
1067 " &AROS_SLIB_ENTRY(GM_UNIQUENAME(OpenLib),%s),\n"
1068 " &AROS_SLIB_ENTRY(GM_UNIQUENAME(CloseLib),%s),\n"
1069 " &AROS_SLIB_ENTRY(GM_UNIQUENAME(ExpungeLib),%s),\n"
1070 " &AROS_SLIB_ENTRY(GM_UNIQUENAME(ExtFuncLib),%s),\n",
1071 cfg
->basename
, cfg
->basename
, cfg
->basename
, cfg
->basename
1075 if (cfg
->modtype
== MCC
|| cfg
->modtype
== MUI
|| cfg
->modtype
== MCP
)
1078 " &AROS_SLIB_ENTRY(MCC_Query,%s),\n",
1083 else if (cfg
->modtype
== DATATYPE
)
1086 " &AROS_SLIB_ENTRY(ObtainEngine,%s),\n",
1091 funclistit
= cfg
->funclist
;
1093 else /* NORESIDENT */
1095 if (cfg
->modtype
!= RESOURCE
)
1098 struct functionhead
*funclistit2
;
1100 funclistit
= cfg
->funclist
;
1101 if (funclistit
->lvo
!= 1)
1103 fprintf(stderr
, "Module without a generated resident structure has to provide the Open function (LVO==1)\n");
1107 funclistit
= funclistit
->next
;
1109 if (funclistit
->lvo
!= 2)
1111 fprintf(stderr
, "Module without a generated resident structure has to provide the Close function (LVO==2)\n");
1115 funclistit
= funclistit
->next
;
1117 if (funclistit
->lvo
== 3)
1118 funclistit
= funclistit
->next
;
1122 if (funclistit
->lvo
== 4)
1123 funclistit
= funclistit
->next
;
1130 "AROS_UFH1(static int, %s_null,\n"
1131 " AROS_UFHA(struct Library *, libbase, A6)\n"
1134 " AROS_USERFUNC_INIT\n"
1136 " AROS_USERFUNC_EXIT\n"
1141 funclistit
= cfg
->funclist
;
1142 funclistit2
= funclistit
->next
;
1145 "const APTR GM_UNIQUENAME(FuncTable)[]=\n"
1147 " &AROS_SLIB_ENTRY(%s,%s),\n"
1148 " &AROS_SLIB_ENTRY(%s,%s),\n",
1149 funclistit
->name
, cfg
->basename
,
1150 funclistit2
->name
, cfg
->basename
1153 funclistit
= funclistit2
->next
;
1155 if (funclistit
->lvo
== 3)
1157 fprintf(out
, " &AROS_SLIB_ENTRY(%s,%s),\n",
1158 funclistit
->name
, cfg
->basename
1160 funclistit
= funclistit
->next
;
1163 fprintf(out
, " &%s_null,\n", cfg
->modulename
);
1166 if (funclistit
->lvo
== 4)
1168 fprintf(out
, " &AROS_SLIB_ENTRY(%s,%s),\n",
1169 funclistit
->name
, cfg
->basename
1171 funclistit
= funclistit
->next
;
1174 fprintf(out
, " &%s_null,\n", cfg
->modulename
);
1179 while (funclistit
!= NULL
)
1181 for (i
= lvo
+1; i
<funclistit
->lvo
; i
++)
1182 fprintf(out
, " NULL,\n");
1183 lvo
= funclistit
->lvo
;
1185 switch (funclistit
->libcall
)
1188 fprintf(out
, " &%s,\n", funclistit
->name
);
1193 fprintf(out
, " &AROS_SLIB_ENTRY(%s,%s),\n", funclistit
->name
, cfg
->basename
);
1197 fprintf(stderr
, "Internal error: unhandled libcall type in writestart\n");
1202 funclistit
= funclistit
->next
;
1205 fprintf(out
, " (void *)-1\n};\n");
1209 static void writesets(FILE *out
, struct config
*cfg
)
1214 "DEFINESET(CTORS)\n"
1215 "DEFINESET(DTORS)\n"
1216 "DEFINESET(INITLIB)\n"
1217 "DEFINESET(EXPUNGELIB)\n"
1218 "DEFINESET(OPENLIB)\n"
1219 "DEFINESET(CLOSELIB)\n"
1220 "DEFINESET(OPENDEV)\n"
1221 "DEFINESET(CLOSEDEV)\n"
1223 if (cfg
->classlist
!= NULL
)
1225 "DEFINESET(CLASSESINIT)\n"
1226 "DEFINESET(CLASSESEXPUNGE)\n"