be_global.cpp

Go to the documentation of this file.
00001 /*
00002  *
00003  *
00004  * Distributed under the OpenDDS License.
00005  * See: http://www.opendds.org/license.html
00006  */
00007 
00008 #include "be_global.h"
00009 #include "be_util.h"
00010 #include "ast_generator.h"
00011 #include "global_extern.h"
00012 #include "idl_defines.h"
00013 #include "utl_err.h"
00014 #include "utl_string.h"
00015 
00016 #include "ace/OS_NS_strings.h"
00017 #include "ace/OS_NS_sys_stat.h"
00018 #include "ace/ARGV.h"
00019 
00020 #include <algorithm>
00021 #include <iostream>
00022 #include <fstream>
00023 #include <sstream>
00024 #include <string>
00025 #include <vector>
00026 #include <set>
00027 
00028 using namespace std;
00029 
00030 BE_GlobalData* be_global = 0;
00031 
00032 BE_GlobalData::BE_GlobalData()
00033   : filename_(0)
00034   , java_(false)
00035   , suppress_idl_(false)
00036   , suppress_typecode_(false)
00037   , generate_wireshark_(false)
00038   , generate_itl_(false)
00039   , v8_(false)
00040   , face_ts_(false)
00041   , seq_("Seq")
00042   , language_mapping_(LANGMAP_NONE)
00043 {
00044 }
00045 
00046 BE_GlobalData::~BE_GlobalData()
00047 {
00048 }
00049 
00050 void
00051 BE_GlobalData::destroy()
00052 {
00053 }
00054 
00055 const char*
00056 BE_GlobalData::filename() const
00057 {
00058   return this->filename_;
00059 }
00060 
00061 void
00062 BE_GlobalData::filename(const char* fname)
00063 {
00064   this->filename_ = fname;
00065 }
00066 
00067 ACE_CString BE_GlobalData::export_macro() const
00068 {
00069   return this->export_macro_;
00070 }
00071 
00072 void BE_GlobalData::export_macro(const ACE_CString& str)
00073 {
00074   this->export_macro_ = str;
00075 }
00076 
00077 ACE_CString BE_GlobalData::export_include() const
00078 {
00079   return this->export_include_;
00080 }
00081 
00082 void BE_GlobalData::export_include(const ACE_CString& str)
00083 {
00084   this->export_include_ = str;
00085 }
00086 
00087 void BE_GlobalData::pch_include(const ACE_CString& str)
00088 {
00089   this->pch_include_ = str;
00090 }
00091 
00092 ACE_CString BE_GlobalData::pch_include() const
00093 {
00094   return this->pch_include_;
00095 }
00096 
00097 void BE_GlobalData::java_arg(const ACE_CString& str)
00098 {
00099   this->java_arg_ = str;
00100 }
00101 
00102 ACE_CString BE_GlobalData::java_arg() const
00103 {
00104   return this->java_arg_;
00105 }
00106 
00107 void BE_GlobalData::language_mapping(LanguageMapping lm)
00108 {
00109   this->language_mapping_ = lm;
00110 }
00111 
00112 BE_GlobalData::LanguageMapping BE_GlobalData::language_mapping() const
00113 {
00114   return this->language_mapping_;
00115 }
00116 
00117 void BE_GlobalData::sequence_suffix(const ACE_CString& str)
00118 {
00119   this->seq_ = str;
00120 }
00121 
00122 ACE_CString BE_GlobalData::sequence_suffix() const
00123 {
00124   return this->seq_;
00125 }
00126 
00127 void BE_GlobalData::java(bool b)
00128 {
00129   this->java_ = b;
00130 }
00131 
00132 bool BE_GlobalData::java() const
00133 {
00134   return this->java_;
00135 }
00136 
00137 void BE_GlobalData::v8(bool b)
00138 {
00139   this->v8_ = b;
00140 }
00141 
00142 bool BE_GlobalData::v8() const
00143 {
00144   return this->v8_;
00145 }
00146 
00147 void BE_GlobalData::face_ts(bool b)
00148 {
00149   this->face_ts_ = b;
00150 }
00151 
00152 bool BE_GlobalData::face_ts() const
00153 {
00154   return this->face_ts_;
00155 }
00156 
00157 // bool
00158 // BE_GlobalData::do_included_files() const
00159 // {
00160 //   return false; //we never process included files
00161 // }
00162 
00163 void
00164 BE_GlobalData::open_streams(const char* filename)
00165 {
00166   this->filename(filename);
00167   size_t len = strlen(filename);
00168 
00169   if ((len < 5 || 0 != ACE_OS::strcasecmp(filename + len - 4, ".idl"))
00170       && (len < 6 || 0 != ACE_OS::strcasecmp(filename + len - 5, ".pidl"))) {
00171     UTL_Error u;
00172     UTL_String str("Input filename must end in \".idl\" or \".pidl\".");
00173     u.back_end(0, &str);
00174     exit(-1);
00175     return;
00176   }
00177 
00178   string filebase(filename);
00179   filebase.erase(filebase.rfind('.'));
00180   size_t idx = filebase.find_last_of("/\\"); // allow either slash
00181 
00182   if (idx != string::npos) {
00183     filebase = filebase.substr(idx + 1);
00184   }
00185 
00186   header_name_ = (filebase + "TypeSupportImpl.h").c_str();
00187   impl_name_ = (filebase + "TypeSupportImpl.cpp").c_str();
00188   idl_name_ = (filebase + "TypeSupport.idl").c_str();
00189   ws_config_name_ = (filebase + "_ws.ini").c_str();
00190   itl_name_ = (filebase + ".itl").c_str();
00191   facets_header_name_ = (filebase + "_TS.hpp").c_str();
00192   facets_impl_name_ = (filebase + "_TS.cpp").c_str();
00193   lang_header_name_ = (filebase + "C.h").c_str();
00194 }
00195 
00196 void
00197 BE_GlobalData::multicast(const char* str)
00198 {
00199   header_ << str;
00200   impl_ << str;
00201   idl_ << str;
00202   if (language_mapping_ != LANGMAP_NONE) lang_header_ << str;
00203 }
00204 
00205 BE_Comment_Guard::BE_Comment_Guard(const char* type, const char* name)
00206   : type_(type), name_(name)
00207 {
00208   if (idl_global->compile_flags() & IDL_CF_INFORMATIVE)
00209     std::cout << type << ": " << name << std::endl;
00210 
00211   be_global->multicast("\n\n/* Begin ");
00212   be_global->multicast(type);
00213   be_global->multicast(": ");
00214   be_global->multicast(name);
00215   be_global->multicast(" */\n\n");
00216 }
00217 
00218 BE_Comment_Guard::~BE_Comment_Guard()
00219 {
00220   be_global->multicast("\n/* End ");
00221   be_global->multicast(type_);
00222   be_global->multicast(": ");
00223   be_global->multicast(name_);
00224   be_global->multicast(" */\n");
00225 }
00226 
00227 ACE_CString
00228 BE_GlobalData::spawn_options()
00229 {
00230   return idl_global->idl_flags();
00231 }
00232 
00233 void
00234 BE_GlobalData::parse_args(long& i, char** av)
00235 {
00236   static const char WB_EXPORT_MACRO[] = "--export=";
00237   static const size_t SZ_WB_EXPORT_MACRO = sizeof(WB_EXPORT_MACRO) - 1;
00238 
00239   switch (av[i][1]) {
00240   case 'o':
00241     idl_global->append_idl_flag(av[i + 1]);
00242     if (ACE_OS::mkdir(av[i + 1]) != 0 && errno != EEXIST) {
00243       ACE_ERROR((LM_ERROR,
00244         ACE_TEXT("IDL: unable to create directory %C")
00245         ACE_TEXT(" specified by -o option\n"), av[i + 1]));
00246     } else {
00247       output_dir_ = av[++i];
00248     }
00249     break;
00250   case 'G':
00251     if (0 == ACE_OS::strcmp(av[i], "-Gws"))
00252       generate_wireshark_ = true;
00253     else if (0 == ACE_OS::strcmp(av[i], "-Gitl"))
00254       generate_itl_ = true;
00255     else if (0 == ACE_OS::strcasecmp(av[i], "-GfaceTS"))
00256       face_ts(true);
00257     else
00258       {
00259         ACE_ERROR((LM_ERROR, ACE_TEXT("IDL: I don't understand the '%C'")
00260                    ACE_TEXT(" option\n"), av[i]));
00261         idl_global->set_compile_flags(idl_global->compile_flags()
00262                                       | IDL_CF_ONLY_USAGE);
00263       }
00264     break;
00265   case 'L':
00266     if (0 == ACE_OS::strcasecmp(av[i], "-Lface"))
00267       language_mapping(LANGMAP_FACE_CXX);
00268     else if (0 == ACE_OS::strcasecmp(av[i], "-Lspcpp"))
00269       language_mapping(LANGMAP_SP_CXX);
00270     else {
00271       ACE_ERROR((LM_ERROR, ACE_TEXT("IDL: I don't understand the '%C'")
00272                   ACE_TEXT(" option\n"), av[i]));
00273       idl_global->set_compile_flags(idl_global->compile_flags()
00274                                     | IDL_CF_ONLY_USAGE);
00275     }
00276     break;
00277   case 'S':
00278     switch (av[i][2]) {
00279     case 'I':
00280       suppress_idl_ = true;
00281       break;
00282     case 't':
00283       suppress_typecode_ = true;
00284       break;
00285     case 'a':
00286       // ignore, accepted for tao_idl compatibility
00287       break;
00288     default:
00289       ACE_ERROR((LM_ERROR, ACE_TEXT("IDL: I don't understand the '%C'")
00290         ACE_TEXT(" option\n"), av[i]));
00291       idl_global->set_compile_flags(idl_global->compile_flags()
00292                                     | IDL_CF_ONLY_USAGE);
00293     }
00294     break;
00295   case 'Z':
00296     switch (av[i][2]) {
00297     case 'C':
00298       add_include (av[++i], STREAM_CPP);
00299       break;
00300     default:
00301       ACE_ERROR((LM_ERROR, ACE_TEXT("IDL: I don't understand the '%C'")
00302                  ACE_TEXT(" option\n"), av[i]));
00303       idl_global->set_compile_flags(idl_global->compile_flags()
00304                                     | IDL_CF_ONLY_USAGE);
00305     }
00306     break;
00307   case '-':
00308     if (0 == ACE_OS::strncasecmp(av[i], WB_EXPORT_MACRO, SZ_WB_EXPORT_MACRO)) {
00309       this->export_macro(av[i] + SZ_WB_EXPORT_MACRO);
00310     }
00311     break;
00312   default:
00313     ACE_ERROR((LM_ERROR, ACE_TEXT("IDL: I don't understand the '%C' option\n"),
00314                av[i]));
00315     idl_global->set_compile_flags(idl_global->compile_flags()
00316                                   | IDL_CF_ONLY_USAGE);
00317   }
00318 }
00319 
00320 
00321 bool
00322 BE_GlobalData::writeFile(const char* fileName, const string& content)
00323 {
00324   string file = (be_global->output_dir_ == "")
00325     ? fileName : (string(be_global->output_dir_.c_str()) + '/' + fileName);
00326   ofstream ofs(file.c_str());
00327 
00328   if (!ofs) {
00329     cerr << "ERROR - couldn't open " << file << " for writing.\n";
00330     return false;
00331   }
00332 
00333   ofs << content;
00334   return !!ofs;
00335 }
00336 
00337 //include file management (assumes a singleton BE_GlobalData object)
00338 
00339 namespace {
00340   typedef set<string> Includes_t;
00341   Includes_t inc_h_, inc_c_, inc_idl_, referenced_idl_, inc_path_, inc_facets_h_,
00342     inc_lang_h_;
00343 }
00344 
00345 void
00346 BE_GlobalData::reset_includes()
00347 {
00348   inc_h_.clear();
00349   inc_c_.clear();
00350   inc_idl_.clear();
00351   inc_facets_h_.clear();
00352   inc_lang_h_.clear();
00353   referenced_idl_.clear();
00354 }
00355 
00356 void
00357 BE_GlobalData::add_inc_path(const char* path)
00358 {
00359   inc_path_.insert(path);
00360 }
00361 
00362 void
00363 BE_GlobalData::set_inc_paths(const char* cmdline)
00364 {
00365   ACE_ARGV argv(ACE_TEXT_CHAR_TO_TCHAR(cmdline), false);
00366   for (int i = 0; i < argv.argc(); ++i) {
00367     std::string arg = ACE_TEXT_ALWAYS_CHAR(argv[i]);
00368     if (arg == "-I" && i + 1 < argv.argc()) {
00369       inc_path_.insert(ACE_TEXT_ALWAYS_CHAR(argv[++i]));
00370     } else if (arg.substr(0, 2) == "-I") {
00371       inc_path_.insert(arg.c_str() + 2);
00372     }
00373   }
00374 }
00375 
00376 void
00377 BE_GlobalData::add_include(const char* file,
00378                            BE_GlobalData::stream_enum_t which)
00379 {
00380   Includes_t* inc = 0;
00381 
00382   switch (which) {
00383   case STREAM_H:
00384     inc = &inc_h_;
00385     break;
00386   case STREAM_CPP:
00387     inc = &inc_c_;
00388     break;
00389   case STREAM_IDL:
00390     inc = &inc_idl_;
00391     break;
00392   case STREAM_FACETS_H:
00393     inc = &inc_facets_h_;
00394     break;
00395   case STREAM_LANG_H:
00396     inc = &inc_lang_h_;
00397     break;
00398   default:
00399     return;
00400   }
00401 
00402   inc->insert(file);
00403 }
00404 
00405 void
00406 BE_GlobalData::add_referenced(const char* file)
00407 {
00408   referenced_idl_.insert(file);
00409 }
00410 
00411 namespace {
00412   std::string transform_referenced(const std::string& idl, const char* suffix)
00413   {
00414     const size_t len = idl.size();
00415     string base_name;
00416     if (len >= 5 && 0 == ACE_OS::strcasecmp(idl.c_str() + len - 4, ".idl")) {
00417       base_name.assign(idl.c_str(), len - 4);
00418 
00419     } else if (len >= 6 &&
00420         0 == ACE_OS::strcasecmp(idl.c_str() + len - 5, ".pidl")) {
00421       base_name.assign(idl.c_str(), len - 5);
00422       size_t slash = base_name.find_last_of("/\\");
00423       if (slash != std::string::npos && slash > 3 && base_name.size() > 3
00424           && base_name.substr(slash - 3, 3) == "tao"
00425           && base_name.substr(base_name.size() - 3) == "Seq") {
00426         base_name = "dds/CorbaSeq/" + base_name.substr(slash + 1);
00427       }
00428     }
00429 
00430     return base_name + suffix;
00431   }
00432 
00433   std::string make_relative(const std::string& absolute)
00434   {
00435     for (Includes_t::const_iterator iter = inc_path_.begin(),
00436         end = inc_path_.upper_bound(absolute); iter != end; ++iter) {
00437       if (absolute.find(*iter) == 0) {
00438         string rel = absolute.substr(iter->size());
00439         if (rel.size() && (rel[0] == '/' || rel[0] == '\\')) {
00440           rel.erase(0, 1);
00441         }
00442         return rel;
00443       }
00444     }
00445     return absolute;
00446   }
00447 
00448   struct InsertIncludes {
00449     std::ostream& ret_;
00450     explicit InsertIncludes(std::ostream& ret) : ret_(ret) {}
00451 
00452     void operator()(const std::string& str) const
00453     {
00454        const char* const quote = (!str.empty() && str[0] != '<') ? "\"" : "";
00455        ret_ << "#include " << quote << str << quote << '\n';
00456     }
00457   };
00458 
00459   struct InsertRefIncludes : InsertIncludes {
00460     const char* const suffix_;
00461 
00462     InsertRefIncludes(std::ostream& ret, const char* suffix)
00463       : InsertIncludes(ret)
00464       , suffix_(suffix)
00465     {}
00466 
00467     void operator()(const std::string& str) const
00468     {
00469       InsertIncludes::operator()(transform_referenced(make_relative(str), suffix_));
00470     }
00471   };
00472 }
00473 
00474 std::string
00475 BE_GlobalData::get_include_block(BE_GlobalData::stream_enum_t which)
00476 {
00477   const Includes_t* inc = 0;
00478 
00479   switch (which) {
00480   case STREAM_H:
00481     inc = &inc_h_;
00482     break;
00483   case STREAM_CPP:
00484     inc = &inc_c_;
00485     break;
00486   case STREAM_IDL:
00487     inc = &inc_idl_;
00488     break;
00489   case STREAM_FACETS_H:
00490     inc = &inc_facets_h_;
00491     break;
00492   case STREAM_LANG_H:
00493     inc = &inc_lang_h_;
00494     break;
00495   default:
00496     return "";
00497   }
00498 
00499   std::ostringstream ret;
00500 
00501   std::for_each(inc->begin(), inc->end(), InsertIncludes(ret));
00502 
00503   switch (which) {
00504   case STREAM_LANG_H:
00505     std::for_each(referenced_idl_.begin(), referenced_idl_.end(),
00506                   InsertRefIncludes(ret, "C.h"));
00507     // fall through
00508   case STREAM_H:
00509     if (!export_include().empty())
00510       ret << "#include \"" << export_include() << "\"\n";
00511     break;
00512 
00513   case STREAM_CPP:
00514     std::for_each(referenced_idl_.begin(), referenced_idl_.end(),
00515                   InsertRefIncludes(ret, "TypeSupportImpl.h"));
00516     break;
00517   default:
00518     break;
00519   }
00520 
00521   return ret.str();
00522 }

Generated on Fri Feb 12 20:05:19 2016 for OpenDDS by  doxygen 1.4.7