Recognize <CSI> '0 v' sequence that should be sent on paste when ConClip is active
[AROS.git] / tools / genmodule / writestart.c
blobc434b0a4ad7a93cff3c115cfb0795c653d8231e2
1 /*
2 Copyright © 1995-2009, 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 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)
27 FILE *out;
28 char line[256], *banner;
29 struct classinfo *cl;
31 snprintf(line, 255, "%s/%s_start.c", cfg->gendir, cfg->modulename);
32 out = fopen(line, "w");
34 if (out == NULL)
36 perror(line);
37 exit(20);
40 banner = getBanner(cfg);
41 fprintf(out, "%s", banner);
42 freeBanner(banner);
44 writedecl(out, 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);
61 writesets(out, cfg);
63 writefunctable(out, cfg);
65 for (cl = cfg->classlist; cl != NULL; cl = cl->next)
67 switch (cl->classtype)
69 case MCC:
70 case MUI:
71 case MCP:
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);
76 break;
77 case GADGET:
78 case DATATYPE:
79 case CLASS:
80 case IMAGE:
81 writeclassinit(out, cl);
82 break;
83 case HIDD:
84 writeoopinit(out, cl);
85 break;
86 default:
87 fprintf(stdout, "Internal error: unsupported classtype in writestart\n");
88 exit(20);
92 fclose(out);
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;
103 char *type, *name;
105 if (cfg->modtype == DEVICE)
107 fprintf(out,
108 "#include <exec/io.h>\n"
109 "#include <exec/errors.h>\n"
112 fprintf(out,
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"
120 "\n"
121 "#include \"%s_libdefs.h\"\n"
122 "\n"
123 "#ifdef SysBase\n"
124 "#undef SysBase\n"
125 "#endif\n"
126 "\n"
127 "#include <proto/exec.h>\n"
128 "#include <proto/alib.h>\n"
129 "#ifndef __AROS__\n"
130 "struct ExecBase *SysBase = NULL;\n"
131 "#endif\n"
132 "\n",
133 cfg->modulename
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)
145 fprintf(out,
146 "#ifndef GM_SEGLIST_FIELD\n"
147 "static BPTR GM_UNIQUENAME(seglist);\n"
148 "#define GM_SEGLIST_FIELD(lh) (GM_UNIQUENAME(seglist))\n"
149 "#endif\n"
152 if (cfg->options & OPTION_DUPBASE)
153 fprintf(out,
154 "#ifndef GM_ROOTBASE_FIELD\n"
155 "static LIBBASETYPEPTR GM_UNIQUENAME(rootbase);\n"
156 "#define GM_ROOTBASE_FIELD(lh) (GM_UNIQUENAME(rootbase))\n"
157 "#endif\n"
159 if (cfg->options & OPTION_DUPPERID)
160 fprintf(out,
161 "#ifdef __GM_OWNGETID\n"
162 "#include <dos/dosextens.h>\n"
163 "IPTR __GM_Id2(void)\n"
164 "{\n"
165 " struct Process *process = (struct Process *)FindTask(NULL);\n"
166 "\n"
167 " if (process->pr_Task.tc_Node.ln_Type == NT_PROCESS)\n"
168 " return (IPTR)process->pr_ReturnAddr;\n"
169 "\n"
170 " return (IPTR)NULL;\n"
171 "}\n"
172 "#endif\n"
173 "\n"
174 "#ifdef GM_GETID2\n"
175 "struct __GM_ID2Node\n"
176 "{\n"
177 " struct MinNode node;\n"
178 " IPTR id2;\n"
179 " struct Library *lh;\n"
180 " ULONG dupopencount;\n"
181 "};\n"
182 "#endif\n"
183 "\n"
184 "struct __GM_AVLNode {\n"
185 " struct AVLNode node;\n"
186 " IPTR id;\n"
187 "#ifndef GM_GETID2\n"
188 " struct Library *lh;\n"
189 " ULONG dupopencount;\n"
190 "#else\n"
191 " struct MinList id2nodes;\n"
192 "#endif\n"
193 "};\n"
194 "struct __GM_BaseAVL {\n"
195 " LIBBASETYPE base;\n"
196 " struct __GM_AVLNode *avlnode, _avlnode;\n"
197 "#ifdef GM_GETID2\n"
198 " struct __GM_ID2Node *id2node, _id2node;\n"
199 "#endif\n"
200 "};\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"
204 ")\n"
205 "{\n"
206 " AROS_USERFUNC_INIT\n"
207 "\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"
213 " else\n"
214 " return (LONG)1;\n"
215 "\n"
216 " AROS_USERFUNC_EXIT\n"
217 "}\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"
221 ")\n"
222 "{\n"
223 " AROS_USERFUNC_INIT\n"
224 "\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"
228 " );\n"
229 "\n"
230 " AROS_USERFUNC_EXIT\n"
231 "}\n"
232 "#define LIBBASESIZE sizeof(struct __GM_BaseAVL)\n"
233 "struct AVLNode *__GM_AVLRoot = NULL;\n"
234 "\n"
235 "#ifdef __GM_OWNPARENTBASEID2\n"
236 "LIBBASETYPEPTR GM_UNIQUENAME(__GetParentLibbase)(LIBBASETYPEPTR lh)\n"
237 "{\n"
238 " struct __GM_ID2Node *id2node = ((struct __GM_BaseAVL *)lh)->id2node;\n"
239 "\n"
240 " id2node = (struct __GM_ID2Node *)GetSucc(id2node);\n"
241 "\n"
242 " if (id2node != NULL)\n"
243 " return (LIBBASETYPEPTR)id2node->lh;\n"
244 " else\n"
245 " return (LIBBASETYPEPTR)NULL;\n"
246 "}\n"
247 "#endif\n"
248 "\n"
250 else
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)
260 fprintf(out,
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"
270 "#endif\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
282 else
284 fprintf(out,
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
294 else
296 if (classlistit->classptr_var == NULL)
298 fprintf(out,
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"
303 "#endif\n",
304 classlistit->basename,
305 classlistit->basename,
306 classlistit->basename, classlistit->basename,
307 classlistit->basename
310 else
312 fprintf(out,
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);
324 fprintf(out, "\n");
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)
334 case MUI:
335 case MCC:
336 case MCP:
337 if (!muiinc)
339 writemuiincludes(out);
340 muiinc = 1;
342 /* Fall through: also write boopsi includes */
343 case GADGET:
344 case DATATYPE:
345 case CLASS:
346 case IMAGE:
347 if (!boopsiinc)
349 writeboopsiincludes(out);
350 boopsiinc = 1;
352 break;
353 case HIDD:
354 if (!oopinc)
356 writeoopincludes(out);
357 oopinc = 1;
359 break;
360 default:
361 fprintf(stderr, "Internal error: unhandled classtype in writedecl\n");
362 exit(20);
368 static void writedeclsets(FILE *out, struct config *cfg)
370 fprintf(out,
371 "THIS_PROGRAM_HANDLES_SYMBOLSETS\n"
372 "DECLARESET(INIT)\n"
373 "DECLARESET(EXIT)\n"
374 "DECLARESET(CTORS)\n"
375 "DECLARESET(DTORS)\n"
376 "DECLARESET(INITLIB)\n"
377 "DECLARESET(EXPUNGELIB)\n"
379 if (cfg->modtype != RESOURCE)
380 fprintf(out,
381 "DECLARESET(OPENLIB)\n"
382 "DECLARESET(CLOSELIB)\n"
384 if (cfg->modtype == DEVICE)
385 fprintf(out,
386 "DECLARESET(OPENDEV)\n"
387 "DECLARESET(CLOSEDEV)\n"
389 if (cfg->classlist != NULL)
390 fprintf(out,
391 "DECLARESET(CLASSESINIT)\n"
392 "DECLARESET(CLASSESEXPUNGE)\n"
393 "#define ADD2INITCLASSES(symbol, pri) ADD2SET(symbol, classesinit, pri)\n"
394 "#define ADD2EXPUNGECLASSES(symbol, pri) ADD2SET(symbol, classesexpunge, pri)\n"
396 fprintf(out, "\n");
400 static void writeresident(FILE *out, struct config *cfg)
402 fprintf(out,
403 "extern const int GM_UNIQUENAME(End);\n"
404 "extern const APTR GM_UNIQUENAME(FuncTable)[];\n"
406 if (cfg->options & OPTION_RESAUTOINIT)
407 fprintf(out, "static const struct InitTable GM_UNIQUENAME(InitTable);\n");
408 fprintf(out,
409 "\n"
410 "extern const char GM_UNIQUENAME(LibName)[];\n"
411 "extern const char GM_UNIQUENAME(LibID)[];\n"
412 "extern const char GM_UNIQUENAME(Copyright)[];\n"
413 "\n"
416 if (cfg->options & OPTION_RESAUTOINIT)
418 if (!(cfg->options & OPTION_DUPPERID))
420 fprintf(out,
421 "#define __freebase(lh)\\\n"
422 "do {\\\n"
423 " UWORD negsize, possize;\\\n"
424 " UBYTE *negptr = (UBYTE *)lh;\\\n"
425 " negsize = ((struct Library *)lh)->lib_NegSize;\\\n"
426 " negptr -= negsize;\\\n"
427 " possize = ((struct Library *)lh)->lib_PosSize;\\\n"
428 " FreeMem (negptr, negsize+possize);\\\n"
429 "} while(0)\n"
430 "\n"
433 else
435 fprintf(out,
436 "#ifndef GM_GETID2\n"
437 "#define __freebase(lh)\\\n"
438 "do {\\\n"
439 " UWORD negsize, possize;\\\n"
440 " UBYTE *negptr = (UBYTE *)lh;\\\n"
441 " struct __GM_AVLNode *avlnode = ((struct __GM_BaseAVL *)lh)->avlnode;\\\n"
442 " AVL_RemNodeByAddress(&__GM_AVLRoot, (struct AVLNode *)avlnode);\\\n"
443 " negsize = ((struct Library *)lh)->lib_NegSize;\\\n"
444 " negptr -= negsize;\\\n"
445 " possize = ((struct Library *)lh)->lib_PosSize;\\\n"
446 " FreeMem (negptr, negsize+possize);\\\n"
447 "} while(0)\n"
448 "#else\n"
449 "#define __freebase(lh)\\\n"
450 "do {\\\n"
451 " UWORD negsize, possize;\\\n"
452 " UBYTE *negptr = (UBYTE *)lh;\\\n"
453 " struct __GM_AVLNode *avlnode = ((struct __GM_BaseAVL *)lh)->avlnode;\\\n"
454 " struct __GM_ID2Node *id2node = ((struct __GM_BaseAVL *)lh)->id2node;\\\n"
455 " BOOL remnode;\\\n"
456 " /* avlnode == NULL for original libbase provided to LibInit */\\\n"
457 " if (avlnode)\\\n"
458 " {\\\n"
459 " Remove((struct Node *)id2node);\\\n"
460 " remnode = GetHead((struct List *)&avlnode->id2nodes) == NULL;\\\n"
461 " if (remnode)\\\n"
462 " AVL_RemNodeByAddress(&__GM_AVLRoot, (struct AVLNode *)avlnode);\\\n"
463 " else if (avlnode == &((struct __GM_BaseAVL *)lh)->_avlnode)\\\n"
464 " /* Do not free as avlnode is still in the AVL Tree\\\n"
465 " This is causing a memory leak because sublibrary is not closed */\\\n"
466 " break;\\\n"
467 " }\\\n"
468 " negsize = ((struct Library *)lh)->lib_NegSize;\\\n"
469 " negptr -= negsize;\\\n"
470 " possize = ((struct Library *)lh)->lib_PosSize;\\\n"
471 " FreeMem (negptr, negsize+possize);\\\n"
472 "} while(0)\n"
473 "#endif\n"
478 fprintf(out,
479 "AROS_UFP3 (LIBBASETYPEPTR, GM_UNIQUENAME(InitLib),\n"
480 " AROS_UFPA(LIBBASETYPEPTR, lh, D0),\n"
481 " AROS_UFPA(BPTR, segList, A0),\n"
482 " AROS_UFPA(struct ExecBase *, sysBase, A6)\n"
483 ");\n"
485 if (cfg->modtype != RESOURCE)
487 fprintf(out,
488 "AROS_LP1(BPTR, GM_UNIQUENAME(ExpungeLib),\n"
489 " AROS_LPA(LIBBASETYPEPTR, extralh, D0),\n"
490 " LIBBASETYPEPTR, lh, 3, %s\n"
491 ");\n"
492 "\n",
493 cfg->basename
496 fprintf(out,
497 "struct Resident const GM_UNIQUENAME(ROMTag) =\n"
498 "{\n"
499 " RTC_MATCHWORD,\n"
500 " (struct Resident *)&GM_UNIQUENAME(ROMTag),\n"
501 " (APTR)&GM_UNIQUENAME(End),\n"
502 " RESIDENTFLAGS,\n"
503 " VERSION_NUMBER,\n"
505 switch (cfg->modtype)
507 case LIBRARY:
508 case MUI:
509 case MCC:
510 case MCP:
511 case GADGET:
512 case DATATYPE:
513 case USBCLASS:
514 case HIDD:
515 fprintf(out, " NT_LIBRARY,\n");
516 break;
517 case DEVICE:
518 fprintf(out, " NT_DEVICE,\n");
519 break;
520 case RESOURCE:
521 fprintf(out, " NT_RESOURCE,\n");
522 break;
523 default:
524 fprintf(stderr, "Internal error: unsupported modtype for NT_...\n");
525 exit(20);
526 break;
528 fprintf(out,
529 " RESIDENTPRI,\n"
530 " (CONST_STRPTR)&GM_UNIQUENAME(LibName)[0],\n"
531 " (CONST_STRPTR)&GM_UNIQUENAME(LibID)[6],\n"
533 if (cfg->options & OPTION_RESAUTOINIT)
535 fprintf(out,
536 " (APTR)&GM_UNIQUENAME(InitTable)\n"
537 "};\n"
538 "\n"
539 "static struct InitTable\n"
540 "{\n"
541 " IPTR Size;\n"
542 " const APTR *FuncTable;\n"
543 " struct DataTable *DataTable;\n"
544 " APTR InitLibTable;\n"
545 "}\n"
546 "const GM_UNIQUENAME(InitTable) =\n"
547 "{\n"
548 " LIBBASESIZE,\n"
549 " &GM_UNIQUENAME(FuncTable)[0],\n"
550 " NULL,\n"
551 " (APTR)GM_UNIQUENAME(InitLib)\n"
552 "};\n"
555 else
556 fprintf(out, " (APTR)GM_UNIQUENAME(InitLib)\n};\n");
558 fprintf(out,
559 "\n"
560 "const char GM_UNIQUENAME(LibName)[] = MOD_NAME_STRING;\n"
561 "const char GM_UNIQUENAME(LibID)[] = VERSION_STRING;\n"
562 "const char GM_UNIQUENAME(Copyright)[] = COPYRIGHT_STRING;\n"
563 "\n"
567 static void writeinitlib(FILE *out, struct config *cfg)
569 fprintf(out,
570 "AROS_UFH3 (LIBBASETYPEPTR, GM_UNIQUENAME(InitLib),\n"
571 " AROS_UFHA(LIBBASETYPEPTR, lh, D0),\n"
572 " AROS_UFHA(BPTR, segList, A0),\n"
573 " AROS_UFHA(struct ExecBase *, sysBase, A6)\n"
574 ")\n"
575 "{\n"
576 " AROS_USERFUNC_INIT\n"
577 "\n"
578 " int ok;\n"
579 "\n"
582 fprintf(out,
583 "#ifndef __AROS__\n"
584 " SysBase = sysBase;\n"
585 "#endif\n"
586 "#ifdef GM_SYSBASE_FIELD\n"
587 " GM_SYSBASE_FIELD(lh) = sysBase;\n"
588 "#endif\n"
591 if (!(cfg->options & OPTION_RESAUTOINIT))
593 unsigned int funccount;
594 struct functionhead *funclistit = cfg->funclist;
595 if (funclistit == NULL)
596 funccount = cfg->firstlvo-1;
597 else
599 while (funclistit->next != NULL)
600 funclistit = funclistit->next;
602 funccount = funclistit->lvo;
604 fprintf(out,
605 " int vecsize;\n"
606 " struct Node *n;\n"
607 " char *mem;\n"
608 "\n"
609 " vecsize = %u*LIB_VECTSIZE;\n"
610 " if (vecsize > 0)\n"
611 " vecsize = ((vecsize-1)/sizeof(IPTR) + 1)*sizeof(IPTR);\n"
612 " mem = AllocMem(vecsize+sizeof(LIBBASETYPE), MEMF_PUBLIC|MEMF_CLEAR);\n"
613 " if (mem == NULL)\n"
614 " return NULL;\n"
615 " lh = (LIBBASETYPEPTR)(mem + vecsize);\n"
616 " n = (struct Node *)lh;\n"
617 " n->ln_Type = NT_RESOURCE;\n"
618 " n->ln_Pri = RESIDENTPRI;\n"
619 " n->ln_Name = (char *)GM_UNIQUENAME(LibName);\n"
620 " MakeFunctions(lh, (APTR)GM_UNIQUENAME(FuncTable), NULL);\n",
621 funccount
624 else
626 fprintf(out,
627 " ((struct Library *)lh)->lib_Revision = REVISION_NUMBER;\n"
631 if (!(cfg->options & OPTION_NOEXPUNGE) && cfg->modtype!=RESOURCE)
632 fprintf(out, " GM_SEGLIST_FIELD(lh) = segList;\n");
633 if (cfg->options & OPTION_DUPBASE)
634 fprintf(out, " GM_ROOTBASE_FIELD(lh) = (LIBBASETYPEPTR)lh;\n");
635 fprintf(out, " if (");
636 if (!(cfg->options & OPTION_NOAUTOLIB))
637 fprintf(out, "set_open_libraries() && ");
638 if (cfg->classlist != NULL)
639 fprintf(out, "set_call_libfuncs(SETNAME(CLASSESINIT), 1, 1, lh) && ");
640 fprintf(out,
641 "set_call_funcs(SETNAME(INIT), 1, 1) )\n"
642 " {\n"
643 " set_call_funcs(SETNAME(CTORS), -1, 0);\n"
644 "\n"
645 " ok = set_call_libfuncs(SETNAME(INITLIB), 1, 1, lh);\n"
646 " }\n"
647 " else\n"
648 " ok = 0;\n"
649 "\n"
650 " if (!ok)\n"
651 " {\n"
652 " set_call_libfuncs(SETNAME(EXPUNGELIB), -1, 0, lh);\n"
653 " set_call_funcs(SETNAME(DTORS), 1, 0);\n"
654 " set_call_funcs(SETNAME(EXIT), -1, 0);\n"
656 if (cfg->classlist != NULL)
657 fprintf(out, " set_call_libfuncs(SETNAME(CLASSESEXPUNGE), -1, 0, lh);\n");
658 if (!(cfg->options & OPTION_NOAUTOLIB))
659 fprintf(out, " set_close_libraries();\n");
660 if (cfg->options & OPTION_RESAUTOINIT)
662 fprintf(out,
663 "\n"
664 " __freebase(lh);\n"
667 else
669 fprintf(out,
670 "\n"
671 " FreeMem(mem, vecsize+LIBBASESIZE);\n"
674 fprintf(out,
675 " return NULL;\n"
676 " }\n"
677 " else\n"
678 " {\n"
681 if (!(cfg->options & OPTION_RESAUTOINIT))
683 fprintf(out,
684 " AddResource(lh);\n"
688 fprintf(out,
689 " return lh;\n"
690 " }\n"
691 "\n"
692 " AROS_USERFUNC_EXIT\n"
693 "}\n"
694 "\n"
699 static void writeopenlib(FILE *out, struct config *cfg)
701 switch (cfg->modtype)
703 case RESOURCE:
704 fprintf(stderr, "Internal error: writeopenlib called for a resource\n");
705 break;
706 case DEVICE:
707 fprintf(out,
708 "AROS_LH3 (void, GM_UNIQUENAME(OpenLib),\n"
709 " AROS_LHA(struct IORequest *, ioreq, A1),\n"
710 " AROS_LHA(ULONG, unitnum, D0),\n"
711 " AROS_LHA(ULONG, flags, D1),\n"
712 " LIBBASETYPEPTR, lh, 1, %s\n"
713 ")\n",
714 cfg->basename
716 fprintf(out,
717 "{\n"
718 " AROS_LIBFUNC_INIT\n"
719 "\n"
720 " if ( set_call_libfuncs(SETNAME(OPENLIB), 1, 1, lh)\n"
721 " && set_call_devfuncs(SETNAME(OPENDEV), 1, 1, lh, ioreq, unitnum, flags)\n"
722 " )\n"
723 " {\n"
724 " ((struct Library *)lh)->lib_OpenCnt++;\n"
725 " ((struct Library *)lh)->lib_Flags &= ~LIBF_DELEXP;\n"
726 "\n"
727 " ioreq->io_Message.mn_Node.ln_Type = NT_REPLYMSG;\n"
728 " }\n"
729 " else\n"
730 " {\n"
731 " if (ioreq->io_Error >= 0)\n"
732 " ioreq->io_Error = IOERR_OPENFAIL;\n"
733 " }\n"
734 "\n"
735 " return;\n"
736 "\n"
737 " AROS_LIBFUNC_EXIT\n"
738 "}\n"
739 "\n"
741 break;
742 default:
743 fprintf(out,
744 "AROS_LH1 (LIBBASETYPEPTR, GM_UNIQUENAME(OpenLib),\n"
745 " AROS_LHA (ULONG, version, D0),\n"
746 " LIBBASETYPEPTR, lh, 1, %s\n"
747 ")\n"
748 "{\n"
749 " AROS_LIBFUNC_INIT\n"
750 "\n",
751 cfg->basename
753 if (!(cfg->options & OPTION_DUPBASE))
755 fprintf(out,
756 " if ( set_call_libfuncs(SETNAME(OPENLIB), 1, 1, lh) )\n"
757 " {\n"
758 " ((struct Library *)lh)->lib_OpenCnt++;\n"
759 " ((struct Library *)lh)->lib_Flags &= ~LIBF_DELEXP;\n"
760 "\n"
761 " return lh;\n"
762 " }\n"
763 "\n"
764 " return NULL;\n"
765 "\n"
766 " AROS_LIBFUNC_EXIT\n"
767 "}\n"
768 "\n"
771 else /* OPTION_DUPBASE */
773 fprintf(out,
774 " struct Library *newlib = NULL;\n"
775 " UWORD possize = ((struct Library *)lh)->lib_PosSize;\n"
777 if (cfg->options & OPTION_DUPPERID)
778 fprintf(out,
779 " struct __GM_AVLNode *avlnode = NULL;\n"
780 " IPTR id = GM_GETID;\n"
781 "#ifdef GM_GETID2\n"
782 " struct __GM_ID2Node *id2node = NULL, *id2node_it;\n"
783 " IPTR id2 = GM_GETID2;\n"
784 "#endif\n"
785 "\n"
786 " avlnode = (struct __GM_AVLNode *)AVL_FindNode(__GM_AVLRoot, (AVLKey)id, (AVLKEYCOMP)__GM_CompKey);\n"
787 "#ifndef GM_GETID2\n"
788 " if (avlnode != NULL)\n"
789 " {\n"
790 " avlnode->dupopencount++;\n"
791 " newlib = avlnode->lh;\n"
792 " }\n"
793 "#else\n"
794 " if (avlnode != NULL)\n"
795 " {\n"
796 " ForeachNode(&avlnode->id2nodes, id2node_it)\n"
797 " {\n"
798 " if (id2node_it->id2 == id2)\n"
799 " id2node = id2node_it;\n"
800 " break;\n"
801 " }\n"
802 " }\n"
803 " if (id2node != NULL)\n"
804 " {\n"
805 " id2node->dupopencount++;\n"
806 " newlib = id2node->lh;\n"
807 " }\n"
808 "#endif\n"
809 "\n"
811 fprintf(out,
812 "\n"
813 " if (newlib == NULL)\n"
814 " {\n"
815 " newlib = MakeLibrary(GM_UNIQUENAME(InitTable).FuncTable,\n"
816 " GM_UNIQUENAME(InitTable).DataTable,\n"
817 " NULL,\n"
818 " GM_UNIQUENAME(InitTable).Size,\n"
819 " (BPTR)NULL\n"
820 " );\n"
821 " if (newlib == NULL)\n"
822 " return NULL;\n"
823 "\n"
824 " CopyMem(lh, newlib, possize);\n"
826 if (cfg->options & OPTION_DUPPERID)
827 fprintf(out,
828 "#ifndef GM_GETID2\n"
829 " avlnode\n"
830 " = ((struct __GM_BaseAVL *)newlib)->avlnode\n"
831 " = &((struct __GM_BaseAVL *)newlib)->_avlnode;\n"
832 " avlnode->id = id;\n"
833 " avlnode->lh = newlib;\n"
834 " avlnode->dupopencount = 1;\n"
835 " AVL_AddNode((struct AVLNode **)&__GM_AVLRoot, (struct AVLNode *)avlnode, (AVLNODECOMP)__GM_CompNode);\n"
836 "#else\n"
837 " if(avlnode == NULL)\n"
838 " {\n"
839 " /* avlnode does not exists yet, use the one in the allocated libbase */\n"
840 " avlnode\n"
841 " = ((struct __GM_BaseAVL *)newlib)->avlnode\n"
842 " = &((struct __GM_BaseAVL *)newlib)->_avlnode;\n"
843 " avlnode->id = id;\n"
844 " NEWLIST(&avlnode->id2nodes);\n"
845 " AVL_AddNode((struct AVLNode **)&__GM_AVLRoot, (struct AVLNode *)avlnode, (AVLNODECOMP)__GM_CompNode);\n"
846 " }\n"
847 " else\n"
848 " /* avlnode already in AVL tree, let avlnode pointer in libbase point to it */\n"
849 " ((struct __GM_BaseAVL *)newlib)->avlnode = avlnode;\n"
850 "\n"
851 " id2node\n"
852 " = ((struct __GM_BaseAVL *)newlib)->id2node\n"
853 " = &((struct __GM_BaseAVL *)newlib)->_id2node;\n"
854 " id2node->id2 = id2;\n"
855 " id2node->lh = newlib;\n"
856 " id2node->dupopencount = 1;\n"
857 " AddHead((struct List *)&avlnode->id2nodes, (struct Node *)id2node);\n"
858 "#endif\n"
860 fprintf(out,
861 "\n"
862 " if (!set_call_libfuncs(SETNAME(OPENLIB), 1, 1, newlib))\n"
863 " {\n"
864 " __freebase(newlib);\n"
865 " return NULL;\n"
866 " }\n"
867 "\n"
868 " ((struct Library *)lh)->lib_OpenCnt++;\n"
869 " ((struct Library *)lh)->lib_Flags &= ~LIBF_DELEXP;\n"
870 " }\n"
871 "\n"
872 " return (LIBBASETYPEPTR)newlib;\n"
873 "\n"
874 " AROS_LIBFUNC_EXIT\n"
875 "}\n"
876 "\n"
883 static void writecloselib(FILE *out, struct config *cfg)
885 if (cfg->modtype != DEVICE)
886 fprintf(out,
887 "AROS_LH0 (BPTR, GM_UNIQUENAME(CloseLib),\n"
888 " LIBBASETYPEPTR, lh, 2, %s\n"
889 ")\n",
890 cfg->basename
892 else
893 fprintf(out,
894 "AROS_LH1(BPTR, GM_UNIQUENAME(CloseLib),\n"
895 " AROS_LHA(struct IORequest *, ioreq, A1),\n"
896 " LIBBASETYPEPTR, lh, 2, %s\n"
897 ")\n",
898 cfg->basename
901 fprintf(out,
902 "{\n"
903 " AROS_LIBFUNC_INIT\n"
904 "\n"
906 if (cfg->modtype == DEVICE)
907 fprintf(out,
908 " if (!set_call_devfuncs(SETNAME(CLOSEDEV), -1, 1, lh, ioreq, 0, 0))\n"
909 " {\n"
910 " return NULL;\n"
911 " }\n"
913 if (!(cfg->options & OPTION_DUPBASE))
915 fprintf(out,
916 " ((struct Library *)lh)->lib_OpenCnt--;\n"
917 " set_call_libfuncs(SETNAME(CLOSELIB), -1, 0, lh);\n"
920 else
922 fprintf(out,
923 " LIBBASETYPEPTR rootbase = GM_ROOTBASE_FIELD(lh);\n"
925 if (cfg->options & OPTION_DUPPERID)
926 fprintf(out,
927 "#ifndef GM_GETID2\n"
928 " struct __GM_AVLNode *avlnode = ((struct __GM_BaseAVL *)lh)->avlnode;\n"
929 " avlnode->dupopencount--;\n"
930 " if (avlnode->dupopencount != 0)\n"
931 " return (BPTR)NULL;\n"
932 "#else\n"
933 " struct __GM_ID2Node *id2node = ((struct __GM_BaseAVL *)lh)->id2node;\n"
934 " id2node->dupopencount--;\n"
935 " if (id2node->dupopencount != 0)\n"
936 " return (BPTR)NULL;\n"
937 "#endif\n"
939 fprintf(out,
940 "\n"
941 " set_call_libfuncs(SETNAME(CLOSELIB), -1, 0, lh);\n"
942 " __freebase(lh);\n"
943 " lh = rootbase;\n"
944 " ((struct Library *)lh)->lib_OpenCnt--;\n"
945 "\n"
948 if (!(cfg->options & OPTION_NOEXPUNGE))
949 fprintf(out,
950 " if\n"
951 " (\n"
952 " (((struct Library *)lh)->lib_OpenCnt == 0)\n"
953 " && (((struct Library *)lh)->lib_Flags & LIBF_DELEXP)\n"
954 " )\n"
955 " {\n"
956 " return AROS_LC1(BPTR, GM_UNIQUENAME(ExpungeLib),\n"
957 " AROS_LCA(LIBBASETYPEPTR, lh, D0),\n"
958 " LIBBASETYPEPTR, lh, 3, %s\n"
959 " );\n"
960 " }\n",
961 cfg->basename
963 fprintf(out,
964 "\n"
965 " return NULL;\n"
966 "\n"
967 " AROS_LIBFUNC_EXIT\n"
968 "}\n"
969 "\n"
974 static void writeexpungelib(FILE *out, struct config *cfg)
976 fprintf(out,
977 "AROS_LH1 (BPTR, GM_UNIQUENAME(ExpungeLib),\n"
978 " AROS_LHA(LIBBASETYPEPTR, extralh, D0),\n"
979 " LIBBASETYPEPTR, lh, 3, %s\n"
980 ")\n",
981 cfg->basename
983 fprintf(out,
984 "{\n"
985 " AROS_LIBFUNC_INIT\n"
986 "\n"
988 if (!(cfg->options & OPTION_NOEXPUNGE))
990 fprintf(out,
991 "\n"
992 " if ( ((struct Library *)lh)->lib_OpenCnt == 0 )\n"
993 " {\n"
994 " BPTR seglist = GM_SEGLIST_FIELD(lh);\n"
995 "\n"
996 " if(!set_call_libfuncs(SETNAME(EXPUNGELIB), -1, 1, lh))\n"
997 " {\n"
998 " ((struct Library *)lh)->lib_Flags |= LIBF_DELEXP;\n"
999 " return NULL;\n"
1000 " }\n"
1001 "\n"
1002 " Remove((struct Node *)lh);\n"
1003 "\n"
1004 " set_call_funcs(SETNAME(DTORS), 1, 0);\n"
1005 " set_call_funcs(SETNAME(EXIT), -1, 0);\n"
1007 if (cfg->classlist != NULL)
1008 fprintf(out, " set_call_libfuncs(SETNAME(CLASSESEXPUNGE), -1, 0, lh);\n");
1009 if (!(cfg->options & OPTION_NOAUTOLIB))
1010 fprintf(out, " set_close_libraries();\n");
1011 fprintf(out,
1012 "\n"
1013 " __freebase(lh);\n"
1014 "\n"
1015 " return seglist;\n"
1016 " }\n"
1017 "\n"
1018 " ((struct Library *)lh)->lib_Flags |= LIBF_DELEXP;\n"
1021 fprintf(out,
1022 "\n"
1023 " return NULL;\n"
1024 "\n"
1025 " AROS_LIBFUNC_EXIT\n"
1026 "}\n"
1027 "\n"
1032 static void writeextfunclib(FILE *out, struct config *cfg)
1034 fprintf(out,
1035 "AROS_LH0 (LIBBASETYPEPTR, GM_UNIQUENAME(ExtFuncLib),\n"
1036 " LIBBASETYPEPTR, lh, 4, %s\n"
1037 ")\n"
1038 "{\n"
1039 " AROS_LIBFUNC_INIT\n"
1040 " return NULL;\n"
1041 " AROS_LIBFUNC_EXIT\n"
1042 "}\n"
1043 "\n",
1044 cfg->basename
1049 static void
1050 writefunctable(FILE *out,
1051 struct config *cfg
1054 struct functionhead *funclistit;
1055 struct functionarg *arglistit;
1056 unsigned int lvo;
1057 int i;
1058 char *name, *type;
1060 /* lvo contains the number of functions already printed in the functable */
1061 lvo = 0;
1063 if (!(cfg->options & OPTION_NORESIDENT))
1065 fprintf(out,
1066 "\n"
1067 "const APTR GM_UNIQUENAME(FuncTable)[]=\n"
1068 "{\n"
1070 if (cfg->modtype != RESOURCE)
1072 fprintf(out,
1073 " &AROS_SLIB_ENTRY(GM_UNIQUENAME(OpenLib),%s),\n"
1074 " &AROS_SLIB_ENTRY(GM_UNIQUENAME(CloseLib),%s),\n"
1075 " &AROS_SLIB_ENTRY(GM_UNIQUENAME(ExpungeLib),%s),\n"
1076 " &AROS_SLIB_ENTRY(GM_UNIQUENAME(ExtFuncLib),%s),\n",
1077 cfg->basename, cfg->basename, cfg->basename, cfg->basename
1079 lvo += 4;
1081 if (cfg->modtype == MCC || cfg->modtype == MUI || cfg->modtype == MCP)
1083 fprintf(out,
1084 " &AROS_SLIB_ENTRY(MCC_Query,%s),\n",
1085 cfg->basename
1087 lvo++;
1089 else if (cfg->modtype == DATATYPE)
1091 fprintf(out,
1092 " &AROS_SLIB_ENTRY(ObtainEngine,%s),\n",
1093 cfg->basename
1095 lvo++;
1097 funclistit = cfg->funclist;
1099 else /* NORESIDENT */
1101 if (cfg->modtype != RESOURCE)
1103 int neednull = 0;
1104 struct functionhead *funclistit2;
1106 funclistit = cfg->funclist;
1107 if (funclistit->lvo != 1)
1109 fprintf(stderr, "Module without a generated resident structure has to provide the Open function (LVO==1)\n");
1110 exit(20);
1112 else
1113 funclistit = funclistit->next;
1115 if (funclistit->lvo != 2)
1117 fprintf(stderr, "Module without a generated resident structure has to provide the Close function (LVO==2)\n");
1118 exit(20);
1120 else
1121 funclistit = funclistit->next;
1123 if (funclistit->lvo == 3)
1124 funclistit = funclistit->next;
1125 else
1126 neednull = 1;
1128 if (funclistit->lvo == 4)
1129 funclistit = funclistit->next;
1130 else
1131 neednull = 1;
1133 if (neednull)
1134 fprintf(out,
1135 "\n"
1136 "AROS_UFH1(static int, %s_null,\n"
1137 " AROS_UFHA(struct Library *, libbase, A6)\n"
1138 ")\n"
1139 "{\n"
1140 " AROS_USERFUNC_INIT\n"
1141 " return 0;\n"
1142 " AROS_USERFUNC_EXIT\n"
1143 "}\n",
1144 cfg->modulename
1147 funclistit = cfg->funclist;
1148 funclistit2 = funclistit->next;
1149 fprintf(out,
1150 "\n"
1151 "const APTR GM_UNIQUENAME(FuncTable)[]=\n"
1152 "{\n"
1153 " &AROS_SLIB_ENTRY(%s,%s),\n"
1154 " &AROS_SLIB_ENTRY(%s,%s),\n",
1155 funclistit->internalname, cfg->basename,
1156 funclistit2->internalname, cfg->basename
1158 lvo += 2;
1159 funclistit = funclistit2->next;
1161 if (funclistit->lvo == 3)
1163 fprintf(out, " &AROS_SLIB_ENTRY(%s,%s),\n",
1164 funclistit->internalname, cfg->basename
1166 funclistit = funclistit->next;
1168 else
1169 fprintf(out, " &%s_null,\n", cfg->modulename);
1170 lvo++;
1172 if (funclistit->lvo == 4)
1174 fprintf(out, " &AROS_SLIB_ENTRY(%s,%s),\n",
1175 funclistit->internalname, cfg->basename
1177 funclistit = funclistit->next;
1179 else
1180 fprintf(out, " &%s_null,\n", cfg->modulename);
1181 lvo++;
1185 while (funclistit != NULL)
1187 for (i = lvo+1; i<funclistit->lvo; i++)
1188 fprintf(out, " NULL,\n");
1189 lvo = funclistit->lvo;
1191 switch (funclistit->libcall)
1193 case STACK:
1194 fprintf(out, " &%s,\n", funclistit->internalname);
1195 break;
1197 case REGISTER:
1198 case REGISTERMACRO:
1199 fprintf(out, " &AROS_SLIB_ENTRY(%s,%s),\n", funclistit->internalname, cfg->basename);
1200 break;
1202 default:
1203 fprintf(stderr, "Internal error: unhandled libcall type in writestart\n");
1204 exit(20);
1205 break;
1208 funclistit = funclistit->next;
1211 fprintf(out, " (void *)-1\n};\n");
1215 static void writesets(FILE *out, struct config *cfg)
1217 fprintf(out,
1218 "DEFINESET(INIT)\n"
1219 "DEFINESET(EXIT)\n"
1220 "DEFINESET(CTORS)\n"
1221 "DEFINESET(DTORS)\n"
1222 "DEFINESET(INITLIB)\n"
1223 "DEFINESET(EXPUNGELIB)\n"
1225 if (cfg->modtype != RESOURCE)
1226 fprintf(out,
1227 "DEFINESET(OPENLIB)\n"
1228 "DEFINESET(CLOSELIB)\n"
1230 if (cfg->modtype == DEVICE)
1231 fprintf(out,
1232 "DEFINESET(OPENDEV)\n"
1233 "DEFINESET(CLOSEDEV)\n"
1235 if (cfg->classlist != NULL)
1236 fprintf(out,
1237 "DEFINESET(CLASSESINIT)\n"
1238 "DEFINESET(CLASSESEXPUNGE)\n"
1240 fprintf(out, "\n");