theKernel 10.0
Loading...
Searching...
No Matches
MkCall_atl.c
Go to the documentation of this file.
1
9/* LABEL-NO */
10
12#include "log_mk.h"
13#include "mk_check_atl.h"
14
15#undef META_CONTEXT_S
16#define META_CONTEXT_S obj
17
18/*****************************************************************************/
19/* */
20/* Proc-Call */
21/* */
22/*****************************************************************************/
23
25{
27 if ((*skipP) >= objc) {
28 WrongNumArgs(hdl,(*skipP), objc, -999, +999, arg);
29 goto error;
30 }
31 Tcl_ResetResult(interp);
32 OT_OBJ_T argsO = objv[(*skipP)++];
33
34 int myobjc;
35 Tcl_Obj **myobjv;
36 check_LNG (Tcl_ListObjGetElements(interp, argsO, &myobjc, &myobjv)) goto tcl_error;
37
38 // BUG-FIX: set the "default" value for "NULL" = ""
39 // defined in: ./lib_TCL.atl → map_M2C
40 // mark=MK_NULL
41 if (OT_LNG_NULL_IS(myobjv[0])) {
42 *retP = NULL;
43 return MK_OK;
44 }
45
46 struct MkCallS *call = *retP;
47
48 if (*retP == NULL) {
49 call = *retP = MkSysCalloc(MK_ERROR_PANIC,1,sizeof(struct MkCallS));
50 call->isAlloc = true;
51 }
52
53 call->signature = MkCallS_SIG;
54 call->args = argsO;
55 call->hdl = hdl;
56 call->amkrt = amkrt;
57 call->nsO = STRN2VAL(Tcl_GetCurrentNamespace(interp)->fullName);
58 call->mkrt = MK_RT_PTR;
59
60//colorGREEN("call<%p>, type<%d>",call,call->type);
61
62 OT_REF_INCR(call->args);
63 OT_REF_INCR(call->nsO);
64
65 return MK_OK;
66tcl_error:
68error:
69 return MkErrorStack_0E();
70}
71
72/*****************************************************************************/
73/* */
74/* Proc-Call */
75/* */
76/*****************************************************************************/
77
78enum MkErrorE NS(ProcResolve) (
80 MK_MNG hdl,
81 struct MkCallS *call
82) {
84 OT_OBJ_T argsO = call->args;
85 call->args = NULL;
86 int objc;
87 OT_OBJ_T *objv;
88
89 assert(call->signature == MkCallS_SIG);
90
91//colorORANGE("call->nsPtr<%p>, call->nsO<%s>",call->nsPtr,VAL2STR(call->nsO));
92 OT_NS_T nsPtr = MoxResolveN(call->nsO);
93 if (nsPtr == NULL) return MK_OK ; /* DEFINITION namespace already deleted */
94
95 if (argsO == NULL) {
96 MkErrorSetC_2M(hdl,"CallbackResolveError: INTERNAL ERROR -> callback is invalid");
97 goto error;
98 }
99
100 check_LNG(Tcl_ListObjGetElements(interp,argsO,&objc,&objv)) {
102 goto error;
103 }
104
105 Tcl_Command procCmd = NULL;
106 OT_OBJ_T arg0 = objv[0];
107 do {
108 // resolve using CURRENT and GLOBAL namespace
109 procCmd = Tcl_FindCommand (interp,VAL2STR(arg0),nsPtr,0);
110 if (procCmd != NULL) break;
111
112 // resolve using toplevel CLASS namespace for METHOD call → test if "objv[0]" is an INSTANCE
113 if (objc == 1) break;
114
115 MOX_NS_T myNsP = MoxResolveN(objv[1]);
116 if (myNsP == NULL) break;
117 OT_OBJ_T clsNsO = MoxMy__CLASS__NN(myNsP,0);
118 if (clsNsO == NULL) break;
119 OT_NS_T clsNsPtr = MoxResolveN(clsNsO);
120 if (clsNsPtr == NULL) break;
121 procCmd = Tcl_FindCommand (interp,VAL2STR(arg0),clsNsPtr,0);
122 if (procCmd == NULL) break;
123
124 // FOUND toplevel CLASS namespace with METHOD "arg0"
125 OT_REF_DECR(call->nsO);
126 call->nsO = clsNsO;
127 OT_REF_INCR(call->nsO);
128
129 } while (0);
130
131 if (procCmd == NULL) {
132 MK_STRN cbS = VAL2STR(arg0);
133 MkErrorSetV_2M(hdl,"CallbackResolveError: unknown method \"%s\" in namespace \"%s\"", cbS, nsPtr->fullName);
134 MkErrorAppendC_2M(hdl," attention: private callback require namespace prefix!");
135 goto error;
136 }
137
138 arg0 = NULL;
139 objc--;objv++;
140
141 call->mth = Tcl_NewObj();
142 Tcl_GetCommandFullName(interp,procCmd,call->mth);
143 OT_REF_INCR(call->mth);
144
145 OT_CLS_T procClass = AtlGetClassFromProc(procCmd);
146
147 if (procClass == NULL) {
148 // just one proc
149 call->type = MkCallS_proc;
150 } else {
151 if (objc == 0) {
152 // DEFINED: instance or class method without my -> own method
153 call->type = MkCallS_own_method;
154 call->my = NULL;
155 } else {
156 OT_OBJ_T myO = objv[0];
157 if (MoxMyIsN(myO)) {
158 // instance method with my
159 call->type = MkCallS_other_method;
160 call->my = myO;
161 OT_REF_INCR(myO);
162 objc--;objv++;
163 } else {
164 // CLASS method
165 call->type = MkCallS_static;
166 call->my = NULL;
167 }
168 }
169 }
170
171 // resolve additional arguments
172 if (objc > MkProcResolve_maxArgsLen) {
173 MkErrorSetV_2M(hdl, "expect max '%d' additional arguments to callback but got '%d' "
174 "with '%s'", MkProcResolve_maxArgsLen, objc, Tcl_GetString(argsO));
175 goto error;
176 } else if (objc > 0) {
177 call->args = Tcl_NewListObj(objc,objv);
178 OT_REF_INCR(call->args);
179 }
180
182 return MK_OK;
183
184error:
185 call->args = argsO;
186 return MkErrorStack_1M(hdl);
187}
188
189// **********************************************************************
190
191
192#if 0
193 #define dbgMsg(fmt,...) printV(fmt,__VA_ARGS__)
194 #define dbgObj(obj) printLngObj(obj)
195#else
196 #define dbgMsg(fmt,...)
197 #define dbgObj(obj)
198#endif
199
200
201/*
202[ObjectDeleteCall signature]
203 callback-args := typeName:MK_STRN[in], typeHdl:MK_HDL[in], objHdl:MK_HDL[in]
204 [proc] proc callback { callback-args ?additional-args...? } ...
205 MkObjectC::DeleteCallbackSetup "NAME" callback "FILTER"
206 [instance] myooX::ClassN ::XXX {
207 proc callback { xxxNs callback-args ?additional-args...? } ...
208 }
209 MkObjectC::DeleteCallbackSetup "NAME" [list callback $xxxNs] "FILTER"
210 [class] myooX::ClassN ::YYY {
211 proc callback { callback-args ?additional-args...? } ...
212 }
213 MkObjectC::DeleteCallbackSetup "NAME" ::YYY::callback "FILTER"
214[ObjectDeleteCall signature]
215*/
216
217enum MkErrorE NS(ObjectDeleteCall) ( MkObjectDeleteCallF_ARGS )
218{
220
221 // if NO self object is available than NO callback is called
222 if (!MkSelfExists(obj)) return MK_OK;
223
224 // 1. setup environment
225 struct MkCallS *call = __data__;
226
227 // 2. Prolog
228 CallProlog(call->hdl);
229 if (call->type == MkCallS_own_method) {
230 return MkErrorSetC_1E("MkCallS_own_method not supported");
231 }
232
233 // 3. setup args
234 objv[objc++] = STR2VAL(typeName);
235 objv[objc++] = HDL2VAL(typeHdl);
236 objv[objc++] = HDL2VAL(objHdl);
237
238 // 4. setup user args
239 if (call->args) MK(ProcResolveAppendArgs)(call,&objc,objv);
240
241 // 5. call the callback
242 int ret = MK(EvalObjv) (interp, objc, objv, 0); /* "MK(EvalObjv)" IS required !! */
243 if (ret != TCL_OK) goto error;
244
245 Tcl_ResetResult(interp);
246 return MkErrorGetCode_0E();
247
248error:
250
251error_mq:
252 return MkErrorStack_0E();
253}
254
255void NS(ObjectDeleteFree) ( MkObjectDeleteFreeF_ARGS )
256{
257 MK(CallFree)(dataP);
258}
259
261 switch (type) {
262 case MkCallS_null : return "null";
263 case MkCallS_init : return "init";
264 case MkCallS_proc : return "proc";
265 case MkCallS_static : return "static";
266 case MkCallS_own_method : return "own_method";
267 case MkCallS_other_method : return "other_method";
268 case MkCallS_error : return "error";
269 default : return "INVALID";
270 }
271}
272
273void MK(CallLog) (
275 MkCallS *call,
276 MK_STRN caller
277) {
279 MkLogV_3(NULL,caller,"MkCallS[%p] : sig=%c, type=%s, isAlloc = %c\n",
280 call, logB(call->signature == MkCallS_SIG), sMkCallTypeEC(call->type), logB(call->isAlloc));
281 if (call->my) { MkLogV_3(NULL,caller, " | my = %s\n", Tcl_GetString(call->my)); }
282 if (call->mth) { MkLogV_3(NULL,caller, " | mth = %s\n", Tcl_GetString(call->mth)); }
283 if (call->args) { MkLogV_3(NULL,caller, " | args = %s\n", Tcl_GetString(call->args)); }
284 while (call->hdl) {
285 MK_OBJ obj = MkObj(call->hdl);
286 if (obj == NULL) { MkLogV_3(NULL,caller, " | hdl = %p (INVALID)\n", call->hdl); break; }
287 OT_OBJ_T objO = META2VAL_O(obj);
288 if (objO == NULL) { MkLogV_3(NULL,caller, " | hdl = %p (NO SELF)\n", call->hdl); break; }
289
290 MkLogV_3(NULL,caller, " | hdl = %s\n", Tcl_GetString(objO));
291 break;
292 }
293 if (call->amkrt) { MkLogV_3(NULL,caller, " | amkrt = %p\n", call->amkrt); }
294 if (call->nsO) { MkLogV_3(NULL,caller, " | nsO = %s\n", Tcl_GetString(call->nsO)); }
296}
#define HDL2VAL(nat)
#define CallProlog(m)
#define MK(n)
#define SETUP_moxrt
#define STR2VAL(ptr)
MOX_NS_T OT_NS_T
#define MkCallS_SIG
#define OT_Check_ARGS
MOX_CLS_T OT_CLS_T
#define NS(n)
#define VAL2STR(val)
#define OT_SETUP_doc
#define check_LNG(code)
#define OT_ERROR_LNG_2_META(m)
#define OT_MK_ARGS
MkCallTypeE
@ MkCallS_init
@ MkCallS_null
@ MkCallS_error
@ MkCallS_own_method
@ MkCallS_other_method
@ MkCallS_proc
@ MkCallS_static
#define MkProcResolve_maxArgsLen
#define AtlGetClassFromProc(cmdT)
#define OT_REF_DECR_AND_NULL(_obj)
#define OT_REF_DECR(_obj)
#define OT_REF_INCR(_obj)
#define META2VAL_O(o)
#define STRN2VAL(nat)
MOX_OBJ_T OT_OBJ_T
tag: nhi1-release-250425
static MK_STRN sMkCallTypeEC(MkCallTypeE type)
Definition MkCall_atl.c:260
#define MkErrorGetCode_0E()
#define MkErrorStack_1M(err)
#define MkErrorStack_0E()
#define MkErrorSetC_1E(message)
#define MkErrorAppendC_2M(m,...)
#define MkErrorSetV_2M(err, printfmt,...)
#define MkErrorSetC_2M(err, message)
#define MK_ERROR_PANIC
MkErrorE
collection for the different error-codes …
@ MK_OK
(persistent) everything is OK.
const MK_STRB * MK_STRN
constant string pointer data-type
MK_PTRB * MK_MNG
managed object pointer, datatype will be checked at runtime
MK_PTRB * MK_CBP
generic pointer to call-back data
static MK_OBJ MkObj(MK_MNG mng)
cast a unknown-object into an MkObjectS pointer or NULL if not possible
#define MkLogV_3(fmtobj, callfunc, printfmt,...)
static bool MkSelfExists(MK_OBJN obj)
Check if the MkObjectS::self exists …
MK_PTR MkSysCalloc(MK_OBJN fmtobj, size_t const nmemb, size_t const size)
calloc syscall with atlmkkernel error plugin
#define MkObjectDeleteCallF_CHECK
validate call to MkObjectDeleteCallF
#define MkObjectDeleteCallF_ARGS
the MkObjectDeleteCallF arguments with default names
#define MkObjectDeleteFreeF_ARGS
the MkObjectDeleteFreeF arguments with default names
#define MkRuntimeLogBufferPush()
#define MkRuntimeLogBufferPop()
#define MK_RT_PTR
#define MK_RT_ARGS
#define WrongNumArgs(...)
MK_EXTERN enum MkErrorE MK_DECL MK CheckCallable(OT_Check_ARGS, MK_CBP *)
OT_OBJ_T args
OT_CLS_T nsO
MkCallTypeE type
MK_SIG signature
OT_MK_RT_T amkrt
object header …