/* * Copyright (C) 2017 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include <sys/stat.h> #include <fstream> #include <memory> #include <regex> #include <set> #include <sstream> #include <string> #include "perfetto/base/file_utils.h" #include "perfetto/ftrace_reader/format_parser.h" #include "perfetto/trace/ftrace/ftrace_event.pbzero.h" #include "tools/ftrace_proto_gen/ftrace_proto_gen.h" int main(int argc, const char** argv) { if (argc != 4) { fprintf(stderr, "Usage: ./%s whitelist_dir input_dir output_dir\n", argv[0]); return 1; } const char* whitelist_path = argv[1]; const char* input_dir = argv[2]; const char* output_dir = argv[3]; std::set<std::string> events = perfetto::GetWhitelistedEvents(whitelist_path); std::vector<std::string> events_info; std::string ftrace; if (!perfetto::base::ReadFile( "protos/perfetto/trace/ftrace/ftrace_event.proto", &ftrace)) { fprintf(stderr, "Failed to open %s\n", "protos/perfetto/trace/ftrace/ftrace_event.proto"); return 1; } std::set<std::string> new_events; for (const auto& event : events) { std::string file_name = event.substr(event.find('/') + 1, std::string::npos); struct stat buf; if (stat(("protos/perfetto/trace/ftrace/" + file_name + ".proto").c_str(), &buf) == -1) { new_events.insert(file_name); } } if (!new_events.empty()) { perfetto::PrintFtraceEventProtoAdditions(new_events); perfetto::PrintEventFormatterMain(new_events); perfetto::PrintEventFormatterUsingStatements(new_events); perfetto::PrintEventFormatterFunctions(new_events); printf( "\nAdd output to ParseInode in " "tools/ftrace_proto_gen/ftrace_inode_handler.cc\n"); } for (auto event : events) { std::string proto_file_name = event.substr(event.find('/') + 1, std::string::npos) + ".proto"; std::string group = event.substr(0, event.find('/')); std::string input_path = input_dir + event + std::string("/format"); std::string output_path = output_dir + std::string("/") + proto_file_name; std::string contents; if (!perfetto::base::ReadFile(input_path, &contents)) { fprintf(stderr, "Failed to open %s\n", input_path.c_str()); return 1; } perfetto::FtraceEvent format; if (!perfetto::ParseFtraceEvent(contents, &format)) { fprintf(stderr, "Could not parse file %s.\n", input_path.c_str()); return 1; } perfetto::Proto proto; if (!perfetto::GenerateProto(format, &proto)) { fprintf(stderr, "Could not generate proto for file %s\n", input_path.c_str()); return 1; } std::smatch match; std::regex event_regex(format.name + "\\s*=\\s*(\\d+)"); std::regex_search(ftrace, match, event_regex); std::string proto_field_id = match[1].str().c_str(); if (proto_field_id == "") { fprintf(stderr, "Could not find proto_field_id for %s in ftrace_event.proto. " "Please add it.\n", format.name.c_str()); return 1; } if (!new_events.empty()) PrintInodeHandlerMain(format.name, proto); events_info.push_back( perfetto::SingleEventInfo(format, proto, group, proto_field_id)); std::ofstream fout(output_path.c_str(), std::ios::out); if (!fout) { fprintf(stderr, "Failed to open %s\n", output_path.c_str()); return 1; } fout << proto.ToString(); fout.close(); } perfetto::GenerateEventInfo(events_info); }