xref: /minix/external/mit/expat/dist/amiga/expat_lib.c (revision e3b78ef1)
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