Subversion Repositories SmartDukaan

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
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
}