Skip to content

Commit

Permalink
closes #8
Browse files Browse the repository at this point in the history
  • Loading branch information
partouf committed Jan 7, 2022
1 parent 1240297 commit 549869e
Show file tree
Hide file tree
Showing 9 changed files with 86 additions and 51 deletions.
9 changes: 6 additions & 3 deletions src/assembly/parser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ bool AsmParser::AssemblyTextParser::handleStabs(const std::string_view line)
if (type == 68)
{
this->state.currentSourceRef =
asm_source_v{ .file = {}, .file_idx = 0, .line = iline, .is_end = false, .is_usercode = false, .inside_proc = false };
asm_source_v{ .file = {}, .file_idx = 0, .line = iline, .column = 0, .is_end = false, .is_usercode = false, .inside_proc = false };
}
else if (type == 100 || type == 132)
{
Expand Down Expand Up @@ -59,14 +59,15 @@ bool AsmParser::AssemblyTextParser::handleFiledef(const std::string_view line)

bool AsmParser::AssemblyTextParser::handleSource(const std::string_view line)
{
const auto [file_index, line_index] = AssemblyTextParserUtils::getSourceRef(line);
const auto [file_index, line_index, column] = AssemblyTextParserUtils::getSourceRef(line);
if (file_index != 0)
{
this->state.hasProcMarkers = true;

this->state.currentSourceRef.file_idx = file_index;

this->state.currentSourceRef.line = line_index;
this->state.currentSourceRef.column = column;
this->state.currentSourceRef.inside_proc = true;

this->amendPreviousLinesWith(this->state.currentSourceRef);
Expand Down Expand Up @@ -141,6 +142,7 @@ bool AsmParser::AssemblyTextParser::handleD2(const std::string_view line)
this->state.currentSourceRef = asm_source_v{ .file = this->state.currentSourceFile,
.file_idx = 0,
.line = line_source.line,
.column = 0,
.is_end = false,
.is_usercode = match_stdin,
.inside_proc = false };
Expand Down Expand Up @@ -170,7 +172,7 @@ bool AsmParser::AssemblyTextParser::handle6502(const std::string_view line)
const auto source = match.value();
if (!source.is_end)
this->state.currentSourceRef = asm_source_v{
.file = source.file, .file_idx = 0, .line = source.line, .is_end = false, .is_usercode = false, .inside_proc = false
.file = source.file, .file_idx = 0, .line = source.line, .column = 0, .is_end = false, .is_usercode = false, .inside_proc = false
};

return true;
Expand Down Expand Up @@ -519,6 +521,7 @@ void AsmParser::AssemblyTextParser::amendPreviousLinesWith(const asm_source_v &s
line->source = asm_source_v{ .file = source.file,
.file_idx = source.file_idx,
.line = source.line,
.column = source.column,
.is_end = false,
.is_usercode = source.is_usercode && !line->is_internal_label,
.inside_proc = source.inside_proc };
Expand Down
2 changes: 1 addition & 1 deletion src/objdump/parser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -333,7 +333,7 @@ void AsmParser::ObjDumpParser::fromStream(std::istream &in)
{
if (c == ':')
{
this->state.currentSourceRef = asm_source{ .file = this->state.text, .line = 0 };
this->state.currentSourceRef = asm_source{ .file = this->state.text, .line = 0, .column = 0 };
this->state.text.clear();
continue;
}
Expand Down
3 changes: 2 additions & 1 deletion src/test/test_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,10 @@

TEST_CASE("Test text assembly utilities", "[asm]")
{
const auto [file, line] = AsmParser::AssemblyTextParserUtils::getSourceRef(R"( .loc 1 351 7)");
const auto [file, line, column] = AsmParser::AssemblyTextParserUtils::getSourceRef(R"( .loc 1 351 7)");
REQUIRE(file == 1);
REQUIRE(line == 351);
REQUIRE(column == 7);

const auto file_def = AsmParser::AssemblyTextParserUtils::getFileDef(
R"( .file 2 "/opt/compiler-explorer/gcc-10.2.0/include/c++/10.2.0/bits/char_traits.h")");
Expand Down
3 changes: 3 additions & 0 deletions src/types/line.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ struct asm_source
std::string file;
int32_t file_idx{ 0 };
int32_t line{ 0 };
int32_t column;
bool is_usercode{};
bool inside_proc{};
};
Expand All @@ -56,6 +57,7 @@ struct asm_source_v
std::string_view file;
int32_t file_idx;
int32_t line;
int32_t column;
bool is_end;
bool is_usercode;
bool inside_proc;
Expand Down Expand Up @@ -153,6 +155,7 @@ class asm_line_v
this->source = asm_source_v{ .file = line.source.file,
.file_idx = line.source.file_idx,
.line = line.source.line,
.column = line.source.column,
.is_end = false,
.is_usercode = line.source.is_usercode,
.inside_proc = line.source.inside_proc };
Expand Down
88 changes: 48 additions & 40 deletions src/utils/jsonwriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,12 @@ void AsmParser::JsonWriter::writeSource(const asm_line_v *line)
if ((!line->is_label || line->has_opcode) && (line->source.line > 0))
{
this->out << "{";

if (line->source.column != 0)
{
this->writeKv("column", line->source.column, jsonopt::trailingcomma);
}

if (line->source.is_usercode || (this->filter.binary && this->filter.compatmode))
{
this->writeKvNull("file", jsonopt::trailingcomma);
Expand All @@ -177,6 +183,7 @@ void AsmParser::JsonWriter::writeSource(const asm_line_v *line)
}

this->writeKv("line", line->source.line, jsonopt::none);

this->out << "}";
}
else
Expand All @@ -194,6 +201,10 @@ void AsmParser::JsonWriter::writeLine(const asm_line_v *line)
if (this->prettyPrint)
this->out << "\n";

this->writeKeyName("labels");
this->writeLabelArray(line);
wroteSomethingInRoot = true;

if (line->opcodes.size() > 0)
{
if (wroteSomethingInRoot)
Expand All @@ -206,23 +217,7 @@ void AsmParser::JsonWriter::writeLine(const asm_line_v *line)
}

this->writeKeyName("opcodes");

this->out << "[";
bool firstOpcode = true;
for (auto &opcode : line->opcodes)
{
if (!firstOpcode)
{
this->out << ", ";
}
else
{
firstOpcode = false;
}

this->out << "\"" << opcode << "\"";
}
this->out << "]";
this->writeOpcodesArray(line);
}

if (line->address.has_value() && !(line->is_label && this->filter.compatmode))
Expand All @@ -239,19 +234,6 @@ void AsmParser::JsonWriter::writeLine(const asm_line_v *line)
this->writeKv("address", line->address.value(), jsonopt::none);
}

{
if (wroteSomethingInRoot)
{
this->out << ", ";
}
else
{
wroteSomethingInRoot = true;
}

this->writeKv("text", line->text, jsonopt::none);
}

if (wroteSomethingInRoot)
{
this->out << ", ";
Expand All @@ -274,16 +256,47 @@ void AsmParser::JsonWriter::writeLine(const asm_line_v *line)
this->writeKv("section", line->section, jsonopt::none);
}

if (wroteSomethingInRoot)
{
this->out << ", ";
if (wroteSomethingInRoot)
{
this->out << ", ";
}
else
{
wroteSomethingInRoot = true;
}

this->writeKv("text", line->text, jsonopt::none);
}
else

if (this->prettyPrint)
this->out << "\n";

this->out << "}";
}

void AsmParser::JsonWriter::writeOpcodesArray(const asm_line_v *line)
{
this->out << "[";
bool firstOpcode = true;
for (auto &opcode : line->opcodes)
{
wroteSomethingInRoot = true;
if (!firstOpcode)
{
this->out << ", ";
}
else
{
firstOpcode = false;
}

this->out << "\"" << opcode << "\"";
}
this->out << "]";
}

this->writeKeyName("labels");
void AsmParser::JsonWriter::writeLabelArray(const asm_line_v *line)
{
this->out << "[";

bool firstLabel = true;
Expand All @@ -310,11 +323,6 @@ void AsmParser::JsonWriter::writeLine(const asm_line_v *line)
this->out << "}";
}
this->out << "]";

if (this->prettyPrint)
this->out << "\n";

this->out << "}";
}

void AsmParser::JsonWriter::JsonWriter::write()
Expand Down
2 changes: 2 additions & 0 deletions src/utils/jsonwriter.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ class JsonWriter
void writeKv(const char *key, const int value, const jsonopt opts);
void writeSource(const asm_line_v *line);
void writeLine(const asm_line_v *line);
void writeLabelArray(const asm_line_v *line);
void writeOpcodesArray(const asm_line_v *line);

public:
JsonWriter(std::ostream &out,
Expand Down
1 change: 1 addition & 0 deletions src/utils/regexes.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ struct Regexes
static constexpr auto commentOnly = ctre::match<R"re(^\h*(((#|@|//).*)|(/\*.*\*/)|(;\s*)|(;[^;].*)|(;;.*\S.*))$)re">;
static constexpr auto commentOnlyNvcc = ctre::match<R"re(^\h*(((#|;|//).*)|(/\*.*\*/))$)re">;
static constexpr auto sourceTag = ctre::match<R"re(^\h*\.loc\h+(\d+)\h+(\d+).*)re">;
static constexpr auto sourceTagWithColumn = ctre::match<R"re(^\h*\.loc\h+(\d+)\h+(\d+)\h+(\d+).*)re">;
static constexpr auto source6502Dbg = ctre::match<R"re(^\h*\.dbg\h+line,\h*"([^"]+)",\h*(\d+))re">;
static constexpr auto source6502DbgEnd = ctre::search<R"re(^\h*\.dbg\h+line)re">;
static constexpr auto sourceStab = ctre::search<R"re(^\h*\.stabn\h+(\d+),0,(\d+),.*)re">;
Expand Down
20 changes: 15 additions & 5 deletions src/utils/regexwrappers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,19 +8,27 @@ inline int svtoi(const std::string_view sv)
return std::atoi(sv.data());
}

std::pair<int, int> AsmParser::AssemblyTextParserUtils::getSourceRef(const std::string_view line)
AsmParser::regexed_sourceref AsmParser::AssemblyTextParserUtils::getSourceRef(const std::string_view line)
{
const auto match = AsmParser::Regexes::sourceTag(line);
if (match)
{
const auto file_index = svtoi(match.get<1>().to_view());
const auto line_index = svtoi(match.get<2>().to_view());

return { file_index, line_index };
int column = 0;

const auto matchWithColumn = AsmParser::Regexes::sourceTagWithColumn(line);
if (matchWithColumn)
{
column = svtoi(matchWithColumn.get<3>().to_view());
}

return { file_index, line_index, column };
}
else
{
return { 0, 0 };
return { 0, 0, 0 };
}
}

Expand Down Expand Up @@ -313,14 +321,16 @@ std::optional<AsmParser::asm_source_v> AsmParser::AssemblyTextParserUtils::get65
const auto iline = svtoi(match.get<2>().to_view());

// todo check if stdin?
return asm_source_v{ .file = file, .file_idx = 0, .line = iline, .is_end = false, .is_usercode = false, .inside_proc = false };
return asm_source_v{
.file = file, .file_idx = 0, .line = iline, .column = 0, .is_end = false, .is_usercode = false, .inside_proc = false
};
}
else
{
const auto matchend = Regexes::source6502DbgEnd(line);
if (matchend)
{
return asm_source_v{ .file = {}, .file_idx = 0, .line = 0, .is_end = true, .is_usercode = false, .inside_proc = false };
return asm_source_v{ .file = {}, .file_idx = 0, .line = 0, .column = 0, .is_end = true, .is_usercode = false, .inside_proc = false };
}
}

Expand Down
9 changes: 8 additions & 1 deletion src/utils/regexwrappers.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,17 @@
namespace AsmParser
{

struct regexed_sourceref
{
int file_index;
int line_index;
int column;
};

class AssemblyTextParserUtils
{
public:
static std::pair<int, int> getSourceRef(const std::string_view line);
static regexed_sourceref getSourceRef(const std::string_view line);
static std::optional<AsmParser::asm_file_def> getFileDef(const std::string_view line);
static bool is_probably_label(const std::string_view line);
static std::string fixLabelIndentation(const std::string_view line);
Expand Down

0 comments on commit 549869e

Please sign in to comment.