| 498 | } |
| 499 | |
| 500 | void CDebugger::PrintValue(const std::string &expr, asIScriptContext *ctx) |
| 501 | { |
| 502 | if( ctx == 0 ) |
| 503 | { |
| 504 | Output("No script is running\n"); |
| 505 | return; |
| 506 | } |
| 507 | |
| 508 | asIScriptEngine *engine = ctx->GetEngine(); |
| 509 | |
| 510 | // Tokenize the input string to get the variable scope and name |
| 511 | asUINT len = 0; |
| 512 | string scope; |
| 513 | string name; |
| 514 | string str = expr; |
| 515 | asETokenClass t = engine->ParseToken(str.c_str(), 0, &len); |
| 516 | while( t == asTC_IDENTIFIER || (t == asTC_KEYWORD && len == 2 && str.compare(0, 2, "::") == 0) ) |
| 517 | { |
| 518 | if( t == asTC_KEYWORD ) |
| 519 | { |
| 520 | if( scope == "" && name == "" ) |
| 521 | scope = "::"; // global scope |
| 522 | else if( scope == "::" || scope == "" ) |
| 523 | scope = name; // namespace |
| 524 | else |
| 525 | scope += "::" + name; // nested namespace |
| 526 | name = ""; |
| 527 | } |
| 528 | else if( t == asTC_IDENTIFIER ) |
| 529 | name.assign(str.c_str(), len); |
| 530 | |
| 531 | // Skip the parsed token and get the next one |
| 532 | str = str.substr(len); |
| 533 | t = engine->ParseToken(str.c_str(), 0, &len); |
| 534 | } |
| 535 | |
| 536 | if( name.size() ) |
| 537 | { |
| 538 | // Find the variable |
| 539 | void *ptr = 0; |
| 540 | int typeId = 0; |
| 541 | |
| 542 | asIScriptFunction *func = ctx->GetFunction(); |
| 543 | if( !func ) return; |
| 544 | |
| 545 | // skip local variables if a scope was informed |
| 546 | if( scope == "" ) |
| 547 | { |
| 548 | // We start from the end, in case the same name is reused in different scopes |
| 549 | for( asUINT n = func->GetVarCount(); n-- > 0; ) |
| 550 | { |
| 551 | if( ctx->IsVarInScope(n) && name == ctx->GetVarName(n) ) |
| 552 | { |
| 553 | ptr = ctx->GetAddressOfVar(n); |
| 554 | typeId = ctx->GetVarTypeId(n); |
| 555 | break; |
| 556 | } |
| 557 | } |
nothing calls this directly
no test coverage detected