isolate Location specifics to private class variables to enforce correct line number ordering

This commit is contained in:
Vern Paxson 2025-07-03 16:41:14 -07:00 committed by Arne Welzel
parent eb6b4a0c46
commit 5c63133226
30 changed files with 172 additions and 136 deletions

View file

@ -133,7 +133,8 @@ bool DbgBreakpoint::SetLocation(ParseLocationRec plr, std::string_view loc_str)
function_name = make_full_var_name(current_module.c_str(), loc_s.c_str()); function_name = make_full_var_name(current_module.c_str(), loc_s.c_str());
at_stmt = plr.stmt; at_stmt = plr.stmt;
const Location* loc = at_stmt->GetLocationInfo(); const Location* loc = at_stmt->GetLocationInfo();
snprintf(description, sizeof(description), "%s at %s:%d", function_name.c_str(), loc->filename, loc->last_line); snprintf(description, sizeof(description), "%s at %s:%d", function_name.c_str(), loc->FileName(),
loc->LastLine());
debug_msg("Breakpoint %d set at %s\n", GetID(), Description()); debug_msg("Breakpoint %d set at %s\n", GetID(), Description());
} }
@ -154,7 +155,7 @@ bool DbgBreakpoint::SetLocation(Stmt* stmt) {
AddToGlobalMap(); AddToGlobalMap();
const Location* loc = stmt->GetLocationInfo(); const Location* loc = stmt->GetLocationInfo();
snprintf(description, sizeof(description), "%s:%d", loc->filename, loc->last_line); snprintf(description, sizeof(description), "%s:%d", loc->FileName(), loc->LastLine());
debug_msg("Breakpoint %d set at %s\n", GetID(), Description()); debug_msg("Breakpoint %d set at %s\n", GetID(), Description());
@ -261,7 +262,7 @@ BreakCode DbgBreakpoint::ShouldBreak(Stmt* s) {
break; break;
case BP_LINE: case BP_LINE:
assert(s->GetLocationInfo()->first_line <= source_line && s->GetLocationInfo()->last_line >= source_line); assert(s->GetLocationInfo()->FirstLine() <= source_line && s->GetLocationInfo()->LastLine() >= source_line);
break; break;
case BP_TIME: assert(false); case BP_TIME: assert(false);
@ -310,7 +311,7 @@ void DbgBreakpoint::PrintHitMsg() {
const Location* loc = at_stmt->GetLocationInfo(); const Location* loc = at_stmt->GetLocationInfo();
debug_msg("Breakpoint %d, %s at %s:%d\n", GetID(), d.Description(), loc->filename, loc->first_line); debug_msg("Breakpoint %d, %s at %s:%d\n", GetID(), d.Description(), loc->FileName(), loc->FirstLine());
} }
return; return;

View file

@ -84,8 +84,8 @@ bool StmtLocMapping::StartsAfter(const StmtLocMapping* m2) {
if ( ! m2 ) if ( ! m2 )
reporter->InternalError("Assertion failed: m2 != 0"); reporter->InternalError("Assertion failed: m2 != 0");
return loc.first_line > m2->loc.first_line || return loc.FirstLine() > m2->loc.FirstLine() ||
(loc.first_line == m2->loc.first_line && loc.first_column > m2->loc.first_column); (loc.FirstLine() == m2->loc.FirstLine() && loc.FirstColumn() > m2->loc.FirstColumn());
} }
// Generic debug message output. // Generic debug message output.
@ -143,7 +143,6 @@ int TraceState::LogTrace(const char* fmt, ...) {
const Stmt* stmt; const Stmt* stmt;
Location loc; Location loc;
loc.filename = nullptr;
if ( g_frame_stack.size() > 0 && g_frame_stack.back() ) { if ( g_frame_stack.size() > 0 && g_frame_stack.back() ) {
stmt = g_frame_stack.back()->GetNextStmt(); stmt = g_frame_stack.back()->GetNextStmt();
@ -156,13 +155,13 @@ int TraceState::LogTrace(const char* fmt, ...) {
} }
} }
if ( ! loc.filename ) { if ( ! loc.FileName() ) {
static constexpr const char str[] = "<no filename>"; static constexpr const char str[] = "<no filename>";
loc.filename = str; loc.SetFile(str);
loc.last_line = 0; loc.SetLastLine(0);
} }
fprintf(trace_file, "%s:%d", loc.filename, loc.last_line); fprintf(trace_file, "%s:%d", loc.FileName(), loc.LastLine());
// Each stack frame is indented. // Each stack frame is indented.
for ( int i = 0; i < int(g_frame_stack.size()); ++i ) for ( int i = 0; i < int(g_frame_stack.size()); ++i )
@ -239,7 +238,7 @@ static void parse_function_name(vector<ParseLocationRec>& result, ParseLocationR
Stmt* first; Stmt* first;
Location stmt_loc; Location stmt_loc;
get_first_statement(bodies[i].stmts.get(), first, stmt_loc); get_first_statement(bodies[i].stmts.get(), first, stmt_loc);
debug_msg("[%d] %s:%d\n", i + 1, stmt_loc.filename, stmt_loc.first_line); debug_msg("[%d] %s:%d\n", i + 1, stmt_loc.FileName(), stmt_loc.FirstLine());
} }
debug_msg("[a] All of the above\n"); debug_msg("[a] All of the above\n");
@ -283,8 +282,8 @@ static void parse_function_name(vector<ParseLocationRec>& result, ParseLocationR
get_first_statement(body, first, stmt_loc); get_first_statement(body, first, stmt_loc);
if ( first ) { if ( first ) {
plr.stmt = first; plr.stmt = first;
plr.filename = stmt_loc.filename; plr.filename = stmt_loc.FileName();
plr.line = stmt_loc.last_line; plr.line = stmt_loc.LastLine();
} }
} }
@ -299,8 +298,8 @@ static void parse_function_name(vector<ParseLocationRec>& result, ParseLocationR
result_plr.type = PLR_FUNCTION; result_plr.type = PLR_FUNCTION;
result_plr.stmt = first; result_plr.stmt = first;
result_plr.filename = stmt_loc.filename; result_plr.filename = stmt_loc.FileName();
result_plr.line = stmt_loc.last_line; result_plr.line = stmt_loc.LastLine();
result.push_back(result_plr); result.push_back(result_plr);
} }
} }
@ -317,7 +316,7 @@ vector<ParseLocationRec> parse_location_string(const string& s) {
std::string loc_filename; std::string loc_filename;
if ( sscanf(s.c_str(), "%d", &plr.line) ) { // just a line number (implicitly referring to the current file) if ( sscanf(s.c_str(), "%d", &plr.line) ) { // just a line number (implicitly referring to the current file)
loc_filename = g_debugger_state.last_loc.filename; loc_filename = g_debugger_state.last_loc.FileName();
plr.type = PLR_FILE_AND_LINE; plr.type = PLR_FILE_AND_LINE;
} }
@ -360,12 +359,12 @@ vector<ParseLocationRec> parse_location_string(const string& s) {
StmtLocMapping* hit = nullptr; StmtLocMapping* hit = nullptr;
for ( const auto entry : *(iter->second) ) { for ( const auto entry : *(iter->second) ) {
plr.filename = entry->Loc().filename; plr.filename = entry->Loc().FileName();
if ( entry->Loc().first_line > plr.line ) if ( entry->Loc().FirstLine() > plr.line )
break; break;
if ( plr.line >= entry->Loc().first_line && plr.line <= entry->Loc().last_line ) { if ( plr.line >= entry->Loc().FirstLine() && plr.line <= entry->Loc().LastLine() ) {
hit = entry; hit = entry;
break; break;
} }
@ -677,13 +676,13 @@ string get_context_description(const Stmt* stmt, const Frame* frame) {
loc = *stmt->GetLocationInfo(); loc = *stmt->GetLocationInfo();
else { else {
static constexpr const char str[] = "<no filename>"; static constexpr const char str[] = "<no filename>";
loc.filename = str; loc.SetFile(str);
loc.last_line = 0; loc.SetLastLine(0);
} }
size_t buf_size = strlen(d.Description()) + strlen(loc.filename) + 1024; size_t buf_size = strlen(d.Description()) + strlen(loc.FileName()) + 1024;
char* buf = new char[buf_size]; char* buf = new char[buf_size];
snprintf(buf, buf_size, "In %s at %s:%d", d.Description(), loc.filename, loc.last_line); snprintf(buf, buf_size, "In %s at %s:%d", d.Description(), loc.FileName(), loc.LastLine());
string retval(buf); string retval(buf);
delete[] buf; delete[] buf;
@ -720,7 +719,7 @@ int dbg_handle_debug_input() {
step_or_next_pending = false; step_or_next_pending = false;
PrintLines(loc.filename, loc.first_line, loc.last_line - loc.first_line + 1, true); PrintLines(loc.FileName(), loc.FirstLine(), loc.LastLine() - loc.FirstLine() + 1, true);
g_debugger_state.last_loc = loc; g_debugger_state.last_loc = loc;
do { do {
@ -872,8 +871,8 @@ ValPtr dbg_eval_expr(const char* expr) {
// Fix filename and line number for the lexer/parser, which record it. // Fix filename and line number for the lexer/parser, which record it.
filename = "<interactive>"; filename = "<interactive>";
line_number = 1; line_number = 1;
yylloc.filename = filename; yylloc.SetFile(filename);
yylloc.first_line = yylloc.last_line = line_number = 1; yylloc.SetLine(1);
// Parse the thing into an expr. // Parse the thing into an expr.
ValPtr result; ValPtr result;

View file

@ -561,22 +561,22 @@ int dbg_cmd_list(DebugCmd cmd, const vector<string>& args) {
return false; return false;
} }
g_debugger_state.last_loc.filename = plr.filename; g_debugger_state.last_loc.SetFile(plr.filename);
g_debugger_state.last_loc.first_line = plr.line; g_debugger_state.last_loc.SetFirstLine(plr.line);
pre_offset = 0; pre_offset = 0;
} }
if ( (int)pre_offset + (int)g_debugger_state.last_loc.first_line - (int)CENTER_IDX < 0 ) if ( (int)pre_offset + (int)g_debugger_state.last_loc.FirstLine() - (int)CENTER_IDX < 0 )
pre_offset = CENTER_IDX - g_debugger_state.last_loc.first_line; pre_offset = CENTER_IDX - g_debugger_state.last_loc.FirstLine();
g_debugger_state.last_loc.first_line += pre_offset; g_debugger_state.last_loc.IncrementLine(pre_offset);
int last_line_in_file = how_many_lines_in(g_debugger_state.last_loc.filename); int last_line_in_file = how_many_lines_in(g_debugger_state.last_loc.FileName());
if ( g_debugger_state.last_loc.first_line > last_line_in_file ) if ( g_debugger_state.last_loc.FirstLine() > last_line_in_file )
g_debugger_state.last_loc.first_line = last_line_in_file; g_debugger_state.last_loc.SetLine(last_line_in_file);
PrintLines(g_debugger_state.last_loc.filename, g_debugger_state.last_loc.first_line - CENTER_IDX, 10, true); PrintLines(g_debugger_state.last_loc.FileName(), g_debugger_state.last_loc.FirstLine() - CENTER_IDX, 10, true);
g_debugger_state.already_did_list = true; g_debugger_state.already_did_list = true;

View file

@ -111,7 +111,7 @@ std::string render_call_stack() {
if ( ci.call ) { if ( ci.call ) {
auto loc = ci.call->GetLocationInfo(); auto loc = ci.call->GetLocationInfo();
rval += util::fmt(" at %s:%d", loc->filename, loc->first_line); rval += util::fmt(" at %s:%d", loc->FileName(), loc->FirstLine());
} }
++lvl; ++lvl;
@ -919,8 +919,8 @@ zeek::RecordValPtr make_backtrace_element(std::string_view name, const VectorVal
elem->Assign(function_args_idx, args); elem->Assign(function_args_idx, args);
if ( loc ) { if ( loc ) {
elem->Assign(file_location_idx, loc->filename); elem->Assign(file_location_idx, loc->FileName());
elem->Assign(line_location_idx, loc->first_line); elem->Assign(line_location_idx, loc->FirstLine());
} }
return elem; return elem;

View file

@ -16,30 +16,34 @@ Location start_location("<start uninitialized>", 0, 0, 0, 0);
Location end_location("<end uninitialized>", 0, 0, 0, 0); Location end_location("<end uninitialized>", 0, 0, 0, 0);
void Location::Describe(ODesc* d) const { void Location::Describe(ODesc* d) const {
if ( filename ) { if ( FileName() ) {
d->Add(filename); d->Add(FileName());
if ( first_line == 0 ) if ( FirstLine() == 0 )
return; return;
d->AddSP(","); d->AddSP(",");
} }
if ( last_line != first_line ) { if ( LastLine() != FirstLine() ) {
if ( LastLine() < FirstLine() )
reporter->InternalError("Location::Describe: %s inconsistent: last_line %d < first_line %d", FileName(),
LastLine(), FirstLine());
d->Add("lines "); d->Add("lines ");
d->Add(first_line); d->Add(FirstLine());
d->Add("-"); d->Add("-");
d->Add(last_line); d->Add(LastLine());
} }
else { else {
d->Add("line "); d->Add("line ");
d->Add(first_line); d->Add(FirstLine());
} }
} }
bool Location::operator==(const Location& l) const { bool Location::operator==(const Location& l) const {
if ( filename == l.filename || (filename && l.filename && util::streq(filename, l.filename)) ) if ( FileName() == l.FileName() || (FileName() && l.FileName() && util::streq(FileName(), l.FileName())) )
return first_line == l.first_line && last_line == l.last_line; return FirstLine() == l.FirstLine() && LastLine() == l.LastLine();
else else
return false; return false;
} }
@ -121,15 +125,15 @@ bool Obj::SetLocationInfo(const detail::Location* start, const detail::Location*
if ( ! start || ! end ) if ( ! start || ! end )
return false; return false;
if ( end->filename && ! util::streq(start->filename, end->filename) ) if ( end->FileName() && ! util::streq(start->FileName(), end->FileName()) )
return false; return false;
if ( location && (start == &detail::no_location || end == &detail::no_location) ) if ( location && (start == &detail::no_location || end == &detail::no_location) )
// We already have a better location, so don't use this one. // We already have a better location, so don't use this one.
return true; return true;
auto new_location = auto new_location = new detail::Location(start->FileName(), start->FirstLine(), end->LastLine(),
new detail::Location(start->filename, start->first_line, end->last_line, start->first_column, end->last_column); start->FirstColumn(), end->LastColumn());
// Don't delete this until we've constructed the new location, in case // Don't delete this until we've constructed the new location, in case
// "start" or "end" are our own location. // "start" or "end" are our own location.
@ -143,8 +147,8 @@ void Obj::UpdateLocationEndInfo(const detail::Location& end) {
if ( ! location ) if ( ! location )
SetLocationInfo(&end, &end); SetLocationInfo(&end, &end);
location->last_line = end.last_line; location->SetLastLine(end.LastLine());
location->last_column = end.last_column; location->SetLastColumn(end.LastColumn());
} }
void Obj::DoMsg(ODesc* d, const char s1[], const Obj* obj2, bool pinpoint_only, void Obj::DoMsg(ODesc* d, const char s1[], const Obj* obj2, bool pinpoint_only,

View file

@ -3,6 +3,7 @@
#pragma once #pragma once
#include <climits> #include <climits>
#include <string>
namespace zeek { namespace zeek {
@ -13,7 +14,9 @@ namespace detail {
class Location final { class Location final {
public: public:
constexpr Location(const char* fname, int line_f, int line_l, int col_f, int col_l) noexcept constexpr Location(const char* fname, int line_f, int line_l, int col_f, int col_l) noexcept
: filename(fname), first_line(line_f), last_line(line_l), first_column(col_f), last_column(col_l) {} : filename(fname), first_column(col_f), last_column(col_l) {
SetLines(line_f, line_l);
}
Location() = default; Location() = default;
@ -22,9 +25,42 @@ public:
bool operator==(const Location& l) const; bool operator==(const Location& l) const;
bool operator!=(const Location& l) const { return ! (*this == l); } bool operator!=(const Location& l) const { return ! (*this == l); }
const char* FileName() const { return filename; }
int FirstLine() const { return first_line; }
int LastLine() const { return last_line; }
// Columns are actually not currently maintained.
auto FirstColumn() const { return first_column; }
auto LastColumn() const { return last_column; }
void SetFile(const char* fname) { filename = fname; }
void SetLine(int line) { SetLines(line, line); }
constexpr void SetLines(int first, int last) {
if ( first > last ) {
// We don't use std::swap() here because it's not
// constexpr-enabled on older versions of C++.
auto tmp = first;
first = last;
last = tmp;
}
first_line = first;
last_line = last;
}
void SetFirstLine(int line) { SetLines(line, last_line); }
void SetLastLine(int line) { SetLines(first_line, line); }
void IncrementLine(int incr = 1) {
first_line += incr;
last_line += incr;
}
void SetFirstColumn(int col) { first_column = col; }
void SetLastColumn(int col) { last_column = col; }
private:
const char* filename = nullptr; const char* filename = nullptr;
int first_line = 0, last_line = 0; int first_line = 0, last_line = 0;
int first_column = 0, last_column = 0; int first_column = 0, last_column = 0; // not currently maintained
}; };
#define YYLTYPE zeek::detail::yyltype #define YYLTYPE zeek::detail::yyltype
@ -73,7 +109,7 @@ public:
// of 0, which should only happen if it's been assigned // of 0, which should only happen if it's been assigned
// to no_location (or hasn't been initialized at all). // to no_location (or hasn't been initialized at all).
location = nullptr; location = nullptr;
if ( detail::start_location.first_line != 0 ) if ( detail::start_location.FirstLine() != 0 )
SetLocationInfo(&detail::start_location, &detail::end_location); SetLocationInfo(&detail::start_location, &detail::end_location);
} }

View file

@ -32,13 +32,13 @@ void ScriptProfile::ChildFinished(const ScriptProfile* child) {
void ScriptProfile::Report(FILE* f, bool with_traces) const { void ScriptProfile::Report(FILE* f, bool with_traces) const {
std::string l; std::string l;
if ( loc.first_line == 0 ) if ( loc.FirstLine() == 0 )
// Rather than just formatting the no-location loc, we'd like // Rather than just formatting the no-location loc, we'd like
// a version that doesn't have a funky "line 0" in it, nor // a version that doesn't have a funky "line 0" in it, nor
// an embedded blank. // an embedded blank.
l = "<no-location>"; l = "<no-location>";
else else
l = std::string(loc.filename) + ":" + std::to_string(loc.first_line); l = util::fmt("%s:%d", loc.FileName(), loc.FirstLine());
std::string ftype = is_BiF ? "BiF" : func->GetType()->FlavorString(); std::string ftype = is_BiF ? "BiF" : func->GetType()->FlavorString();
std::string call_stacks; std::string call_stacks;

View file

@ -152,7 +152,7 @@ bool Stmt::SetLocationInfo(const Location* start, const Location* end) {
// Update the Filemap of line number -> statement mapping for // Update the Filemap of line number -> statement mapping for
// breakpoints (Debug.h). // breakpoints (Debug.h).
auto map_iter = g_dbgfilemaps.find(location->filename); auto map_iter = g_dbgfilemaps.find(location->FileName());
if ( map_iter == g_dbgfilemaps.end() ) if ( map_iter == g_dbgfilemaps.end() )
return false; return false;

View file

@ -109,7 +109,7 @@ Trigger::Trigger(std::shared_ptr<WhenInfo> wi, const IDSet& _globals, std::vecto
attached = nullptr; attached = nullptr;
if ( loc ) if ( loc )
name = util::fmt("%s:%d-%d", loc->filename, loc->first_line, loc->last_line); name = util::fmt("%s:%d-%d", loc->FileName(), loc->FirstLine(), loc->LastLine());
else else
name = "<no-trigger-location>"; name = "<no-trigger-location>";

View file

@ -155,9 +155,9 @@ std::string_view determine_script_location() {
// remove wrapper function. // remove wrapper function.
const auto* loc = ce->GetLocationInfo(); const auto* loc = ce->GetLocationInfo();
std::string normalized_location = zeek::util::detail::without_zeekpath_component(loc->filename); std::string normalized_location = zeek::util::detail::without_zeekpath_component(loc->FileName());
normalized_location.append(":"); normalized_location.append(":");
normalized_location.append(std::to_string(loc->first_line)); normalized_location.append(std::to_string(loc->FirstLine()));
auto [it, inserted] = location_cache.emplace(ce, std::move(normalized_location)); auto [it, inserted] = location_cache.emplace(ce, std::move(normalized_location));
assert(inserted); assert(inserted);

View file

@ -149,7 +149,7 @@ bool Ascii::OpenFile() {
if ( ! read_location ) { if ( ! read_location ) {
read_location = LocationPtr(new zeek::detail::Location()); read_location = LocationPtr(new zeek::detail::Location());
read_location->filename = util::copy_string(fname.c_str(), fname.size()); read_location->SetFile(util::copy_string(fname.c_str(), fname.size()));
} }
StopWarningSuppression(); StopWarningSuppression();
@ -228,8 +228,7 @@ bool Ascii::ReadHeader(bool useCached) {
bool Ascii::GetLine(string& str) { bool Ascii::GetLine(string& str) {
while ( getline(file, str) ) { while ( getline(file, str) ) {
if ( read_location ) { if ( read_location ) {
read_location->first_line++; read_location->IncrementLine();
read_location->last_line++;
} }
if ( str.empty() ) if ( str.empty() )
@ -255,10 +254,8 @@ bool Ascii::DoUpdate() {
if ( ! OpenFile() ) if ( ! OpenFile() )
return ! fail_on_file_problem; return ! fail_on_file_problem;
if ( read_location ) { if ( read_location )
read_location->first_line = 0; read_location->SetLine(0);
read_location->last_line = 0;
}
switch ( Info().mode ) { switch ( Info().mode ) {
case MODE_REREAD: { case MODE_REREAD: {
@ -331,7 +328,7 @@ bool Ascii::DoUpdate() {
// add non-present field // add non-present field
fields[fpos] = new Value(fit.type, false); fields[fpos] = new Value(fit.type, false);
if ( read_location ) if ( read_location )
fields[fpos]->SetFileLineNumber(read_location->first_line); fields[fpos]->SetFileLineNumber(read_location->FirstLine());
fpos++; fpos++;
continue; continue;
} }
@ -367,7 +364,7 @@ bool Ascii::DoUpdate() {
} }
if ( read_location ) if ( read_location )
val->SetFileLineNumber(read_location->first_line); val->SetFileLineNumber(read_location->FirstLine());
if ( fit.secondary_position != -1 ) { if ( fit.secondary_position != -1 ) {
// we have a port definition :) // we have a port definition :)

View file

@ -94,7 +94,7 @@ private:
// correctly when the unique_ptr gets reset. // correctly when the unique_ptr gets reset.
struct LocationDeleter { struct LocationDeleter {
void operator()(zeek::detail::Location* loc) const { void operator()(zeek::detail::Location* loc) const {
delete[] loc->filename; delete[] loc->FileName();
delete loc; delete loc;
} }
}; };

View file

@ -369,7 +369,7 @@ zeek:
// associated with the last @load'd file rather than // associated with the last @load'd file rather than
// the script that includes the global statements. // the script that includes the global statements.
auto loc = zeek::detail::GetCurrentLocation(); auto loc = zeek::detail::GetCurrentLocation();
if ( loc.filename ) if ( loc.FileName() )
set_location(loc); set_location(loc);
} }
stmt_list stmt_list

View file

@ -456,7 +456,7 @@ void rules_error(const char* msg, const char* addl) {
void rules_error(zeek::detail::Rule* r, const char* msg) { void rules_error(zeek::detail::Rule* r, const char* msg) {
const zeek::detail::Location& l = r->GetLocation(); const zeek::detail::Location& l = r->GetLocation();
zeek::reporter->Error("Error in signature %s (%s:%d): %s", r->ID(), l.filename, l.first_line, msg); zeek::reporter->Error("Error in signature %s (%s:%d): %s", r->ID(), l.FileName(), l.FirstLine(), msg);
zeek::detail::rule_matcher->SetParseError(); zeek::detail::rule_matcher->SetParseError();
} }

View file

@ -273,8 +273,7 @@ ESCSEQ (\\([^\r\n]|[0-7]+|x[[:xdigit:]]+))
<INITIAL,IGNORE>\r?\n { <INITIAL,IGNORE>\r?\n {
++line_number; ++line_number;
++yylloc.first_line; yylloc.IncrementLine();
++yylloc.last_line;
} }
/* IPv6 literal constant patterns */ /* IPv6 literal constant patterns */
@ -748,24 +747,26 @@ F RET_CONST(zeek::val_mgr->False()->Ref())
YYLTYPE zeek::detail::GetCurrentLocation() { YYLTYPE zeek::detail::GetCurrentLocation() {
static YYLTYPE currloc; static YYLTYPE currloc;
currloc.filename = filename; currloc.SetFile(filename);
currloc.first_line = currloc.last_line = line_number; currloc.SetLine(line_number);
return currloc; return currloc;
} }
void zeek::detail::SetCurrentLocation(YYLTYPE currloc) { void zeek::detail::SetCurrentLocation(YYLTYPE currloc) {
::filename = currloc.filename; ::filename = currloc.FileName();
line_number = currloc.first_line; line_number = currloc.FirstLine();
} }
static int switch_to(const char* file, YY_BUFFER_STATE buffer) { static int switch_to(const char* file, YY_BUFFER_STATE buffer) {
yy_switch_to_buffer(buffer); yy_switch_to_buffer(buffer);
yylloc.first_line = yylloc.last_line = line_number = 1; line_number = 1;
yylloc.SetLine(1);
// Don't delete the old filename - it's pointed to by // Don't delete the old filename - it's pointed to by
// every Obj created when parsing it. // every Obj created when parsing it.
yylloc.filename = filename = zeek::util::copy_string(file); filename = zeek::util::copy_string(file);
yylloc.SetFile(filename);
current_file_has_conditionals = files_with_conditionals.count(filename) > 0; current_file_has_conditionals = files_with_conditionals.count(filename) > 0;
@ -866,7 +867,8 @@ static int load_files(const char* orig_file) {
} }
yy_switch_to_buffer(buffer); yy_switch_to_buffer(buffer);
yylloc.first_line = yylloc.last_line = line_number = 1; line_number = 1;
yylloc.SetLine(1);
return switch_to(file_path.c_str(), buffer); return switch_to(file_path.c_str(), buffer);
} }
@ -1178,7 +1180,8 @@ int yywrap() {
} }
zeek::detail::params.clear(); zeek::detail::params.clear();
yylloc.filename = filename = "<params>"; filename = "<params>";
yylloc.SetFile(filename);
yy_scan_string(policy.c_str()); yy_scan_string(policy.c_str());
return 0; return 0;
} }
@ -1192,7 +1195,8 @@ int yywrap() {
int tmp_len = strlen(zeek::detail::command_line_policy) + 32; int tmp_len = strlen(zeek::detail::command_line_policy) + 32;
char* tmp = new char[tmp_len]; char* tmp = new char[tmp_len];
snprintf(tmp, tmp_len, "%s\n;\n", zeek::detail::command_line_policy); snprintf(tmp, tmp_len, "%s\n;\n", zeek::detail::command_line_policy);
yylloc.filename = filename = "<command line>"; filename = "<command line>";
yylloc.SetFile(filename);
yy_scan_string(tmp); yy_scan_string(tmp);
delete[] tmp; delete[] tmp;
@ -1219,8 +1223,10 @@ FileInfo::~FileInfo() {
fclose(yyin); fclose(yyin);
yy_switch_to_buffer(buffer_state); yy_switch_to_buffer(buffer_state);
yylloc.filename = filename = name; filename = name;
yylloc.first_line = yylloc.last_line = line_number = line; line_number = line;
yylloc.SetFile(filename);
yylloc.SetLine(line);
if ( restore_module != "" ) if ( restore_module != "" )
zeek::detail::current_module = restore_module; zeek::detail::current_module = restore_module;

View file

@ -148,7 +148,7 @@ void CPPCompile::DeclareSubclass(const FuncTypePtr& ft, const ProfileFunc* pf, c
stmts = pf->ProfiledExpr(); stmts = pf->ProfiledExpr();
auto loc = stmts->GetLocationInfo(); auto loc = stmts->GetLocationInfo();
auto loc_info = string("\"") + loc->filename + "\", " + Fmt(loc->first_line); auto loc_info = string("\"") + loc->FileName() + "\", " + Fmt(loc->FirstLine());
Emit("%s_cl(const char* name%s) : CPPStmt(name, %s)%s { }", fname, addl_args, loc_info, inits); Emit("%s_cl(const char* name%s) : CPPStmt(name, %s)%s { }", fname, addl_args, loc_info, inits);
// An additional constructor just used to generate place-holder // An additional constructor just used to generate place-holder

View file

@ -193,7 +193,7 @@ bool CPPCompile::AnalyzeFuncBody(FuncInfo& fi, unordered_set<string>& filenames_
const auto& f = fi.Func(); const auto& f = fi.Func();
auto& body = fi.Body(); auto& body = fi.Body();
string fn = body->GetLocationInfo()->filename; string fn = body->GetLocationInfo()->FileName();
if ( ! analysis_options.allow_cond && ! fi.ShouldSkip() ) { if ( ! analysis_options.allow_cond && ! fi.ShouldSkip() ) {
if ( ! analysis_options.only_files.empty() && files_with_conditionals.count(fn) > 0 ) { if ( ! analysis_options.only_files.empty() && files_with_conditionals.count(fn) > 0 ) {
@ -358,7 +358,7 @@ void CPPCompile::RegisterCompiledBody(const string& f) {
auto h = body_hashes[f]; auto h = body_hashes[f];
auto p = body_priorities[f]; auto p = body_priorities[f];
auto loc = body_locs[f]; auto loc = body_locs[f];
auto body_info = Fmt(p) + ", " + Fmt(h) + ", \"" + loc->filename + " (C++)\", " + Fmt(loc->first_line); auto body_info = Fmt(p) + ", " + Fmt(h) + ", \"" + loc->FileName() + " (C++)\", " + Fmt(loc->FirstLine());
Emit("\tCPP_RegisterBody(\"%s\", (void*) %s, %s, %s, std::vector<std::string>(%s)),", f, f, Fmt(type_signature), Emit("\tCPP_RegisterBody(\"%s\", (void*) %s, %s, %s, std::vector<std::string>(%s)),", f, f, Fmt(type_signature),
body_info, events); body_info, events);

View file

@ -182,8 +182,8 @@ string CPPCompile::BodyName(const FuncInfo& func) {
// Extend name with location information. // Extend name with location information.
auto loc = body->GetLocationInfo(); auto loc = body->GetLocationInfo();
if ( loc->filename ) { if ( loc->FileName() ) {
auto fn = loc->filename; auto fn = loc->FileName();
// Skip leading goop that gets added by search paths. // Skip leading goop that gets added by search paths.
while ( *fn == '.' || *fn == '/' ) while ( *fn == '.' || *fn == '/' )

View file

@ -11,7 +11,7 @@ using namespace std;
void CPPCompile::GenStmt(const Stmt* s) { void CPPCompile::GenStmt(const Stmt* s) {
auto loc = s->GetLocationInfo(); auto loc = s->GetLocationInfo();
if ( loc != &detail::no_location && s->Tag() != STMT_LIST ) if ( loc != &detail::no_location && s->Tag() != STMT_LIST )
Emit("// %s:%s", loc->filename, to_string(loc->first_line)); Emit("// %s:%d", loc->FileName(), loc->FirstLine());
switch ( s->Tag() ) { switch ( s->Tag() ) {
case STMT_INIT: GenInitStmt(s->AsInitStmt()); break; case STMT_INIT: GenInitStmt(s->AsInitStmt()); break;
@ -498,8 +498,8 @@ void CPPCompile::GenAssertStmt(const AssertStmt* a) {
Emit("auto msg_val = zeek::val_mgr->EmptyString();"); Emit("auto msg_val = zeek::val_mgr->EmptyString();");
auto loc = a->GetLocationInfo(); auto loc = a->GetLocationInfo();
Emit("static Location loc(\"%s\", %s, %s, %s, %s);", loc->filename, std::to_string(loc->first_line), Emit("static Location loc(\"%s\", %s, %s, %s, %s);", loc->FileName(), std::to_string(loc->FirstLine()),
std::to_string(loc->last_line), std::to_string(loc->first_column), std::to_string(loc->last_column)); std::to_string(loc->LastLine()), std::to_string(loc->FirstColumn()), std::to_string(loc->LastColumn()));
Emit("report_assert(assert_result, \"%s\", msg_val, &loc);", CPPEscape(a->CondDesc().c_str()).c_str()); Emit("report_assert(assert_result, \"%s\", msg_val, &loc);", CPPEscape(a->CondDesc().c_str()).c_str());
EndBlock(); EndBlock();

View file

@ -205,7 +205,7 @@ shared_ptr<CPP_InitInfo> CPPCompile::RegisterType(const TypePtr& tp) {
auto tr = tp->AsRecordType(); auto tr = tp->AsRecordType();
for ( auto i = tr->NumOrigFields(); i < tr->NumFields(); ++i ) { for ( auto i = tr->NumOrigFields(); i < tr->NumFields(); ++i ) {
auto fd = tr->FieldDecl(i); auto fd = tr->FieldDecl(i);
if ( filename_matches_opt_files(fd->GetLocationInfo()->filename) ) { if ( filename_matches_opt_files(fd->GetLocationInfo()->FileName()) ) {
if ( addl_fields == 0 ) if ( addl_fields == 0 )
addl_fields = i; addl_fields = i;
} }

View file

@ -1450,12 +1450,12 @@ static std::unordered_map<std::string, std::string> filename_module;
void switch_to_module(const char* module_name) { void switch_to_module(const char* module_name) {
auto loc = GetCurrentLocation(); auto loc = GetCurrentLocation();
if ( loc.first_line != 0 && filename_module.count(loc.filename) == 0 ) if ( loc.FirstLine() != 0 && filename_module.count(loc.FileName()) == 0 )
filename_module[loc.filename] = module_name; filename_module[loc.FileName()] = module_name;
} }
std::string func_name_at_loc(std::string fname, const Location* loc) { std::string func_name_at_loc(std::string fname, const Location* loc) {
auto find_module = filename_module.find(loc->filename); auto find_module = filename_module.find(loc->FileName());
if ( find_module == filename_module.end() ) if ( find_module == filename_module.end() )
// No associated module. // No associated module.
return fname; return fname;
@ -1476,15 +1476,14 @@ std::string func_name_at_loc(std::string fname, const Location* loc) {
TraversalCode SetBlockLineNumbers::PreStmt(const Stmt* s) { TraversalCode SetBlockLineNumbers::PreStmt(const Stmt* s) {
auto loc = const_cast<Location*>(s->GetLocationInfo()); auto loc = const_cast<Location*>(s->GetLocationInfo());
UpdateLocInfo(loc); UpdateLocInfo(loc);
block_line_range.emplace_back(loc->first_line, loc->last_line); block_line_range.emplace_back(loc->FirstLine(), loc->LastLine());
return TC_CONTINUE; return TC_CONTINUE;
} }
TraversalCode SetBlockLineNumbers::PostStmt(const Stmt* s) { TraversalCode SetBlockLineNumbers::PostStmt(const Stmt* s) {
auto loc = const_cast<Location*>(s->GetLocationInfo()); auto loc = const_cast<Location*>(s->GetLocationInfo());
auto r = block_line_range.back(); auto r = block_line_range.back();
loc->first_line = r.first; loc->SetLines(r.first, r.second);
loc->last_line = r.second;
block_line_range.pop_back(); block_line_range.pop_back();
@ -1505,12 +1504,8 @@ TraversalCode SetBlockLineNumbers::PreExpr(const Expr* e) {
} }
void SetBlockLineNumbers::UpdateLocInfo(Location* loc) { void SetBlockLineNumbers::UpdateLocInfo(Location* loc) {
// Sometimes locations are generated with inverted line coverage. auto first_line = loc->FirstLine();
if ( loc->first_line > loc->last_line ) auto last_line = loc->LastLine();
std::swap(loc->first_line, loc->last_line);
auto first_line = loc->first_line;
auto last_line = loc->last_line;
if ( ! block_line_range.empty() ) { if ( ! block_line_range.empty() ) {
auto& r = block_line_range.back(); auto& r = block_line_range.back();
@ -1573,7 +1568,7 @@ TraversalCode ASTBlockAnalyzer::PreExpr(const Expr* e) {
} }
std::string ASTBlockAnalyzer::BuildExpandedDescription(const Location* loc) { std::string ASTBlockAnalyzer::BuildExpandedDescription(const Location* loc) {
ASSERT(loc && loc->first_line != 0); ASSERT(loc && loc->FirstLine() != 0);
auto ls = LocWithFunc(loc); auto ls = LocWithFunc(loc);
if ( ! parents.empty() ) { if ( ! parents.empty() ) {

View file

@ -686,17 +686,17 @@ private:
// Return the key used to associate a Location object with its full // Return the key used to associate a Location object with its full
// descriptiion. // descriptiion.
std::string LocKey(const Location* loc) const { std::string LocKey(const Location* loc) const {
return std::string(loc->filename) + ":" + std::to_string(loc->first_line) + "-" + return std::string(loc->FileName()) + ":" + std::to_string(loc->FirstLine()) + "-" +
std::to_string(loc->last_line); std::to_string(loc->LastLine());
} }
// Return the description of a location including its the function // Return the description of a location including its the function
// in which it's embedded. // in which it's embedded.
std::string LocWithFunc(const Location* loc) const { std::string LocWithFunc(const Location* loc) const {
auto res = func_name_prefix + std::to_string(loc->first_line); auto res = func_name_prefix + std::to_string(loc->FirstLine());
if ( loc->first_line != loc->last_line ) if ( loc->FirstLine() != loc->LastLine() )
res += "-" + std::to_string(loc->last_line); res += "-" + std::to_string(loc->LastLine());
return res; return res;
} }

View file

@ -139,7 +139,7 @@ bool filename_matches_opt_files(const char* filename) {
return false; return false;
} }
bool obj_matches_opt_files(const Obj* obj) { return filename_matches_opt_files(obj->GetLocationInfo()->filename); } bool obj_matches_opt_files(const Obj* obj) { return filename_matches_opt_files(obj->GetLocationInfo()->FileName()); }
static bool optimize_AST(ScriptFuncPtr f, std::shared_ptr<ProfileFunc>& pf, std::shared_ptr<Reducer>& rc, static bool optimize_AST(ScriptFuncPtr f, std::shared_ptr<ProfileFunc>& pf, std::shared_ptr<Reducer>& rc,
ScopePtr scope, StmtPtr& body) { ScopePtr scope, StmtPtr& body) {

View file

@ -22,9 +22,9 @@ ZAMCompiler::ZAMCompiler(ScriptFuncPtr f, std::shared_ptr<ProfileFuncs> _pfs, st
frame_sizeI = 0; frame_sizeI = 0;
auto loc = body->GetLocationInfo(); auto loc = body->GetLocationInfo();
ASSERT(loc->first_line != 0 || body->Tag() == STMT_NULL); ASSERT(loc->FirstLine() != 0 || body->Tag() == STMT_NULL);
auto loc_copy = auto loc_copy = std::make_shared<Location>(loc->FileName(), loc->FirstLine(), loc->LastLine(), loc->FirstColumn(),
std::make_shared<Location>(loc->filename, loc->first_line, loc->last_line, loc->first_column, loc->last_column); loc->LastColumn());
ZAM::curr_func = func->GetName(); ZAM::curr_func = func->GetName();
ZAM::curr_loc = std::make_shared<ZAMLocInfo>(ZAM::curr_func, std::move(loc_copy), nullptr); ZAM::curr_loc = std::make_shared<ZAMLocInfo>(ZAM::curr_func, std::move(loc_copy), nullptr);

View file

@ -39,9 +39,9 @@ std::string ZAMLocInfo::Describe(bool include_lines) const {
desc = func_name; desc = func_name;
if ( include_lines ) { if ( include_lines ) {
desc += ";" + func_name + ":" + std::to_string(loc->first_line); desc += ";" + func_name + ":" + std::to_string(loc->FirstLine());
if ( loc->last_line > loc->first_line ) if ( loc->LastLine() > loc->FirstLine() )
desc += "-" + std::to_string(loc->last_line); desc += "-" + std::to_string(loc->LastLine());
} }
} }

View file

@ -12,9 +12,9 @@ namespace zeek::detail {
const ZAMStmt ZAMCompiler::CompileStmt(const Stmt* s) { const ZAMStmt ZAMCompiler::CompileStmt(const Stmt* s) {
auto loc = s->GetLocationInfo(); auto loc = s->GetLocationInfo();
ASSERT(loc->first_line != 0 || s->Tag() == STMT_NULL); ASSERT(loc->FirstLine() != 0 || s->Tag() == STMT_NULL);
auto loc_copy = auto loc_copy = std::make_shared<Location>(loc->FileName(), loc->FirstLine(), loc->LastLine(), loc->FirstColumn(),
std::make_shared<Location>(loc->filename, loc->first_line, loc->last_line, loc->first_column, loc->last_column); loc->LastColumn());
ASSERT(! AST_blocks || s->Tag() == STMT_NULL || AST_blocks->HaveExpDesc(loc_copy.get())); ASSERT(! AST_blocks || s->Tag() == STMT_NULL || AST_blocks->HaveExpDesc(loc_copy.get()));
auto loc_parent = ZAM::curr_loc->Parent(); auto loc_parent = ZAM::curr_loc->Parent();
ZAM::curr_loc = std::make_shared<ZAMLocInfo>(ZAM::curr_func, std::move(loc_copy), ZAM::curr_loc->Parent()); ZAM::curr_loc = std::make_shared<ZAMLocInfo>(ZAM::curr_func, std::move(loc_copy), ZAM::curr_loc->Parent());

View file

@ -488,16 +488,14 @@ static std::unique_ptr<detail::Location> _makeLocation(const std::string& locati
return nullptr; return nullptr;
auto loc = std::make_unique<detail::Location>(); auto loc = std::make_unique<detail::Location>();
loc->filename = filenames.insert(std::string(x[0])).first->c_str(); // we retain ownership loc->SetFile(filenames.insert(std::string(x[0])).first->c_str()); // we retain ownership
if ( x.size() >= 2 ) { if ( x.size() >= 2 ) {
auto y = hilti::rt::split(x[1], "-"); auto y = hilti::rt::split(x[1], "-");
if ( y.size() >= 2 ) { if ( y.size() >= 2 )
loc->first_line = std::stoi(std::string(y[0])); loc->SetLines(std::stoi(std::string(y[0])), std::stoi(std::string(y[1])));
loc->last_line = std::stoi(std::string(y[1]));
}
else if ( y[0].size() ) else if ( y[0].size() )
loc->first_line = loc->last_line = std::stoi(std::string(y[0])); loc->SetLine(std::stoi(std::string(y[0])));
} }
return loc; return loc;

View file

@ -239,7 +239,7 @@ void Manager::StartType(zeek::detail::IDPtr id) {
return; return;
} }
string script = normalize_script_path(id->GetLocationInfo()->filename); string script = normalize_script_path(id->GetLocationInfo()->FileName());
ScriptInfo* script_info = scripts.GetInfo(script); ScriptInfo* script_info = scripts.GetInfo(script);
if ( ! script_info ) { if ( ! script_info ) {
@ -291,7 +291,7 @@ void Manager::Identifier(zeek::detail::IDPtr id, bool from_redef) {
return; return;
} }
string script = normalize_script_path(id->GetLocationInfo()->filename); string script = normalize_script_path(id->GetLocationInfo()->FileName());
ScriptInfo* script_info = scripts.GetInfo(script); ScriptInfo* script_info = scripts.GetInfo(script);
if ( ! script_info ) { if ( ! script_info ) {

View file

@ -173,7 +173,7 @@ std::optional<std::string> source_code_range(const zeek::detail::ID* id) {
if ( id->IsType() ) { if ( id->IsType() ) {
loc = type->GetLocationInfo(); loc = type->GetLocationInfo();
if ( zeek::util::ends_with(loc->filename, ".bif.zeek") ) if ( zeek::util::ends_with(loc->FileName(), ".bif.zeek") )
// Source code won't be available to reference, so fall back // Source code won't be available to reference, so fall back
// to identifier location which may actually be in a regular // to identifier location which may actually be in a regular
// .zeek script. // .zeek script.
@ -191,8 +191,8 @@ std::optional<std::string> source_code_range(const zeek::detail::ID* id) {
if ( loc == &zeek::detail::no_location ) if ( loc == &zeek::detail::no_location )
return {}; return {};
return util::fmt("%s %d %d", normalize_script_path(loc->filename).data(), loc->first_line, return util::fmt("%s %d %d", normalize_script_path(loc->FileName()).data(), loc->FirstLine(),
loc->last_line + extra_lines); loc->LastLine() + extra_lines);
} }
} // namespace zeek::zeekygen::detail } // namespace zeek::zeekygen::detail

View file

@ -24,7 +24,7 @@ std::pair<int, std::optional<std::string>> Plugin::HookLoadFileExtended(const Lo
const std::string& resolved) { const std::string& resolved) {
// Zeek implicitly provides the location where the current '@load' // Zeek implicitly provides the location where the current '@load'
// originated. If no location is available, filename will be a nullptr. // originated. If no location is available, filename will be a nullptr.
auto src = zeek::detail::GetCurrentLocation().filename; auto src = zeek::detail::GetCurrentLocation().FileName();
if ( ! src ) if ( ! src )
src = "n/a"; src = "n/a";