From 33d25238937cc7656d3867fece2b0ad46d9134b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonathan=20M=C3=BCller?= Date: Mon, 30 Oct 2017 16:30:34 +0100 Subject: [PATCH] Extract common main function of examples --- example/CMakeLists.txt | 2 +- example/ast_printer.cpp | 76 ++++++++++++-------------------------- example/example_parser.hpp | 51 +++++++++++++++++++++++++ 3 files changed, 75 insertions(+), 54 deletions(-) create mode 100644 example/example_parser.hpp diff --git a/example/CMakeLists.txt b/example/CMakeLists.txt index 4b5f547..867bdd8 100644 --- a/example/CMakeLists.txt +++ b/example/CMakeLists.txt @@ -3,7 +3,7 @@ # found in the top-level directory of this distribution. function(_cppast_example name) - add_executable(cppast_example_${name} ${name}.cpp) + add_executable(cppast_example_${name} ${name}.cpp example_parser.hpp) target_link_libraries(cppast_example_${name} PUBLIC cppast) endfunction() diff --git a/example/ast_printer.cpp b/example/ast_printer.cpp index 5346563..b6acb0c 100644 --- a/example/ast_printer.cpp +++ b/example/ast_printer.cpp @@ -5,61 +5,31 @@ /// \file /// This is a very primitive version of the cppast tool. -#include +#include // visit() -#include // libclang_compilation_database, libclang_parser, etc. -#include // visit() +#include "example_parser.hpp" + +void print_ast(const cppast::cpp_file& file) +{ + std::string prefix; + // visit each entity in the file + cppast::visit(file, [&](const cppast::cpp_entity& e, cppast::visitor_info info) { + if (info.event == cppast::visitor_info::container_entity_exit) // exiting an old container + prefix.pop_back(); + else if (info.event == cppast::visitor_info::container_entity_enter) + // entering a new container + { + std::cout << prefix << "'" << e.name() << "' - " << cppast::to_string(e.kind()) << '\n'; + prefix += "\t"; + } + else // if (info.event == cppast::visitor_info::leaf_entity) // a non-container entity + std::cout << prefix << "'" << e.name() << "' - " << cppast::to_string(e.kind()) << '\n'; + + return true; // continue with visit + }); +} int main(int argc, char* argv[]) { - if (argc != 2) - { - std::cerr << "usage: " << argv[0] << " \n"; - return 1; - } - else - { - cppast::libclang_compilation_database database(argv[1]); // the compilation database - cppast::cpp_entity_index index; // only needed for cross referencing in the AST - - // simple_file_parser allows parsing multiple files and stores the results for us - cppast::simple_file_parser parser(type_safe::ref(index)); - try - { - cppast::parse_database(parser, database); // parse all files in the database - } - catch (cppast::libclang_error& ex) - { - std::cerr << "fatal libclang error: " << ex.what() << '\n'; - return 1; - } - - if (parser.error()) - // a non-fatal parse error - // error has been logged to stderr - return 1; - - for (auto& file : parser.files()) // for each file in the project - { - std::string prefix; - // visit each entity in the file - cppast::visit(file, [&](const cppast::cpp_entity& e, cppast::visitor_info info) { - if (info.event - == cppast::visitor_info::container_entity_exit) // exiting an old container - prefix.pop_back(); - else if (info.event == cppast::visitor_info::container_entity_enter) - // entering a new container - { - std::cout << prefix << "'" << e.name() << "' - " << cppast::to_string(e.kind()) - << '\n'; - prefix += "\t"; - } - else // if (info.event == cppast::visitor_info::leaf_entity) // a non-container entity - std::cout << prefix << "'" << e.name() << "' - " << cppast::to_string(e.kind()) - << '\n'; - - return true; // continue with visit - }); - } - } + return example_main(argc, argv, {}, &print_ast); } diff --git a/example/example_parser.hpp b/example/example_parser.hpp new file mode 100644 index 0000000..ab200a7 --- /dev/null +++ b/example/example_parser.hpp @@ -0,0 +1,51 @@ +// Copyright (C) 2017 Jonathan Müller +// This file is subject to the license terms in the LICENSE file +// found in the top-level directory of this distribution. + +#ifndef CPPAST_EXAMPLE_PARSER_HPP_INCLUDED +#define CPPAST_EXAMPLE_PARSER_HPP_INCLUDED + +#include + +#include + +// reads the database directory from the command line argument +// parses all files in that directory +// and invokes the callback for each of them +template +int example_main(int argc, char* argv[], const cppast::cpp_entity_index& index, Callback cb) +{ + if (argc != 2) + { + std::cerr << "usage: " << argv[0] << " \n"; + return 1; + } + else + { + cppast::libclang_compilation_database database(argv[1]); // the compilation database + + // simple_file_parser allows parsing multiple files and stores the results for us + cppast::simple_file_parser parser(type_safe::ref(index)); + try + { + cppast::parse_database(parser, database); // parse all files in the database + } + catch (cppast::libclang_error& ex) + { + std::cerr << "fatal libclang error: " << ex.what() << '\n'; + return 1; + } + + if (parser.error()) + // a non-fatal parse error + // error has been logged to stderr + return 1; + + for (auto& file : parser.files()) + cb(file); + } + + return 0; +} + +#endif // CPPAST_EXAMPLE_PARSER_HPP_INCLUDED