void AMXStackFramePrinter::PrintCallerName(const AMXStackFrame &frame) { if (IsMain(frame.amx(), frame.caller_address())) { stream_ << "main"; return; } if (debug_info_.IsLoaded()) { AMXDebugSymbol caller = debug_info_.GetExactFunction(frame.caller_address()); if (caller) { if (IsPublicFunction(frame.amx(), caller.GetCodeStart()) && !IsMain(frame.amx(), caller.GetCodeStart())) { stream_ << "public "; } PrintTag(caller); stream_ << caller.GetName(); return; } } const char *name = 0; if (frame.caller_address() != 0) { name = frame.amx().FindPublic(frame.caller_address()); } if (name != 0) { stream_ << "public " << name; } else { stream_ << "??"; } }
void AMXStackFramePrinter::PrintCallerName(const AMXStackFrame &frame, const AMXDebugSymbol &caller) { bool is_public = IsPublicFunction(frame.amx(), caller.GetCodeStart()); bool is_main = IsMain(frame.amx(), caller.GetCodeStart()); if (is_public && !is_main) { *stream_ << "public "; } PrintTag(caller); *stream_ << caller.GetName(); }
void AMXStackFramePrinter::PrintArgumentValue(const AMXStackFrame &frame, const AMXDebugSymbol &arg, int index) { std::string tag_name = debug_info_->GetTagName(arg.GetTag()); cell value = GetArgumentValue(frame.amx(), frame.address(), index); if (arg.IsVariable()) { if (tag_name == "bool") { *stream_ << (value ? "true" : "false"); } else if (tag_name == "Float") { *stream_ << std::fixed << std::setprecision(5) << amx_ctof(value); } else { *stream_ << value; } } else { std::vector<AMXDebugSymbolDim> dims = arg.GetDims(); // For arrays/references we just output their AMX address. char old_fill = stream_->fill('0'); *stream_ << "@0x" << std::hex << std::setw(kCellWidthChars) << value << std::dec; stream_->fill(old_fill); if ((arg.IsArray() || arg.IsArrayRef()) && dims.size() == 1 && tag_name == "_" && debug_info_->GetTagName(dims[0].GetTag()) == "_") { std::string string; bool packed; GetStringContents(frame.amx(), value, dims[0].GetSize(), string, packed); *stream_ << (packed ? " !" : " "); static const std::size_t kMaxString = 30; if (string.length() > kMaxString) { string.replace(kMaxString, string.length() - kMaxString, "..."); } *stream_ << "\"" << string << "\""; } } }
void AMXStackFramePrinter::PrintArgument(const AMXStackFrame &frame, const AMXDebugSymbol &arg, int index) { if (arg.IsReference()) { *stream_ << "&"; } PrintTag(arg); *stream_ << arg.GetName(); if (!arg.IsVariable()) { std::vector<AMXDebugSymbolDim> dims = arg.GetDims(); if (arg.IsArray() || arg.IsArrayRef()) { for (std::size_t i = 0; i < dims.size(); ++i) { if (dims[i].GetSize() == 0) { *stream_ << "[]"; } else { std::string tag = debug_info_->GetTagName(dims[i].GetTag()) + ":"; if (tag == "_:") tag.clear(); *stream_ << "[" << tag << dims[i].GetSize() << "]"; } } } } *stream_ << "="; PrintArgumentValue(frame, arg, index); }
void AMXStackFramePrinter::PrintArgumentValue(const AMXStackFrame &frame, const AMXDebugSymbol &arg, int index) { std::string tag_name = debug_info_.GetTagName(arg.GetTag()); cell value = GetArgumentValue(frame, index); if (arg.IsVariable()) { PrintValue(tag_name, value); return; } stream_ << "@"; PrintAddress(value); if (arg.IsReference()) { if (cell *ptr = GetDataPtr(frame.amx(), value)) { stream_ << " "; PrintValue(tag_name, *ptr); } return; } if (arg.IsArray() || arg.IsArrayRef()) { std::vector<AMXDebugSymbolDim> dims = arg.GetDims(); // Try to filter out non-printable arrays (e.g. non-strings). // This doesn't work 100% of the time, but it's better than nothing. if (dims.size() == 1 && tag_name == "_" && debug_info_.GetTagName(dims[0].GetTag()) == "_") { std::string string; bool packed; GetStringContents(frame.amx(), value, dims[0].GetSize(), string, packed); stream_ << (packed ? " !" : " "); static const std::size_t kMaxString = 80; if (string.length() > kMaxString) { string.replace(kMaxString, string.length() - kMaxString, "..."); } stream_ << "\"" << string << "\""; } } }
void AMXStackFramePrinter::PrintTag(const AMXDebugSymbol &symbol) { std::string tag_name = debug_info_->GetTagName(symbol.GetTag()); if (!tag_name.empty() && tag_name != "_") { *stream_ << tag_name << ":"; } }