Initial commit
[amiga/BoopsiListView.git] / BoopsiStubs.h
1 #ifndef BOOPSISTUBS_H
2 #define BOOPSISTUBS_H
3 /*
4 **      $VER: BoopsiStubs.h 1.2 (1.9.97)
5 **
6 **      Copyright (C) 1997 Bernardo Innocenti. All rights reserved.
7 **
8 **      Use 4 chars wide TABs to read this file
9 **
10 **      Using these inline versions of the amiga.lib boopsi support functions
11 **      results in faster and smaller code against their linked library
12 **      counterparts. When debug is active, these functions will also
13 **      validate the parameters you pass in.
14 **
15 */
16
17 #ifndef COMPILERSPECIFIC_H
18 #include "CompilerSpecific.h"
19 #endif /* COMPILERSPECIFIC_H */
20
21 #ifndef DEBUG_H
22 #include "Debug.h"
23 #endif /* DEBUG_H */
24
25 /* This definition will prevent the redefinition of the following stubs with
26  * their amiga.lib equivalents. This only works if you are using a patched
27  * version of <clib/alib_protos.h>
28  */
29 #define USE_BOOPSI_STUBS
30
31
32
33 /* the _HookPtr type is a shortcut for a pointer to a hook function */
34
35 typedef ASMCALL ULONG (*_HookPtr)
36         (REG(a0, Class *), REG(a2, Object *), REG(a1, APTR));
37
38 INLINE ULONG CoerceMethodA (struct IClass *cl, Object *o, Msg message)
39 {
40         ASSERT_VALIDNO0(cl)
41         ASSERT_VALID(o)
42
43         return ((_HookPtr)cl->cl_Dispatcher.h_Entry) ((APTR)cl, (APTR)o, (APTR)message);
44 }
45
46 INLINE ULONG DoSuperMethodA (struct IClass *cl, Object *o, Msg message)
47 {
48         ASSERT_VALIDNO0(cl)
49         ASSERT_VALID(o)
50
51         cl = cl->cl_Super;
52         return ((_HookPtr)cl->cl_Dispatcher.h_Entry) ((APTR)cl, (APTR)o, (APTR)message);
53 }
54
55 INLINE ULONG DoMethodA (Object *o, Msg message)
56 {
57         Class *cl;
58         ASSERT_VALIDNO0(o)
59         cl = OCLASS (o);
60         ASSERT_VALIDNO0(cl)
61
62         return ((_HookPtr)cl->cl_Dispatcher.h_Entry) ((APTR)cl, (APTR)o, (APTR)message);
63 }
64
65
66
67 /* Var-args versions of the above functions.  SAS/C is clever enough to inline these,
68  * while gcc and egcs refuse to inline a function with '...' (yikes!).  The GCC
69  * versions of these functions are macro blocks similar to those  used in the
70  * inline/#?.h headers.
71  */
72 #if defined(__SASC) || defined (__STORM__)
73
74         INLINE ULONG CoerceMethod (struct IClass *cl, Object *o, ULONG MethodID, ...)
75         {
76                 ASSERT_VALIDNO0(cl)
77                 ASSERT_VALID(o)
78
79                 return ((_HookPtr)cl->cl_Dispatcher.h_Entry) ((APTR)cl, (APTR)o, (APTR)&MethodID);
80         }
81
82         INLINE ULONG DoSuperMethod (struct IClass *cl, Object *o, ULONG MethodID, ...)
83         {
84                 ASSERT_VALIDNO0(cl)
85                 ASSERT_VALID(o)
86
87                 cl = cl->cl_Super;
88                 return ((_HookPtr)cl->cl_Dispatcher.h_Entry) ((APTR)cl, (APTR)o, (APTR)&MethodID);
89         }
90
91         INLINE ULONG DoMethod (Object *o, ULONG MethodID, ...)
92         {
93                 Class *cl;
94
95                 ASSERT_VALIDNO0(o)
96                 cl = OCLASS (o);
97                 ASSERT_VALIDNO0(cl)
98
99                 return ((_HookPtr)cl->cl_Dispatcher.h_Entry) ((APTR)cl, (APTR)o, (APTR)&MethodID);
100         }
101
102         /* varargs stub for the OM_NOTIFY method */
103         INLINE void NotifyAttrs (Object *o, struct GadgetInfo *gi, ULONG flags, Tag attr1, ...)
104         {
105                 ASSERT_VALIDNO0(o)
106                 ASSERT_VALID(gi)
107
108                 DoMethod (o, OM_NOTIFY, &attr1, gi, flags);
109         }
110
111         /* varargs stub for the OM_UPDATE method */
112         INLINE void UpdateAttrs (Object *o, struct GadgetInfo *gi, ULONG flags, Tag attr1, ...)
113         {
114                 ASSERT_VALIDNO0(o)
115                 ASSERT_VALID(gi)
116
117                 DoMethod (o, OM_UPDATE, &attr1, gi, flags);
118         }
119
120 #elif defined(__GNUC__)
121
122         #define CoerceMethod(cl, o, msg...)                                                                                             \
123         ({                                                                                                                                                              \
124                 ULONG _msg[] = { msg };                                                                                                         \
125                 ASSERT_VALIDNO0(cl)                                                                                                                     \
126                 ASSERT_VALID(o)                                                                                                                         \
127                 ((_HookPtr)cl->cl_Dispatcher.h_Entry) ((APTR)cl, (APTR)o, (APTR)_msg);          \
128         })
129
130         #define DoSuperMethod(cl, o, msg...)                                                                                    \
131         ({                                                                                                                                                              \
132                 Class *_cl;                                                                                                                                     \
133                 ULONG _msg[] = { msg };                                                                                                         \
134                 ASSERT_VALID(o)                                                                                                                         \
135                 ASSERT_VALIDNO0(cl)                                                                                                                     \
136                 _cl = cl = cl->cl_Super;                                                                                                        \
137                 ASSERT_VALIDNO0(_cl)                                                                                                            \
138                 ((_HookPtr)_cl->cl_Dispatcher.h_Entry) ((APTR)_cl, (APTR)o, (APTR)_msg);        \
139         })
140
141         #define DoMethod(o, msg...)                                                                                                             \
142         ({                                                                                                                                                              \
143                 Class *_cl;                                                                                                                                     \
144                 ULONG _msg[] = { msg };                                                                                                         \
145                 ASSERT_VALIDNO0(o)                                                                                                                      \
146                 _cl = OCLASS(o);                                                                                                                        \
147                 ASSERT_VALIDNO0(_cl)                                                                                                            \
148                 ((_HookPtr)_cl->cl_Dispatcher.h_Entry) ((APTR)_cl, (APTR)o, (APTR)_msg);        \
149         })
150
151         /* Var-args stub for the OM_NOTIFY method */
152         #define NotifyAttrs(o, gi, flags, attrs...)                                                                             \
153         ({                                                                                                                                                              \
154                 Class *_cl;                                                                                                                                     \
155                 ULONG _attrs[] = { attrs };                                                                                                     \
156                 ULONG _msg[] = { OM_NOTIFY, (ULONG)_attrs, (ULONG)gi, flags };                          \
157                 ASSERT_VALIDNO0(o)                                                                                                                      \
158                 _cl = OCLASS(o);                                                                                                                        \
159                 ASSERT_VALIDNO0(_cl)                                                                                                            \
160                 ASSERT_VALID(gi)                                                                                                                        \
161                 ((_HookPtr)_cl->cl_Dispatcher.h_Entry) ((APTR)_cl, (APTR)o, (APTR)_msg);        \
162         })
163
164         /* Var-args stub for the OM_UPDATE method */
165         #define UpdateAttrs(o, gi, flags, attrs...)                                                                             \
166         ({                                                                                                                                                              \
167                 Class *_cl;                                                                                                                                     \
168                 ULONG _attrs[] = { attrs };                                                                                                     \
169                 ULONG _msg[] = { OM_UPDATE, (ULONG)_attrs, (ULONG)gi, flags };                          \
170                 ASSERT_VALIDNO0(o)                                                                                                                      \
171                 _cl = OCLASS(o);                                                                                                                        \
172                 ASSERT_VALIDNO0(_cl)                                                                                                            \
173                 ASSERT_VALID(gi)                                                                                                                        \
174                 ((_HookPtr)_cl->cl_Dispatcher.h_Entry) ((APTR)_cl, (APTR)o, (APTR)_msg);        \
175         })
176 #endif
177
178 /* Nobody else needs this anymore... */
179 #undef _HookPtr
180
181 #endif /* !BOOPSISTUBS_H */