- Timestamp:
- Mar 1, 2013 11:46:09 PM (12 years ago)
- Location:
- trunk/src/VBox/Storage/testcase
- Files:
-
- 1 added
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Storage/testcase/VDScript.cpp
r44855 r44901 181 181 PVDSCRIPTTOKEN pTokenNext; 182 182 } VDTOKENIZER; 183 184 /**185 * Script function which can be called.186 */187 typedef struct VDSCRIPTFN188 {189 /** String space core. */190 RTSTRSPACECORE Core;191 /** Flag whether function is defined in the source or was192 * registered from the outside. */193 bool fExternal;194 /** Flag dependent data. */195 union196 {197 /** Data for functions defined in the source. */198 struct199 {200 /** Pointer to the AST defining the function. */201 PVDSCRIPTASTFN pAstFn;202 } Internal;203 /** Data for external defined functions. */204 struct205 {206 /** Callback function. */207 PFNVDSCRIPTCALLBACK pfnCallback;208 /** Opaque user data. */209 void *pvUser;210 } External;211 } Type;212 /** Return type of the function. */213 VDSCRIPTTYPE enmTypeRetn;214 /** Number of arguments the function takes. */215 unsigned cArgs;216 /** Variable sized array of argument types. */217 VDSCRIPTTYPE aArgTypes[1];218 } VDSCRIPTFN;219 typedef VDSCRIPTFN *PVDSCRIPTFN;220 183 221 184 /** … … 2661 2624 } 2662 2625 2663 pFn = (PVDSCRIPTFN)RTMemAllocZ(RT_OFFSETOF(VDSCRIPTFN, a ArgTypes[paCallbacks->cArgs]));2626 pFn = (PVDSCRIPTFN)RTMemAllocZ(RT_OFFSETOF(VDSCRIPTFN, aenmArgTypes[paCallbacks->cArgs])); 2664 2627 if (!pFn) 2665 2628 { … … 2678 2641 2679 2642 for (unsigned i = 0; i < paCallbacks->cArgs; i++) 2680 pFn->a ArgTypes[i] = paCallbacks->paArgs[i];2643 pFn->aenmArgTypes[i] = paCallbacks->paArgs[i]; 2681 2644 2682 2645 RTStrSpaceInsert(&pThis->hStrSpaceFn, &pFn->Core); -
trunk/src/VBox/Storage/testcase/VDScriptAst.h
r44855 r44901 54 54 /** Expression node. */ 55 55 VDSCRIPTASTCLASS_EXPRESSION, 56 /** @todo: Add if ... else, loops, ... */57 56 /** 32bit blowup. */ 58 57 VDSCRIPTASTCLASS_32BIT_HACK = 0x7fffffff -
trunk/src/VBox/Storage/testcase/VDScriptInternal.h
r44891 r44901 22 22 23 23 #include "VDScript.h" 24 25 /** 26 * Script function which can be called. 27 */ 28 typedef struct VDSCRIPTFN 29 { 30 /** String space core. */ 31 RTSTRSPACECORE Core; 32 /** Flag whether function is defined in the source or was 33 * registered from the outside. */ 34 bool fExternal; 35 /** Flag dependent data. */ 36 union 37 { 38 /** Data for functions defined in the source. */ 39 struct 40 { 41 /** Pointer to the AST defining the function. */ 42 PVDSCRIPTASTFN pAstFn; 43 } Internal; 44 /** Data for external defined functions. */ 45 struct 46 { 47 /** Callback function. */ 48 PFNVDSCRIPTCALLBACK pfnCallback; 49 /** Opaque user data. */ 50 void *pvUser; 51 } External; 52 } Type; 53 /** Return type of the function. */ 54 VDSCRIPTTYPE enmTypeRetn; 55 /** Number of arguments the function takes. */ 56 unsigned cArgs; 57 /** Variable sized array of argument types. */ 58 VDSCRIPTTYPE aenmArgTypes[1]; 59 } VDSCRIPTFN; 60 /** Pointer to a script function registration structure. */ 61 typedef VDSCRIPTFN *PVDSCRIPTFN; 24 62 25 63 /** Pointer to a tokenize state. */ … … 56 94 * @returns VBox status code. 57 95 * @param pThis The script context. 58 * @param p AstFn The function AST to interpret.96 * @param pszFn The function name to interprete. 59 97 * @param paArgs Arguments to pass to the function. 60 98 * @param cArgs Number of arguments. 61 99 * @param pRet Where to store the return value on success. 100 * 101 * @note: The AST is not modified in any way during the interpretation process. 62 102 */ 63 DECLHIDDEN(int) vdScriptCtxInterprete(PVDSCRIPTCTXINT pThis, PVDSCRIPTASTFN pAstFn,103 DECLHIDDEN(int) vdScriptCtxInterprete(PVDSCRIPTCTXINT pThis, const char *pszFn, 64 104 PVDSCRIPTARG paArgs, unsigned cArgs, 65 105 PVDSCRIPTARG pRet); -
trunk/src/VBox/Storage/testcase/VDScriptInterp.cpp
r44891 r44901 24 24 25 25 #include "VDScriptAst.h" 26 #include "VDScriptStack.h" 26 27 #include "VDScriptInternal.h" 28 29 /** 30 * Interpreter variable. 31 */ 32 typedef struct VDSCRIPTINTERPVAR 33 { 34 /** String space core. */ 35 RTSTRSPACECORE Core; 36 /** Value. */ 37 VDSCRIPTARG Value; 38 } VDSCRIPTINTERPVAR; 39 /** Pointer to an interpreter variable. */ 40 typedef VDSCRIPTINTERPVAR *PVDSCRIPTINTERPVAR; 27 41 28 42 /** … … 33 47 /** Pointer to the enclosing scope if available. */ 34 48 struct VDSCRIPTINTERPSCOPE *pParent; 35 /** String space of accessible variables. */49 /** String space of declared variables in this scope. */ 36 50 RTSTRSPACE hStrSpaceVar; 37 51 } VDSCRIPTINTERPSCOPE; … … 59 73 typedef struct VDSCRIPTINTERPCTX 60 74 { 75 /** Pointer to the script context. */ 76 PVDSCRIPTCTXINT pScriptCtx; 61 77 /** Current function call entry. */ 62 78 PVDSCRIPTINTERPFNCALL pFnCallCurr; 63 79 /** Stack of calculated values. */ 64 PVDSCRIPTARG pStackVal; 65 /** Number of values on the stack. */ 66 unsigned cValuesOnStack; 67 /** Maximum number of values the stack can hold currently. */ 68 unsigned cValuesOnStackMax; 69 /** Stack of executed AST nodes. */ 70 PVDSCRIPTASTCORE *ppStackAstCompute; 71 /** Number of AST nodes on the stack. */ 72 unsigned cAstNodesOnStack; 73 /** Maximum number of AST nodes the stack can hold. */ 74 unsigned cAstNodesOnStackMax; 80 VDSCRIPTSTACK StackValues; 81 /** Evaluation control stack. */ 82 VDSCRIPTSTACK StackCtrl; 75 83 } VDSCRIPTINTERPCTX; 76 84 /** Pointer to an interpreter context. */ … … 78 86 79 87 /** 88 * Interpreter control type. 89 */ 90 typedef enum VDSCRIPTINTERPCTRLTYPE 91 { 92 VDSCRIPTINTERPCTRLTYPE_INVALID = 0, 93 /** Function call to evaluate now, all values are computed 94 * and are stored on the value stack. 95 */ 96 VDSCRIPTINTERPCTRLTYPE_FN_CALL, 97 /** Cleanup the function call, deleting the scope and restoring the previous one. */ 98 VDSCRIPTINTERPCTRLTYPE_FN_CALL_CLEANUP, 99 /** If statement to evaluate now, the guard is on the stack. */ 100 VDSCRIPTINTERPCTRLTYPE_IF, 101 VDSCRIPTINTERPCTRLTYPE_32BIT_HACK = 0x7fffffff 102 } VDSCRIPTINTERPCTRLTYPE; 103 /** Pointer to a control type. */ 104 typedef VDSCRIPTINTERPCTRLTYPE *PVDSCRIPINTERPCTRLTYPE; 105 106 /** 107 * Interpreter stack control entry. 108 */ 109 typedef struct VDSCRIPTINTERPCTRL 110 { 111 /** Flag whether this entry points to an AST node to evaluate. */ 112 bool fEvalAst; 113 /** Flag dependent data. */ 114 union 115 { 116 /** Pointer to the AST node to interprete. */ 117 PVDSCRIPTASTCORE pAstNode; 118 /** Interpreter control structure. */ 119 struct 120 { 121 /** Type of control. */ 122 VDSCRIPTINTERPCTRLTYPE enmCtrlType; 123 /** Function call data. */ 124 struct 125 { 126 /** Function to call. */ 127 PVDSCRIPTASTFN pAstFn; 128 } FnCall; 129 } Ctrl; 130 }; 131 } VDSCRIPTINTERPCTRL; 132 /** Pointer to an exec stack control entry. */ 133 typedef VDSCRIPTINTERPCTRL *PVDSCRIPTINTERPCTRL; 134 135 /** 80 136 * Record an error while interpreting. 81 137 * 82 138 * @returns VBox status code passed. 83 * @param pThis The scriptcontext.139 * @param pThis The interpreter context. 84 140 * @param rc The status code to record. 85 141 * @param RT_SRC_POS Position in the source code. 86 142 * @param pszFmt Format string. 87 143 */ 88 static int vdScriptInterpreterError(PVDSCRIPTCTXINT pThis, int rc, RT_SRC_POS_DECL, const char *pszFmt, ...) 89 { 90 return rc; 91 } 92 93 DECLHIDDEN(int) vdScriptCtxInterprete(PVDSCRIPTCTXINT pThis, PVDSCRIPTASTFN pAstFn, 144 static int vdScriptInterpreterError(PVDSCRIPTINTERPCTX pThis, int rc, RT_SRC_POS_DECL, const char *pszFmt, ...) 145 { 146 return rc; 147 } 148 149 /** 150 * Pops the topmost value from the value stack. 151 * 152 * @returns nothing. 153 * @param pThis The interpreter context. 154 * @param pVal Where to store the value. 155 */ 156 DECLINLINE(void) vdScriptInterpreterPopValue(PVDSCRIPTINTERPCTX pThis, PVDSCRIPTARG pVal) 157 { 158 PVDSCRIPTARG pValStack = (PVDSCRIPTARG)vdScriptStackGetUsed(&pThis->StackValues); 159 AssertPtrReturnVoid(pValStack); 160 161 *pVal = *pValStack; 162 vdScriptStackPop(&pThis->StackValues); 163 } 164 165 /** 166 * Pushes a given value onto the value stack. 167 */ 168 DECLINLINE(int) vdScriptInterpreterPushValue(PVDSCRIPTINTERPCTX pThis, PVDSCRIPTARG pVal) 169 { 170 PVDSCRIPTARG pValStack = (PVDSCRIPTARG)vdScriptStackGetUsed(&pThis->StackValues); 171 if (!pValStack) 172 return vdScriptInterpreterError(pThis, VERR_NO_MEMORY, RT_SRC_POS, "Out of memory pushing a value on the value stack"); 173 174 *pValStack = *pVal; 175 vdScriptStackPush(&pThis->StackValues); 176 return VINF_SUCCESS; 177 } 178 179 /** 180 * Pushes a control entry without additional data onto the stack. 181 * 182 * @returns VBox status code. 183 * @param pThis The interpreter context. 184 * @param enmCtrlType The control entry type. 185 */ 186 DECLINLINE(int) vdScriptInterpreterPushNonDataCtrlEntry(PVDSCRIPTINTERPCTX pThis, 187 VDSCRIPTINTERPCTRLTYPE enmCtrlType) 188 { 189 PVDSCRIPTINTERPCTRL pCtrl = NULL; 190 191 pCtrl = (PVDSCRIPTINTERPCTRL)vdScriptStackGetUnused(&pThis->StackCtrl); 192 if (pCtrl) 193 { 194 pCtrl->fEvalAst = false; 195 pCtrl->Ctrl.enmCtrlType = enmCtrlType; 196 vdScriptStackPush(&pThis->StackCtrl); 197 return VINF_SUCCESS; 198 } 199 200 return vdScriptInterpreterError(pThis, VERR_NO_MEMORY, RT_SRC_POS, "Out of memory adding an entry on the control stack"); 201 } 202 203 /** 204 * Pushes an AST node onto the control stack. 205 * 206 * @returns VBox status code. 207 * @param pThis The interpreter context. 208 * @param enmCtrlType The control entry type. 209 */ 210 DECLINLINE(int) vdScriptInterpreterPushAstEntry(PVDSCRIPTINTERPCTX pThis, 211 PVDSCRIPTASTCORE pAstNode) 212 { 213 PVDSCRIPTINTERPCTRL pCtrl = NULL; 214 215 pCtrl = (PVDSCRIPTINTERPCTRL)vdScriptStackGetUnused(&pThis->StackCtrl); 216 217 if (pCtrl) 218 { 219 pCtrl->fEvalAst = true; 220 pCtrl->pAstNode = pAstNode; 221 vdScriptStackPush(&pThis->StackCtrl); 222 return VINF_SUCCESS; 223 } 224 225 return vdScriptInterpreterError(pThis, VERR_NO_MEMORY, RT_SRC_POS, "Out of memory adding an entry on the control stack"); 226 } 227 228 /** 229 * Evaluate a statement. 230 * 231 * @returns VBox status code. 232 * @param pThis The interpreter context. 233 * @param pStmt The statement to evaluate. 234 */ 235 static int vdScriptInterpreterEvaluateStatement(PVDSCRIPTINTERPCTX pThis, PVDSCRIPTASTSTMT pStmt) 236 { 237 int rc = VERR_NOT_IMPLEMENTED; 238 return rc; 239 } 240 241 /** 242 * Evaluate an expression. 243 * 244 * @returns VBox status code. 245 * @param pThis The interpreter context. 246 * @param pExpr The expression to evaluate. 247 */ 248 static int vdScriptInterpreterEvaluateExpression(PVDSCRIPTINTERPCTX pThis, PVDSCRIPTASTEXPR pExpr) 249 { 250 int rc = VERR_NOT_IMPLEMENTED; 251 return rc; 252 } 253 254 /** 255 * Evaluates the given AST node. 256 * 257 * @returns VBox statuse code. 258 * @param pThis The interpreter context. 259 * @param pAstNode The AST node to interpret. 260 */ 261 static int vdScriptInterpreterEvaluateAst(PVDSCRIPTINTERPCTX pThis, PVDSCRIPTASTCORE pAstNode) 262 { 263 int rc = VERR_NOT_IMPLEMENTED; 264 265 switch (pAstNode->enmClass) 266 { 267 case VDSCRIPTASTCLASS_DECLARATION: 268 { 269 break; 270 } 271 case VDSCRIPTASTCLASS_IDENTIFIER: 272 { 273 /* 274 * Identifiers are pushed only to the stack as an identifier for a variable. 275 * Look it up and push the value onto the value stack. 276 */ 277 PVDSCRIPTASTIDE pIde = (PVDSCRIPTASTIDE)pAstNode; 278 PVDSCRIPTINTERPVAR pVar = (PVDSCRIPTINTERPVAR)RTStrSpaceGet(&pThis->pFnCallCurr->pScopeCurr->hStrSpaceVar, pIde->aszIde); 279 280 AssertPtrReturn(pVar, VERR_IPE_UNINITIALIZED_STATUS); 281 rc = vdScriptInterpreterPushValue(pThis, &pVar->Value); 282 break; 283 } 284 case VDSCRIPTASTCLASS_STATEMENT: 285 { 286 rc = vdScriptInterpreterEvaluateStatement(pThis, (PVDSCRIPTASTSTMT)pAstNode); 287 break; 288 } 289 case VDSCRIPTASTCLASS_EXPRESSION: 290 { 291 rc = vdScriptInterpreterEvaluateExpression(pThis, (PVDSCRIPTASTEXPR)pAstNode); 292 break; 293 } 294 /* These should never ever appear here. */ 295 case VDSCRIPTASTCLASS_FUNCTION: 296 case VDSCRIPTASTCLASS_FUNCTIONARG: 297 case VDSCRIPTASTCLASS_INVALID: 298 default: 299 AssertMsgFailed(("Invalid AST node class: %d\n", pAstNode->enmClass)); 300 } 301 302 return rc; 303 } 304 305 /** 306 * Destroy variable string space callback. 307 */ 308 static DECLCALLBACK(int) vdScriptInterpreterVarSpaceDestroy(PRTSTRSPACECORE pStr, void *pvUser) 309 { 310 RTMemFree(pStr); 311 return VINF_SUCCESS; 312 } 313 314 /** 315 * Evaluate a function call. 316 * 317 * @returns VBox status code. 318 * @param pThis The interpreter context. 319 * @param 320 */ 321 static int vdScriptInterpreterFnCall(PVDSCRIPTINTERPCTX pThis, PVDSCRIPTASTFN pAstFn) 322 { 323 int rc = VINF_SUCCESS; 324 325 /* Add function call cleanup marker on the stack first. */ 326 rc = vdScriptInterpreterPushNonDataCtrlEntry(pThis, VDSCRIPTINTERPCTRLTYPE_FN_CALL_CLEANUP); 327 if (RT_SUCCESS(rc)) 328 { 329 /* Create function call frame and set it up. */ 330 PVDSCRIPTINTERPFNCALL pFnCall = (PVDSCRIPTINTERPFNCALL)RTMemAllocZ(sizeof(VDSCRIPTINTERPFNCALL)); 331 if (pFnCall) 332 { 333 pFnCall->pCaller = pThis->pFnCallCurr; 334 pFnCall->ScopeRoot.pParent = NULL; 335 pFnCall->ScopeRoot.hStrSpaceVar = NULL; 336 337 /* Add the variables, remember order. The first variable in the argument has the value at the top of the value stack. */ 338 PVDSCRIPTASTFNARG pArg = RTListGetFirst(&pAstFn->ListArgs, VDSCRIPTASTFNARG, Core.ListNode); 339 for (unsigned i = 0; i < pAstFn->cArgs; i++) 340 { 341 PVDSCRIPTINTERPVAR pVar = (PVDSCRIPTINTERPVAR)RTMemAllocZ(sizeof(VDSCRIPTINTERPVAR)); 342 if (pVar) 343 { 344 pVar->Core.pszString = pArg->pArgIde->aszIde; 345 pVar->Core.cchString = pArg->pArgIde->cchIde; 346 vdScriptInterpreterPopValue(pThis, &pVar->Value); 347 bool fInserted = RTStrSpaceInsert(&pFnCall->ScopeRoot.hStrSpaceVar, &pVar->Core); 348 Assert(fInserted); 349 } 350 else 351 { 352 rc = vdScriptInterpreterError(pThis, VERR_NO_MEMORY, RT_SRC_POS, "Out of memory creating a variable"); 353 break; 354 } 355 pArg = RTListGetNext(&pAstFn->ListArgs, pArg, VDSCRIPTASTFNARG, Core.ListNode); 356 } 357 358 if (RT_SUCCESS(rc)) 359 { 360 /* 361 * Push compount statement on the control stack and make the newly created 362 * call frame the current one. 363 */ 364 rc = vdScriptInterpreterPushAstEntry(pThis, &pAstFn->pCompoundStmts->Core); 365 if (RT_SUCCESS(rc)) 366 pThis->pFnCallCurr = pFnCall; 367 } 368 369 if (RT_FAILURE(rc)) 370 { 371 RTStrSpaceDestroy(&pFnCall->ScopeRoot.hStrSpaceVar, vdScriptInterpreterVarSpaceDestroy, NULL); 372 RTMemFree(pFnCall); 373 } 374 } 375 else 376 rc = vdScriptInterpreterError(pThis, VERR_NO_MEMORY, RT_SRC_POS, "Out of memory creating a call frame"); 377 } 378 379 return rc; 380 } 381 382 /** 383 * The interpreter evaluation core loop. 384 * 385 * @returns VBox status code. 386 * @param pThis The interpreter context. 387 */ 388 static int vdScriptInterpreterEvaluate(PVDSCRIPTINTERPCTX pThis) 389 { 390 int rc = VINF_SUCCESS; 391 PVDSCRIPTINTERPCTRL pCtrl = NULL; 392 393 pCtrl = (PVDSCRIPTINTERPCTRL)vdScriptStackGetUsed(&pThis->StackCtrl); 394 while (pCtrl) 395 { 396 if (pCtrl->fEvalAst) 397 { 398 PVDSCRIPTASTCORE pAstNode = pCtrl->pAstNode; 399 vdScriptStackPop(&pThis->StackCtrl); 400 401 rc = vdScriptInterpreterEvaluateAst(pThis, pAstNode); 402 } 403 else 404 { 405 switch (pCtrl->Ctrl.enmCtrlType) 406 { 407 case VDSCRIPTINTERPCTRLTYPE_FN_CALL: 408 { 409 PVDSCRIPTASTFN pAstFn = pCtrl->Ctrl.FnCall.pAstFn; 410 411 vdScriptStackPop(&pThis->StackCtrl); 412 rc = vdScriptInterpreterFnCall(pThis, pAstFn); 413 break; 414 } 415 case VDSCRIPTINTERPCTRLTYPE_FN_CALL_CLEANUP: 416 { 417 vdScriptStackPop(&pThis->StackCtrl); 418 419 /* Delete function call entry. */ 420 AssertPtr(pThis->pFnCallCurr); 421 PVDSCRIPTINTERPFNCALL pFnCallFree = pThis->pFnCallCurr; 422 423 pThis->pFnCallCurr = pFnCallFree->pCaller; 424 Assert(pFnCallFree->pScopeCurr == &pFnCallFree->ScopeRoot); 425 RTStrSpaceDestroy(&pFnCallFree->ScopeRoot.hStrSpaceVar, vdScriptInterpreterVarSpaceDestroy, NULL); 426 RTMemFree(pFnCallFree); 427 break; 428 } 429 default: 430 AssertMsgFailed(("Invalid evaluation control type on the stack: %d\n", 431 pCtrl->Ctrl.enmCtrlType)); 432 } 433 } 434 pCtrl = (PVDSCRIPTINTERPCTRL)vdScriptStackGetUsed(&pThis->StackCtrl); 435 } 436 437 return rc; 438 } 439 440 DECLHIDDEN(int) vdScriptCtxInterprete(PVDSCRIPTCTXINT pThis, const char *pszFn, 94 441 PVDSCRIPTARG paArgs, unsigned cArgs, 95 442 PVDSCRIPTARG pRet) 96 443 { 97 return VERR_NOT_IMPLEMENTED; 98 } 444 int rc = VINF_SUCCESS; 445 VDSCRIPTINTERPCTX InterpCtx; 446 PVDSCRIPTFN pFn = NULL; 447 448 AssertPtrReturn(pThis, VERR_INVALID_POINTER); 449 AssertPtrReturn(pszFn, VERR_INVALID_POINTER); 450 AssertReturn( (!cArgs && !paArgs) 451 || (cArgs && paArgs), VERR_INVALID_PARAMETER); 452 453 InterpCtx.pScriptCtx = pThis; 454 InterpCtx.pFnCallCurr = NULL; 455 vdScriptStackInit(&InterpCtx.StackValues, sizeof(VDSCRIPTARG)); 456 vdScriptStackInit(&InterpCtx.StackCtrl, sizeof(VDSCRIPTINTERPCTRL)); 457 458 pFn = (PVDSCRIPTFN)RTStrSpaceGet(&pThis->hStrSpaceFn, pszFn); 459 if (pFn) 460 { 461 if (cArgs == pFn->cArgs) 462 { 463 /* Push the arguments onto the stack. */ 464 /** @todo: Check expected and given argument types. */ 465 for (unsigned i = 0; i < cArgs; i++) 466 { 467 PVDSCRIPTARG pArg = (PVDSCRIPTARG)vdScriptStackGetUnused(&InterpCtx.StackValues); 468 *pArg = paArgs[i]; 469 vdScriptStackPush(&InterpCtx.StackValues); 470 } 471 472 if (RT_SUCCESS(rc)) 473 { 474 /* Push the AST onto the stack. */ 475 PVDSCRIPTINTERPCTRL pCtrlFn = (PVDSCRIPTINTERPCTRL)vdScriptStackGetUnused(&InterpCtx.StackCtrl); 476 pCtrlFn->fEvalAst = false; 477 pCtrlFn->Ctrl.enmCtrlType = VDSCRIPTINTERPCTRLTYPE_FN_CALL; 478 pCtrlFn->Ctrl.FnCall.pAstFn = pFn->Type.Internal.pAstFn; 479 vdScriptStackPush(&InterpCtx.StackCtrl); 480 481 /* Run the interpreter. */ 482 rc = vdScriptInterpreterEvaluate(&InterpCtx); 483 } 484 } 485 else 486 rc = vdScriptInterpreterError(&InterpCtx, VERR_INVALID_PARAMETER, RT_SRC_POS, "Invalid number of parameters, expected %d got %d", pFn->cArgs, cArgs); 487 } 488 else 489 rc = vdScriptInterpreterError(&InterpCtx, VERR_NOT_FOUND, RT_SRC_POS, "Function with identifier \"%s\" not found", pszFn); 490 491 492 return rc; 493 }
Note:
See TracChangeset
for help on using the changeset viewer.