| 30 |
ashish |
1 |
/*
|
|
|
2 |
* Licensed to the Apache Software Foundation (ASF) under one
|
|
|
3 |
* or more contributor license agreements. See the NOTICE file
|
|
|
4 |
* distributed with this work for additional information
|
|
|
5 |
* regarding copyright ownership. The ASF licenses this file
|
|
|
6 |
* to you under the Apache License, Version 2.0 (the
|
|
|
7 |
* "License"); you may not use this file except in compliance
|
|
|
8 |
* with the License. You may obtain a copy of the License at
|
|
|
9 |
*
|
|
|
10 |
* http://www.apache.org/licenses/LICENSE-2.0
|
|
|
11 |
*
|
|
|
12 |
* Unless required by applicable law or agreed to in writing,
|
|
|
13 |
* software distributed under the License is distributed on an
|
|
|
14 |
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
|
15 |
* KIND, either express or implied. See the License for the
|
|
|
16 |
* specific language governing permissions and limitations
|
|
|
17 |
* under the License.
|
|
|
18 |
*/
|
|
|
19 |
|
|
|
20 |
#include "t_generator.h"
|
|
|
21 |
using namespace std;
|
|
|
22 |
|
|
|
23 |
/**
|
|
|
24 |
* Top level program generation function. Calls the generator subclass methods
|
|
|
25 |
* for preparing file streams etc. then iterates over all the parts of the
|
|
|
26 |
* program to perform the correct actions.
|
|
|
27 |
*
|
|
|
28 |
* @param program The thrift program to compile into C++ source
|
|
|
29 |
*/
|
|
|
30 |
void t_generator::generate_program() {
|
|
|
31 |
// Initialize the generator
|
|
|
32 |
init_generator();
|
|
|
33 |
|
|
|
34 |
// Generate enums
|
|
|
35 |
vector<t_enum*> enums = program_->get_enums();
|
|
|
36 |
vector<t_enum*>::iterator en_iter;
|
|
|
37 |
for (en_iter = enums.begin(); en_iter != enums.end(); ++en_iter) {
|
|
|
38 |
generate_enum(*en_iter);
|
|
|
39 |
}
|
|
|
40 |
|
|
|
41 |
// Generate typedefs
|
|
|
42 |
vector<t_typedef*> typedefs = program_->get_typedefs();
|
|
|
43 |
vector<t_typedef*>::iterator td_iter;
|
|
|
44 |
for (td_iter = typedefs.begin(); td_iter != typedefs.end(); ++td_iter) {
|
|
|
45 |
generate_typedef(*td_iter);
|
|
|
46 |
}
|
|
|
47 |
|
|
|
48 |
// Generate constants
|
|
|
49 |
vector<t_const*> consts = program_->get_consts();
|
|
|
50 |
generate_consts(consts);
|
|
|
51 |
|
|
|
52 |
// Generate structs, exceptions, and unions in declared order
|
|
|
53 |
vector<t_struct*> objects = program_->get_objects();
|
|
|
54 |
vector<t_struct*>::iterator o_iter;
|
|
|
55 |
for (o_iter = objects.begin(); o_iter != objects.end(); ++o_iter) {
|
|
|
56 |
if ((*o_iter)->is_xception()) {
|
|
|
57 |
generate_xception(*o_iter);
|
|
|
58 |
} else {
|
|
|
59 |
generate_struct(*o_iter);
|
|
|
60 |
}
|
|
|
61 |
}
|
|
|
62 |
|
|
|
63 |
// Generate services
|
|
|
64 |
vector<t_service*> services = program_->get_services();
|
|
|
65 |
vector<t_service*>::iterator sv_iter;
|
|
|
66 |
for (sv_iter = services.begin(); sv_iter != services.end(); ++sv_iter) {
|
|
|
67 |
service_name_ = get_service_name(*sv_iter);
|
|
|
68 |
generate_service(*sv_iter);
|
|
|
69 |
}
|
|
|
70 |
|
|
|
71 |
// Close the generator
|
|
|
72 |
close_generator();
|
|
|
73 |
}
|
|
|
74 |
|
|
|
75 |
string t_generator::escape_string(const string &in) const {
|
|
|
76 |
string result = "";
|
|
|
77 |
for (string::const_iterator it = in.begin(); it < in.end(); it++) {
|
|
|
78 |
std::map<char, std::string>::const_iterator res = escape_.find(*it);
|
|
|
79 |
if (res != escape_.end()) {
|
|
|
80 |
result.append(res->second);
|
|
|
81 |
} else {
|
|
|
82 |
result.push_back(*it);
|
|
|
83 |
}
|
|
|
84 |
}
|
|
|
85 |
return result;
|
|
|
86 |
}
|
|
|
87 |
|
|
|
88 |
void t_generator::generate_consts(vector<t_const*> consts) {
|
|
|
89 |
vector<t_const*>::iterator c_iter;
|
|
|
90 |
for (c_iter = consts.begin(); c_iter != consts.end(); ++c_iter) {
|
|
|
91 |
generate_const(*c_iter);
|
|
|
92 |
}
|
|
|
93 |
}
|
|
|
94 |
|
|
|
95 |
void t_generator::generate_docstring_comment(ofstream& out,
|
|
|
96 |
const string& comment_start,
|
|
|
97 |
const string& line_prefix,
|
|
|
98 |
const string& contents,
|
|
|
99 |
const string& comment_end) {
|
|
|
100 |
if (comment_start != "") indent(out) << comment_start;
|
|
|
101 |
stringstream docs(contents, ios_base::in);
|
|
|
102 |
while (!docs.eof()) {
|
|
|
103 |
char line[1024];
|
|
|
104 |
docs.getline(line, 1024);
|
|
|
105 |
if (strlen(line) > 0 || !docs.eof()) { // skip the empty last line
|
|
|
106 |
indent(out) << line_prefix << line << std::endl;
|
|
|
107 |
}
|
|
|
108 |
}
|
|
|
109 |
if (comment_end != "") indent(out) << comment_end;
|
|
|
110 |
}
|
|
|
111 |
|
|
|
112 |
|
|
|
113 |
void t_generator_registry::register_generator(t_generator_factory* factory) {
|
|
|
114 |
gen_map_t& the_map = get_generator_map();
|
|
|
115 |
if (the_map.find(factory->get_short_name()) != the_map.end()) {
|
|
|
116 |
failure("Duplicate generators for language \"%s\"!\n", factory->get_short_name().c_str());
|
|
|
117 |
}
|
|
|
118 |
the_map[factory->get_short_name()] = factory;
|
|
|
119 |
}
|
|
|
120 |
|
|
|
121 |
t_generator* t_generator_registry::get_generator(t_program* program,
|
|
|
122 |
const string& options) {
|
|
|
123 |
string::size_type colon = options.find(':');
|
|
|
124 |
string language = options.substr(0, colon);
|
|
|
125 |
|
|
|
126 |
map<string, string> parsed_options;
|
|
|
127 |
if (colon != string::npos) {
|
|
|
128 |
string::size_type pos = colon+1;
|
|
|
129 |
while (pos != string::npos && pos < options.size()) {
|
|
|
130 |
string::size_type next_pos = options.find(',', pos);
|
|
|
131 |
string option = options.substr(pos, next_pos-pos);
|
|
|
132 |
pos = ((next_pos == string::npos) ? next_pos : next_pos+1);
|
|
|
133 |
|
|
|
134 |
string::size_type separator = option.find('=');
|
|
|
135 |
string key, value;
|
|
|
136 |
if (separator == string::npos) {
|
|
|
137 |
key = option;
|
|
|
138 |
value = "";
|
|
|
139 |
} else {
|
|
|
140 |
key = option.substr(0, separator);
|
|
|
141 |
value = option.substr(separator+1);
|
|
|
142 |
}
|
|
|
143 |
|
|
|
144 |
parsed_options[key] = value;
|
|
|
145 |
}
|
|
|
146 |
}
|
|
|
147 |
|
|
|
148 |
gen_map_t& the_map = get_generator_map();
|
|
|
149 |
gen_map_t::iterator iter = the_map.find(language);
|
|
|
150 |
|
|
|
151 |
if (iter == the_map.end()) {
|
|
|
152 |
return NULL;
|
|
|
153 |
}
|
|
|
154 |
|
|
|
155 |
return iter->second->get_generator(program, parsed_options, options);
|
|
|
156 |
}
|
|
|
157 |
|
|
|
158 |
t_generator_registry::gen_map_t& t_generator_registry::get_generator_map() {
|
|
|
159 |
// http://www.parashift.com/c++-faq-lite/ctors.html#faq-10.12
|
|
|
160 |
static gen_map_t* the_map = new gen_map_t();
|
|
|
161 |
return *the_map;
|
|
|
162 |
}
|
|
|
163 |
|
|
|
164 |
t_generator_factory::t_generator_factory(
|
|
|
165 |
const std::string& short_name,
|
|
|
166 |
const std::string& long_name,
|
|
|
167 |
const std::string& documentation)
|
|
|
168 |
: short_name_(short_name)
|
|
|
169 |
, long_name_(long_name)
|
|
|
170 |
, documentation_(documentation)
|
|
|
171 |
{
|
|
|
172 |
t_generator_registry::register_generator(this);
|
|
|
173 |
}
|