Skip to content

Commit b981843

Browse files
committed
Parsing header works
1 parent 947776e commit b981843

1 file changed

Lines changed: 197 additions & 11 deletions

File tree

drogon_ctl/create_swagger.cc

Lines changed: 197 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,202 @@
3232
#include <regex>
3333

3434
using namespace drogon_ctl;
35+
namespace internal
36+
{
37+
class StructNode;
38+
using StructNodePtr = std::shared_ptr<StructNode>;
39+
class StructNode
40+
{
41+
public:
42+
enum NodeType
43+
{
44+
kRoot = 0,
45+
kClass,
46+
kNameSpace
47+
};
3548

49+
StructNode(const std::string &content,
50+
const std::string &name,
51+
NodeType type = kRoot)
52+
: type_(type), name_(name), content_(content)
53+
{
54+
LOG_DEBUG << "new node:" << name << "-" << type;
55+
if (type != kClass)
56+
children_ = parse(content);
57+
}
58+
const std::string &content() const
59+
{
60+
return content_;
61+
}
62+
const std::string &name() const
63+
{
64+
return name_;
65+
}
66+
NodeType type() const
67+
{
68+
return type_;
69+
}
70+
void print() const
71+
{
72+
print(0);
73+
}
74+
75+
private:
76+
std::vector<StructNodePtr> children_;
77+
std::string content_;
78+
NodeType type_;
79+
std::string name_;
80+
std::pair<std::string, std::string> findContentOfClassOrNameSpace(
81+
const std::string &content,
82+
std::string::size_type start)
83+
{
84+
int braces = 0;
85+
std::string::size_type pos1{start};
86+
std::string::size_type pos2{content.size() - 1};
87+
for (auto i = start; i < content.size(); i++)
88+
{
89+
if (content[i] == '{')
90+
{
91+
braces++;
92+
if (braces == 1)
93+
{
94+
pos1 = i + 1;
95+
}
96+
}
97+
else if (content[i] == '}')
98+
{
99+
braces--;
100+
if (braces == 0)
101+
{
102+
pos2 = i;
103+
break;
104+
}
105+
}
106+
}
107+
return {content.substr(pos1, pos2 - pos1), content.substr(pos2 + 1)};
108+
}
109+
std::pair<StructNodePtr, std::string> findClass(const std::string &content)
110+
{
111+
LOG_DEBUG << "findClass: " << content;
112+
if (content.empty())
113+
return {nullptr, ""};
114+
std::regex rx(R"(class[ \r\n]+([^ \r\n]+)[ \r\n]+)");
115+
std::smatch results;
116+
if (std::regex_search(content, results, rx))
117+
{
118+
assert(results.size() > 1);
119+
auto nextPart =
120+
findContentOfClassOrNameSpace(content, results.position());
121+
return {std::make_shared<StructNode>(nextPart.first,
122+
results[1].str(),
123+
kClass),
124+
nextPart.second};
125+
}
126+
return {nullptr, ""};
127+
}
128+
std::tuple<std::string, StructNodePtr, std::string> findNameSpace(
129+
const std::string &content)
130+
{
131+
LOG_DEBUG << "findNameSpace";
132+
if (content.empty())
133+
return {"", nullptr, ""};
134+
std::regex rx(R"(namespace[ \r\n]+([^ \r\n]+)[ \r\n]*\{)");
135+
std::smatch results;
136+
if (std::regex_search(content, results, rx))
137+
{
138+
assert(results.size() > 1);
139+
auto pos = results.position();
140+
auto first = content.substr(0, pos);
141+
auto nextPart = findContentOfClassOrNameSpace(content, pos);
142+
auto npNodePtr = std::make_shared<StructNode>(nextPart.first,
143+
results[1].str(),
144+
kNameSpace);
145+
146+
return {first, npNodePtr, nextPart.second};
147+
}
148+
else
149+
{
150+
return {"", nullptr, ""};
151+
}
152+
}
153+
std::vector<StructNodePtr> parse(const std::string &content)
154+
{
155+
std::vector<StructNodePtr> res;
156+
auto t = findNameSpace(content);
157+
if (std::get<1>(t))
158+
{
159+
res.emplace_back(std::get<1>(t));
160+
auto firstPart = std::get<0>(t);
161+
while (1)
162+
{
163+
auto p = findClass(firstPart);
164+
if (p.first)
165+
{
166+
res.emplace_back(p.first);
167+
firstPart = p.second;
168+
}
169+
else
170+
{
171+
break;
172+
}
173+
}
174+
auto subsequentNode = parse(std::get<2>(t));
175+
for (auto &node : subsequentNode)
176+
{
177+
res.emplace_back(node);
178+
}
179+
return res;
180+
}
181+
std::string classPart = content;
182+
while (1)
183+
{
184+
auto p = findClass(classPart);
185+
if (p.first)
186+
{
187+
res.emplace_back(p.first);
188+
classPart = p.second;
189+
}
190+
else
191+
{
192+
break;
193+
}
194+
}
195+
return res;
196+
}
197+
void print(int indent) const
198+
{
199+
std::string ind(indent, ' ');
200+
std::cout << ind;
201+
switch (type_)
202+
{
203+
case kRoot:
204+
{
205+
std::cout << "Root\n" << ind << "{\n";
206+
break;
207+
}
208+
case kClass:
209+
{
210+
std::cout << "class " << name_ << "\n" << ind << "{\n";
211+
break;
212+
}
213+
case kNameSpace:
214+
{
215+
std::cout << "namespace " << name_ << "\n" << ind << "{\n";
216+
break;
217+
}
218+
}
219+
220+
for (auto child : children_)
221+
{
222+
child->print(indent + 2);
223+
}
224+
std::cout << ind << "}";
225+
if (type_ == kClass)
226+
std::cout << ";";
227+
std::cout << "\n";
228+
}
229+
};
230+
} // namespace internal
36231
static void forEachControllerHeaderIn(
37232
std::string strPath,
38233
const std::function<void(const std::string &)> &cb)
@@ -95,17 +290,8 @@ static void parseControllerHeader(const std::string &headerFile,
95290
pbuf->sgetn(&fileContent[0], filesize);
96291
std::cout << fileContent;
97292

98-
std::regex rx(R"(namespace[ \r\n]+([^ \r\n]+)[ \r\n]*\{)");
99-
std::smatch results;
100-
while (std::regex_search(fileContent, results, rx))
101-
{
102-
if (results.size() > 1)
103-
{
104-
for (int i = 1; i < results.size(); i++)
105-
std::cout << "nnn:" << i << results[i] << std::endl;
106-
}
107-
fileContent = results.suffix();
108-
}
293+
internal::StructNode r(fileContent, "root", internal::StructNode::kRoot);
294+
r.print();
109295
}
110296
static std::string makeSwaggerDocument(const Json::Value &config)
111297
{

0 commit comments

Comments
 (0)