1 #include <sngcpp/lexer/CppLexer.hpp>
  
    2 #include <soulng/lexer/XmlParsingLog.hpp>
  
    3 #include <sngcpp/parser/SourceFile.hpp>
  
    4 #include <sngcpp/ast/InitDone.hpp>
  
    5 #include <sngcpp/pp/InitDone.hpp>
  
    6 #include <sngcpp/pp/PP.hpp>
  
    7 #include <soulng/util/InitDone.hpp>
  
    8 #include <soulng/util/Path.hpp>
  
    9 #include <soulng/util/TextUtils.hpp>
  
   10 #include <iostream>
  
   11 #include <stdexcept>
  
   12 
  
   13 using namespace soulng::util;
  
   14 using namespace sngcpp::pp;
  
   15 using namespace soulng::lexer;
  
   16 
  
   17 void PrintUsage()
  
   18 {
  
   19     std::cout << "sngcpp parser tester" << std::endl;
  
   20     std::cout << "usage: sngcppparsertester [options] { file.cpp | file.hpp }" << std::endl;
  
   21     std::cout << "options:" << std::endl;
  
   22     std::cout << "--help | -h" << std::endl;
  
   23     std::cout << "  Print help and exit." << std::endl;
  
   24     std::cout << "--verbose | -v" << std::endl;
  
   25     std::cout << "  Be verbose." << std::endl;
  
   26     std::cout << "--root DIR" << std::endl;
  
   27     std::cout << "  Set root directory to DIR." << std::endl;
  
   28     std::cout << "--include PATH" << std::endl;
  
   29     std::cout << "  Set include path to PATH." << std::endl;
  
   30     std::cout << "--debug | -d" << std::endl;
  
   31     std::cout << "  Debug parsing." << std::endl;
  
   32 }
  
   33 
  
   34 struct Initializer 
  
   35 {
  
   36     Initializer()
  
   37     {
  
   38         soulng::util::Init();
  
   39         sngcpp::pp::Init();
  
   40         sngcpp::ast::Init();
  
   41     }
  
   42     ~Initializer()
  
   43     {
  
   44         sngcpp::ast::Done();
  
   45         sngcpp::pp::Done();
  
   46         soulng::util::Done();
  
   47     }
  
   48 };
  
   49 
  
   50 int main(int argc, const char** argv)
  
   51 {
  
   52     Initializer initializer;
  
   53     try
  
   54     {
  
   55         bool verbose = false;
  
   56         bool debug = false;
  
   57         std::string root;
  
   58         std::string includePath;
  
   59         std::vector<std::string> fileNames;
  
   60         for (int i = 1; i < argc; ++i)
  
   61         {
  
   62             std::string arg = argv[i];
  
   63             if (StartsWith(arg, "--"))
  
   64             {
  
   65                 if (arg == "--help")
  
   66                 {
  
   67                     PrintUsage();
  
   68                     return 1;
  
   69                 }
  
   70                 else if (arg == "--verbose")
  
   71                 {
  
   72                     verbose = true;
  
   73                 }
  
   74                 else if (arg == "--root")
  
   75                 {
  
   76                     ++i;
  
   77                     if (i < argc)
  
   78                     {
  
   79                         arg = argv[i];
  
   80                         root = GetFullPath(arg);
  
   81                     }
  
   82                     else
  
   83                     {
  
   84                         throw std::runtime_error("argument expected");
  
   85                     }
  
   86                 }
  
   87                 else if (arg == "--include")
  
   88                 {
  
   89                     ++i;
  
   90                     if (i < argc)
  
   91                     {
  
   92                         arg = argv[i];
  
   93                         includePath = GetFullPath(arg);
  
   94                     }
  
   95                     else
  
   96                     {
  
   97                         throw std::runtime_error("argument expected");
  
   98                     }
  
   99                 }
  
  100                 else if (arg == "--debug")
  
  101                 {
  
  102                     debug = true;
  
  103                 }
  
  104                 else
  
  105                 {
  
  106                     throw std::runtime_error("unknown option '" + arg + "'");
  
  107                 }
  
  108             }
  
  109             else if (StartsWith(arg, "-"))
  
  110             {
  
  111                 std::string options = arg.substr(1);
  
  112                 if (options.empty())
  
  113                 {
  
  114                     throw std::runtime_error("unknown option '" + arg + "'");
  
  115                 }
  
  116                 for (char o : options)
  
  117                 {
  
  118                     if (o == 'h')
  
  119                     {
  
  120                         PrintUsage();
  
  121                         return 1;
  
  122                     }
  
  123                     else if (o == 'v')
  
  124                     {
  
  125                         verbose = true;
  
  126                     }
  
  127                     else if (o == 'd')
  
  128                     {
  
  129                         debug = true;
  
  130                     }
  
  131                     else
  
  132                     {
  
  133                         throw std::runtime_error("unknown option '-" + std::string(1, o) + "'");
  
  134                     }
  
  135                 }
  
  136             }
  
  137             else
  
  138             {
  
  139                 fileNames.push_back(GetFullPath(arg));
  
  140             }
  
  141         }
  
  142         EvaluationContext evaluationContext;
  
  143         std::vector<std::std::unique_ptr<SourceFileNode>>sourceFiles;
  
  144         int fileIndex = 0;
  
  145         for (const std::string& fileName : fileNames)
  
  146         {
  
  147             if (verbose)
  
  148             {
  
  149                 std::cout << "> " << fileName << std::endl;
  
  150             }
  
  151             PP pp(evaluationContext);
  
  152             if (!root.empty())
  
  153             {
  
  154                 pp.root = root;
  
  155                 pp.rootMode = true;
  
  156             }
  
  157             if (!includePath.empty())
  
  158             {
  
  159                 pp.includePath = Split(includePath, ';');
  
  160             }
  
  161             pp.Define(sngcpp::pp::ndebug);
  
  162             if (verbose)
  
  163             {
  
  164                 pp.verbose = true;
  
  165             }
  
  166             Preprocess(fileName, &pp);
  
  167             std::unique_ptr<std::u32string> content(new std::u32string(std::move(pp.text)));
  
  168             XmlParsingLog log(std::cerr);
  
  169             CppLexer lexer(content->c_str(), content->c_str() + content->length(), fileName, fileIndex);
  
  170             lexer.SetSeparatorChar('\n');
  
  171             if (debug)
  
  172             {
  
  173                 lexer.SetLog(&log);
  
  174             }
  
  175             std::unique_ptr<SourceFileNode> sourceFile(new SourceFileNode(lexer.GetSpan(), fileName, Path::GetFileName(fileName), U""));
  
  176             sourceFile->SetSourceFileIndex(fileIndex);
  
  177             SourceFileParser::Parse(lexer, sourceFile.get());
  
  178             sourceFile->SetContent(std::move(content));
  
  179             sourceFile->SetHeaderFilePaths(std::move(pp.headerFilePaths));
  
  180             sourceFiles.push_back(std::move(sourceFile));
  
  181             ++fileIndex;
  
  182         }
  
  183     }
  
  184     catch (const std::exception& ex;)
  
  185     {
  
  186         std::cerr << ex.what() << std::endl;
  
  187         return 1;
  
  188     }
  
  189     return 0;
  
  190 }