added concrete implementations of putc(), getc(), getchar() and gets()
[tangerine.git] / tools / genmodule / writestart.c
blobed01711e7ff8972f3f2ded7cdcb8561d0b11d5d4
1 /*
2 Copyright © 1995-2006, 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 "muisupport.h"
10 #include "dtsupport.h"
11 #include "boopsisupport.h"
13 static void writedecl(FILE *, struct config *);
14 static void writedeclsets(FILE *, struct config *);
15 static void writeresident(FILE *, struct config *);
16 static void writeinitlib(FILE *, struct config *);
17 static void writeopenlib(FILE *, struct config *);
18 static void writecloselib(FILE *, struct config *);
19 static void writeexpungelib(FILE *, struct config *);
20 static void writeextfunclib(FILE *, struct config *);
21 static void writefunctable(FILE *, struct config *);
22 static void writesets(FILE *, struct config *);
24 void writestart(struct config *cfg)
26 FILE *out;
27 char line[256];
28 struct classinfo *cl;
30 snprintf(line, 255, "%s/%s_start.c", cfg->gendir, cfg->modulename);
31 out = fopen(line, "w");
33 if (out == NULL)
35 perror(line);
36 exit(20);
39 fprintf(out, getBanner(cfg));
41 writedecl(out, cfg);
42 if (!(cfg->options & OPTION_NORESIDENT))
44 writeresident(out, cfg);
45 writedeclsets(out, cfg);
46 writeinitlib(out, cfg);
47 if (cfg->modtype != RESOURCE)
49 writeopenlib(out, cfg);
50 writecloselib(out, cfg);
51 writeexpungelib(out, cfg);
52 writeextfunclib(out, cfg);
53 if (cfg->modtype == MCC || cfg->modtype == MUI || cfg->modtype == MCP)
54 writemccquery(out, cfg);
55 else if (cfg->modtype == DATATYPE)
56 writeobtainengine(out, cfg);
58 writesets(out, cfg);
60 writefunctable(out, cfg);
62 for (cl = cfg->classlist; cl != NULL; cl = cl->next)
64 switch (cl->classtype)
66 case MCC:
67 case MUI:
68 case MCP:
69 /* Second argument to next call: the class is not the main class if it is not
70 * the first class or the modtype is not a MUI class
72 writemccinit(out, cl != cfg->classlist || cfg->modtype != cl->classtype, cl);
73 break;
74 case GADGET:
75 case DATATYPE:
76 case CLASS:
77 case IMAGE:
78 writeclassinit(out, cl);
79 break;
80 case HIDD:
81 writeoopinit(out, cl);
82 break;
83 default:
84 fprintf(stdout, "Internal error: unsupported classtype in writestart\n");
85 exit(20);
89 fclose(out);
93 static void writedecl(FILE *out, struct config *cfg)
95 struct stringlist *linelistit;
96 int boopsiinc=0, muiinc=0, oopinc=0;
97 struct functionhead *funclistit;
98 struct functionarg *arglistit;
99 struct classinfo *classlistit;
100 char *type, *name;
102 if (cfg->modtype == DEVICE)
104 fprintf(out,
105 "#include <exec/io.h>\n"
106 "#include <exec/errors.h>\n"
109 fprintf(out,
110 "#include <exec/types.h>\n"
111 "#include <exec/libraries.h>\n"
112 "#include <exec/resident.h>\n"
113 "#include <aros/libcall.h>\n"
114 "#include <aros/asmcall.h>\n"
115 "#include <aros/symbolsets.h>\n"
116 "#include <dos/dos.h>\n"
117 "\n"
118 "#include \"%s_libdefs.h\"\n"
119 "\n"
120 "#ifdef SysBase\n"
121 "#undef SysBase\n"
122 "#endif\n"
123 "\n"
124 "#include <proto/exec.h>\n"
125 "\n",
126 cfg->modulename
129 /* Write out declaration section provided in the config file */
130 for (linelistit = cfg->cdeflines; linelistit != NULL; linelistit = linelistit->next)
132 fprintf(out, "%s\n", linelistit->s);
135 /* Is there a variable for storing the segList ? */
136 if (!(cfg->options & OPTION_NOEXPUNGE) && cfg->modtype!=RESOURCE)
138 fprintf(out,
139 "#ifndef GM_SEGLIST_FIELD\n"
140 "static BPTR GM_UNIQUENAME(seglist);\n"
141 "#define GM_SEGLIST_FIELD(lh) (GM_UNIQUENAME(seglist))\n"
142 "#endif\n"
144 if (cfg->options & OPTION_DUPBASE)
145 fprintf(out,
146 "#ifndef GM_ROOTBASE_FIELD\n"
147 "static LIBBASETYPEPTR GM_UNIQUENAME(rootbase);\n"
148 "#define GM_ROOTBASE_FIELD(lh) (GM_UNIQUENAME(rootbase))\n"
149 "#endif\n"
151 for (classlistit = cfg->classlist; classlistit != NULL; classlistit = classlistit->next)
153 /* For the main class basename is the same a the module basename */
154 if (strcmp(classlistit->basename, cfg->basename) == 0)
156 if (classlistit->classptr_var == NULL)
158 fprintf(out,
159 "#if !defined(GM_CLASSPTR_FIELD) && !defined(%s_CLASSPTR_FIELD)\n"
160 "static APTR GM_UNIQUENAME(%sClass);\n"
161 "#define GM_CLASSPTR_FIELD(lh) (GM_UNIQUENAME(%sClass))\n"
162 "#define %s_CLASSPTR_FIELD(lh) (GM_UNIQUENAME(%sClass))\n"
163 "#define %s_STORE_CLASSPTR 1\n"
164 "#elif defined(GM_CLASSPTR_FIELD) && !defined(%s_CLASSPTR_FIELD)\n"
165 "#define %s_CLASSPTR_FIELD(lh) (GM_CLASSPTR_FIELD(lh))\n"
166 "#elif !defined(GM_CLASSPTR_FIELD) && defined(%s_CLASSPTR_FIELD)\n"
167 "#define GM_CLASSPTR_FIELD(lh) (%s_CLASSPTR_FIELD(lh))\n"
168 "#endif\n",
169 classlistit->basename,
170 classlistit->basename,
171 classlistit->basename,
172 classlistit->basename, classlistit->basename,
173 classlistit->basename,
174 classlistit->basename,
175 classlistit->basename,
176 classlistit->basename,
177 classlistit->basename
180 else
182 fprintf(out,
183 "#define GM_CLASSPTR_FIELD(lh) (%s)\n"
184 "#define %s_CLASSPTR_FIELD(lh) (%s)\n"
185 "#define %s_STORE_CLASSPTR 1\n",
186 classlistit->classptr_var,
187 classlistit->basename, classlistit->classptr_var,
188 classlistit->basename
192 else
194 if (classlistit->classptr_var == NULL)
196 fprintf(out,
197 "#if !defined(%s_CLASSPTR_FIELD)\n"
198 "static APTR GM_UNIQUENAME(%sClass);\n"
199 "#define %s_CLASSPTR_FIELD(lh) (GM_UNIQUENAME(%sClass))\n"
200 "#define %s_STORE_CLASSPTR 1\n"
201 "#endif\n",
202 classlistit->basename,
203 classlistit->basename,
204 classlistit->basename, classlistit->basename,
205 classlistit->basename
208 else
210 fprintf(out,
211 "#define %s_CLASSPTR_FIELD(lh) (%s)\n"
212 "#define %s_STORE_CLASSPTR 1\n",
213 classlistit->basename, classlistit->classptr_var,
214 classlistit->basename
221 /* Write out the defines for the functions of the function table */
222 writefuncdefs(out, cfg, cfg->funclist);
223 fprintf(out, "\n");
225 /* Write out the includes needed for the classes */
226 if (cfg->classlist != NULL)
227 writeboopsiincludes(out);
229 for (classlistit = cfg->classlist; classlistit != NULL; classlistit = classlistit->next)
231 switch (classlistit->classtype)
233 case MUI:
234 case MCC:
235 case MCP:
236 if (!muiinc)
238 writemuiincludes(out);
239 muiinc = 1;
241 /* Fall through: also write boopsi includes */
242 case GADGET:
243 case DATATYPE:
244 case CLASS:
245 case IMAGE:
246 if (!boopsiinc)
248 writeboopsiincludes(out);
249 boopsiinc = 1;
251 break;
252 case HIDD:
253 if (!oopinc)
255 writeoopincludes(out);
256 oopinc = 1;
258 break;
259 default:
260 fprintf(stderr, "Internal error: unhandled classtype in writedecl\n");
261 exit(20);
267 static void writedeclsets(FILE *out, struct config *cfg)
269 fprintf(out,
270 "THIS_PROGRAM_HANDLES_SYMBOLSETS\n"
271 "DECLARESET(INIT)\n"
272 "DECLARESET(EXIT)\n"
273 "DECLARESET(CTORS)\n"
274 "DECLARESET(DTORS)\n"
275 "DECLARESET(INITLIB)\n"
276 "DECLARESET(EXPUNGELIB)\n"
277 "DECLARESET(OPENLIB)\n"
278 "DECLARESET(CLOSELIB)\n"
279 "DECLARESET(OPENDEV)\n"
280 "DECLARESET(CLOSEDEV)\n"
282 if (cfg->classlist != NULL)
283 fprintf(out,
284 "DECLARESET(CLASSESINIT)\n"
285 "DECLARESET(CLASSESEXPUNGE)\n"
286 "#define ADD2INITCLASSES(symbol, pri) ADD2SET(symbol, classesinit, pri)\n"
287 "#define ADD2EXPUNGECLASSES(symbol, pri) ADD2SET(symbol, classesexpunge, pri)\n"
289 fprintf(out, "\n");
293 static void writeresident(FILE *out, struct config *cfg)
295 fprintf(out,
296 "extern const int GM_UNIQUENAME(End);\n"
297 "extern const APTR GM_UNIQUENAME(FuncTable)[];\n"
299 if (cfg->modtype != RESOURCE)
300 fprintf(out, "static const struct InitTable GM_UNIQUENAME(InitTable);\n");
301 fprintf(out,
302 "\n"
303 "extern const char GM_UNIQUENAME(LibName)[];\n"
304 "extern const char GM_UNIQUENAME(LibID)[];\n"
305 "extern const char GM_UNIQUENAME(Copyright)[];\n"
306 "\n"
309 if (cfg->modtype != RESOURCE)
311 fprintf(out,
312 "#define __freebase(lh)\\\n"
313 "do {\\\n"
314 " UWORD negsize, possize;\\\n"
315 " UBYTE *negptr = (UBYTE *)lh;\\\n"
316 " negsize = ((struct Library *)lh)->lib_NegSize;\\\n"
317 " negptr -= negsize;\\\n"
318 " possize = ((struct Library *)lh)->lib_PosSize;\\\n"
319 " FreeMem (negptr, negsize+possize);\\\n"
320 "} while(0)\n"
321 "\n"
325 fprintf(out,
326 "AROS_UFP3 (LIBBASETYPEPTR, GM_UNIQUENAME(InitLib),\n"
327 " AROS_UFPA(LIBBASETYPEPTR, lh, D0),\n"
328 " AROS_UFPA(BPTR, segList, A0),\n"
329 " AROS_UFPA(struct ExecBase *, SysBase, A6)\n"
330 ");\n"
332 if (cfg->modtype != RESOURCE)
334 fprintf(out,
335 "AROS_LP1(BPTR, GM_UNIQUENAME(ExpungeLib),\n"
336 " AROS_LPA(LIBBASETYPEPTR, lh, D0),\n"
337 " struct ExecBase *, SysBase, 3, %s\n"
338 ");\n"
339 "\n",
340 cfg->basename
343 fprintf(out,
344 "struct Resident const GM_UNIQUENAME(ROMTag) =\n"
345 "{\n"
346 " RTC_MATCHWORD,\n"
347 " (struct Resident *)&GM_UNIQUENAME(ROMTag),\n"
348 " (APTR)&GM_UNIQUENAME(End),\n"
349 " RESIDENTFLAGS,\n"
350 " VERSION_NUMBER,\n"
352 switch (cfg->modtype)
354 case LIBRARY:
355 case MUI:
356 case MCC:
357 case MCP:
358 case GADGET:
359 case DATATYPE:
360 case HIDD:
361 fprintf(out, " NT_LIBRARY,\n");
362 break;
363 case DEVICE:
364 fprintf(out, " NT_DEVICE,\n");
365 break;
366 case RESOURCE:
367 fprintf(out, " NT_RESOURCE,\n");
368 break;
369 default:
370 fprintf(stderr, "Internal error: unsupported modtype for NT_...\n");
371 exit(20);
372 break;
374 fprintf(out,
375 " RESIDENTPRI,\n"
376 " (char *)&GM_UNIQUENAME(LibName)[0],\n"
377 " (char *)&GM_UNIQUENAME(LibID)[6],\n"
379 if (cfg->modtype != RESOURCE)
381 fprintf(out,
382 " (APTR)&GM_UNIQUENAME(InitTable)\n"
383 "};\n"
384 "\n"
385 "static struct InitTable\n"
386 "{\n"
387 " IPTR Size;\n"
388 " const APTR *FuncTable;\n"
389 " const struct DataTable *DataTable;\n"
390 " APTR InitLibTable;\n"
391 "}\n"
392 "const GM_UNIQUENAME(InitTable) =\n"
393 "{\n"
394 " sizeof(LIBBASETYPE),\n"
395 " &GM_UNIQUENAME(FuncTable)[0],\n"
396 " NULL,\n"
397 " (APTR)GM_UNIQUENAME(InitLib)\n"
398 "};\n"
401 else /* RESOURCE */
402 fprintf(out, " (APTR)GM_UNIQUENAME(InitLib)\n};\n");
404 fprintf(out,
405 "\n"
406 "const char GM_UNIQUENAME(LibName)[] = MOD_NAME_STRING;\n"
407 "const char GM_UNIQUENAME(LibID)[] = VERSION_STRING;\n"
408 "const char GM_UNIQUENAME(Copyright)[] = COPYRIGHT_STRING;\n"
409 "\n"
413 static void writeinitlib(FILE *out, struct config *cfg)
415 fprintf(out,
416 "AROS_UFH3 (LIBBASETYPEPTR, GM_UNIQUENAME(InitLib),\n"
417 " AROS_UFHA(LIBBASETYPEPTR, lh, D0),\n"
418 " AROS_UFHA(BPTR, segList, A0),\n"
419 " AROS_UFHA(struct ExecBase *, SysBase, A6)\n"
420 ")\n"
421 "{\n"
422 " AROS_USERFUNC_INIT\n"
423 "\n"
424 " int ok;\n"
425 "\n"
427 if (cfg->modtype == RESOURCE)
429 unsigned int funccount;
430 struct functionhead *funclistit = cfg->funclist;
431 if (funclistit == NULL)
432 funccount = cfg->firstlvo-1;
433 else
435 while (funclistit->next != NULL)
436 funclistit = funclistit->next;
438 funccount = funclistit->lvo;
440 fprintf(out,
441 " int vecsize;\n"
442 " struct Node *n;\n"
443 " char *mem;\n"
444 "\n"
445 " vecsize = %u*LIB_VECTSIZE;\n"
446 " if (vecsize > 0)\n"
447 " vecsize = ((vecsize-1)/sizeof(IPTR) + 1)*sizeof(IPTR);\n"
448 " mem = AllocMem(vecsize+sizeof(LIBBASETYPE), MEMF_PUBLIC);\n"
449 " if (mem == NULL)\n"
450 " return NULL;\n"
451 " lh = (LIBBASETYPEPTR)(mem + vecsize);\n"
452 " n = (struct Node *)lh;\n"
453 " n->ln_Type = NT_RESOURCE;\n"
454 " n->ln_Pri = RESIDENTPRI;\n"
455 " n->ln_Name = (char *)GM_UNIQUENAME(LibName);\n"
456 " MakeFunctions(lh, (APTR)GM_UNIQUENAME(FuncTable), NULL);\n",
457 funccount
460 fprintf(out,
461 "#ifdef GM_SYSBASE_FIELD\n"
462 " GM_SYSBASE_FIELD(lh) = SysBase;\n"
463 "#endif\n"
466 else
468 fprintf(out,
469 "#ifdef GM_SYSBASE_FIELD\n"
470 " GM_SYSBASE_FIELD(lh) = SysBase;\n"
471 "#endif\n"
472 " ((struct Library *)lh)->lib_Revision = REVISION_NUMBER;\n"
476 if (!(cfg->options & OPTION_NOEXPUNGE) && cfg->modtype!=RESOURCE)
477 fprintf(out, " GM_SEGLIST_FIELD(lh) = segList;\n");
478 if (cfg->options & OPTION_DUPBASE)
479 fprintf(out, " GM_ROOTBASE_FIELD(lh) = (LIBBASETYPEPTR)lh;\n");
480 fprintf(out, " if (");
481 if (!(cfg->options & OPTION_NOAUTOLIB))
482 fprintf(out, "set_open_libraries() && ");
483 if (cfg->classlist != NULL)
484 fprintf(out, "set_call_libfuncs(SETNAME(CLASSESINIT), 1, 1, lh) && ");
485 fprintf(out,
486 "set_call_funcs(SETNAME(INIT), 1, 1) )\n"
487 " {\n"
488 " set_call_funcs(SETNAME(CTORS), -1, 0);\n"
489 "\n"
490 " ok = set_call_libfuncs(SETNAME(INITLIB), 1, 1, lh);\n"
491 " }\n"
492 " else\n"
493 " ok = 0;\n"
494 "\n"
495 " if (!ok)\n"
496 " {\n"
497 " set_call_libfuncs(SETNAME(EXPUNGELIB), -1, 0, lh);\n"
498 " set_call_funcs(SETNAME(DTORS), 1, 0);\n"
499 " set_call_funcs(SETNAME(EXIT), -1, 0);\n"
501 if (cfg->classlist != NULL)
502 fprintf(out, " set_call_libfuncs(SETNAME(CLASSESEXPUNGE), -1, 0, lh);\n");
503 if (!(cfg->options & OPTION_NOAUTOLIB))
504 fprintf(out, " set_close_libraries();\n");
505 if (cfg->modtype != RESOURCE)
507 fprintf(out,
508 "\n"
509 " __freebase(lh);\n"
512 else
514 fprintf(out,
515 "\n"
516 " FreeMem(mem, vecsize+sizeof(LIBBASETYPE));\n"
519 fprintf(out,
520 " return NULL;\n"
521 " }\n"
522 " else\n"
523 " {\n"
526 if (cfg->modtype == RESOURCE)
528 fprintf(out,
529 " AddResource(lh);\n"
533 fprintf(out,
534 " return lh;\n"
535 " }\n"
536 "\n"
537 " AROS_USERFUNC_EXIT\n"
538 "}\n"
539 "\n"
544 static void writeopenlib(FILE *out, struct config *cfg)
546 switch (cfg->modtype)
548 case RESOURCE:
549 fprintf(stderr, "Internal error: writeopenlib called for a resource\n");
550 break;
551 case DEVICE:
552 fprintf(out,
553 "AROS_LH3 (void, GM_UNIQUENAME(OpenLib),\n"
554 " AROS_LHA(struct IORequest *, ioreq, A1),\n"
555 " AROS_LHA(ULONG, unitnum, D0),\n"
556 " AROS_LHA(ULONG, flags, D1),\n"
557 " LIBBASETYPEPTR, lh, 1, %s\n"
558 ")\n",
559 cfg->basename
561 fprintf(out,
562 "{\n"
563 " AROS_LIBFUNC_INIT\n"
564 "\n"
565 " if ( set_call_libfuncs(SETNAME(OPENLIB), 1, 1, lh)\n"
566 " && set_call_devfuncs(SETNAME(OPENDEV), 1, 1, lh, ioreq, unitnum, flags)\n"
567 " )\n"
568 " {\n"
569 " ((struct Library *)lh)->lib_OpenCnt++;\n"
570 " ((struct Library *)lh)->lib_Flags &= ~LIBF_DELEXP;\n"
571 "\n"
572 " ioreq->io_Message.mn_Node.ln_Type = NT_REPLYMSG;\n"
573 " }\n"
574 " else\n"
575 " {\n"
576 " if (ioreq->io_Error >= 0)\n"
577 " ioreq->io_Error = IOERR_OPENFAIL;\n"
578 " }\n"
579 "\n"
580 " return;\n"
581 "\n"
582 " AROS_LIBFUNC_EXIT\n"
583 "}\n"
584 "\n"
586 break;
587 default:
588 fprintf(out,
589 "AROS_LH1 (LIBBASETYPEPTR, GM_UNIQUENAME(OpenLib),\n"
590 " AROS_LHA (ULONG, version, D0),\n"
591 " LIBBASETYPEPTR, lh, 1, %s\n"
592 ")\n"
593 "{\n"
594 " AROS_LIBFUNC_INIT\n"
595 "\n",
596 cfg->basename
598 if (!(cfg->options & OPTION_DUPBASE))
600 fprintf(out,
601 " if ( set_call_libfuncs(SETNAME(OPENLIB), 1, 1, lh) )\n"
602 " {\n"
603 " ((struct Library *)lh)->lib_OpenCnt++;\n"
604 " ((struct Library *)lh)->lib_Flags &= ~LIBF_DELEXP;\n"
605 "\n"
606 " return lh;\n"
607 " }\n"
608 "\n"
609 " return NULL;\n"
610 "\n"
611 " AROS_LIBFUNC_EXIT\n"
612 "}\n"
613 "\n"
616 else
618 fprintf(out,
619 " struct Library *newlib;\n"
620 " UWORD possize = ((struct Library *)lh)->lib_PosSize;\n"
621 "\n"
622 " newlib = MakeLibrary(GM_UNIQUENAME(InitTable).FuncTable,\n"
623 " GM_UNIQUENAME(InitTable).DataTable,\n"
624 " NULL,\n"
625 " GM_UNIQUENAME(InitTable).Size,\n"
626 " (BPTR)NULL\n"
627 " );\n"
628 " if (newlib == NULL)\n"
629 " return 0;\n"
630 "\n"
631 " CopyMem(lh, newlib, possize);\n"
632 "\n"
633 " if ( set_call_libfuncs(SETNAME(OPENLIB), 1, 1, newlib) )\n"
634 " {\n"
635 " ((struct Library *)lh)->lib_OpenCnt++;\n"
636 " ((struct Library *)lh)->lib_Flags &= ~LIBF_DELEXP;\n"
637 "\n"
638 " return newlib;\n"
639 " }\n"
640 " else\n"
641 " {\n"
642 " __freebase(newlib);\n"
643 " return NULL;\n"
644 " }\n"
645 "\n"
646 " AROS_LIBFUNC_EXIT\n"
647 "}\n"
648 "\n"
655 static void writecloselib(FILE *out, struct config *cfg)
657 if (cfg->modtype != DEVICE)
658 fprintf(out,
659 "AROS_LH0 (BPTR, GM_UNIQUENAME(CloseLib),\n"
660 " LIBBASETYPEPTR, lh, 2, %s\n"
661 ")\n",
662 cfg->basename
664 else
665 fprintf(out,
666 "AROS_LH1(BPTR, GM_UNIQUENAME(CloseLib),\n"
667 " AROS_LHA(struct IORequest *, ioreq, A1),\n"
668 " LIBBASETYPEPTR, lh, 2, %s\n"
669 ")\n",
670 cfg->basename
673 fprintf(out,
674 "{\n"
675 " AROS_LIBFUNC_INIT\n"
676 "\n"
678 if (cfg->modtype == DEVICE)
679 fprintf(out,
680 " if (!set_call_devfuncs(SETNAME(CLOSEDEV), -1, 1, lh, ioreq, 0, 0));\n"
681 " return NULL;\n"
683 if (!(cfg->options & OPTION_DUPBASE))
685 fprintf(out,
686 " ((struct Library *)lh)->lib_OpenCnt--;\n"
687 " set_call_libfuncs(SETNAME(CLOSELIB), -1, 0, lh);\n"
690 else
692 fprintf(out,
693 " if (lh != GM_ROOTBASE_FIELD(lh))\n"
694 " {\n"
695 " LIBBASETYPEPTR rootbase = GM_ROOTBASE_FIELD(lh);\n"
696 " set_call_libfuncs(SETNAME(CLOSELIB), -1, 0, lh);\n"
697 " __freebase(lh);\n"
698 " lh = rootbase;\n"
699 " }\n"
700 " ((struct Library *)lh)->lib_OpenCnt--;\n"
701 "\n"
704 if (!(cfg->options & OPTION_NOEXPUNGE))
705 fprintf(out,
706 " if\n"
707 " (\n"
708 " (((struct Library *)lh)->lib_OpenCnt == 0)\n"
709 " && (((struct Library *)lh)->lib_Flags & LIBF_DELEXP)\n"
710 " )\n"
711 " {\n"
712 " return AROS_LC1(BPTR, GM_UNIQUENAME(ExpungeLib),\n"
713 " AROS_LCA(LIBBASETYPEPTR, lh, D0),\n"
714 " struct ExecBase *, SysBase, 3, %s\n"
715 " );\n"
716 " }\n",
717 cfg->basename
719 fprintf(out,
720 "\n"
721 " return NULL;\n"
722 "\n"
723 " AROS_LIBFUNC_EXIT\n"
724 "}\n"
725 "\n"
730 static void writeexpungelib(FILE *out, struct config *cfg)
732 fprintf(out,
733 "AROS_LH1 (BPTR, GM_UNIQUENAME(ExpungeLib),\n"
734 " AROS_LHA(LIBBASETYPEPTR, lh, D0),\n"
735 " struct ExecBase *, SysBase, 3, %s\n"
736 ")\n",
737 cfg->basename
739 fprintf(out,
740 "{\n"
741 " AROS_LIBFUNC_INIT\n"
742 "\n"
744 if (!(cfg->options & OPTION_NOEXPUNGE))
746 fprintf(out,
747 "\n"
748 " if ( ((struct Library *)lh)->lib_OpenCnt == 0 )\n"
749 " {\n"
750 " BPTR seglist = GM_SEGLIST_FIELD(lh);\n"
751 "\n"
752 " if(!set_call_libfuncs(SETNAME(EXPUNGELIB), -1, 1, lh))\n"
753 " {\n"
754 " ((struct Library *)lh)->lib_Flags |= LIBF_DELEXP;\n"
755 " return NULL;\n"
756 " }\n"
757 "\n"
758 " Remove((struct Node *)lh);\n"
759 "\n"
760 " set_call_funcs(SETNAME(DTORS), 1, 0);\n"
761 " set_call_funcs(SETNAME(EXIT), -1, 0);\n"
763 if (cfg->classlist != NULL)
764 fprintf(out, " set_call_libfuncs(SETNAME(CLASSESEXPUNGE), -1, 0, lh);\n");
765 if (!(cfg->options & OPTION_NOAUTOLIB))
766 fprintf(out, " set_close_libraries();\n");
767 fprintf(out,
768 "\n"
769 " __freebase(lh);\n"
770 "\n"
771 " return seglist;\n"
772 " }\n"
773 "\n"
774 " ((struct Library *)lh)->lib_Flags |= LIBF_DELEXP;\n"
777 fprintf(out,
778 "\n"
779 " return NULL;\n"
780 "\n"
781 " AROS_LIBFUNC_EXIT\n"
782 "}\n"
783 "\n"
788 static void writeextfunclib(FILE *out, struct config *cfg)
790 fprintf(out,
791 "AROS_LH0 (LIBBASETYPEPTR, GM_UNIQUENAME(ExtFuncLib),\n"
792 " LIBBASETYPEPTR, lh, 4, %s\n"
793 ")\n"
794 "{\n"
795 " AROS_LIBFUNC_INIT\n"
796 " return NULL;\n"
797 " AROS_LIBFUNC_EXIT\n"
798 "}\n"
799 "\n",
800 cfg->basename
805 static void
806 writefunctable(FILE *out,
807 struct config *cfg
810 struct functionhead *funclistit;
811 struct functionarg *arglistit;
812 unsigned int lvo;
813 int i;
814 char *name, *type;
816 /* lvo contains the number of functions already printed in the functable */
817 lvo = 0;
819 if (!(cfg->options & OPTION_NORESIDENT))
821 fprintf(out,
822 "\n"
823 "const APTR GM_UNIQUENAME(FuncTable)[]=\n"
824 "{\n"
826 if (cfg->modtype != RESOURCE)
828 fprintf(out,
829 " &AROS_SLIB_ENTRY(GM_UNIQUENAME(OpenLib),%s),\n"
830 " &AROS_SLIB_ENTRY(GM_UNIQUENAME(CloseLib),%s),\n"
831 " &AROS_SLIB_ENTRY(GM_UNIQUENAME(ExpungeLib),%s),\n"
832 " &AROS_SLIB_ENTRY(GM_UNIQUENAME(ExtFuncLib),%s),\n",
833 cfg->basename, cfg->basename, cfg->basename, cfg->basename
835 lvo += 4;
837 if (cfg->modtype == MCC || cfg->modtype == MUI || cfg->modtype == MCP)
839 fprintf(out,
840 " &AROS_SLIB_ENTRY(MCC_Query,%s),\n",
841 cfg->basename
843 lvo++;
845 else if (cfg->modtype == DATATYPE)
847 fprintf(out,
848 " &AROS_SLIB_ENTRY(ObtainEngine,%s),\n",
849 cfg->basename
851 lvo++;
853 funclistit = cfg->funclist;
855 else /* NORESIDENT */
857 if (cfg->modtype != RESOURCE)
859 int neednull = 0;
860 struct functionhead *funclistit2;
862 funclistit = cfg->funclist;
863 if (funclistit->lvo != 1)
865 fprintf(stderr, "Module without a generated resident structure has to provide the Open function (LVO==1)\n");
866 exit(20);
868 else
869 funclistit = funclistit->next;
871 if (funclistit->lvo != 2)
873 fprintf(stderr, "Module without a generated resident structure has to provide the Close function (LVO==2)\n");
874 exit(20);
876 else
877 funclistit = funclistit->next;
879 if (funclistit->lvo == 3)
880 funclistit = funclistit->next;
881 else
882 neednull = 1;
884 if (funclistit->lvo == 4)
885 funclistit = funclistit->next;
886 else
887 neednull = 1;
889 if (neednull)
890 fprintf(out,
891 "\n"
892 "AROS_UFH1(static int, %s_null,\n"
893 " AROS_UFHA(struct Library *, libbase, A6)\n"
894 ")\n"
895 "{\n"
896 " AROS_USERFUNC_INIT\n"
897 " return 0;\n"
898 " AROS_USERFUNC_EXIT\n"
899 "}\n",
900 cfg->modulename
903 funclistit = cfg->funclist;
904 funclistit2 = funclistit->next;
905 fprintf(out,
906 "\n"
907 "const APTR GM_UNIQUENAME(FuncTable)[]=\n"
908 "{\n"
909 " &AROS_SLIB_ENTRY(%s,%s),\n"
910 " &AROS_SLIB_ENTRY(%s,%s),\n",
911 funclistit->name, cfg->basename,
912 funclistit2->name, cfg->basename
914 lvo += 2;
915 funclistit = funclistit2->next;
917 if (funclistit->lvo == 3)
919 fprintf(out, " &AROS_SLIB_ENTRY(%s,%s),\n",
920 funclistit->name, cfg->basename
922 funclistit = funclistit->next;
924 else
925 fprintf(out, " &%s_null,\n", cfg->modulename);
926 lvo++;
928 if (funclistit->lvo == 4)
930 fprintf(out, " &AROS_SLIB_ENTRY(%s,%s),\n",
931 funclistit->name, cfg->basename
933 funclistit = funclistit->next;
935 else
936 fprintf(out, " &%s_null,\n", cfg->modulename);
937 lvo++;
941 while (funclistit != NULL)
943 for (i = lvo+1; i<funclistit->lvo; i++)
944 fprintf(out, " NULL,\n");
945 lvo = funclistit->lvo;
947 switch (funclistit->libcall)
949 case STACK:
950 fprintf(out, " &%s,\n", funclistit->name);
951 break;
953 case REGISTER:
954 case REGISTERMACRO:
955 fprintf(out, " &AROS_SLIB_ENTRY(%s,%s),\n", funclistit->name, cfg->basename);
956 break;
958 default:
959 fprintf(stderr, "Internal error: unhandled libcall type in writestart\n");
960 exit(20);
961 break;
964 funclistit = funclistit->next;
967 fprintf(out, " (void *)-1\n};\n");
971 static void writesets(FILE *out, struct config *cfg)
973 fprintf(out,
974 "DEFINESET(INIT)\n"
975 "DEFINESET(EXIT)\n"
976 "DEFINESET(CTORS)\n"
977 "DEFINESET(DTORS)\n"
978 "DEFINESET(INITLIB)\n"
979 "DEFINESET(EXPUNGELIB)\n"
980 "DEFINESET(OPENLIB)\n"
981 "DEFINESET(CLOSELIB)\n"
982 "DEFINESET(OPENDEV)\n"
983 "DEFINESET(CLOSEDEV)\n"
985 if (cfg->classlist != NULL)
986 fprintf(out,
987 "DEFINESET(CLASSESINIT)\n"
988 "DEFINESET(CLASSESEXPUNGE)\n"
990 fprintf(out, "\n");