Merge "Switch everything to platforms"
diff --git a/aos/events/logging/log_cat.cc b/aos/events/logging/log_cat.cc
index 7dabc18..1168e6f 100644
--- a/aos/events/logging/log_cat.cc
+++ b/aos/events/logging/log_cat.cc
@@ -5,7 +5,6 @@
#include <string>
#include <string_view>
#include <vector>
-#include "dirent.h"
#include "aos/configuration.h"
#include "aos/events/logging/logger.h"
@@ -32,11 +31,9 @@
"If positive, vectors longer than this will not be printed");
DEFINE_bool(pretty, false,
"If true, pretty print the messages on multiple lines");
-
-bool EndsWith(std::string_view str, std::string_view ending) {
- return str.size() >= ending.size() &&
- str.substr(str.size() - ending.size()) == ending;
-}
+DEFINE_bool(print, true,
+ "If true, actually print the messages. If false, discard them, "
+ "confirming they can be parsed.");
// Print the flatbuffer out to stdout, both to remove the unnecessary cruft from
// glog and to allow the user to readily redirect just the logged output
@@ -64,33 +61,6 @@
}
}
-void SearchDirectory(std::vector<std::string> *files, std::string filename) {
- DIR *directory = opendir(filename.c_str());
-
- if (directory == nullptr) {
- // its not a directory
- // it could be a file
- // or it could not exist
- if (EndsWith(filename, ".bfbs") || EndsWith(filename, ".bfbs.xz")) {
- files->emplace_back(filename);
- }
- return;
- }
-
- struct dirent *directory_entry;
- while ((directory_entry = readdir(directory)) != nullptr) {
- std::string next_filename = directory_entry->d_name;
- if (next_filename == "." || next_filename == "..") {
- continue;
- }
-
- std::string path = filename + "/" + next_filename;
- SearchDirectory(files, path);
- }
-
- closedir(directory);
-}
-
int main(int argc, char **argv) {
gflags::SetUsageMessage(
"Usage:\n"
@@ -156,10 +126,8 @@
LOG(FATAL) << "Expected at least 1 logfile as an argument.";
}
- std::vector<std::string> unsorted_logfiles;
- for (int i = 1; i < argc; ++i) {
- SearchDirectory(&unsorted_logfiles, argv[i]);
- }
+ const std::vector<std::string> unsorted_logfiles =
+ aos::logger::FindLogs(argc, argv);
const std::vector<aos::logger::LogFile> logfiles =
aos::logger::SortParts(unsorted_logfiles);
@@ -238,7 +206,9 @@
printer_event_loop->MakeRawWatcher(
channel, [channel, node_name, &builder](const aos::Context &context,
const void * /*message*/) {
- PrintMessage(node_name, channel, context, &builder);
+ if (FLAGS_print) {
+ PrintMessage(node_name, channel, context, &builder);
+ }
});
found_channel = true;
}
@@ -247,8 +217,10 @@
// Print the messages from before the log start time.
// TODO(austin): Sort between nodes too when it becomes annoying enough.
for (const MessageInfo &message : messages_before_start) {
- PrintMessage(message.node_name, message.fetcher->channel(),
- message.fetcher->context(), &builder);
+ if (FLAGS_print) {
+ PrintMessage(message.node_name, message.fetcher->channel(),
+ message.fetcher->context(), &builder);
+ }
}
printer_event_loops.emplace_back(std::move(printer_event_loop));
diff --git a/aos/events/logging/logfile_sorting.cc b/aos/events/logging/logfile_sorting.cc
index 168230e..1998119 100644
--- a/aos/events/logging/logfile_sorting.cc
+++ b/aos/events/logging/logfile_sorting.cc
@@ -5,6 +5,8 @@
#include <string>
#include <utility>
#include <vector>
+#include "dirent.h"
+#include "sys/stat.h"
#include "aos/events/logging/logfile_utils.h"
#include "aos/flatbuffers.h"
@@ -14,6 +16,60 @@
namespace logger {
namespace chrono = std::chrono;
+namespace {
+
+// Check if string ends with ending
+bool EndsWith(std::string_view str, std::string_view ending) {
+ return str.size() >= ending.size() &&
+ str.substr(str.size() - ending.size()) == ending;
+}
+
+bool FileExists(std::string filename) {
+ struct stat stat_results;
+ int error = stat(filename.c_str(), &stat_results);
+ return error == 0;
+}
+
+} // namespace
+
+void FindLogs(std::vector<std::string> *files, std::string filename) {
+ DIR *directory = opendir(filename.c_str());
+
+ if (directory == nullptr) {
+ if (EndsWith(filename, ".bfbs") || EndsWith(filename, ".bfbs.xz")) {
+ files->emplace_back(filename);
+ }
+ return;
+ }
+
+ struct dirent *directory_entry;
+ while ((directory_entry = readdir(directory)) != nullptr) {
+ std::string next_filename = directory_entry->d_name;
+ if (next_filename == "." || next_filename == "..") {
+ continue;
+ }
+
+ std::string path = filename + "/" + next_filename;
+ FindLogs(files, path);
+ }
+
+ closedir(directory);
+}
+
+std::vector<std::string> FindLogs(int argc, char **argv) {
+ std::vector<std::string> found_logfiles;
+
+ for (int i = 1; i < argc; i++) {
+ std::string filename = argv[i];
+ if (FileExists(filename)) {
+ aos::logger::FindLogs(&found_logfiles, filename);
+ } else {
+ LOG(FATAL) << "File " << filename << " does not exist";
+ }
+ }
+ return found_logfiles;
+}
+
std::vector<LogFile> SortParts(const std::vector<std::string> &parts) {
std::vector<std::string> corrupted;
@@ -260,7 +316,7 @@
std::vector<std::string> FindNodes(const std::vector<LogFile> &parts) {
std::set<std::string> nodes;
for (const LogFile &log_file : parts) {
- for (const LogParts& part : log_file.parts) {
+ for (const LogParts &part : log_file.parts) {
nodes.insert(part.node);
}
}
@@ -275,7 +331,7 @@
std::string_view node) {
std::vector<LogParts> result;
for (const LogFile &log_file : parts) {
- for (const LogParts& part : log_file.parts) {
+ for (const LogParts &part : log_file.parts) {
if (part.node == node) {
result.emplace_back(part);
}
diff --git a/aos/events/logging/logfile_sorting.h b/aos/events/logging/logfile_sorting.h
index 94cb771..b955a09 100644
--- a/aos/events/logging/logfile_sorting.h
+++ b/aos/events/logging/logfile_sorting.h
@@ -2,8 +2,8 @@
#define AOS_EVENTS_LOGGING_LOGFILE_SORTING_H_
#include <iostream>
-#include <vector>
#include <string>
+#include <vector>
#include "aos/events/logging/uuid.h"
#include "aos/time/time.h"
@@ -62,6 +62,13 @@
std::vector<LogParts> FilterPartsForNode(const std::vector<LogFile> &parts,
std::string_view node);
+// Recursively searches the file/folder for .bfbs and .bfbs.xz files and adds
+// them to the vector.
+void FindLogs(std::vector<std::string> *files, std::string filename);
+
+// Recursively searches for logfiles in argv[1] and onward.
+std::vector<std::string> FindLogs(int argc, char **argv);
+
} // namespace logger
} // namespace aos
diff --git a/aos/events/logging/logfile_utils.cc b/aos/events/logging/logfile_utils.cc
index 9316795..98527dc 100644
--- a/aos/events/logging/logfile_utils.cc
+++ b/aos/events/logging/logfile_utils.cc
@@ -362,7 +362,11 @@
ResizeableBuffer data;
data.resize(config_data.size());
memcpy(data.data(), config_data.begin(), data.size());
- return SizePrefixedFlatbufferVector<LogFileHeader>(std::move(data));
+ SizePrefixedFlatbufferVector<LogFileHeader> result(std::move(data));
+ if (!result.Verify()) {
+ return std::nullopt;
+ }
+ return result;
}
std::optional<SizePrefixedFlatbufferVector<MessageHeader>> ReadNthMessage(
@@ -382,7 +386,11 @@
ResizeableBuffer data;
data.resize(data_span.size());
memcpy(data.data(), data_span.begin(), data.size());
- return SizePrefixedFlatbufferVector<MessageHeader>(std::move(data));
+ SizePrefixedFlatbufferVector<MessageHeader> result(std::move(data));
+ if (!result.Verify()) {
+ return std::nullopt;
+ }
+ return result;
}
MessageReader::MessageReader(std::string_view filename)
diff --git a/aos/events/pong.cc b/aos/events/pong.cc
index f9f35c2..2f5a0a5 100644
--- a/aos/events/pong.cc
+++ b/aos/events/pong.cc
@@ -9,9 +9,7 @@
DEFINE_string(config, "aos/events/pingpong_config.json", "Path to the config.");
int main(int argc, char **argv) {
- FLAGS_logtostderr = true;
- google::InitGoogleLogging(argv[0]);
- ::gflags::ParseCommandLineFlags(&argc, &argv, true);
+ aos::InitGoogle(&argc, &argv);
aos::FlatbufferDetachedBuffer<aos::Configuration> config =
aos::configuration::ReadConfig(FLAGS_config);
diff --git a/aos/events/simulated_event_loop.cc b/aos/events/simulated_event_loop.cc
index 4c28039..9c8bb09 100644
--- a/aos/events/simulated_event_loop.cc
+++ b/aos/events/simulated_event_loop.cc
@@ -856,7 +856,9 @@
aos::monotonic_clock::time_point monotonic_remote_time,
aos::realtime_clock::time_point realtime_remote_time,
uint32_t remote_queue_index) {
- CHECK_LE(size, this->size()) << ": Attempting to send too big a message.";
+ CHECK_LE(size, this->size())
+ << ": Attempting to send too big a message on "
+ << configuration::CleanedChannelToString(simulated_channel_->channel());
// This is wasteful, but since flatbuffers fill from the back end of the
// queue, we need it to be full sized.
diff --git a/third_party/flatbuffers/build_defs.bzl b/third_party/flatbuffers/build_defs.bzl
index 4462c8e..5994848 100644
--- a/third_party/flatbuffers/build_defs.bzl
+++ b/third_party/flatbuffers/build_defs.bzl
@@ -22,6 +22,7 @@
"--keep-prefix",
"--cpp-std",
"c++17",
+ "--require-explicit-ids",
"--gen-mutable",
"--reflect-names",
"--cpp-ptr-type flatbuffers::unique_ptr",
diff --git a/third_party/flatbuffers/reflection/reflection.fbs b/third_party/flatbuffers/reflection/reflection.fbs
index d9e2dc4..61d2f0c 100644
--- a/third_party/flatbuffers/reflection/reflection.fbs
+++ b/third_party/flatbuffers/reflection/reflection.fbs
@@ -31,84 +31,84 @@
}
table Type {
- base_type:BaseType;
- element:BaseType = None; // Only if base_type == Vector
- // or base_type == Array.
- index:int = -1; // If base_type == Object, index into "objects" below.
- // If base_type == Union, UnionType, or integral derived
- // from an enum, index into "enums" below.
- fixed_length:uint16 = 0; // Only if base_type == Array.
+ base_type:BaseType (id: 0);
+ element:BaseType = None (id: 1); // Only if base_type == Vector
+ // or base_type == Array.
+ index:int = -1 (id: 2); // If base_type == Object, index into "objects" below.
+ // If base_type == Union, UnionType, or integral derived
+ // from an enum, index into "enums" below.
+ fixed_length:uint16 = 0 (id: 3); // Only if base_type == Array.
}
table KeyValue {
- key:string (required, key);
- value:string;
+ key:string (required, key, id: 0);
+ value:string (id: 1);
}
table EnumVal {
- name:string (required);
- value:long (key);
- object:Object; // Will be deprecated in favor of union_type in the future.
- union_type:Type;
- documentation:[string];
+ name:string (required, id: 0);
+ value:long (key, id: 1);
+ object:Object (id: 2); // Will be deprecated in favor of union_type in the future.
+ union_type:Type (id: 3);
+ documentation:[string] (id: 4);
}
table Enum {
- name:string (required, key);
- values:[EnumVal] (required); // In order of their values.
- is_union:bool = false;
- underlying_type:Type (required);
- attributes:[KeyValue];
- documentation:[string];
+ name:string (required, key, id: 0);
+ values:[EnumVal] (required, id: 1); // In order of their values.
+ is_union:bool = false (id: 2);
+ underlying_type:Type (required, id: 3);
+ attributes:[KeyValue] (id: 4);
+ documentation:[string] (id: 5);
}
table Field {
- name:string (required, key);
- type:Type (required);
- id:ushort;
- offset:ushort; // Offset into the vtable for tables, or into the struct.
- default_integer:long = 0;
- default_real:double = 0.0;
- deprecated:bool = false;
- required:bool = false;
- key:bool = false;
- attributes:[KeyValue];
- documentation:[string];
- optional:bool = false;
+ name:string (required, key, id: 0);
+ type:Type (required, id: 1);
+ id:ushort (id: 2);
+ offset:ushort (id: 3); // Offset into the vtable for tables, or into the struct.
+ default_integer:long = 0 (id: 4);
+ default_real:double = 0.0 (id: 5);
+ deprecated:bool = false (id: 6);
+ required:bool = false (id: 7);
+ key:bool = false (id: 8);
+ attributes:[KeyValue] (id: 9);
+ documentation:[string] (id: 10);
+ optional:bool = false (id: 11);
}
table Object { // Used for both tables and structs.
- name:string (required, key);
- fields:[Field] (required); // Sorted.
- is_struct:bool = false;
- minalign:int;
- bytesize:int; // For structs.
- attributes:[KeyValue];
- documentation:[string];
+ name:string (required, key, id: 0);
+ fields:[Field] (required, id: 1); // Sorted.
+ is_struct:bool = false (id: 2);
+ minalign:int (id: 3);
+ bytesize:int (id: 4); // For structs.
+ attributes:[KeyValue] (id: 5);
+ documentation:[string] (id: 6);
}
table RPCCall {
- name:string (required, key);
- request:Object (required); // must be a table (not a struct)
- response:Object (required); // must be a table (not a struct)
- attributes:[KeyValue];
- documentation:[string];
+ name:string (required, key, id: 0);
+ request:Object (required, id: 1); // must be a table (not a struct)
+ response:Object (required, id: 2); // must be a table (not a struct)
+ attributes:[KeyValue] (id: 3);
+ documentation:[string] (id: 4);
}
table Service {
- name:string (required, key);
- calls:[RPCCall];
- attributes:[KeyValue];
- documentation:[string];
+ name:string (required, key, id: 0);
+ calls:[RPCCall] (id: 1);
+ attributes:[KeyValue] (id: 2);
+ documentation:[string] (id: 3);
}
table Schema {
- objects:[Object] (required); // Sorted.
- enums:[Enum] (required); // Sorted.
- file_ident:string;
- file_ext:string;
- root_table:Object;
- services:[Service]; // Sorted.
+ objects:[Object] (required, id: 0); // Sorted.
+ enums:[Enum] (required, id: 1); // Sorted.
+ file_ident:string (id: 2);
+ file_ext:string (id: 3);
+ root_table:Object (id: 4);
+ services:[Service] (id: 5); // Sorted.
}
root_type Schema;