Merge branch 'vendor/EXPAT'
[dragonfly.git] / contrib / expat / amiga / expat_lib.c
1 /*
2 ** Copyright (c) 2001-2007 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 #include <dos/dos.h>
25 #include <proto/exec.h>
26
27 #define LIBNAME         "expat.library"
28 #define LIBPRI          0
29 #define VERSION         4
30 #define REVISION        2
31 #define VSTRING         "expat.library 4.2 (2.6.2007)"  /* dd.mm.yyyy */
32
33
34 static const char* __attribute__((used)) verstag = "\0$VER: " VSTRING;
35
36
37 struct ExpatBase {
38         struct Library libNode;
39         uint16 pad;
40         BPTR SegList;
41 };
42
43
44 struct ExpatBase * libInit(struct ExpatBase *libBase, BPTR seglist, struct ExecIFace *ISys);
45 uint32 libObtain (struct LibraryManagerInterface *Self);
46 uint32 libRelease (struct LibraryManagerInterface *Self);
47 struct ExpatBase *libOpen (struct LibraryManagerInterface *Self, uint32 version);
48 BPTR libClose (struct LibraryManagerInterface *Self);
49 BPTR libExpunge (struct LibraryManagerInterface *Self);
50
51
52 static APTR lib_manager_vectors[] = {
53         libObtain,
54         libRelease,
55         NULL,
56         NULL,
57         libOpen,
58         libClose,
59         libExpunge,
60         NULL,
61         (APTR)-1,
62 };
63
64
65 static struct TagItem lib_managerTags[] = {
66         { MIT_Name, (uint32)"__library" },
67         { MIT_VectorTable, (uint32)lib_manager_vectors },
68         { MIT_Version, 1 },
69         { TAG_END, 0 }
70 };
71
72
73 extern void *main_vectors[];
74
75 static struct TagItem lib_mainTags[] = {
76         { MIT_Name, (uint32)"main" },
77         { MIT_VectorTable, (uint32)main_vectors },
78         { MIT_Version, 1 },
79         { TAG_END, 0 }
80 };
81
82
83 static APTR libInterfaces[] = {
84         lib_managerTags,
85         lib_mainTags,
86         NULL
87 };
88
89
90 static struct TagItem libCreateTags[] = {
91         { CLT_DataSize, sizeof(struct ExpatBase) },
92         { CLT_InitFunc, (uint32)libInit },
93         { CLT_Interfaces, (uint32)libInterfaces },
94         { TAG_END, 0 }
95 };
96
97
98 static struct Resident __attribute__((used)) lib_res = {
99         RTC_MATCHWORD,  // rt_MatchWord
100         &lib_res,               // rt_MatchTag
101         &lib_res+1,             // rt_EndSkip
102         RTF_NATIVE | RTF_AUTOINIT,      // rt_Flags
103         VERSION,                // rt_Version
104         NT_LIBRARY,             // rt_Type
105         LIBPRI,                 // rt_Pri
106         LIBNAME,                // rt_Name
107         VSTRING,                // rt_IdString
108         libCreateTags   // rt_Init
109 };
110
111
112 struct Library *DOSLib = 0;
113 struct Library *UtilityBase = 0;
114
115 struct ExecIFace *IExec = 0;
116 struct DOSIFace *IDOS = 0;
117 struct UtilityIFace *IUtility = 0;
118
119
120 void _start()
121 {
122 }
123
124
125 struct ExpatBase *libInit(struct ExpatBase *libBase, BPTR seglist, struct ExecIFace *ISys)
126 {
127         libBase->libNode.lib_Node.ln_Type = NT_LIBRARY;
128         libBase->libNode.lib_Node.ln_Pri = LIBPRI;
129         libBase->libNode.lib_Node.ln_Name = LIBNAME;
130         libBase->libNode.lib_Flags = LIBF_SUMUSED|LIBF_CHANGED;
131         libBase->libNode.lib_Version = VERSION;
132         libBase->libNode.lib_Revision = REVISION;
133         libBase->libNode.lib_IdString = VSTRING;
134         libBase->SegList = seglist;
135
136         IExec = ISys;
137
138         DOSLib = OpenLibrary("dos.library", 51);
139         if ( DOSLib != 0 )  {
140                 IDOS = (struct DOSIFace *)GetInterface(DOSLib, "main", 1, NULL);
141                 if ( IDOS != 0 )  {
142                         UtilityBase = OpenLibrary("utility.library", 51);
143                         if ( UtilityBase != 0 )  {
144                                 IUtility = (struct UtilityIFace*)GetInterface(UtilityBase, "main", 1, NULL);
145                                 if ( IUtility != 0 )  {
146                                         return libBase;
147                                 }
148
149                                 CloseLibrary(UtilityBase);
150                         }
151
152                         DropInterface((struct Interface *)IDOS);
153                 }
154
155                 CloseLibrary(DOSLib);
156         }
157
158         return NULL;
159 }
160
161
162 uint32 libObtain( struct LibraryManagerInterface *Self )
163 {
164         ++Self->Data.RefCount;
165         return Self->Data.RefCount;
166 }
167
168
169 uint32 libRelease( struct LibraryManagerInterface *Self )
170 {
171         --Self->Data.RefCount;
172         return Self->Data.RefCount;
173 }
174
175
176 struct ExpatBase *libOpen( struct LibraryManagerInterface *Self, uint32 version )
177 {
178         struct ExpatBase *libBase;
179
180         libBase = (struct ExpatBase *)Self->Data.LibBase;
181
182         ++libBase->libNode.lib_OpenCnt;
183         libBase->libNode.lib_Flags &= ~LIBF_DELEXP;
184
185         return libBase;
186 }
187
188
189 BPTR libClose( struct LibraryManagerInterface *Self )
190 {
191         struct ExpatBase *libBase;
192
193         libBase = (struct ExpatBase *)Self->Data.LibBase;
194
195         --libBase->libNode.lib_OpenCnt;
196         if ( libBase->libNode.lib_OpenCnt ) {
197                 return 0;
198         }
199
200         if ( libBase->libNode.lib_Flags & LIBF_DELEXP ) {
201                 return (BPTR)Self->LibExpunge();
202         }
203         else {
204                 return 0;
205         }
206 }
207
208
209 BPTR libExpunge( struct LibraryManagerInterface *Self )
210 {
211         struct ExpatBase *libBase;
212         BPTR result = 0;
213
214         libBase = (struct ExpatBase *)Self->Data.LibBase;
215
216         if (libBase->libNode.lib_OpenCnt == 0) {
217                 Remove(&libBase->libNode.lib_Node);
218
219                 result = libBase->SegList;
220
221                 DropInterface((struct Interface *)IUtility);
222                 CloseLibrary(UtilityBase);
223                 DropInterface((struct Interface *)IDOS);
224                 CloseLibrary(DOSLib);
225
226                 DeleteLibrary(&libBase->libNode);
227         }
228         else {
229                 libBase->libNode.lib_Flags |= LIBF_DELEXP;
230         }
231
232         return result;
233 }