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 argcconst 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(1o) + "'");
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()fileNamefileIndex);
170             lexer.SetSeparatorChar('\n');
171             if (debug)
172             {
173                 lexer.SetLog(&log);
174             }
175             std::unique_ptr<SourceFileNode> sourceFile(new SourceFileNode(lexer.GetSpan()fileNamePath::GetFileName(fileName)U""));
176             sourceFile->SetSourceFileIndex(fileIndex);
177             SourceFileParser::Parse(lexersourceFile.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 }