doh - add the warn flags to the correct cflags.
[AROS.git] / test / sdi / SDI_hook.h
blob049bcf0799de42820ee0e4c41d08f30deda2fdc5
1 #ifndef SDI_HOOK_H
2 #define SDI_HOOK_H
4 /* Includeheader
6 Name: SDI_hook.h
7 Versionstring: $VER: SDI_hook.h 1.27 (04.04.2015)
8 Authors: Dirk Stoecker, Jens Maus
9 Distribution: PD
10 Project page: https://github.com/adtools/SDI
11 Description: defines to hide compiler specific hook stuff
13 1.0 21.06.02 : based on the work made for freeciv and YAM with
14 additional texts partly taken from YAM_hook.h changes made
15 by Jens Langner, largely reworked the mechanism
16 1.1 07.10.02 : added HOOKPROTONP and HOOKPROTONONP requested by Jens
17 1.2 18.10.02 : reverted to old MorphOS-method for GCC
18 1.3 08.02.04 : modified to get it compatible to AmigaOS4
19 1.4 17.02.04 : modified to get compatible to latest SDI_compiler.h changes
20 1.5 02.03.04 : added UNUSED define to OS4 hook specification so that the
21 compiler can ignore some warnings.
22 1.6 02.03.04 : added (APTR) casts to MorphOS prototype definition to
23 reduce compiler warnings.
24 1.7 04.07.04 : removed static from all DISPATCHERPROTO definitions as there
25 may be dispatchers that are of course non static.
26 1.8 07.04.05 : added MakeHookWithData (Sebastian Bauer)
27 1.9 08.04.05 : changed MorphOS hooks to use HookEntry (Ilkka Lehtoranta)
28 1.10 16.05.05 : simplified and fixed for vbcc/MorphOS (Frank Wille)
29 1.11 17.05.05 : changed cast in DISPATCHERPROTO from (void(*)()) to APTR
30 cause SDI version of the EmulLibEntry uses APTR for easy
31 usage.
32 Added #ifndef SDI_TRAP_LIB to avoid double defines when
33 combining with SDI_interrupt.h or SDI_misc.h (Guido
34 Mersmann)
35 1.12 18.05.05 : DISPATCHERPROTO wasn't working, because of the missing REG_Ax
36 definitions. Added include <emul/emulregs.h> (Guido Mersmann)
37 1.13 11.12.05 : fixed a minor typo in the PPC HOOKPROTONP macro.
38 (Jens Langner)
39 1.14 20.04.06 : unified static of MorphOs with non-MorphOS vesion
40 1.15 30.04.06 : modified to get it compatible to AROS. (Guido Mersmann)
41 1.16 06.10.06 : added new DISPATCHER() macro and separated it from the
42 DISPATCHERPROTO() definition. Now the DISPATCHERPROTO() should
43 only be used to get the correct prototype and the plain
44 DISPATCHER() for defining the dispatcher itself.
45 1.17 14.07.08 : added "_" to all UNUSED variable specifications to make sure
46 a user does not use those definition on accident.
47 1.18 20.03.09 : modified macros to be somewhat more compatible for an AROS
48 usage (Pavel Fedin)
49 1.19 25.03.09 : fixed the DISPATCHERPROTO() macros for x86_64 AROS.
50 1.20 26.03.09 : fixed m68k define checks.
51 1.21 19.05.09 : added SDISPATCHER() to generate a static dispatcher.
52 1.22 24.06.10 : fixed AROS macros (Matthias Rustler).
53 1.23 12.08.10 : added missing proto/alib.h include for AROS
54 1.24 03.03.11 : fixed AROS macros for m68k (Jason McMullan)
55 1.25 18.07.12 : added crosscall macros for functions with 1 and 2 parameters.
56 These macros are to be used in case i.e. PPC code is to be called
57 from m68k code. The function pointer must be passed with ENTRY().
58 1.26 17.10.12 : added crosscall macros for functions with 1 and 2 parameters but
59 no return value.
60 1.27 04.04.15 : fixed HOOKPROTO for vbcc (Fredrik Wikstrom)
61 1.28 12.07.16 : fixed HOOKPROTO for vbcc (O. Sezer)
66 ** This is PD (Public Domain). This means you can do with it whatever you want
67 ** without any restrictions. I only ask you to tell me improvements, so I may
68 ** fix the main line of this files as well.
70 ** To keep confusion level low: When changing this file, please note it in
71 ** above history list and indicate that the change was not made by myself
72 ** (e.g. add your name or nick name).
74 ** Find the latest version of this file at:
75 ** https://github.com/adtools/SDI
77 ** Jens Maus <mail@jens-maus.de>
78 ** Dirk Stoecker <soft@dstoecker.de>
81 #include "SDI_compiler.h"
84 ** Hook macros to handle the creation of Hooks/Dispatchers for different
85 ** Operating System versions.
86 ** Currently AmigaOS, AROS, and MorphOS are supported.
88 ** For more information about hooks see include file <utility/hooks.h> or
89 ** the relevant descriptions in utility.library autodocs.
91 ** Example:
93 ** Creates a hook with the name "TestHook" that calls a corresponding
94 ** function "TestFunc" that will be called with a pointer "text"
95 ** (in register A1) and returns a long.
97 ** HOOKPROTONHNO(TestFunc, LONG, STRPTR text)
98 ** {
99 ** Printf(text);
100 ** return 0;
101 ** }
102 ** MakeHook(TestHook, TestFunc);
104 ** Every function that is created with HOOKPROTO* must have a MakeHook() or
105 ** MakeStaticHook() to create the corresponding hook. Best is to call this
106 ** directly after the hook function. This is required by the GCC macros.
108 ** The naming convention for the Hook Prototype macros is as followed:
110 ** HOOKPROTO[NH][NO][NP]
111 ** ^^ ^^ ^^
112 ** NoHook | NoParameter
113 ** NoObject
115 ** So a plain HOOKPROTO() creates you a Hook function that requires
116 ** 4 parameters, the "name" of the hookfunction, the "obj" in REG_A2,
117 ** the "param" in REG_A1 and a "hook" in REG_A0. Usually you will always
118 ** use NH, as the hook structure itself is nearly never required.
120 ** The DISPATCHERPROTO macro is for MUI dispatcher functions. It gets the
121 ** functionname as argument. To supply this function for use by MUI, use
122 ** The ENTRY macro, which also gets the function name as argument.
125 #if !defined(__AROS__) && (defined(_M68000) || defined(__M68000) || defined(__mc68000) || defined(__M68K__))
126 #define HOOKPROTO(name, ret, obj, param) static SAVEDS ASM ret \
127 name(REG(a0, struct Hook *hook), REG(a2, obj), REG(a1, param))
128 #define HOOKPROTONO(name, ret, param) static SAVEDS ASM ret \
129 name(REG(a0, struct Hook *hook), REG(a1, param))
130 #define HOOKPROTONP(name, ret, obj) static SAVEDS ASM ret \
131 name(REG(a0, struct Hook *hook), REG(a2, obj))
132 #define HOOKPROTONONP(name, ret) static SAVEDS ASM ret \
133 name(REG(a0, struct Hook *hook))
134 #define HOOKPROTONH(name, ret, obj, param) static SAVEDS ASM ret \
135 name(REG(a2, obj), REG(a1, param))
136 #define HOOKPROTONHNO(name, ret, param) static SAVEDS ASM ret \
137 name(REG(a1, param))
138 #define HOOKPROTONHNP(name, ret, obj) static SAVEDS ASM ret \
139 name(REG(a2, obj))
140 #define HOOKPROTONHNONP(name, ret) static SAVEDS ret name(void)
141 #else
142 /* NOTE: This is fine for AROS, since HookEntry will handle stack params
144 #define HOOKPROTO(name, ret, obj, param) static SAVEDS ret \
145 name(struct Hook *hook, obj, param)
146 #define HOOKPROTONO(name, ret, param) static SAVEDS ret \
147 name(struct Hook *hook, UNUSED APTR _obj, param)
148 #define HOOKPROTONP(name, ret, obj) static SAVEDS ret \
149 name(struct Hook *hook, obj, UNUSED APTR _param)
150 #define HOOKPROTONONP(name, ret) static SAVEDS ret \
151 name(struct Hook *hook, UNUSED APTR _obj, UNUSED APTR _param)
152 #define HOOKPROTONH(name, ret, obj, param) static SAVEDS ret \
153 name(UNUSED struct Hook *_hook, obj, param)
154 #define HOOKPROTONHNO(name, ret, param) static SAVEDS ret \
155 name(UNUSED struct Hook *_hook, UNUSED APTR _obj, param)
156 #define HOOKPROTONHNP(name, ret, obj) static SAVEDS ret \
157 name(UNUSED struct Hook *_hook, obj, UNUSED APTR _param)
158 #define HOOKPROTONHNONP(name, ret) static SAVEDS ret name(void)
159 #endif
161 #ifdef __MORPHOS__
163 #ifndef SDI_TRAP_LIB /* avoid defining this twice */
164 #include <proto/alib.h>
165 #include <emul/emulregs.h>
167 #define SDI_TRAP_LIB 0xFF00 /* SDI prefix to reduce conflicts */
169 struct SDI_EmulLibEntry
171 UWORD Trap;
172 UWORD pad;
173 APTR Func;
175 #endif
177 #define MakeHook(hookname, funcname) struct Hook hookname = {{NULL, NULL}, \
178 (HOOKFUNC)HookEntry, (HOOKFUNC)funcname, NULL}
179 #define MakeHookWithData(hookname, funcname, data) struct Hook hookname = \
180 {{NULL, NULL}, (HOOKFUNC)HookEntry, (HOOKFUNC)funcname, (APTR)data}
181 #define MakeStaticHook(hookname, funcname) static struct Hook hookname = \
182 {{NULL, NULL}, (HOOKFUNC)HookEntry, (HOOKFUNC)funcname, NULL}
183 #define DISPATCHERPROTO(name) ULONG name(struct IClass * cl, Object * obj, \
184 Msg msg); \
185 extern const struct SDI_EmulLibEntry Gate_##name
186 #define DISPATCHER(name) \
187 struct IClass; \
188 ULONG name(struct IClass * cl, Object * obj, Msg msg); \
189 static ULONG Trampoline_##name(void) {return name((struct IClass *) \
190 REG_A0, (Object *) REG_A2, (Msg) REG_A1);} \
191 const struct SDI_EmulLibEntry Gate_##name = {SDI_TRAP_LIB, 0, \
192 (APTR) Trampoline_##name}; \
193 ULONG name(struct IClass * cl, Object * obj, Msg msg)
194 #define SDISPATCHER(name) \
195 struct IClass; \
196 static ULONG name(struct IClass * cl, Object * obj, Msg msg); \
197 static ULONG Trampoline_##name(void) {return name((struct IClass *) \
198 REG_A0, (Object *) REG_A2, (Msg) REG_A1);} \
199 static const struct SDI_EmulLibEntry Gate_##name = {SDI_TRAP_LIB, 0, \
200 (APTR) Trampoline_##name}; \
201 static ULONG name(struct IClass * cl, Object * obj, Msg msg)
202 #define CROSSCALL1(name, ret, type1, param1) \
203 static STDARGS SAVEDS ret name(type1 param1); \
204 static ret Trampoline_##name(void) \
206 ULONG *stk = (ULONG *)REG_A7; \
207 type1 param1 = (type1)stk[1]; \
208 return name(param1); \
210 static const struct SDI_EmulLibEntry Gate_##name = {SDI_TRAP_LIB, 0, \
211 (APTR) Trampoline_##name}; \
212 static STDARGS SAVEDS ret name(type1 param1, type2 param2)
213 #define CROSSCALL1NR(name, type1, param1) \
214 static STDARGS SAVEDS void name(type1 param1); \
215 static void Trampoline_##name(void) \
217 ULONG *stk = (ULONG *)REG_A7; \
218 type1 param1 = (type1)stk[1]; \
219 name(param1); \
221 static const struct SDI_EmulLibEntry Gate_##name = {SDI_TRAP_LIB, 0, \
222 (APTR) Trampoline_##name}; \
223 static STDARGS SAVEDS void name(type1 param1)
224 #define CROSSCALL2(name, ret, type1, param1, type2, param2) \
225 static STDARGS SAVEDS ret name(type1 param1, type2 param2); \
226 static ret Trampoline_##name(void) \
228 ULONG *stk = (ULONG *)REG_A7; \
229 type1 param1 = (type1)stk[1]; \
230 type2 param2 = (type2)stk[2]; \
231 return name(param1, param2); \
233 static const struct SDI_EmulLibEntry Gate_##name = {SDI_TRAP_LIB, 0, \
234 (APTR) Trampoline_##name}; \
235 static STDARGS SAVEDS ret name(type1 param1, type2 param2)
236 #define CROSSCALL2NR(name, type1, param1, type2, param2) \
237 static STDARGS SAVEDS void name(type1 param1, type2 param2); \
238 static void Trampoline_##name(void) \
240 ULONG *stk = (ULONG *)REG_A7; \
241 type1 param1 = (type1)stk[1]; \
242 type2 param2 = (type2)stk[2]; \
243 name(param1, param2); \
245 static const struct SDI_EmulLibEntry Gate_##name = {SDI_TRAP_LIB, 0, \
246 (APTR) Trampoline_##name}; \
247 static STDARGS SAVEDS void name(type1 param1, type2 param2)
248 #define ENTRY(func) (APTR)&Gate_##func
250 #elif defined(__AROS__)
251 #include <proto/alib.h>
253 #define MakeHook(hookname, funcname) struct Hook hookname = {{NULL, NULL}, \
254 (HOOKFUNC)HookEntry, (HOOKFUNC)funcname, NULL}
255 #define MakeHookWithData(hookname, funcname, data) struct Hook hookname = \
256 {{NULL, NULL}, (HOOKFUNC)HookEntry, (HOOKFUNC)funcname, (APTR)data}
257 #define MakeStaticHook(hookname, funcname) static struct Hook hookname = \
258 {{NULL, NULL}, (HOOKFUNC)HookEntry, (HOOKFUNC)funcname, NULL}
259 #define DISPATCHERPROTO(name) \
260 IPTR name(struct IClass * cl, Object * obj, Msg msg); \
261 AROS_UFP3(IPTR, Gate_##name, \
262 AROS_UFPA(struct IClass *, cl, A0), \
263 AROS_UFPA(Object *, obj, A2), \
264 AROS_UFPA(Msg, msg, A1))
265 #define DISPATCHERx(x,name) \
266 x IPTR name(struct IClass * cl, Object * obj, Msg msg); \
267 x AROS_UFH3(IPTR, Gate_##name, \
268 AROS_UFHA(struct IClass *, cl, A0), \
269 AROS_UFHA(Object *, obj, A2), \
270 AROS_UFHA(Msg, msg, A1)) \
271 { AROS_USERFUNC_INIT \
272 return name(cl, obj, msg); \
273 AROS_USERFUNC_EXIT \
275 x IPTR name(struct IClass * cl, Object * obj, Msg msg)
276 #define DISPATCHER(name) DISPATCHERx(,name)
277 #define SDISPATCHER(name) DISPATCHERx(static,name)
278 #define CROSSCALL1(name, ret, type1, param1) \
279 static STDARGS SAVEDS ret Gate_##name(type1 param1)
280 #define CROSSCALL1NR(name, type1, param1) \
281 static STDARGS SAVEDS void Gate_##name(type1 param1)
282 #define CROSSCALL2(name, ret, type1, param1, type2, param2) \
283 static STDARGS SAVEDS ret Gate_##name(type1 param1, type2 param2)
284 #define CROSSCALL2NR(name, type1, param1, type2, param2) \
285 static STDARGS SAVEDS void Gate_##name(type1 param1, type2 param2)
286 #define ENTRY(func) (APTR)Gate_##func
288 #else /* !__MORPHOS__ && !__AROS__*/
290 #define MakeHook(hookname, funcname) struct Hook hookname = {{NULL, NULL}, \
291 (HOOKFUNC)funcname, NULL, NULL}
292 #define MakeHookWithData(hookname, funcname, data) struct Hook hookname = \
293 {{NULL, NULL}, (HOOKFUNC)funcname, NULL, (APTR)data}
294 #define MakeStaticHook(hookname, funcname) static struct Hook hookname = \
295 {{NULL, NULL}, (HOOKFUNC)funcname, NULL, NULL}
296 #define DISPATCHERPROTO(name) SAVEDS ASM IPTR name(REG(a0, \
297 struct IClass * cl), REG(a2, Object * obj), REG(a1, Msg msg))
298 #define DISPATCHER(name) DISPATCHERPROTO(name)
299 #define SDISPATCHER(name) static DISPATCHERPROTO(name)
300 #define CROSSCALL1(name, ret, type1, param1) \
301 static STDARGS SAVEDS ret name(type1 param1)
302 #define CROSSCALL1NR(name, type1, param1) \
303 static STDARGS SAVEDS void name(type1 param1)
304 #define CROSSCALL2(name, ret, type1, param1, type2, param2) \
305 static STDARGS SAVEDS ret name(type1 param1, type2 param2)
306 #define CROSSCALL2NR(name, type1, param1, type2, param2) \
307 static STDARGS SAVEDS void name(type1 param1, type2 param2)
308 #define ENTRY(func) (APTR)func
310 #endif
312 #define InitHook(hook, orighook, data) ((hook)->h_Entry = (orighook).h_Entry,\
313 (hook)->h_SubEntry = (orighook).h_SubEntry,(hook)->h_Data = (APTR)(data))
315 #endif /* SDI_HOOK_H */