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