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::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 << "\""; } } }