1
2
3
4
5
6 #include <iostream>
7 #include <stdexcept>
8 #include <soulng/util/Path.hpp>
9 #include <soulng/util/TextUtils.hpp>
10 #include <soulng/util/InitDone.hpp>
11 #include <sngxml/xpath/InitDone.hpp>
12 #include <sngcpp/pp/InitDone.hpp>
13 #include <sngcpp/ast/InitDone.hpp>
14 #include <gendoc/gendoc/Project.hpp>
15 #include <gendoc/html/Html.hpp>
16
17 using namespace soulng::util;
18
19 const char* Version()
20 {
21 return "1.0.0";
22 }
23
24 void PrintUsage()
25 {
26 std::cout << "gendoc version " << Version() << std::endl;
27 std::cout << "Reverse engineering tool for Windows x64." << std::endl;
28 std::cout << "Usage: gendoc [options] [[PATH\\]gendoc.xml]" << std::endl;
29 std::cout << "Generate HTML content for a Visual C++ project defined in the gendoc.xml." << std::endl;
30 std::cout << "If no gendoc.xml parameter is given, assumes that the current working directory contains gendoc.xml." << std::endl;
31 std::cout << "Options:" << std::endl;
32 std::cout << "--help | -h" << std::endl;
33 std::cout << " Print help and exit." << std::endl;
34 std::cout << "--verbose | -v" << std::endl;
35 std::cout << " Be verbose." << std::endl;
36 std::cout << "--rebuild | -r" << std::endl;
37 std::cout << " Rebuild everything." << std::endl;
38 std::cout << "--clean | -l" << std::endl;
39 std::cout << " Clean everything." << std::endl;
40 std::cout << "--ast | -a" << std::endl;
41 std::cout << " Generate just ASTs." << std::endl;
42 std::cout << "--content | -c" << std::endl;
43 std::cout << " Generate content when ASTS are already generated." << std::endl;
44 std::cout << "--end-message | -e" << std::endl;
45 std::cout << " Generate status.msg in the same directory (used when executed recursively from the parent directory)." << std::endl;
46 std::cout << "--single-process | -s" << std::endl;
47 std::cout << " Run in single process." << std::endl;
48 }
49
50 struct Initializer
51 {
52 Initializer()
53 {
54 soulng::util::Init();
55 sngxml::xpath::Init();
56 sngcpp::pp::Init();
57 sngcpp::ast::Init();
58 gendoc::html::InitHeaderElementNames();
59 }
60 ~Initializer()
61 {
62 sngcpp::ast::Done();
63 sngcpp::pp::Done();
64 sngxml::xpath::Done();
65 soulng::util::Done();
66 }
67 };
68
69 int main(int argc, const char** argv)
70 {
71 Initializer initializer;
72 try
73 {
74 bool verbose = false;
75 bool rebuild = false;
76 bool clean = false;
77 bool ast = false;
78 bool content = false;
79 bool endMessage = false;
80 bool single = false;
81 std::vector<std::string> docFilePaths;
82 for (int i = 1; i < argc; ++i)
83 {
84 std::string arg = argv[i];
85 if (StartsWith(arg, "--"))
86 {
87 if (arg == "--help")
88 {
89 PrintUsage();
90 return 1;
91 }
92 else if (arg == "--verbose")
93 {
94 verbose = true;
95 }
96 else if (arg == "--rebuild")
97 {
98 rebuild = true;
99 }
100 else if (arg == "--clean")
101 {
102 clean = true;
103 }
104 else if (arg == "--ast")
105 {
106 ast = true;
107 }
108 else if (arg == "--content")
109 {
110 content = true;
111 }
112 else if (arg == "--end-message")
113 {
114 endMessage = true;
115 }
116 else if (arg == "--single-process")
117 {
118 single = true;
119 }
120 else
121 {
122 throw std::runtime_error("unknown option '" + arg + "'");
123 }
124 }
125 else if (StartsWith(arg, "-"))
126 {
127 std::string options = arg.substr(1);
128 if (options.empty())
129 {
130 throw std::runtime_error("unknown option '" + arg + "'");
131 }
132 for (char o : options)
133 {
134 if (o == 'h')
135 {
136 PrintUsage();
137 return 1;
138 }
139 else if (o == 'v')
140 {
141 verbose = true;
142 }
143 else if (o == 'r')
144 {
145 rebuild = true;
146 }
147 else if (o == 'l')
148 {
149 clean = true;
150 }
151 else if (o == 'a')
152 {
153 ast = true;
154 }
155 else if (o == 'c')
156 {
157 content = true;
158 }
159 else if (o == 'e')
160 {
161 endMessage = true;
162 }
163 else if (o == 's')
164 {
165 single = true;
166 }
167 else
168 {
169 throw std::runtime_error("unknown option '-" + std::string(1, o) + "'");
170 }
171 }
172 }
173 else
174 {
175 docFilePaths.push_back(GetFullPath(arg));
176 }
177 }
178 if (docFilePaths.empty())
179 {
180 std::string docFilePath = GetFullPath(Path::Combine(GetCurrentWorkingDirectory(), "gendoc.xml"));
181 docFilePaths.push_back(docFilePath);
182 }
183 for (const std::string& docFilePath : docFilePaths)
184 {
185 if (verbose && !ast && !content)
186 {
187 std::cout << "> " << docFilePath << std::endl;
188 }
189 gendoc::Project project(docFilePath);
190 if (clean)
191 {
192 project.Clean(verbose, single);
193 }
194 else if (ast)
195 {
196 project.GenerateAst(verbose, rebuild, false);
197 }
198 else if (content)
199 {
200 project.GenerateContent(verbose, rebuild, endMessage, single);
201 }
202 else
203 {
204 project.Process(verbose, rebuild, single);
205 }
206 }
207 }
208 catch (const std::exception& ex;)
209 {
210 std::cerr << ex.what() << std::endl;
211 return 1;
212 }
213 return 0;
214 }