16 #include <ast_generator.h> 17 #include <global_extern.h> 18 #include <idl_defines.h> 20 #include <utl_string.h> 22 #include <ast_structure.h> 23 #include <ast_field.h> 24 #include <ast_union.h> 25 #include <ast_annotation_decl.h> 26 #include <ast_annotation_member.h> 49 , suppress_idl_(false)
50 , suppress_typecode_(false)
51 , suppress_xtypes_(false)
52 , no_default_gen_(false)
53 , generate_itl_(false)
54 , generate_value_reader_writer_(true)
55 , generate_xtypes_complete_(false)
57 , filename_only_includes_(false)
58 , sequence_suffix_(
"Seq")
59 , language_mapping_(LANGMAP_NONE)
60 , root_default_nested_(true)
61 , warn_about_dcps_data_type_(true)
63 , default_enum_extensibility_zero_(false)
66 , old_typeobject_encoding_(false)
67 , old_typeobject_member_order_(false)
69 default_data_representation_.set_all(
true);
71 platforms_.insert(
"*");
72 platforms_.insert(
"DDS");
73 platforms_.insert(
"OpenDDS");
99 return this->export_macro_;
102 void BE_GlobalData::export_macro(
const ACE_CString& str)
104 this->export_macro_ = str;
109 return this->export_include_;
112 void BE_GlobalData::export_include(
const ACE_CString& str)
114 this->export_include_ = str;
119 return this->versioning_name_;
122 void BE_GlobalData::versioning_name(
const ACE_CString& str)
124 this->versioning_name_ = str;
127 ACE_CString BE_GlobalData::versioning_begin()
const 129 return this->versioning_begin_;
132 void BE_GlobalData::versioning_begin(
const ACE_CString& str)
134 this->versioning_begin_ = str;
139 return this->versioning_end_;
142 void BE_GlobalData::versioning_end(
const ACE_CString& str)
144 this->versioning_end_ = str;
147 void BE_GlobalData::pch_include(
const ACE_CString& str)
149 this->pch_include_ = str;
154 return this->pch_include_;
157 void BE_GlobalData::add_cpp_include(
const string& str)
159 this->cpp_includes_.insert(make_pair(str,
""));
162 const set<pair<string, string> >& BE_GlobalData::cpp_includes()
const 164 return this->cpp_includes_;
167 void BE_GlobalData::java_arg(
const ACE_CString& str)
169 this->java_arg_ = str;
174 return this->java_arg_;
177 void BE_GlobalData::language_mapping(LanguageMapping lm)
179 this->language_mapping_ = lm;
182 BE_GlobalData::LanguageMapping BE_GlobalData::language_mapping()
const 184 return this->language_mapping_;
187 void BE_GlobalData::sequence_suffix(
const ACE_CString& str)
189 this->sequence_suffix_ = str;
194 return this->sequence_suffix_;
197 void BE_GlobalData::java(
bool b)
202 bool BE_GlobalData::java()
const 207 void BE_GlobalData::no_default_gen(
bool b)
209 this->no_default_gen_ = b;
212 bool BE_GlobalData::no_default_gen()
const 214 return this->no_default_gen_;
217 void BE_GlobalData::filename_only_includes(
bool b)
219 this->filename_only_includes_ = b;
222 bool BE_GlobalData::filename_only_includes()
const 224 return this->filename_only_includes_;
228 void BE_GlobalData::itl(
bool b)
230 this->generate_itl_ = b;
233 bool BE_GlobalData::itl()
const 235 return this->generate_itl_;
238 void BE_GlobalData::value_reader_writer(
bool b)
240 this->generate_value_reader_writer_ = b;
243 bool BE_GlobalData::value_reader_writer()
const 245 return this->generate_value_reader_writer_;
248 void BE_GlobalData::face_ts(
bool b)
253 bool BE_GlobalData::face_ts()
const 255 return this->face_ts_;
258 void BE_GlobalData::xtypes_complete(
bool b)
260 this->generate_xtypes_complete_ = b;
263 bool BE_GlobalData::xtypes_complete()
const 265 return this->generate_xtypes_complete_;
269 BE_GlobalData::open_streams(
const char*
filename)
271 size_t len =
strlen(filename);
274 ACE_ERROR((
LM_ERROR,
"Error - Input filename must end in \".idl\" or \".pidl\".\n"));
278 string filebase(filename);
279 filebase.erase(filebase.rfind(
'.'));
280 size_t idx = filebase.find_last_of(
"/\\");
281 if (idx != string::npos) {
282 filebase = filebase.substr(idx + 1);
284 header_name_ = (filebase +
"TypeSupportImpl.h").c_str();
285 impl_name_ = (filebase +
"TypeSupportImpl.cpp").c_str();
286 idl_name_ = (filebase +
"TypeSupport.idl").c_str();
287 itl_name_ = (filebase +
".itl").c_str();
288 facets_header_name_ = (filebase +
"_TS.hpp").c_str();
289 facets_impl_name_ = (filebase +
"_TS.cpp").c_str();
290 lang_header_name_ = (filebase +
"C.h").c_str();
294 BE_GlobalData::multicast(
const char* str)
299 if (language_mapping_ != LANGMAP_NONE) lang_header_ << str;
303 : type_(type), name_(name)
305 if (idl_global->compile_flags() & IDL_CF_INFORMATIVE)
306 cout << type <<
": " << name << endl;
308 be_global->multicast(
"\n\n/* Begin ");
309 be_global->multicast(type);
310 be_global->multicast(
": ");
311 be_global->multicast(name);
312 be_global->multicast(
" */\n\n");
317 be_global->multicast(
"\n/* End ");
318 be_global->multicast(
type_);
319 be_global->multicast(
": ");
320 be_global->multicast(
name_);
321 be_global->multicast(
" */\n");
327 return idl_global->idl_flags();
333 ACE_TEXT(
"opendds_idl: I don't understand the '%C' option\n"), option));
334 idl_global->parse_args_exit(1);
340 static const char EXPORT_FLAG[] =
"--export=";
341 static const size_t EXPORT_FLAG_SIZE =
sizeof(EXPORT_FLAG) - 1;
343 static const char DEFAULT_NESTED_FLAG[] =
"--default-nested";
344 static const size_t DEFAULT_NESTED_FLAG_SIZE =
sizeof(DEFAULT_NESTED_FLAG) - 1;
346 static const char NO_DEFAULT_NESTED_FLAG[] =
"--no-default-nested";
347 static const size_t NO_DEFAULT_NESTED_FLAG_SIZE =
sizeof(NO_DEFAULT_NESTED_FLAG) - 1;
349 static const char NO_DCPS_DATA_TYPE_WARNINGS_FLAG[] =
"--no-dcps-data-type-warnings";
350 static const size_t NO_DCPS_DATA_TYPE_WARNINGS_FLAG_SIZE =
sizeof(NO_DCPS_DATA_TYPE_WARNINGS_FLAG) - 1;
352 static const char FILENAME_ONLY_INCLUDES_FLAG[] =
"--filename-only-includes";
353 static const size_t FILENAME_ONLY_INCLUDES_FLAG_SIZE =
sizeof(FILENAME_ONLY_INCLUDES_FLAG) - 1;
359 idl_global->parse_args_exit(1);
361 idl_global->append_idl_flag(av[i]);
364 ACE_TEXT(
" specified by -o option\n"), av[i]));
365 idl_global->parse_args_exit(1);
378 xtypes_complete(
true);
386 language_mapping(LANGMAP_FACE_CXX);
388 language_mapping(LANGMAP_SP_CXX);
390 language_mapping(LANGMAP_CXX11);
398 no_default_gen_ =
true;
401 if (av[i][2] && av[i][3]) {
407 suppress_idl_ =
true;
410 suppress_typecode_ =
true;
413 generate_value_reader_writer_ =
false;
416 suppress_xtypes_ =
true;
428 this->export_macro(av[i] + EXPORT_FLAG_SIZE);
430 root_default_nested_ =
true;
431 }
else if (!
ACE_OS::strncasecmp(av[i], NO_DEFAULT_NESTED_FLAG, NO_DEFAULT_NESTED_FLAG_SIZE)) {
432 root_default_nested_ =
false;
433 }
else if (!
ACE_OS::strncasecmp(av[i], NO_DCPS_DATA_TYPE_WARNINGS_FLAG, NO_DCPS_DATA_TYPE_WARNINGS_FLAG_SIZE)) {
434 warn_about_dcps_data_type_ =
false;
435 }
else if (!
ACE_OS::strncasecmp(av[i], FILENAME_ONLY_INCLUDES_FLAG, FILENAME_ONLY_INCLUDES_FLAG_SIZE)) {
436 filename_only_includes_ =
true;
437 }
else if (!
strcmp(av[i],
"--default-extensibility")) {
440 idl_global->parse_args_exit(1);
441 }
else if (!
strcmp(av[i],
"final")) {
443 }
else if (!
strcmp(av[i],
"appendable")) {
445 }
else if (!
strcmp(av[i],
"mutable")) {
449 ACE_TEXT(
"Invalid argument to --default-extensibility: %C\n"), av[i]));
450 idl_global->parse_args_exit(1);
452 }
else if (!
strcmp(av[i],
"--default-enum-extensibility-zero")) {
453 default_enum_extensibility_zero_ =
true;
454 }
else if (!
strcmp(av[i],
"--default-autoid")) {
457 idl_global->parse_args_exit(1);
458 }
else if (!
strcmp(av[i],
"sequential")) {
460 }
else if (!
strcmp(av[i],
"hash")) {
464 ACE_TEXT(
"Invalid argument to --default-autoid: %C\n"), av[i]));
465 idl_global->parse_args_exit(1);
467 }
else if (!
strcmp(av[i],
"--default-try-construct")) {
470 idl_global->parse_args_exit(1);
471 }
else if (!
strcmp(av[i],
"discard")) {
473 }
else if (!
strcmp(av[i],
"use-default")) {
475 }
else if (!
strcmp(av[i],
"trim")) {
479 ACE_TEXT(
"Invalid argument to --default-try-construct: %C\n"), av[i]));
480 idl_global->parse_args_exit(1);
482 }
else if (!
strcmp(av[i],
"--old-typeobject-encoding")) {
483 old_typeobject_encoding_ =
true;
484 }
else if (!
strcmp(av[i],
"--old-typeobject-member-order")) {
485 old_typeobject_member_order_ =
true;
498 BE_GlobalData::writeFile(
const char* fileName,
const string& content)
500 string file = (be_global->output_dir_ ==
"")
501 ? fileName : (
string(be_global->output_dir_.
c_str()) +
'/' + fileName);
502 ofstream ofs(file.c_str());
505 cerr <<
"ERROR - couldn't open " << file <<
" for writing.\n";
516 typedef set<pair<string, string> > Includes;
517 Includes all_includes[BE_GlobalData::STREAM_COUNT];
518 set<string> referenced_idl, inc_path;
519 vector<string> inc_path_vector;
523 BE_GlobalData::reset_includes()
525 inc_path_vector.clear();
526 for (
int i = 0; i < BE_GlobalData::STREAM_COUNT; ++i) {
527 all_includes[i].clear();
532 BE_GlobalData::add_inc_path(
const char* path)
534 if (inc_path.insert(path).second) {
535 inc_path_vector.push_back(path);
540 BE_GlobalData::set_inc_paths(
const char* cmdline)
543 for (
int i = 0; i < argv.
argc(); ++i) {
545 if (arg ==
"-I" && i + 1 < argv.
argc()) {
547 }
else if (arg.substr(0, 2) ==
"-I") {
548 add_inc_path(arg.c_str() + 2);
554 BE_GlobalData::add_include(
const char* file, stream_enum_t which)
556 conditional_include(file, which,
"");
560 BE_GlobalData::conditional_include(
const char* file,
562 const char* condition)
564 all_includes[which].insert(make_pair(file, condition));
568 BE_GlobalData::add_referenced(
const char* file)
570 referenced_idl.insert(file);
574 pair<string, string> transform_referenced(
const string& idl,
const char* suffix)
576 const size_t len = idl.size();
579 base_name.assign(idl.c_str(), len - 4);
581 }
else if (len >= 6 &&
583 base_name.assign(idl.c_str(), len - 5);
584 const size_t slash = base_name.find_last_of(
"/\\");
585 if (slash != string::npos && slash >= 3 && base_name.size() > 3
586 && base_name.substr(slash - 3, 3) ==
"tao" 587 && base_name.substr(base_name.size() - 3) ==
"Seq") {
588 base_name =
"dds/CorbaSeq/" + base_name.substr(slash + 1);
592 return make_pair(base_name + suffix,
"");
595 string make_relative(
const string& absolute,
bool filename_only_includes)
597 for (vector<string>::reverse_iterator iter = inc_path_vector.rbegin(),
598 end = inc_path_vector.rend(); iter != end; ++iter) {
599 if (absolute.find(*iter) == 0) {
600 string rel = absolute.substr(iter->size());
602 if (rel.size() && (rel[0] ==
'/' || rel[0] ==
'\\')) {
606 if (filename_only_includes) {
607 size_t loc = rel.rfind(
'/', rel.length());
608 const size_t locw = rel.rfind(
'\\', rel.length());
610 if (loc != string::npos && locw != string::npos) {
612 loc = loc > locw ? loc : locw;
613 }
else if (loc == string::npos) {
617 if (loc != string::npos) {
618 rel = rel.substr(loc + 1, rel.length() - loc);
629 struct InsertIncludes {
631 explicit InsertIncludes(
ostream& ret) : ret_(ret) {}
633 void operator()(
const pair<string, string>& inc)
const 635 const string& str = inc.first;
636 const char*
const quote = (!str.empty() && str[0] !=
'<') ?
"\"" :
"";
637 if (inc.second.size()) {
638 ret_ << inc.second <<
"\n ";
640 ret_ <<
"#include " << quote << str << quote <<
'\n';
641 if (inc.second.size()) {
647 struct InsertRefIncludes : InsertIncludes {
648 const char*
const suffix_;
649 bool filename_only_includes_;
651 InsertRefIncludes(
ostream& ret,
const char* suffix,
const bool filename_only_includes)
652 : InsertIncludes(ret)
654 , filename_only_includes_(filename_only_includes)
657 void operator()(
const string& str)
const 659 InsertIncludes::operator()(transform_referenced(make_relative(str, filename_only_includes_), suffix_));
665 BE_GlobalData::get_include_block(BE_GlobalData::stream_enum_t which)
667 Includes& inc = all_includes[which];
670 for_each(inc.begin(), inc.end(), InsertIncludes(ret));
674 for_each(referenced_idl.begin(), referenced_idl.end(),
675 InsertRefIncludes(ret,
"C.h", filename_only_includes_));
678 if (!export_include().empty())
679 ret <<
"#include \"" << export_include() <<
"\"\n";
682 for_each(cpp_includes().begin(), cpp_includes().end(), InsertIncludes(ret));
683 for_each(referenced_idl.begin(), referenced_idl.end(),
684 InsertRefIncludes(ret,
"TypeSupportImpl.h", filename_only_includes_));
693 bool BE_GlobalData::is_topic_type(AST_Decl* node)
695 return !is_nested(node);
698 bool BE_GlobalData::is_nested(AST_Decl* node)
705 if (platforms_.count(value.
platform)) {
712 builtin_annotations_[
"::@nested"]);
718 return is_default_nested(node->defined_in());
721 bool BE_GlobalData::is_default_nested(UTL_Scope* scope)
723 AST_Decl* module =
dynamic_cast<AST_Decl*
>(scope);
725 builtin_annotations_[
"::@default_nested"]);
732 return is_default_nested(module->defined_in());
735 return root_default_nested_;
738 bool BE_GlobalData::check_key(AST_Decl* node,
bool&
value)
const 745 bool BE_GlobalData::union_discriminator_is_key(AST_Union* node)
751 void BE_GlobalData::warning(
const char* msg,
const char* filename,
unsigned lineno)
753 if (idl_global->print_warnings()) {
756 idl_global->prog_name(), filename, lineno, msg));
759 idl_global->prog_name(), msg));
762 idl_global->err()->last_warning = UTL_Error::EIDL_MISC;
765 void BE_GlobalData::error(
const char* msg,
const char* filename,
unsigned lineno)
769 idl_global->prog_name(), filename, lineno, msg));
772 idl_global->prog_name(), msg));
774 idl_global->set_err_count(idl_global->err_count() + 1);
775 idl_global->err()->last_error = UTL_Error::EIDL_MISC;
778 bool BE_GlobalData::warn_about_dcps_data_type()
780 if (!warn_about_dcps_data_type_) {
783 warn_about_dcps_data_type_ =
false;
784 return idl_global->print_warnings();
789 has_annotation =
true;
791 if (builtin_annotations_[
"::@final"]->find_on(node)) {
795 if (builtin_annotations_[
"::@appendable"]->find_on(node)) {
799 if (builtin_annotations_[
"::@mutable"]->find_on(node)) {
805 builtin_annotations_[
"::@extensibility"]);
808 value = default_extensibility;
809 has_annotation =
false;
816 if (builtin_annotations_[
"::@final"]->find_on(node)) {
820 if (builtin_annotations_[
"::@appendable"]->find_on(node)) {
824 if (builtin_annotations_[
"::@mutable"]->find_on(node)) {
830 builtin_annotations_[
"::@extensibility"]);
833 value = default_extensibility;
843 AutoidKind BE_GlobalData::autoid(AST_Decl* node)
const 846 builtin_annotations_[
"::@autoid"]);
851 return scoped_autoid(node->defined_in());
854 AutoidKind BE_GlobalData::scoped_autoid(UTL_Scope* scope)
const 856 AST_Decl* module =
dynamic_cast<AST_Decl*
>(scope);
858 builtin_annotations_[
"::@autoid"]);
864 return scoped_autoid(module->defined_in());
866 return root_default_autoid_;
872 dynamic_cast<IdAnnotation*
>(builtin_annotations_[
"::@id"]);
876 bool BE_GlobalData::hashid(AST_Decl* node,
string&
value)
const 883 bool BE_GlobalData::is_optional(AST_Decl* node)
const 887 builtin_annotations_[
"::@optional"]);
893 bool BE_GlobalData::is_must_understand(AST_Decl* node)
const 897 builtin_annotations_[
"::@must_understand"]);
903 bool BE_GlobalData::is_effectively_must_understand(AST_Decl* node)
const 905 return is_must_understand(node) ||
is_key(node);
908 bool BE_GlobalData::is_key(AST_Decl* node)
const 911 check_key(node, value);
915 bool BE_GlobalData::is_external(AST_Decl* node)
const 919 builtin_annotations_[
"::@external"]);
925 bool BE_GlobalData::is_plain(AST_Decl* node)
const 929 builtin_annotations_[
"::@external"]);
932 builtin_annotations_[
"::@try_construct"]);
934 for (AST_Annotation_Appls::iterator i = node->annotations().begin();
935 i != node->annotations().end(); ++i) {
936 AST_Annotation_Appl* appl = i->get();
938 appl->annotation_decl() != external_annotation->
declaration() &&
939 appl->annotation_decl() != try_construct_annotation->
declaration()) {
951 builtin_annotations_[
"::@try_construct"]);
954 value = default_try_construct_;
977 return try_construct_annotation->
union_value(node);
981 AST_Decl* node)
const 986 builtin_annotations_[
"::OpenDDS::@data_representation"]);
989 value = default_data_representation_;
997 const MemberIdMap::const_iterator pos = member_id_map_.find(field);
998 if (pos != member_id_map_.end()) {
1007 if (
id(field, member_id)) {
1010 }
else if (hashid(field, hash_id)) {
1021 GlobalMemberIdCollisionMap::iterator git = member_id_collision_map_.find(stru);
1022 if (git == member_id_collision_map_.end()) {
1023 git = member_id_collision_map_.insert(
1024 std::pair<AST_Structure*, MemberIdCollisionMap>(stru, MemberIdCollisionMap())).first;
1026 MemberIdCollisionMap::iterator lit = git->second.find(mid);
1027 if (lit != git->second.end()) {
1028 std::ostringstream msg;
1029 msg <<
"Member id " << mid <<
" is the same as on field " <<
canonical_name(lit->second);
1032 git->second.insert(std::pair<MemberId, AST_Field*>(mid, field));
1035 std::ostringstream msg;
1036 msg <<
"Member id " << mid <<
" exceeds the maximum allowed value (" <<
1040 member_id_map_[field] = mid;
1046 const MemberIdMap::const_iterator pos = member_id_map_.find(field);
1047 if (pos != member_id_map_.end()) {
1054 bool BE_GlobalData::dynamic_data_adapter(AST_Decl* node)
const 1056 return !builtin_annotations_[
"::OpenDDS::internal::@no_dynamic_data_adapter"]->find_on(node);
1059 bool BE_GlobalData::special_serialization(AST_Decl* node, std::string& template_name)
const 1062 const Anno*
const anno =
1063 dynamic_cast<const Anno*
>(builtin_annotations_[
"::OpenDDS::internal::@special_serialization"]);
1064 if (!anno->node_value_exists(node, template_name)) {
1067 if (template_name.empty()) {
const char * filename(void) const
bool is_key(DDS::DynamicType_ptr type, const char *field)
const char * c_str(void) const
const LogLevel::Value value
void parse_args(long &i, char **av)
TryConstructFailAction union_value(AST_Union *node) const
static const ACE_CDR::ULong MEMBER_ID_MAX
Maximum value for member id.
TryConstructFailAction array_element_value(AST_Array *node) const
int strncasecmp(const char *s, const char *t, size_t len)
BE_GlobalData * be_global
#define ACE_TEXT_ALWAYS_CHAR(STRING)
size_t strlen(const char *s)
AST_Annotation_Decl * declaration() const
std::string canonical_name(UTL_ScopedName *sn)
ACE_CDR::ULong hash_member_name_to_id(const OPENDDS_STRING &name)
int mkdir(const char *path, mode_t mode=ACE_DEFAULT_DIR_PERMS)
TryConstructFailAction sequence_element_value(AST_Sequence *node) const
virtual bool node_value_exists(AST_Decl *node, T &value) const
virtual ~BE_GlobalData(void)
#define ACE_TEXT_CHAR_TO_TCHAR(STRING)
BE_Comment_Guard(const char *type, const char *name)
int strcmp(const char *s, const char *t)
void invalid_option(char *option)
bool node_value_exists(AST_Decl *node, DataRepresentation &value) const
ACE_CString spawn_options(void)
int strcasecmp(const char *s, const char *t)
bool union_value(AST_Union *node) const
void misc_error_and_abort(const std::string &message, AST_Decl *node=0)
Report a miscellaneous error and abort.
The Internal API and Implementation of OpenDDS.
extensibility(MUTABLE) struct TypeLookup_getTypes_In