Home | History | Annotate | Download | only in amiga
      1 /*
      2 ** Copyright (c) 2001-2009 Expat maintainers.
      3 **
      4 ** Permission is hereby granted, free of charge, to any person obtaining
      5 ** a copy of this software and associated documentation files (the
      6 ** "Software"), to deal in the Software without restriction, including
      7 ** without limitation the rights to use, copy, modify, merge, publish,
      8 ** distribute, sublicense, and/or sell copies of the Software, and to
      9 ** permit persons to whom the Software is furnished to do so, subject to
     10 ** the following conditions:
     11 **
     12 ** The above copyright notice and this permission notice shall be included
     13 ** in all copies or substantial portions of the Software.
     14 **
     15 ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
     16 ** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
     17 ** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
     18 ** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
     19 ** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
     20 ** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
     21 ** SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
     22 */
     23 
     24 #ifdef __USE_INLINE__
     25 #undef __USE_INLINE__
     26 #endif
     27 
     28 #define __NOLIBBASE__
     29 #define __NOGLOBALIFACE__
     30 
     31 #include <dos/dos.h>
     32 #include <proto/exec.h>
     33 
     34 #include "expat_base.h"
     35 
     36 
     37 #define LIBNAME		"expat.library"
     38 #define LIBPRI		0
     39 #define VERSION		53
     40 #define REVISION	1
     41 #define VSTRING		"expat.library 53.1 (7.8.2009)"  /* dd.mm.yyyy */
     42 
     43 
     44 static const char* __attribute__((used)) verstag = "\0$VER: " VSTRING;
     45 
     46 
     47 struct Interface *INewlib = 0;
     48 
     49 
     50 struct ExpatBase * libInit(struct ExpatBase *libBase, BPTR seglist, struct ExecIFace *ISys);
     51 uint32 libObtain (struct LibraryManagerInterface *Self);
     52 uint32 libRelease (struct LibraryManagerInterface *Self);
     53 struct ExpatBase *libOpen (struct LibraryManagerInterface *Self, uint32 version);
     54 BPTR libClose (struct LibraryManagerInterface *Self);
     55 BPTR libExpunge (struct LibraryManagerInterface *Self);
     56 struct Interface *openInterface(struct ExecIFace *IExec, CONST_STRPTR libName, uint32 libVer);
     57 void closeInterface(struct ExecIFace *IExec, struct Interface *iface);
     58 
     59 
     60 static APTR lib_manager_vectors[] = {
     61 	libObtain,
     62 	libRelease,
     63 	NULL,
     64 	NULL,
     65 	libOpen,
     66 	libClose,
     67 	libExpunge,
     68 	NULL,
     69 	(APTR)-1,
     70 };
     71 
     72 
     73 static struct TagItem lib_managerTags[] = {
     74 	{ MIT_Name, (uint32)"__library" },
     75 	{ MIT_VectorTable, (uint32)lib_manager_vectors },
     76 	{ MIT_Version, 1 },
     77 	{ TAG_END, 0 }
     78 };
     79 
     80 
     81 extern void *main_vectors[];
     82 
     83 static struct TagItem lib_mainTags[] = {
     84 	{ MIT_Name, (uint32)"main" },
     85 	{ MIT_VectorTable, (uint32)main_vectors },
     86 	{ MIT_Version, 1 },
     87 	{ TAG_END, 0 }
     88 };
     89 
     90 
     91 static APTR libInterfaces[] = {
     92 	lib_managerTags,
     93 	lib_mainTags,
     94 	NULL
     95 };
     96 
     97 
     98 extern void *VecTable68K[];
     99 
    100 static struct TagItem libCreateTags[] = {
    101 	{ CLT_DataSize, sizeof(struct ExpatBase) },
    102 	{ CLT_InitFunc, (uint32)libInit },
    103 	{ CLT_Interfaces, (uint32)libInterfaces },
    104 	{ CLT_Vector68K, (uint32)VecTable68K },
    105 	{ TAG_END, 0 }
    106 };
    107 
    108 
    109 static struct Resident __attribute__((used)) lib_res = {
    110 	RTC_MATCHWORD,	// rt_MatchWord
    111 	&lib_res,		// rt_MatchTag
    112 	&lib_res+1,		// rt_EndSkip
    113 	RTF_NATIVE | RTF_AUTOINIT,	// rt_Flags
    114 	VERSION,		// rt_Version
    115 	NT_LIBRARY,		// rt_Type
    116 	LIBPRI,			// rt_Pri
    117 	LIBNAME,		// rt_Name
    118 	VSTRING,		// rt_IdString
    119 	libCreateTags	// rt_Init
    120 };
    121 
    122 
    123 int32 _start()
    124 {
    125 	return RETURN_FAIL;
    126 }
    127 
    128 
    129 struct ExpatBase *libInit(struct ExpatBase *libBase, BPTR seglist, struct ExecIFace *iexec)
    130 {
    131 	libBase->libNode.lib_Node.ln_Type = NT_LIBRARY;
    132 	libBase->libNode.lib_Node.ln_Pri = LIBPRI;
    133 	libBase->libNode.lib_Node.ln_Name = LIBNAME;
    134 	libBase->libNode.lib_Flags = LIBF_SUMUSED|LIBF_CHANGED;
    135 	libBase->libNode.lib_Version = VERSION;
    136 	libBase->libNode.lib_Revision = REVISION;
    137 	libBase->libNode.lib_IdString = VSTRING;
    138 
    139 	libBase->SegList = seglist;
    140 
    141 	libBase->IExec = iexec;
    142 	INewlib        = openInterface(iexec, "newlib.library", 0);
    143 
    144 	if ( INewlib != 0 )  {
    145 		return libBase;
    146 	}
    147 
    148 	closeInterface(iexec, INewlib);
    149 	INewlib = 0;
    150 
    151 	iexec->DeleteLibrary(&libBase->libNode);
    152 
    153 	return NULL;
    154 }
    155 
    156 
    157 uint32 libObtain( struct LibraryManagerInterface *Self )
    158 {
    159 	++Self->Data.RefCount;
    160 	return Self->Data.RefCount;
    161 }
    162 
    163 
    164 uint32 libRelease( struct LibraryManagerInterface *Self )
    165 {
    166 	--Self->Data.RefCount;
    167 	return Self->Data.RefCount;
    168 }
    169 
    170 
    171 struct ExpatBase *libOpen( struct LibraryManagerInterface *Self, uint32 version )
    172 {
    173 	struct ExpatBase *libBase;
    174 
    175 	libBase = (struct ExpatBase *)Self->Data.LibBase;
    176 
    177 	++libBase->libNode.lib_OpenCnt;
    178 	libBase->libNode.lib_Flags &= ~LIBF_DELEXP;
    179 
    180 	return libBase;
    181 }
    182 
    183 
    184 BPTR libClose( struct LibraryManagerInterface *Self )
    185 {
    186 	struct ExpatBase *libBase;
    187 
    188 	libBase = (struct ExpatBase *)Self->Data.LibBase;
    189 
    190 	--libBase->libNode.lib_OpenCnt;
    191 	if ( libBase->libNode.lib_OpenCnt ) {
    192 		return 0;
    193 	}
    194 
    195 	if ( libBase->libNode.lib_Flags & LIBF_DELEXP ) {
    196 		return (BPTR)Self->LibExpunge();
    197 	}
    198 	else {
    199 		return ZERO;
    200 	}
    201 }
    202 
    203 
    204 BPTR libExpunge( struct LibraryManagerInterface *Self )
    205 {
    206 	struct ExpatBase *libBase = (struct ExpatBase *)Self->Data.LibBase;
    207 	BPTR result = ZERO;
    208 
    209 	if (libBase->libNode.lib_OpenCnt == 0) {
    210 		libBase->IExec->Remove(&libBase->libNode.lib_Node);
    211 
    212 		result = libBase->SegList;
    213 
    214 		closeInterface(libBase->IExec, INewlib);
    215 		INewlib = 0;
    216 
    217 		libBase->IExec->DeleteLibrary(&libBase->libNode);
    218 	}
    219 	else {
    220 		libBase->libNode.lib_Flags |= LIBF_DELEXP;
    221 	}
    222 
    223 	return result;
    224 }
    225 
    226 
    227 struct Interface *openInterface(struct ExecIFace *IExec, CONST_STRPTR libName, uint32 libVer)
    228 {
    229 	struct Library *base = IExec->OpenLibrary(libName, libVer);
    230 	struct Interface *iface = IExec->GetInterface(base, "main", 1, 0);
    231 	if (iface == 0) {
    232 		IExec->CloseLibrary(base);
    233 	}
    234 
    235 	return iface;
    236 }
    237 
    238 
    239 void closeInterface(struct ExecIFace *IExec, struct Interface *iface)
    240 {
    241 	if (iface != 0)
    242 	{
    243 		struct Library *base = iface->Data.LibBase;
    244 		IExec->DropInterface(iface);
    245 		IExec->CloseLibrary(base);
    246 	}
    247 }
    248