Arquivos
hhvm/hphp/runtime/eval/debugger/cmd/cmd_variable.cpp
T
Mike Magruder 7a928e7689 Consolidate client/server functions in debugger commands
Cleaned up some of the superfluous variations of onServer*()/onClient*() in the debugger commands. The separation was a leftover of the days when we had the VM and the compiler. The entire DebuggerCommand interface, what's public/protected/private, etc. could use a serious cleanup, but I'm not going that far now. I mostly wanted to clean this up to make some other work we need to do server-side less complicated.
2013-04-25 00:50:12 -07:00

162 linhas
5.2 KiB
C++

/*
+----------------------------------------------------------------------+
| HipHop for PHP |
+----------------------------------------------------------------------+
| Copyright (c) 2010- Facebook, Inc. (http://www.facebook.com) |
+----------------------------------------------------------------------+
| This source file is subject to version 3.01 of the PHP license, |
| that is bundled with this package in the file LICENSE, and is |
| available through the world-wide-web at the following url: |
| http://www.php.net/license/3_01.txt |
| If you did not receive a copy of the PHP license and are unable to |
| obtain it through the world-wide-web, please send a note to |
| license@php.net so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
*/
#include <runtime/eval/debugger/cmd/cmd_variable.h>
#include <runtime/base/hphp_system.h>
namespace HPHP { namespace Eval {
///////////////////////////////////////////////////////////////////////////////
void CmdVariable::sendImpl(DebuggerThriftBuffer &thrift) {
DebuggerCommand::sendImpl(thrift);
thrift.write(m_frame);
{
String sdata;
DebuggerWireHelpers::WireSerialize(m_variables, sdata);
thrift.write(sdata);
}
thrift.write(m_global);
}
void CmdVariable::recvImpl(DebuggerThriftBuffer &thrift) {
DebuggerCommand::recvImpl(thrift);
thrift.read(m_frame);
{
String sdata;
thrift.read(sdata);
if (DebuggerWireHelpers::WireUnserialize(sdata, m_variables) !=
DebuggerWireHelpers::NoError) {
m_variables = null_array;
m_wireError = sdata;
}
}
thrift.read(m_global);
}
bool CmdVariable::help(DebuggerClient *client) {
client->helpTitle("Variable Command");
client->helpCmds(
"[v]ariable", "lists all local variables on stack",
"[v]ariable {text}", "full-text search local variables",
nullptr
);
client->helpBody(
"This will print names and values of all variables that are currently "
"accessible by simple names. Use '[w]here', '[u]p {num}', '[d]own {num}', "
"'[f]rame {index}' commands to choose a different frame to view variables "
"at different level of the stack.\n"
"\n"
"Specify some free text to print local variables that contain the text "
"either in their names or values. The search is case-insensitive and "
"string-based."
);
return true;
}
void CmdVariable::PrintVariables(DebuggerClient *client, CArrRef variables,
bool global, CStrRef text) {
bool system = true;
int i = 0;
bool found = false;
for (ArrayIter iter(variables); iter; ++iter) {
String name = iter.first().toString();
String value = DebuggerClient::FormatVariable(iter.second(), 200);
if (!text.empty()) {
String fullvalue = DebuggerClient::FormatVariable(iter.second(), -1);
if (name.find(text, 0, false) >= 0 ||
fullvalue.find(text, 0, false) >= 0) {
client->print("%s = %s", name.data(), value.data());
found = true;
}
} else {
if (global && system) {
client->print("$%s = %s", name.data(), value.data());
} else {
client->output("$%s = %s", name.data(), value.data());
}
// we knew this is the last system global
if (global && name == "http_response_header") {
client->output("");
system = false;
}
++i;
if (!client->isApiMode() &&
i % DebuggerClient::ScrollBlockSize == 0 &&
client->ask("There are %d more variables. Continue? [Y/n]",
variables.size() - i) == 'n') {
break;
}
}
}
if (!text.empty() && !found) {
client->info("(unable to find specified text in any variables)");
}
}
bool CmdVariable::onClient(DebuggerClient *client) {
if (DebuggerCommand::onClient(client)) return true;
String text;
if (client->argCount() == 1) {
text = client->argValue(1);
} else if (client->argCount() != 0) {
return help(client);
}
m_frame = client->getFrame();
CmdVariablePtr cmd = client->xend<CmdVariable>(this);
if (cmd->m_variables.empty()) {
client->info("(no variable was defined)");
} else {
m_variables = cmd->m_variables;
PrintVariables(client, cmd->m_variables, cmd->m_global, text);
}
return true;
}
void CmdVariable::setClientOutput(DebuggerClient *client) {
client->setOutputType(DebuggerClient::OTValues);
Array values;
for (ArrayIter iter(m_variables); iter; ++iter) {
String name = iter.first().toString();
if (client->getDebuggerClientApiModeSerialize()) {
values.set(name,
DebuggerClient::FormatVariable(iter.second(), 200));
} else {
values.set(name, iter.second());
}
}
client->setOTValues(values);
}
Array CmdVariable::GetGlobalVariables() {
Array ret = g_vmContext->m_globalVarEnv->getDefinedVariables();
ret.remove("GLOBALS");
return ret;
}
bool CmdVariable::onServer(DebuggerProxy *proxy) {
m_variables = g_vmContext->getLocalDefinedVariables(m_frame);
return proxy->sendToClient(this);
}
///////////////////////////////////////////////////////////////////////////////
}}