be_produce.cpp
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067 #include "global_extern.h"
00068
00069 #include "be_extern.h"
00070 #include "dds_visitor.h"
00071
00072 #include "ast_root.h"
00073 #include "utl_string.h"
00074
00075 #include "ace/OS_NS_strings.h"
00076 #include "ace/OS_NS_sys_time.h"
00077 #include "ace/OS_NS_unistd.h"
00078
00079 #include "../Version.h"
00080 #include "ace/Version.h"
00081
00082 #include <iostream>
00083 #include <fstream>
00084 #include <sstream>
00085 #include <string>
00086 #include <limits>
00087 #include <cassert>
00088
00089 using namespace std;
00090
00091
00092
00093 void
00094 BE_cleanup()
00095 {
00096 idl_global->destroy();
00097 }
00098
00099
00100 void
00101 BE_abort()
00102 {
00103 ACE_ERROR((LM_ERROR, ACE_TEXT("Fatal Error - Aborting\n")));
00104 BE_cleanup();
00105 ACE_OS::exit(1);
00106 }
00107
00108 namespace {
00109
00110
00111 string to_macro(const char* fn)
00112 {
00113 string ret = "OPENDDS_IDL_GENERATED_";
00114
00115 for (size_t i = 0; i < strlen(fn); ++i) {
00116 if (isalnum(fn[i])) {
00117 ret += static_cast<char>(toupper(fn[i]));
00118 } else if (ret[ret.size() - 1] != '_') {
00119 ret += '_';
00120 }
00121 }
00122
00123
00124
00125
00126
00127 const size_t NUM_CHARS = 6;
00128
00129 const ACE_Time_Value now = ACE_OS::gettimeofday();
00130 ACE_UINT64 msec;
00131 now.msec(msec);
00132
00133 msec += ACE_OS::getpid() + (size_t) ACE_OS::thr_self();
00134
00135 unsigned int seed = static_cast<unsigned int>(msec);
00136 #ifdef max
00137 #undef max
00138 #endif
00139 const float MAX_VAL = static_cast<float>(numeric_limits<char>::max());
00140 const float coefficient = static_cast<float>(MAX_VAL / (RAND_MAX + 1.0f));
00141
00142 if (ret[ret.size() - 1] != '_') ret += '_';
00143
00144 for (unsigned int n = 0; n < NUM_CHARS; ++n) {
00145 char r;
00146 do {
00147 r = static_cast<char>(coefficient * ACE_OS::rand_r(&seed));
00148 } while (!isalnum(r));
00149
00150 ret += static_cast<char>(toupper(r));
00151 }
00152
00153 return ret;
00154 }
00155
00156
00157 string to_header(const char* cpp_name)
00158 {
00159 size_t len = strlen(cpp_name);
00160 assert(len >= 5 && 0 == ACE_OS::strcasecmp(cpp_name + len - 4, ".cpp"));
00161 string base_name(cpp_name, len - 4);
00162 return base_name + ".h";
00163 }
00164
00165 void postprocess(const char* fn, ostringstream& content,
00166 BE_GlobalData::stream_enum_t which)
00167 {
00168 ostringstream out;
00169
00170 if (which == BE_GlobalData::STREAM_H ||
00171 which == BE_GlobalData::STREAM_LANG_H) {
00172 out << "/* -*- C++ -*- */\n";
00173 }
00174
00175 if (which != BE_GlobalData::STREAM_WS)
00176 out << "/* ";
00177 else
00178 out << "# ";
00179 out << "Generated by " << idl_global->prog_name()
00180 << " version " DDS_VERSION " (ACE version " ACE_VERSION
00181 << ") running on input file "
00182 << idl_global->main_filename()->get_string();
00183 if (which != BE_GlobalData::STREAM_WS)
00184 out << " */";
00185 out << "\n";
00186
00187
00188 string macrofied;
00189
00190 switch (which) {
00191 case BE_GlobalData::STREAM_H:
00192 case BE_GlobalData::STREAM_FACETS_H:
00193 case BE_GlobalData::STREAM_LANG_H: {
00194 macrofied = to_macro(fn);
00195 out << "#ifndef " << macrofied << "\n#define " << macrofied << '\n';
00196 if (which == BE_GlobalData::STREAM_LANG_H) {
00197 if (be_global->language_mapping() == BE_GlobalData::LANGMAP_FACE_CXX ||
00198 be_global->language_mapping() == BE_GlobalData::LANGMAP_SP_CXX) {
00199 out << "#include <tao/orbconf.h>\n"
00200 "#include <tao/Basic_Types.h>\n";
00201 }
00202 } else {
00203 string taoheader = be_global->header_name_.c_str();
00204 taoheader.replace(taoheader.find("TypeSupportImpl.h"), 17, "C.h");
00205 out << "#include \"" << be_global->tao_inc_pre_ << taoheader << "\"\n";
00206 }
00207 if (which == BE_GlobalData::STREAM_H) {
00208 out << "#include \"dds/DCPS/Definitions.h\"\n";
00209 out << "#include \"dds/DdsDcpsC.h\"\n";
00210 }
00211 }
00212 break;
00213 case BE_GlobalData::STREAM_CPP: {
00214 ACE_CString pch = be_global->pch_include();
00215 if (pch.length()) {
00216 out << "#include \"" << pch << "\"\n";
00217 }
00218 if (be_global->java_arg().length() == 0) {
00219 string header = to_header(fn);
00220 out << "#include \"" << header << "\"\n\n";
00221 } else {
00222 out << "#include \"" << be_global->header_name_.c_str() << "\"\n\n";
00223 }
00224 }
00225 break;
00226 case BE_GlobalData::STREAM_FACETS_CPP: {
00227 ACE_CString pch = be_global->pch_include();
00228 if (pch.length()) {
00229 out << "#include \"" << pch << "\"\n";
00230 }
00231 out << "#include \"" << be_global->facets_header_name_.c_str() << "\"\n"
00232 "#include \"" << be_global->header_name_.c_str() << "\"\n"
00233 "#include \"dds/FACE/FaceTSS.h\"\n\n"
00234 "namespace FACE { namespace TS {\n\n";
00235 }
00236 break;
00237 case BE_GlobalData::STREAM_IDL: {
00238 macrofied = to_macro(fn);
00239 out << "#ifndef " << macrofied << "\n#define " << macrofied << '\n';
00240
00241 #ifdef ACE_HAS_CDR_FIXED
00242 out << "#define __OPENDDS_IDL_HAS_FIXED\n";
00243 #endif
00244
00245 string filebase(be_global->filename());
00246 const size_t idx = filebase.find_last_of("/\\");
00247 if (idx != string::npos) {
00248 filebase = filebase.substr(idx + 1);
00249 }
00250 out << "#include \"" << filebase << "\"\n\n";
00251 }
00252 break;
00253 default:
00254 ;
00255 }
00256
00257 out << be_global->get_include_block(which);
00258
00259 out << content.str();
00260
00261 switch (which) {
00262 case BE_GlobalData::STREAM_H:
00263 case BE_GlobalData::STREAM_IDL:
00264 case BE_GlobalData::STREAM_FACETS_H:
00265 case BE_GlobalData::STREAM_LANG_H:
00266 out << "#endif /* " << macrofied << " */\n";
00267 break;
00268 case BE_GlobalData::STREAM_FACETS_CPP:
00269 out << "}}\n";
00270 break;
00271 default:
00272 ;
00273 }
00274
00275 if (!BE_GlobalData::writeFile(fn, out.str())) {
00276 BE_abort();
00277 }
00278 }
00279
00280 }
00281
00282
00283 void
00284 BE_produce()
00285 {
00286
00287 const char* idl_fn = idl_global->main_filename()->get_string();
00288
00289 const BE_GlobalData::stream_enum_t out_stream =
00290 be_global->language_mapping() == BE_GlobalData::LANGMAP_NONE
00291 ? BE_GlobalData::STREAM_H : BE_GlobalData::STREAM_LANG_H;
00292
00293 ifstream idl(idl_fn);
00294 const size_t buffer_sz = 512;
00295 char buffer[buffer_sz];
00296
00297 while (idl) {
00298 idl.getline(buffer, buffer_sz);
00299
00300 if (0 == strncmp("#include", buffer, 8)) {
00301 string inc(buffer + 8);
00302 size_t delim1 = inc.find_first_of("<\"");
00303 size_t delim2 = inc.find_first_of(">\"", delim1 + 1);
00304 string included(inc, delim1 + 1, delim2 - delim1 - 1);
00305 size_t len = included.size();
00306 string base_name;
00307
00308 if (len >= 5 &&
00309 0 == ACE_OS::strcasecmp(included.c_str() + len - 4, ".idl")) {
00310 base_name.assign(included.c_str(), len - 4);
00311
00312 } else if (len >= 6 &&
00313 0 == ACE_OS::strcasecmp(included.c_str() + len - 5, ".pidl")) {
00314 base_name.assign(included.c_str(), len - 5);
00315
00316 } else {
00317 ACE_ERROR((LM_ERROR, ACE_TEXT("(%N:%l) BE_produce - included ")
00318 ACE_TEXT("file must end in .idl or .pidl\n")));
00319 BE_abort();
00320 }
00321
00322 string stb_inc = base_name + "C.h";
00323 if (stb_inc != "tao/orbC.h") {
00324 be_global->add_include(stb_inc.c_str(), out_stream);
00325 if (stb_inc == "orbC.h" ||
00326 (stb_inc.size() >= 7
00327 && stb_inc.substr(stb_inc.size() - 7) == "/orbC.h") ) {
00328 ACE_DEBUG((LM_WARNING,
00329 ACE_TEXT("Warning: (%s) Potential inclusion of TAO orbC.H ")
00330 ACE_TEXT(" Include TAO orb.idl with path of tao/orb.idl")
00331 ACE_TEXT(" to prevent compilation errors\n"), idl_fn));
00332 }
00333 }
00334
00335 }
00336 }
00337
00338 idl.close();
00339
00340 be_global->open_streams(idl_fn);
00341
00342 AST_Decl* d = idl_global->root();
00343 AST_Root* root = AST_Root::narrow_from_decl(d);
00344
00345 if (root == 0) {
00346 ACE_ERROR((LM_ERROR,
00347 ACE_TEXT("(%N:%l) BE_produce - ")
00348 ACE_TEXT("No Root\n")));
00349
00350 BE_abort();
00351 }
00352
00353 be_global->set_inc_paths(idl_global->idl_flags());
00354
00355 const bool java_ts_only = be_global->java_arg().length() > 0;
00356
00357 dds_visitor visitor(d, java_ts_only);
00358
00359 if (root->ast_accept(&visitor) == -1) {
00360 ACE_ERROR((LM_ERROR,
00361 ACE_TEXT("(%N:%l) BE_produce -")
00362 ACE_TEXT(" failed to accept adding visitor\n")));
00363 BE_abort();
00364 }
00365
00366 if (!java_ts_only) {
00367 postprocess(be_global->header_name_.c_str(),
00368 be_global->header_, BE_GlobalData::STREAM_H);
00369 if (!be_global->suppress_idl()) {
00370 postprocess(be_global->idl_name_.c_str(),
00371 be_global->idl_, BE_GlobalData::STREAM_IDL);
00372 }
00373 }
00374
00375 postprocess(be_global->impl_name_.c_str(),
00376 be_global->impl_, BE_GlobalData::STREAM_CPP);
00377
00378 if (be_global->generate_wireshark()) {
00379 postprocess(be_global->ws_config_name_.c_str(),
00380 be_global->ws_config_, BE_GlobalData::STREAM_WS);
00381 }
00382
00383 if (be_global->generate_itl()) {
00384 if (!BE_GlobalData::writeFile(be_global->itl_name_.c_str(), be_global->itl_.str())) {
00385 BE_abort();
00386 }
00387 }
00388
00389 if (be_global->face_ts()) {
00390 postprocess(be_global->facets_header_name_.c_str(), be_global->facets_header_,
00391 BE_GlobalData::STREAM_FACETS_H);
00392 postprocess(be_global->facets_impl_name_.c_str(), be_global->facets_impl_,
00393 BE_GlobalData::STREAM_FACETS_CPP);
00394 }
00395
00396 if (be_global->language_mapping() == BE_GlobalData::LANGMAP_FACE_CXX ||
00397 be_global->language_mapping() == BE_GlobalData::LANGMAP_SP_CXX) {
00398 postprocess(be_global->lang_header_name_.c_str(), be_global->lang_header_,
00399 BE_GlobalData::STREAM_LANG_H);
00400 }
00401
00402 BE_cleanup();
00403 }