diff options
Diffstat (limited to 'expat/amiga/expat_lib.c')
-rw-r--r-- | expat/amiga/expat_lib.c | 247 |
1 files changed, 247 insertions, 0 deletions
diff --git a/expat/amiga/expat_lib.c b/expat/amiga/expat_lib.c new file mode 100644 index 000000000..70e91b101 --- /dev/null +++ b/expat/amiga/expat_lib.c @@ -0,0 +1,247 @@ +/* +** Copyright (c) 2001-2009 Expat maintainers. +** +** Permission is hereby granted, free of charge, to any person obtaining +** a copy of this software and associated documentation files (the +** "Software"), to deal in the Software without restriction, including +** without limitation the rights to use, copy, modify, merge, publish, +** distribute, sublicense, and/or sell copies of the Software, and to +** permit persons to whom the Software is furnished to do so, subject to +** the following conditions: +** +** The above copyright notice and this permission notice shall be included +** in all copies or substantial portions of the Software. +** +** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +** SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#ifdef __USE_INLINE__ +#undef __USE_INLINE__ +#endif + +#define __NOLIBBASE__ +#define __NOGLOBALIFACE__ + +#include <dos/dos.h> +#include <proto/exec.h> + +#include "expat_base.h" + + +#define LIBNAME "expat.library" +#define LIBPRI 0 +#define VERSION 53 +#define REVISION 1 +#define VSTRING "expat.library 53.1 (7.8.2009)" /* dd.mm.yyyy */ + + +static const char* __attribute__((used)) verstag = "\0$VER: " VSTRING; + + +struct Interface *INewlib = 0; + + +struct ExpatBase * libInit(struct ExpatBase *libBase, BPTR seglist, struct ExecIFace *ISys); +uint32 libObtain (struct LibraryManagerInterface *Self); +uint32 libRelease (struct LibraryManagerInterface *Self); +struct ExpatBase *libOpen (struct LibraryManagerInterface *Self, uint32 version); +BPTR libClose (struct LibraryManagerInterface *Self); +BPTR libExpunge (struct LibraryManagerInterface *Self); +struct Interface *openInterface(struct ExecIFace *IExec, CONST_STRPTR libName, uint32 libVer); +void closeInterface(struct ExecIFace *IExec, struct Interface *iface); + + +static APTR lib_manager_vectors[] = { + libObtain, + libRelease, + NULL, + NULL, + libOpen, + libClose, + libExpunge, + NULL, + (APTR)-1, +}; + + +static struct TagItem lib_managerTags[] = { + { MIT_Name, (uint32)"__library" }, + { MIT_VectorTable, (uint32)lib_manager_vectors }, + { MIT_Version, 1 }, + { TAG_END, 0 } +}; + + +extern void *main_vectors[]; + +static struct TagItem lib_mainTags[] = { + { MIT_Name, (uint32)"main" }, + { MIT_VectorTable, (uint32)main_vectors }, + { MIT_Version, 1 }, + { TAG_END, 0 } +}; + + +static APTR libInterfaces[] = { + lib_managerTags, + lib_mainTags, + NULL +}; + + +extern void *VecTable68K[]; + +static struct TagItem libCreateTags[] = { + { CLT_DataSize, sizeof(struct ExpatBase) }, + { CLT_InitFunc, (uint32)libInit }, + { CLT_Interfaces, (uint32)libInterfaces }, + { CLT_Vector68K, (uint32)VecTable68K }, + { TAG_END, 0 } +}; + + +static struct Resident __attribute__((used)) lib_res = { + RTC_MATCHWORD, // rt_MatchWord + &lib_res, // rt_MatchTag + &lib_res+1, // rt_EndSkip + RTF_NATIVE | RTF_AUTOINIT, // rt_Flags + VERSION, // rt_Version + NT_LIBRARY, // rt_Type + LIBPRI, // rt_Pri + LIBNAME, // rt_Name + VSTRING, // rt_IdString + libCreateTags // rt_Init +}; + + +int32 _start() +{ + return RETURN_FAIL; +} + + +struct ExpatBase *libInit(struct ExpatBase *libBase, BPTR seglist, struct ExecIFace *iexec) +{ + libBase->libNode.lib_Node.ln_Type = NT_LIBRARY; + libBase->libNode.lib_Node.ln_Pri = LIBPRI; + libBase->libNode.lib_Node.ln_Name = LIBNAME; + libBase->libNode.lib_Flags = LIBF_SUMUSED|LIBF_CHANGED; + libBase->libNode.lib_Version = VERSION; + libBase->libNode.lib_Revision = REVISION; + libBase->libNode.lib_IdString = VSTRING; + + libBase->SegList = seglist; + + libBase->IExec = iexec; + INewlib = openInterface(iexec, "newlib.library", 0); + + if ( INewlib != 0 ) { + return libBase; + } + + closeInterface(iexec, INewlib); + INewlib = 0; + + iexec->DeleteLibrary(&libBase->libNode); + + return NULL; +} + + +uint32 libObtain( struct LibraryManagerInterface *Self ) +{ + ++Self->Data.RefCount; + return Self->Data.RefCount; +} + + +uint32 libRelease( struct LibraryManagerInterface *Self ) +{ + --Self->Data.RefCount; + return Self->Data.RefCount; +} + + +struct ExpatBase *libOpen( struct LibraryManagerInterface *Self, uint32 version ) +{ + struct ExpatBase *libBase; + + libBase = (struct ExpatBase *)Self->Data.LibBase; + + ++libBase->libNode.lib_OpenCnt; + libBase->libNode.lib_Flags &= ~LIBF_DELEXP; + + return libBase; +} + + +BPTR libClose( struct LibraryManagerInterface *Self ) +{ + struct ExpatBase *libBase; + + libBase = (struct ExpatBase *)Self->Data.LibBase; + + --libBase->libNode.lib_OpenCnt; + if ( libBase->libNode.lib_OpenCnt ) { + return 0; + } + + if ( libBase->libNode.lib_Flags & LIBF_DELEXP ) { + return (BPTR)Self->LibExpunge(); + } + else { + return ZERO; + } +} + + +BPTR libExpunge( struct LibraryManagerInterface *Self ) +{ + struct ExpatBase *libBase = (struct ExpatBase *)Self->Data.LibBase; + BPTR result = ZERO; + + if (libBase->libNode.lib_OpenCnt == 0) { + libBase->IExec->Remove(&libBase->libNode.lib_Node); + + result = libBase->SegList; + + closeInterface(libBase->IExec, INewlib); + INewlib = 0; + + libBase->IExec->DeleteLibrary(&libBase->libNode); + } + else { + libBase->libNode.lib_Flags |= LIBF_DELEXP; + } + + return result; +} + + +struct Interface *openInterface(struct ExecIFace *IExec, CONST_STRPTR libName, uint32 libVer) +{ + struct Library *base = IExec->OpenLibrary(libName, libVer); + struct Interface *iface = IExec->GetInterface(base, "main", 1, 0); + if (iface == 0) { + IExec->CloseLibrary(base); + } + + return iface; +} + + +void closeInterface(struct ExecIFace *IExec, struct Interface *iface) +{ + if (iface != 0) + { + struct Library *base = iface->Data.LibBase; + IExec->DropInterface(iface); + IExec->CloseLibrary(base); + } +} |