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 }
00210 }
00211 break;
00212 case BE_GlobalData::STREAM_CPP: {
00213 ACE_CString pch = be_global->pch_include();
00214 if (pch.length()) {
00215 out << "#include \"" << pch << "\"\n";
00216 }
00217 if (be_global->java_arg().length() == 0) {
00218 string header = to_header(fn);
00219 out << "#include \"" << header << "\"\n\n";
00220 } else {
00221 out << "#include \"" << be_global->header_name_.c_str() << "\"\n\n";
00222 }
00223 }
00224 break;
00225 case BE_GlobalData::STREAM_FACETS_CPP: {
00226 ACE_CString pch = be_global->pch_include();
00227 if (pch.length()) {
00228 out << "#include \"" << pch << "\"\n";
00229 }
00230 out << "#include \"" << be_global->facets_header_name_.c_str() << "\"\n"
00231 "#include \"" << be_global->header_name_.c_str() << "\"\n"
00232 "#include \"dds/FACE/FaceTSS.h\"\n\n"
00233 "namespace FACE { namespace TS {\n\n";
00234 }
00235 break;
00236 case BE_GlobalData::STREAM_IDL: {
00237 macrofied = to_macro(fn);
00238 out << "#ifndef " << macrofied << "\n#define " << macrofied << '\n';
00239
00240 #ifdef ACE_HAS_CDR_FIXED
00241 out << "#define __OPENDDS_IDL_HAS_FIXED\n";
00242 #endif
00243
00244 string filebase(be_global->filename());
00245 const size_t idx = filebase.find_last_of("/\\");
00246 if (idx != string::npos) {
00247 filebase = filebase.substr(idx + 1);
00248 }
00249 out << "#include \"" << filebase << "\"\n\n";
00250 }
00251 break;
00252 default:
00253 ;
00254 }
00255
00256 out << be_global->get_include_block(which);
00257
00258 out << content.str();
00259
00260 switch (which) {
00261 case BE_GlobalData::STREAM_H:
00262 case BE_GlobalData::STREAM_IDL:
00263 case BE_GlobalData::STREAM_FACETS_H:
00264 case BE_GlobalData::STREAM_LANG_H:
00265 out << "#endif /* " << macrofied << " */\n";
00266 break;
00267 case BE_GlobalData::STREAM_FACETS_CPP:
00268 out << "}}\n";
00269 break;
00270 default:
00271 ;
00272 }
00273
00274 if (!BE_GlobalData::writeFile(fn, out.str())) {
00275 BE_abort();
00276 }
00277 }
00278
00279 }
00280
00281
00282 void
00283 BE_produce()
00284 {
00285
00286 const char* idl_fn = idl_global->main_filename()->get_string();
00287
00288 ifstream idl(idl_fn);
00289 const size_t buffer_sz = 512;
00290 char buffer[buffer_sz];
00291
00292 while (idl) {
00293 idl.getline(buffer, buffer_sz);
00294
00295 if (0 == strncmp("#include", buffer, 8)) {
00296 string inc(buffer + 8);
00297 size_t delim1 = inc.find_first_of("<\"");
00298 size_t delim2 = inc.find_first_of(">\"", delim1 + 1);
00299 string included(inc, delim1 + 1, delim2 - delim1 - 1);
00300 size_t len = included.size();
00301 string base_name;
00302
00303 if (len >= 5 &&
00304 0 == ACE_OS::strcasecmp(included.c_str() + len - 4, ".idl")) {
00305 base_name.assign(included.c_str(), len - 4);
00306
00307 } else if (len >= 6 &&
00308 0 == ACE_OS::strcasecmp(included.c_str() + len - 5, ".pidl")) {
00309 base_name.assign(included.c_str(), len - 5);
00310
00311 } else {
00312 ACE_ERROR((LM_ERROR, ACE_TEXT("(%N:%l) BE_produce - included ")
00313 ACE_TEXT("file must end in .idl or .pidl\n")));
00314 BE_abort();
00315 }
00316
00317 string stb_inc = base_name + "C.h";
00318 if (stb_inc != "tao/orbC.h") {
00319 be_global->add_include(stb_inc.c_str());
00320 if (stb_inc == "orbC.h" ||
00321 (stb_inc.size() >= 7
00322 && stb_inc.substr(stb_inc.size() - 7) == "/orbC.h") ) {
00323 ACE_DEBUG((LM_WARNING,
00324 ACE_TEXT("Warning: (%s) Potential inclusion of TAO orbC.H ")
00325 ACE_TEXT(" Include TAO orb.idl with path of tao/orb.idl")
00326 ACE_TEXT(" to prevent compilation errors\n"), idl_fn));
00327 }
00328 }
00329
00330 }
00331 }
00332
00333 idl.close();
00334
00335 be_global->open_streams(idl_fn);
00336
00337 AST_Decl* d = idl_global->root();
00338 AST_Root* root = AST_Root::narrow_from_decl(d);
00339
00340 if (root == 0) {
00341 ACE_ERROR((LM_ERROR,
00342 ACE_TEXT("(%N:%l) BE_produce - ")
00343 ACE_TEXT("No Root\n")));
00344
00345 BE_abort();
00346 }
00347
00348 be_global->set_inc_paths(idl_global->idl_flags());
00349
00350 const bool java_ts_only = be_global->java_arg().length() > 0;
00351
00352 dds_visitor visitor(d, java_ts_only);
00353
00354 if (root->ast_accept(&visitor) == -1) {
00355 ACE_ERROR((LM_ERROR,
00356 ACE_TEXT("(%N:%l) BE_produce -")
00357 ACE_TEXT(" failed to accept adding visitor\n")));
00358 BE_abort();
00359 }
00360
00361 if (!java_ts_only) {
00362 postprocess(be_global->header_name_.c_str(),
00363 be_global->header_, BE_GlobalData::STREAM_H);
00364 if (!be_global->suppress_idl()) {
00365 postprocess(be_global->idl_name_.c_str(),
00366 be_global->idl_, BE_GlobalData::STREAM_IDL);
00367 }
00368 }
00369
00370 postprocess(be_global->impl_name_.c_str(),
00371 be_global->impl_, BE_GlobalData::STREAM_CPP);
00372
00373 if (be_global->generate_wireshark()) {
00374 postprocess(be_global->ws_config_name_.c_str(),
00375 be_global->ws_config_, BE_GlobalData::STREAM_WS);
00376 }
00377
00378 if (be_global->generate_itl()) {
00379 if (!BE_GlobalData::writeFile(be_global->itl_name_.c_str(), be_global->itl_.str())) {
00380 BE_abort();
00381 }
00382 }
00383
00384 if (be_global->face_ts()) {
00385 postprocess(be_global->facets_header_name_.c_str(), be_global->facets_header_,
00386 BE_GlobalData::STREAM_FACETS_H);
00387 postprocess(be_global->facets_impl_name_.c_str(), be_global->facets_impl_,
00388 BE_GlobalData::STREAM_FACETS_CPP);
00389 }
00390
00391 if (be_global->language_mapping() == BE_GlobalData::LANGMAP_FACE_CXX ||
00392 be_global->language_mapping() == BE_GlobalData::LANGMAP_SP_CXX) {
00393 postprocess(be_global->lang_header_name_.c_str(), be_global->lang_header_,
00394 BE_GlobalData::STREAM_LANG_H);
00395 }
00396
00397 BE_cleanup();
00398 }