diff options
Diffstat (limited to 'modules/CIAO/CCF/CCF/CodeGenerationKit')
12 files changed, 1866 insertions, 0 deletions
diff --git a/modules/CIAO/CCF/CCF/CodeGenerationKit/CodeGenerationKit.mpc b/modules/CIAO/CCF/CCF/CodeGenerationKit/CodeGenerationKit.mpc new file mode 100644 index 00000000000..e978244e1ae --- /dev/null +++ b/modules/CIAO/CCF/CCF/CodeGenerationKit/CodeGenerationKit.mpc @@ -0,0 +1,7 @@ +//$Id$ + +project(CodeGenerationKit): cidlc { + sharedname = + staticname = CodeGenerationKit + libout = .. +} diff --git a/modules/CIAO/CCF/CCF/CodeGenerationKit/CommandLine.cpp b/modules/CIAO/CCF/CCF/CodeGenerationKit/CommandLine.cpp new file mode 100644 index 00000000000..018aea6ffcf --- /dev/null +++ b/modules/CIAO/CCF/CCF/CodeGenerationKit/CommandLine.cpp @@ -0,0 +1,5 @@ +// file : CCF/CodeGenerationKit/CommandLine.cpp +// author : Boris Kolpackov <boris@dre.vanderbilt.edu> +// cvs-id : $Id$ + +#include "CCF/CodeGenerationKit/CommandLine.hpp" diff --git a/modules/CIAO/CCF/CCF/CodeGenerationKit/CommandLine.hpp b/modules/CIAO/CCF/CCF/CodeGenerationKit/CommandLine.hpp new file mode 100644 index 00000000000..6c3d84b2481 --- /dev/null +++ b/modules/CIAO/CCF/CCF/CodeGenerationKit/CommandLine.hpp @@ -0,0 +1,222 @@ +// file : CCF/CodeGenerationKit/CommandLine.hpp +// author : Boris Kolpackov <boris@dre.vanderbilt.edu> +// cvs-id : $Id$ + +#ifndef COMMAND_LINE_HPP +#define COMMAND_LINE_HPP + +#include <algorithm> +#include <vector> +#include <string> + +//@@ this stuff needs proper reimplementation + +class CommandLine +{ +public: + CommandLine () + { + } + + // Option constrain checking +public: + + bool + require (std::string option) const throw () + { + return std::find_if (options.begin (), + options.end (), + OptionNamePredicat (option)) != options.end (); + } + + bool + depends (std::string dependant, + std::string principal) const throw () + { + Options::const_iterator begin = options.begin (); + Options::const_iterator end = options.end (); + + if (std::find_if (begin, end, OptionNamePredicat (dependant)) != end) + { + return std::find_if (begin, end, OptionNamePredicat (principal)) != end; + } + else + { + return true; + } + } + + bool + inconsistent (std::string a, + std::string b) const throw () + { + Options::const_iterator begin = options.begin (); + Options::const_iterator end = options.end (); + + if (std::find_if (begin, end, OptionNamePredicat (a)) != end) + { + return std::find_if (begin, end, OptionNamePredicat (b)) == end; + } + else + { + return true; + } + } + + std::string + get_value (std::string name, std::string const& not_found_value) const + { + Options::const_iterator i = std::find_if ( + options.begin (), + options.end (), + OptionNamePredicat (name)); + + if (i != options.end () && !(i->value ().empty ())) + { + return i->value (); + } + else + { + return not_found_value; + } + } + + // @@ the option should probably be searched in reverse order + // + + std::string + get_value (std::string name, char const* not_found_value) const + { + Options::const_iterator i = std::find_if ( + options.begin (), + options.end (), + OptionNamePredicat (name)); + + if (i != options.end () && !(i->value ().empty ())) + { + return i->value (); + } + else + { + return std::string (not_found_value); + } + } + + bool + get_value (std::string name, bool not_found_value) const + { + Options::const_iterator i = std::find_if ( + options.begin (), + options.end (), + OptionNamePredicat (name)); + + if (i != options.end ()) + { + return true; + } + else + { + return not_found_value; + } + } + + + struct Option + { + Option (std::string const& name) + : name_ (name) + { + } + + Option (std::string const& name, + std::string const& value) + : name_ (name), + value_ (value) + { + } + + std::string const& + name () const + { + return name_; + } + + std::string const& + value () const + { + return value_; + } + + private: + std::string name_; + std::string value_; + }; + + typedef + std::vector<Option> + Options; + + typedef + Options::const_iterator + OptionsIterator; + + OptionsIterator + options_begin () const + { + return options.begin (); + } + + OptionsIterator + options_end () const + { + return options.end (); + } + + // Arguments + // + // + + typedef + std::vector<std::string> + Arguments; + + typedef + Arguments::const_iterator + ArgumentsIterator; + + ArgumentsIterator + arguments_begin () const + { + return arguments.begin (); + } + + ArgumentsIterator + arguments_end () const + { + return arguments.end (); + } + +public: + + struct OptionNamePredicat + { + OptionNamePredicat (std::string const& name) + : name_ (name) + { + } + + bool operator ()(Option const& option) throw () + { + return name_ == option.name (); + } + + private: + std::string const name_; + }; + + std::string command; + Options options; + Arguments arguments; +}; + +#endif // COMMAND_LINE_HPP diff --git a/modules/CIAO/CCF/CCF/CodeGenerationKit/CommandLineDescriptor.hpp b/modules/CIAO/CCF/CCF/CodeGenerationKit/CommandLineDescriptor.hpp new file mode 100644 index 00000000000..a7c6961cf1f --- /dev/null +++ b/modules/CIAO/CCF/CCF/CodeGenerationKit/CommandLineDescriptor.hpp @@ -0,0 +1,338 @@ +// file : CCF/CodeGenerationKit/CommandLineDescriptor.hpp +// author : Boris Kolpackov <boris@dre.vanderbilt.edu> +// cvs-id : $Id$ + +#ifndef COMMAND_LINE_DESCRIPTOR_H +#define COMMAND_LINE_DESCRIPTOR_H + +#include <map> +#include <list> +#include <vector> +#include <string> +#include <ostream> +#include <cassert> + + +namespace CL +{ + struct OptionType + { + enum Value + { + flag, + value + }; + + OptionType (Value v) + : v_ (v) + { + } + + operator Value () const + { + return v_; + } + + private: + Value v_; + }; + + + class OptionDescription + { + public: + OptionDescription (std::string name, + std::string description, + OptionType type, + bool optional = true) + : optional_ (optional), + type_ (type), + name_ (name), + value_synopsis_ (), + description_ (description) + { + // There should be value_synopsis for non-flag options. + // + assert (type == OptionType::flag); + } + + + OptionDescription (std::string name, + std::string value_synopsis, + std::string description, + OptionType type, + bool optional = true) + : optional_ (optional), + type_ (type), + name_ (name), + value_synopsis_ (value_synopsis), + description_ (description) + { + } + + public: + bool + optional () const + { + return optional_; + } + + OptionType + type () const + { + return type_; + } + + std::string + name () const + { + return name_; + } + + std::string + value_synopsis () const + { + return value_synopsis_; + } + + std::string + description () const + { + return description_; + } + + + private: + bool optional_; + OptionType type_; + std::string name_; + std::string value_synopsis_; + std::string description_; + }; + + + class Description + { + public: + Description (std::string command) + : command_ (command) + { + } + + private: + Description (Description const&); + + Description& + operator= (Description const&); + + private: + // We are storing pointer to elements in this list in the map below. + // To prevent element moving we will use list instead of vector. + // + typedef + std::list<OptionDescription> + OptionDescriptionList; + + typedef + std::map<std::string, OptionDescription*> + OptionDescriptionMap; + + public: + + std::string + command () const + { + return command_; + } + + + public: + typedef + OptionDescriptionList::const_iterator + OptionIterator; + + OptionIterator + begin_option () const + { + return options_.begin (); + } + + OptionIterator + end_option () const + { + return options_.end (); + } + + typedef + OptionDescriptionMap::const_iterator + OptionMapIterator; + + OptionDescription const* + find_option (std::string const& option) const + { + OptionDescriptionMap::const_iterator i ( + option_map_.find (option)); + + return i == option_map_.end () ? 0 : i->second; + } + + void + add_option (OptionDescription const& od) + { + options_.push_back (od); + option_map_[od.name ()] = &options_.back (); + } + + private: + typedef + std::vector<std::string> + ArgumentDescriptionList; + + public: + typedef + ArgumentDescriptionList::const_iterator + ArgumentIterator; + + ArgumentIterator + begin_argument () const + { + return arguments_.begin (); + } + + ArgumentIterator + end_argument () const + { + return arguments_.end (); + } + + void + add_argument (std::string arg) + { + arguments_.push_back (arg); + } + + private: + std::string command_; + OptionDescriptionList options_; + OptionDescriptionMap option_map_; + ArgumentDescriptionList arguments_; + }; + + inline void + print_text (std::ostream& os, Description const& d) + { + using std::endl; + + os << d.command (); + + Description::OptionIterator ob = d.begin_option (); + Description::OptionIterator oe = d.end_option (); + + if (ob != oe) + { + os << " { OPTIONS }"; + } + + Description::ArgumentIterator ab = d.begin_argument (); + Description::ArgumentIterator ae = d.end_argument (); + + for (; ab != ae; ab++) + { + os << " <" << *ab << ">"; + } + + os << endl << endl; + + for (; ob != oe; ob++) + { + bool flag (ob->type () == OptionType::flag); + bool optional (ob->optional ()); + std::string prefix (ob->name ().length () == 1 ? "-" : "--"); + + os << (optional ? "[" : "") << prefix << ob->name () + << (flag ? "" : " ") << ob->value_synopsis () + << (optional ? "]" : "") + << endl; + + os << "\t\t" << ob->description () << endl << endl; + } + + } + + + inline void + print_html (std::ostream& os, Description const& d) + { + using std::endl; + + os << "<html>" << endl + << "<body>" << endl + << "<div align=\"center\">" << endl + << "<table width=\"700\" border=\"0\" cellspacing=\"0\" " + << "cellpadding=\"0\">" << endl + << "<tr>" << endl + << "<td>" << endl; + + os << "<p>" << endl + << "<code>" << endl; + + os << d.command (); + + Description::OptionIterator ob = d.begin_option (); + Description::OptionIterator oe = d.end_option (); + + if (ob != oe) + { + os << " { OPTIONS }"; + } + + Description::ArgumentIterator ab = d.begin_argument (); + Description::ArgumentIterator ae = d.end_argument (); + + for (; ab != ae; ab++) + { + os << " <" << *ab << ">"; + } + + os << endl + << "</code>" << endl + << "</p>" << endl; + + + os << "<dl>" << endl; + + for (; ob != oe; ob++) + { + bool flag (ob->type () == OptionType::flag); + bool optional (ob->optional ()); + std::string prefix (ob->name ().length () == 1 ? "-" : "--"); + + os << "<dt>" << endl + << "<code>" << endl + << (optional ? "[" : "") << prefix << ob->name () + << (flag ? "" : " ") << ob->value_synopsis () + << (optional ? "]" : "") << endl + << "</code>" << endl + << "</dt>" << endl; + + os << "<dd>" << endl + << "<p>" << endl + << ob->description () << endl + << "</p>" << endl + << "</dd>" << endl; + } + + os << "</dl>" << endl; + + os << "</td>" << endl + << "</tr>" << endl + << "</table>" << endl + << "</div>" << endl + << "</body>" << endl + << "</html>" << endl; + + } +} + + +#endif // COMMAND_LINE_DESCRIPTOR_H diff --git a/modules/CIAO/CCF/CCF/CodeGenerationKit/CommandLineParser.cpp b/modules/CIAO/CCF/CCF/CodeGenerationKit/CommandLineParser.cpp new file mode 100644 index 00000000000..5f7d1d603bd --- /dev/null +++ b/modules/CIAO/CCF/CCF/CodeGenerationKit/CommandLineParser.cpp @@ -0,0 +1,120 @@ +// file : CCF/CodeGenerationKit/CommandLineParser.cpp +// author : Boris Kolpackov <boris@dre.vanderbilt.edu> +// cvs-id : $Id$ + +#include "CCF/CodeGenerationKit/CommandLineParser.hpp" + +#include <string> +#include <iostream> + +using std::cerr; +using std::endl; + +bool +parse (int argc, char* argv[], CL::Description const& cld, CommandLine& cl) +{ + cl.command = argv[0]; + + bool seen_double_dash (false); + + for (int i (1); i < argc; ++i) + { + std::string arg (argv[i]); + + if (seen_double_dash) + { + cl.arguments.push_back (arg); + continue; + } + + if (arg == "--") + { + seen_double_dash = true; + continue; + } + + if (arg.length () > 0 && arg[0] == '-') + { + if (arg.length () > 1 && arg[1] == '-') + { + // Double-dash (long) option. + // + + std::string op (arg, 2); + + if (CL::OptionDescription const* d = cld.find_option (op)) + { + if (d->type () == CL::OptionType::value) + { + if (++i >= argc) + { + cerr << argv[0] << ": argument expected for option '--" + << op << "'" << endl; + return false; + } + + // cerr << "--" << op << ": " << argv[i] << endl; + + cl.options.push_back (CommandLine::Option (op, argv[i])); + } + else + cl.options.push_back (CommandLine::Option (op)); + + continue; + } + } + else + { + // Single-dash (short) option. We support two formats: '-D foo' and + // -Dfoo. + // + std::string op (arg, 1, 1); + + if (CL::OptionDescription const* d = cld.find_option (op)) + { + if (d->type () == CL::OptionType::value) + { + std::string value; + + if (arg.length () > 2) + { + value.assign (arg, 2, arg.size () - 2); + } + else + { + if (++i >= argc) + { + cerr << argv[0] << ": argument expected for option '-" + << op << "'" << endl; + return false; + } + + value = argv[i]; + } + + // cerr << "-" << op << ": " << value << endl; + + cl.options.push_back (CommandLine::Option (op, value)); + } + else + { + if (arg.length () > 2) + { + cerr << argv[0] << ": argument not expected for option '-" + << op << "' in '" << arg << "'" << endl; + return false; + } + + cl.options.push_back (CommandLine::Option (op)); + } + + continue; + } + } + } + + cl.arguments.push_back (arg); + } + + return true; +} diff --git a/modules/CIAO/CCF/CCF/CodeGenerationKit/CommandLineParser.hpp b/modules/CIAO/CCF/CCF/CodeGenerationKit/CommandLineParser.hpp new file mode 100644 index 00000000000..2e85dc7e266 --- /dev/null +++ b/modules/CIAO/CCF/CCF/CodeGenerationKit/CommandLineParser.hpp @@ -0,0 +1,14 @@ +// file : CCF/CodeGenerationKit/CommandLineParser.hpp +// author : Boris Kolpackov <boris@dre.vanderbilt.edu> +// cvs-id : $Id$ + +#ifndef COMMAND_LINE_PARSER_H +#define COMMAND_LINE_PARSER_H + +#include "CCF/CodeGenerationKit/CommandLine.hpp" +#include "CCF/CodeGenerationKit/CommandLineDescriptor.hpp" + +bool +parse (int argc, char* argv[], CL::Description const&, CommandLine&); + +#endif // COMMAND_LINE_PARSER_H diff --git a/modules/CIAO/CCF/CCF/CodeGenerationKit/IndentationBuffer.hpp b/modules/CIAO/CCF/CCF/CodeGenerationKit/IndentationBuffer.hpp new file mode 100644 index 00000000000..713f917e834 --- /dev/null +++ b/modules/CIAO/CCF/CCF/CodeGenerationKit/IndentationBuffer.hpp @@ -0,0 +1,61 @@ +// file : CCF/CodeGenerationKit/IndentationBuffer.hpp +// author : Boris Kolpackov <boris@dre.vanderbilt.edu> +// cvs-id : $Id$ + +#ifndef CCF_CODE_GENERATION_KIT_INDENTATION_BUFFER_HPP +#define CCF_CODE_GENERATION_KIT_INDENTATION_BUFFER_HPP + +#include "CCF/CompilerElements/ExH.hpp" + +#include <string> + +namespace Indentation +{ + template <typename C> + class Buffer + { + public: + class Exception_ {}; + typedef + ExH::Compound <Exception_, ExH::Logic::DescriptiveException> + Exception; + + class EndOfStream_ {}; + typedef + ExH::Compound <EndOfStream_, Exception> + EndOfStream; + + public: + virtual + ~Buffer () throw () {} + + public: + typedef + std::char_traits<C> + traits_type; + + typedef + typename traits_type::char_type + char_type; + + typedef + typename traits_type::int_type + int_type; + + public: + virtual int_type + put (char_type c) throw (Exception, ExH::System::Exception) = 0; + + // Unbuffer flushes internal formatting buffers (if any). + // Note that unbuffer is not exactly flushing since it can + // result in formatting errors and in general can not be + // called at arbitrary points. Natural use case would be + // to call unbuffer at the end of the stream when no more + // data is expected. + // + virtual void + unbuffer () throw (EndOfStream, Exception, ExH::System::Exception) = 0; + }; +} + +#endif // CCF_CODE_GENERATION_KIT_INDENTATION_BUFFER_HPP diff --git a/modules/CIAO/CCF/CCF/CodeGenerationKit/IndentationCxx.hpp b/modules/CIAO/CCF/CCF/CodeGenerationKit/IndentationCxx.hpp new file mode 100644 index 00000000000..b7451969555 --- /dev/null +++ b/modules/CIAO/CCF/CCF/CodeGenerationKit/IndentationCxx.hpp @@ -0,0 +1,385 @@ +// file : CCF/CodeGenerationKit/IndentationCxx.hpp +// author : Boris Kolpackov <boris@dre.vanderbilt.edu> +// cvs-id : $Id$ + +#ifndef CCF_CODE_GENERATION_KIT_INDENTATION_CXX_HPP +#define CCF_CODE_GENERATION_KIT_INDENTATION_CXX_HPP + +#include <deque> +#include <stack> + +#include "CCF/CodeGenerationKit/IndentationBuffer.hpp" + +namespace Indentation +{ + template <typename C> + class Cxx : public Buffer<C> + { + public: + typedef + typename Buffer<C>::traits_type + traits_type; + + typedef + typename Buffer<C>::char_type + char_type; + + typedef + typename Buffer<C>::int_type + int_type; + + typedef + typename Buffer<C>::EndOfStream + EndOfStream; + + public: + Cxx (Buffer<C>& out) + : out_ (out), + position_ (0), + paren_balance_ (0), + spaces_ (2), + construct_ (OTHER) + { + indentation_.push (0); + } + + virtual + ~Cxx () throw () {} + + public: + virtual int_type + put (char_type c) throw (ExH::System::Exception) + { + int_type result = traits_type::to_int_type (c); + + try + { + bool defaulting = false; + + if (!hold_.empty () && hold_.back () == '(') + { + unbuffer (); // We don't need to hold it any more. + + if (c == '\n') + indentation_.push (indentation_.top () + spaces_); + else + indentation_.push (position_); + } + + switch (c) + { + case '\n': + { + hold_.push_back (c); + position_ = 0; // Starting a new line. + + if (construct_ == CXX_COMMENT) + { + //std::cerr << "end comment" << endl; + construct_ = OTHER; + } + + break; + } + case '{': + { + ensure_new_line (); + output_indentation (); + result = write (c); + ensure_new_line (); + + indentation_.push (indentation_.top () + spaces_); + + break; + } + case '}': + { + if (indentation_.size () > 1) + indentation_.pop (); + + // Reduce multiple newlines to one. + while (hold_.size () > 1) + { + typename Hold::reverse_iterator i = hold_.rbegin (); + if (*i == '\n' && *(i + 1) == '\n') hold_.pop_back (); + else break; + } + + ensure_new_line (); + output_indentation (); + + hold_.push_back (c); + + + // Add double newline after '}'. + // + hold_.push_back ('\n'); + hold_.push_back ('\n'); + position_ = 0; + + break; + } + case ';': + { + if (paren_balance_ != 0) + { + // We are inside for (;;) statement. Nothing to do here. + // + defaulting = true; + } + else + { + // Handling '};' case. + // + + bool brace (false); + + if (hold_.size () > 1 && hold_.back () == '\n') + { + bool pop_nl (false); + + for (typename Hold::reverse_iterator + i (hold_.rbegin ()), e (hold_.rend ()); i != e; ++i) + { + if (*i != '\n') + { + if (*i == '}') brace = pop_nl = true; + break; + } + } + + if (pop_nl) while (hold_.back () == '\n') hold_.pop_back (); + } + + output_indentation (); + result = write (c); + position_++; + + if (brace) + { + hold_.push_back ('\n'); + hold_.push_back ('\n'); + } + + if (construct_ != STRING_LITERAL && construct_ != CHAR_LITERAL) + { + ensure_new_line (); + } + } + + break; + } + case '\\': + { + if (construct_ != CXX_COMMENT) + { + output_indentation (); + hold_.push_back (c); + position_++; + } + else + defaulting = true; + + break; + } + case '\"': + { + if (construct_ != CXX_COMMENT && + (hold_.empty () || hold_.back () != '\\')) + { + // not escape sequence + if (construct_ == STRING_LITERAL) construct_ = OTHER; + else construct_ = STRING_LITERAL; + } + + defaulting = true; + break; + } + case '\'': + { + if (construct_ != CXX_COMMENT && + (hold_.empty () || hold_.back () != '\\')) + { + // not escape sequence + if (construct_ == CHAR_LITERAL) construct_ = OTHER; + else + { + //std::cerr << "char literal" << endl; + construct_ = CHAR_LITERAL; + } + + } + + defaulting = true; + break; + } + case '(': + { + if (construct_ == OTHER) + { + // Hold it so that we can see what's coming next. + // + output_indentation (); + hold_.push_back (c); + position_++; + paren_balance_++; + } + else + defaulting = true; + + break; + } + case ')': + { + if (construct_ == OTHER) + { + if (indentation_.size () > 1) + indentation_.pop (); + + if (paren_balance_ > 0) + paren_balance_--; + } + + defaulting = true; + break; + } + case '/': + { + if (construct_ == OTHER) + { + if (!hold_.empty () && hold_.back () == '/') + { + construct_ = CXX_COMMENT; + //std::cerr << "start comment" << endl; + defaulting = true; + } + else + { + output_indentation (); + hold_.push_back (c); + position_++; + } + } + else + { + defaulting = true; + } + + break; + } + default: + { + defaulting = true; + break; + } + } + + if (defaulting) + { + output_indentation (); + result = write (c); + position_++; + } + } + catch (Full const&) + { + result = traits_type::eof (); + } + + return result; + } + + virtual void + unbuffer () throw (EndOfStream, ExH::System::Exception) + { + int_type result; + + while (!hold_.empty ()) + { + result = out_.put (hold_.front ()); + + //@@ failed + if (result == traits_type::eof ()) + { + throw EndOfStream ("unable to flush buffer"); + } + + hold_.pop_front (); + } + } + + private: + class Full {}; + + void + ensure_new_line () + { + if (hold_.empty () || hold_.back () != '\n') + { + hold_.push_back ('\n'); + position_ = 0; // Starting a new line. + } + } + + + void + output_indentation () throw (Full) + { + if (!hold_.empty () && hold_.back () == '\n') + { + for (unsigned long i = 0; i < indentation_.top (); i++) + write (' '); + + position_ += indentation_.top (); + } + } + + int_type + write (char_type c) throw (Full) + { + hold_.push_back (c); + + int_type result (traits_type::eof ()); + + while (!hold_.empty ()) + { + result = out_.put (hold_.front ()); + + if (result == traits_type::eof ()) + throw Full (); + + hold_.pop_front (); + } + + return result; + } + + + private: + Buffer<C>& out_; + unsigned long position_; // Current position on the line. + unsigned long paren_balance_; // ( ) balance. + std::stack<unsigned long> indentation_; + unsigned long spaces_; + + bool suppress_nl_; + + enum Construct + { + OTHER, + CXX_COMMENT, + STRING_LITERAL, + CHAR_LITERAL + }; + + Construct construct_; + + typedef + std::deque<int_type> + Hold; + + Hold hold_; + }; +} + +#endif // CCF_CODE_GENERATION_KIT_INDENTATION_IDL_HPP diff --git a/modules/CIAO/CCF/CCF/CodeGenerationKit/IndentationIDL.hpp b/modules/CIAO/CCF/CCF/CodeGenerationKit/IndentationIDL.hpp new file mode 100644 index 00000000000..24f9866eac4 --- /dev/null +++ b/modules/CIAO/CCF/CCF/CodeGenerationKit/IndentationIDL.hpp @@ -0,0 +1,277 @@ +// file : CCF/CodeGenerationKit/IndentationIDL.hpp +// author : Boris Kolpackov <boris@dre.vanderbilt.edu> +// cvs-id : $Id$ + +#ifndef CCF_CODE_GENERATION_KIT_INDENTATION_IDL_HPP +#define CCF_CODE_GENERATION_KIT_INDENTATION_IDL_HPP + +#include <deque> + +#include "CCF/CodeGenerationKit/IndentationBuffer.hpp" + +namespace Indentation +{ + template <typename C> + class IDL : public Buffer<C> + { + public: + typedef + typename Buffer<C>::traits_type + traits_type; + + typedef + typename Buffer<C>::char_type + char_type; + + typedef + typename Buffer<C>::int_type + int_type; + + typedef + typename Buffer<C>::EndOfStream + EndOfStream; + + public: + IDL (Buffer<C>& out) + : out_ (out), + indentation_ (0), + spaces_ (2), + construct_ (OTHER) + { + } + + virtual + ~IDL () throw () {} + + public: + virtual int_type + put (char_type c) throw (ExH::System::Exception) + { + int_type result = traits_type::to_int_type (c); + + try + { + bool defaulting = false; + switch (c) + { + case '\n': + { + hold_.push_back (c); + break; + } + case '{': + { + ensure_new_line (); + output_indentation (); + result = write (c); + ensure_new_line (); + indentation_++; + break; + } + case '}': + { + if (indentation_ > 0) indentation_--; + + // Reduce multiple newlines to one. + while (hold_.size () > 1) + { + typename Hold::reverse_iterator i = hold_.rbegin (); + if (*i == '\n' && *(i + 1) == '\n') hold_.pop_back (); + else break; + } + + ensure_new_line (); + output_indentation (); + + hold_.push_back (c); + + // result = write (c); + + //ensure_new_line (); + + // Add double newline after '}'. + // + hold_.push_back ('\n'); + hold_.push_back ('\n'); + + + break; + } + case ';': + { + // Handling '};' case. + // + + bool brace (false); + + if (hold_.size () > 1 && hold_.back () == '\n') + { + bool pop_nl (false); + + for (typename Hold::reverse_iterator + i (hold_.rbegin ()), e (hold_.rend ()); i != e; ++i) + { + if (*i != '\n') + { + if (*i == '}') brace = pop_nl = true; + break; + } + } + + if (pop_nl) while (hold_.back () == '\n') hold_.pop_back (); + } + + output_indentation (); + result = write (c); + + if (brace) + { + hold_.push_back ('\n'); + hold_.push_back ('\n'); + } + + if (construct_ != STRING_LITERAL && construct_ != CHAR_LITERAL) + { + ensure_new_line (); + } + break; + } + case '\\': + { + hold_.push_back (c); + break; + } + case '\"': + { + if (hold_.empty () || hold_.back () != '\\') + { + // not escape sequence + if (construct_ == STRING_LITERAL) construct_ = OTHER; + else construct_ = STRING_LITERAL; + } + + defaulting = true; + break; + } + case '\'': + { + if (hold_.empty () || hold_.back () != '\\') + { + // not escape sequence + if (construct_ == CHAR_LITERAL) construct_ = OTHER; + else construct_ = CHAR_LITERAL; + } + + defaulting = true; + break; + } + default: + { + defaulting = true; + break; + } + } + + if (defaulting) + { + output_indentation (); + result = write (c); + } + } + catch (Full const&) + { + result = traits_type::eof (); + } + + return result; + } + + virtual void + unbuffer () throw (EndOfStream, ExH::System::Exception) + { + int_type result; + + while (!hold_.empty ()) + { + result = out_.put (hold_.front ()); + + //@@ failed + if (result == traits_type::eof ()) + { + throw EndOfStream ("unable to flush buffer"); + } + + hold_.pop_front (); + } + } + + private: + class Full {}; + + void + ensure_new_line () + { + if (hold_.empty () || hold_.back () != '\n') + { + hold_.push_back ('\n'); + } + } + + + void + output_indentation () throw (Full) + { + if (!hold_.empty () && hold_.back () == '\n') + { + for (unsigned long i = 0; i < indentation_ * spaces_; i++) + { + write (' '); + } + } + } + + int_type + write (char_type c) throw (Full) + { + hold_.push_back (c); + + int_type result (traits_type::eof ()); + + while (!hold_.empty ()) + { + result = out_.put (hold_.front ()); + + if (result == traits_type::eof ()) throw Full (); + + hold_.pop_front (); + } + + return result; + } + + + private: + Buffer<C>& out_; + unsigned long indentation_; + unsigned long spaces_; + + bool suppress_nl_; + + enum Construct + { + OTHER, + STRING_LITERAL, + CHAR_LITERAL + }; + + Construct construct_; + + typedef + std::deque<int_type> + Hold; + + Hold hold_; + }; +} + +#endif // CCF_CODE_GENERATION_KIT_INDENTATION_IDL_HPP diff --git a/modules/CIAO/CCF/CCF/CodeGenerationKit/IndentationImplanter.hpp b/modules/CIAO/CCF/CCF/CodeGenerationKit/IndentationImplanter.hpp new file mode 100644 index 00000000000..40259a694f6 --- /dev/null +++ b/modules/CIAO/CCF/CCF/CodeGenerationKit/IndentationImplanter.hpp @@ -0,0 +1,153 @@ +// file : CCF/CodeGenerationKit/IndentationImplanter.hpp +// author : Boris Kolpackov <boris@dre.vanderbilt.edu> +// cvs-id : $Id$ + +#ifndef CCF_CODE_GENERATION_KIT_INDENTATION_IMPLANTER +#define CCF_CODE_GENERATION_KIT_INDENTATION_IMPLANTER + +#include <ostream> + +#include "CCF/CodeGenerationKit/IndentationBuffer.hpp" + +namespace Indentation +{ + template <typename C> + class ToStreamBufAdapter : public std::basic_streambuf<C> + { + public: + typedef + typename std::basic_streambuf<C>::traits_type + traits_type; + + typedef + typename std::basic_streambuf<C>::char_type + char_type; + + typedef + typename std::basic_streambuf<C>::int_type + int_type; + + public: + ToStreamBufAdapter (Buffer<C>& b) + : buffer_ (b) + { + } + + virtual int_type + overflow (int_type c) + { + return buffer_.put (traits_type::to_char_type (c)); + } + + virtual int + sync () + { + return 0; + } + + private: + Buffer<C>& buffer_; + }; + + template <typename C> + class FromStreamBufAdapter : public Buffer<C> + { + public: + typedef + typename Buffer<C>::traits_type + traits_type; + + typedef + typename Buffer<C>::char_type + char_type; + + typedef + typename Buffer<C>::int_type + int_type; + + typedef + typename Buffer<C>::Exception + Exception; + + public: + FromStreamBufAdapter (std::basic_streambuf<C>& b) + : buffer_ (b) + { + } + + virtual int_type + put (char_type c) throw (Exception, ExH::System::Exception) + { + return buffer_.sputc (c); + } + + virtual void + unbuffer () throw (ExH::System::Exception) + { + try + { + if (buffer_.pubsync () == 0) return; + } + catch (std::ios_base::failure const&) + { + } + + throw Exception ("underlying std::streambuf::sync failed"); + } + + private: + std::basic_streambuf<C>& buffer_; + }; + + template <template <typename> class BufferType, typename C = char> + class Implanter + { + public: + Implanter (std::basic_ostream<C>& os) + : os_ (os), + prev_ (os_.rdbuf ()), + from_adapter_ (*prev_), + buffer_ (from_adapter_), + to_adapter_ (buffer_) + { + os_.rdbuf (&to_adapter_); + } + + template <typename Arg0> + Implanter (std::basic_ostream<C>& os, Arg0 a0) + : os_ (os), + prev_ (os_.rdbuf ()), + from_adapter_ (*prev_), + buffer_ (from_adapter_, a0), + to_adapter_ (buffer_) + { + os_.rdbuf (&to_adapter_); + } + + ~Implanter () + { + try + { + buffer_.unbuffer (); + } + catch (...) + { + // there is nothing I can do... + } + + os_.rdbuf (prev_); + } + + private: + std::basic_ostream<C>& os_; + std::basic_streambuf<C>* prev_; + + FromStreamBufAdapter<C> from_adapter_; + + BufferType<C> buffer_; + + ToStreamBufAdapter<C> to_adapter_; + }; +} + +#endif // CCF_CODE_GENERATION_KIT_INDENTATION_IMPLANTER diff --git a/modules/CIAO/CCF/CCF/CodeGenerationKit/IndentationXML.hpp b/modules/CIAO/CCF/CCF/CodeGenerationKit/IndentationXML.hpp new file mode 100644 index 00000000000..774a70e501f --- /dev/null +++ b/modules/CIAO/CCF/CCF/CodeGenerationKit/IndentationXML.hpp @@ -0,0 +1,233 @@ +// file : CCF/CodeGenerationKit/IndentationXML.hpp +// author : Diego Sevilla Ruiz <dsevilla@ditec.um.es> +// author : Boris Kolpackov <boris@dre.vanderbilt.edu> +// cvs-id : $Id$ + +#ifndef CCF_CODE_GENERATION_KIT_INDENTATION_XML_HPP +#define CCF_CODE_GENERATION_KIT_INDENTATION_XML_HPP + +#include <deque> + +#include "CCF/CodeGenerationKit/IndentationBuffer.hpp" + +namespace Indentation +{ + template <typename C> + class XML : public Buffer<C> + { + public: + typedef + typename Buffer<C>::traits_type + traits_type; + + typedef + typename Buffer<C>::char_type + char_type; + + typedef + typename Buffer<C>::int_type + int_type; + + typedef + typename Buffer<C>::EndOfStream + EndOfStream; + + public: + XML (Buffer<C>& out) + : out_ (out), + indentation_ (0), + base_indent_ (indentation_), + spaces_ (2), + construct_ (OTHER) + { + } + + virtual + ~XML () throw () {} + + public: + virtual int_type + put (char_type c) throw (ExH::System::Exception) + { + int_type result = traits_type::to_int_type (c); + + try + { + switch (c) + { + case '\n': + { + flush_buffer (); + + // If we are inside a tag, just output an artificial tab character + if (construct_ == INSIDE_TAG) + { + hold_.push_back (c); + c = traits_type::to_int_type (' '); + + // spaces_ - 1 because at the end the last space will be + // put into the hold_ queue. + for (unsigned long i = 0; i < spaces_ - 1; i++) + hold_.push_back (c); + } + + base_indent_ = indentation_; + + break; + } + + // Case with <?xxx and <!DOCTYPE (for example). + // We still don't handle XML comments + case '?': + case '!': + { + if (construct_ == INSIDE_TAG && hold_.back () == '<') + indentation_--; + + break; + } + + case '<': + { + //@@ This construct must not be INSIDE_TAG + if (construct_ == OTHER) + { + construct_ = INSIDE_TAG; + indentation_++; + } + + break; + } + + case '>': + { + if (construct_ == INSIDE_TAG) + construct_ = OTHER; + + break; + } + + case '/': + { + if (construct_ == INSIDE_TAG) + { + if (hold_.back () == '<') + indentation_ -= 2; + else + indentation_--; + + if (indentation_ < 0) + indentation_ = 0; + } + + break; + } + + case '\"': + { + if (construct_ == INSIDE_TAG) + construct_ = STRING_LITERAL; + else if (construct_ == STRING_LITERAL) + construct_ = INSIDE_TAG; + + break; + } + + } + + hold_.push_back (c); + + } + catch (Full const&) + { + result = traits_type::eof (); + } + + return result; + } + + virtual void + unbuffer () throw (EndOfStream, ExH::System::Exception) + { + try + { + flush_buffer (); + } catch (const Full&) + { + throw EndOfStream ("unable to flush buffer"); + } + } + + private: + class Full {}; + + void + flush_buffer () throw (Full) + { + long delta = indentation_ - base_indent_; + + if (delta > 0) + delta = 0; + + while (!hold_.empty ()) + { + int_type c = hold_.front (); + + write (c); + + if (c == '\n') + output_indentation (base_indent_ + delta); + + hold_.pop_front (); + } + } + + void + output_indentation (unsigned long indentation) throw (Full) + { + for (unsigned long i = 0; i < indentation * spaces_; i++) + { + write (' '); + } + } + + int_type + write (int_type c) throw (Full) + { + int_type result; + + result = out_.put (c); + + if (result == traits_type::eof ()) throw Full (); + + return result; + } + + + private: + Buffer<C>& out_; + long indentation_; + unsigned long base_indent_; + unsigned long spaces_; + + enum Construct + { + OTHER, + /* Strings literals can only happen inside tags, like: + * <tag whatever="xxx + */ + STRING_LITERAL, + INSIDE_TAG + }; + + Construct construct_; + + typedef + std::deque<int_type> + Hold; + + Hold hold_; + }; +} + +#endif // CCF_CODE_GENERATION_KIT_INDENTATION_XML_HPP diff --git a/modules/CIAO/CCF/CCF/CodeGenerationKit/Regex.hpp b/modules/CIAO/CCF/CCF/CodeGenerationKit/Regex.hpp new file mode 100644 index 00000000000..b92ed9d4f42 --- /dev/null +++ b/modules/CIAO/CCF/CCF/CodeGenerationKit/Regex.hpp @@ -0,0 +1,51 @@ +// file : CCF/CodeGenerationKit/Regex.hpp +// author : Boris Kolpackov <boris@dre.vanderbilt.edu> +// cvs-id : $Id$ + +#ifndef CCF_RUNTIME_REGEX_HPP +#define CCF_RUNTIME_REGEX_HPP + +#include <string> +#include <boost/regex.hpp> + +namespace regex +{ + template <typename C> + std::basic_string<C> + perl_s (std::basic_string<C> const& src, std::basic_string<C> const& e) + { + typedef std::basic_string<C> string; + typedef typename string::size_type size; + + if (e.empty ()) + return src; + + C delimiter (e[0]); + + size first = e.find (delimiter); + size middle = e.find (delimiter, first + 1); + size last = e.find (delimiter, middle + 1); + + string pattern (e, first + 1, middle - first - 1); + string format (e, middle + 1, last - middle - 1); + + //std::cout << pattern << " " << format << std::endl; + + boost::basic_regex<C> expr (pattern); + + return regex_merge ( + src, + expr, + format, + boost::match_default | boost::format_all ); + } + + template <typename C> + std::basic_string<C> + perl_s (std::basic_string<C> const& src, C const* e) + { + return perl_s (src, std::basic_string<C> (e)); + } +} + +#endif // CCF_RUNTIME_REGEX_HPP |