diff options
Diffstat (limited to 'modules/CIAO/CIDLC/ServantGenerator.cpp')
-rw-r--r-- | modules/CIAO/CIDLC/ServantGenerator.cpp | 220 |
1 files changed, 220 insertions, 0 deletions
diff --git a/modules/CIAO/CIDLC/ServantGenerator.cpp b/modules/CIAO/CIDLC/ServantGenerator.cpp new file mode 100644 index 00000000000..f817087b92d --- /dev/null +++ b/modules/CIAO/CIDLC/ServantGenerator.cpp @@ -0,0 +1,220 @@ +// file : CIDLC/ServantGenerator.cpp +// author : Jeff Parsons <j.parsons@vanderbilt.edu> +// cvs-id : $Id$ + +#include "ServantGenerator.hpp" +#include "ServantHeaderGenerator.hpp" +#include "ServantSourceGenerator.hpp" +#include "CxxNamePrinter.hpp" + +#include "CCF/CodeGenerationKit/Regex.hpp" +#include "CCF/CodeGenerationKit/IndentationCxx.hpp" +#include "CCF/CodeGenerationKit/IndentationImplanter.hpp" + +using namespace CCF; +using namespace CIDL; +using namespace SemanticGraph; +using namespace Traversal; + +using std::string; +using std::ostream; + +namespace +{ + // On some platforms toupper can be something else than a + // function. + int + upcase (int c) + { + return toupper (c); + } +} + +ServantGenerator::ServantGenerator (CommandLine const& cl) + : cl_ (cl), + file_name_ (""), + export_macro_ ("") +{ +} + +void ServantGenerator::options (CL::Description& d) +{ + d.add_option (CL::OptionDescription ( + "svnt-hdr-file-suffix", + "suffix", + "Use provided suffix instead of default \'_svnt.h\' " + "when constructing name of servant file.", + CL::OptionType::value)); + + d.add_option (CL::OptionDescription ( + "svnt-hdr-file-regex", + "regex", + "Use provided regular expression when constructing " + "name of servant file.", + CL::OptionType::value)); + + d.add_option (CL::OptionDescription ( + "svnt-src-file-suffix", + "suffix", + "Use provided suffix instead of default \'_svnt.cpp\' " + "when constructing name of servant file.", + CL::OptionType::value)); + + d.add_option (CL::OptionDescription ( + "svnt-src-file-regex", + "regex", + "Use provided regular expression when constructing " + "name of servant file.", + CL::OptionType::value)); + + d.add_option (CL::OptionDescription ( + "svnt-export-macro", + "macro", + "Replace default servant DLL export macro " + "with provided ,acro.", + CL::OptionType::value)); + + d.add_option (CL::OptionDescription ( + "svnt-export-include", + "file", + "Replace default servant export include file " + "with provided file.", + CL::OptionType::value)); + + d.add_option (CL::OptionDescription ( + "suppress-register-factory", + "Suppress generation of code to register eventtype " + "factories for event sinks.", + CL::OptionType::flag)); + + d.add_option (CL::OptionDescription ( + "custom-container", + "type", + "Generate code for custom container of the provided type.", + CL::OptionType::value)); +} + + +void ServantGenerator::generate (SemanticGraph::TranslationUnit& u, + fs::path const& file) +{ + // Generate files + compute_export_macro (file); + + { + fs::ofstream hdr_ofs; + ostream& hdr_os = configure_stream ("svnt-hdr-file-suffix", + "_svnt.h", + "svnt-hdr-file-regex", + hdr_ofs); + + Indentation::Implanter<Indentation::Cxx> header_guard (hdr_os); + + // Set C++ name printer for os. + // + CxxNamePrinter name_printer; + hdr_os.pword (name_printer_index) = &name_printer; + + ServantHeaderEmitter hdr_emitter (hdr_os, + cl_, + export_macro_, + file); + hdr_emitter.generate (u); + } + + { + fs::ofstream src_ofs; + ostream& src_os = configure_stream ("svnt-src-file-suffix", + "_svnt.cpp", + "svnt-src-file-regex", + src_ofs); + + Indentation::Implanter<Indentation::Cxx> header_guard (src_os); + + // Set C++ name printer for os. + // + CxxNamePrinter name_printer; + src_os.pword (name_printer_index) = &name_printer; + + ServantSourceEmitter src_emitter (src_os, + cl_, + export_macro_, + file); + src_emitter.generate (u); + } +} + +void +ServantGenerator::compute_export_macro (const fs::path& file_path) +{ + if (!file_path.empty ()) + { + file_name_ = file_path.leaf (); + } + + export_macro_ = cl_.get_value ("svnt-export-macro", ""); + + if (export_macro_.empty () && !file_name_.empty ()) + { + // Modify a copy of the filename string. + export_macro_ = file_name_; + + // Convert filename string to upper case. + transform (export_macro_.begin (), + export_macro_.end (), + export_macro_.begin (), + upcase); + + // Replace the suffix. + export_macro_ = + regex::perl_s (export_macro_, + "/^(.+?)(\\.(IDL|CIDL|CDL))?$/$1_SVNT_Export/"); + + // Replace any remaining '.' in the string with '_'. + export_macro_ = regex::perl_s (export_macro_, + "/\\./_/"); + } +} + + + +ostream& +ServantGenerator::configure_stream (string const& suffix_option, + string const& default_suffix, + string const& regex_option, + fs::ofstream& ofs) +{ + if (! file_name_.empty ()) + { + string file_suffix = cl_.get_value (suffix_option, + default_suffix); + string file_expr = + cl_.get_value (regex_option, + "/^(.+?)(\\.(idl|cidl|cdl))?$/$1" + file_suffix + "/"); + + string file_name = regex::perl_s (file_name_, file_expr); + + fs::path file_path (file_name); + + ofs.open (file_path, std::ios_base::out); + + if (!ofs.is_open ()) + { + cerr << file_name + << ": error: unable to open file in write mode" + << endl; + } + } + + return ofs.is_open () + ? static_cast<ostream&> (ofs) + : static_cast<ostream&> (std::cout); +} + + +/* + * Local Variables: + * mode: C++ + * c-basic-offset: 2 + * End: + */ |