diff options
Diffstat (limited to 'libbackend-elements/backend-elements')
| -rw-r--r-- | libbackend-elements/backend-elements/indentation/buffer.hxx | 61 | ||||
| -rw-r--r-- | libbackend-elements/backend-elements/indentation/buffer.txx | 12 | ||||
| -rw-r--r-- | libbackend-elements/backend-elements/indentation/clip.hxx | 173 | ||||
| -rw-r--r-- | libbackend-elements/backend-elements/indentation/clip.txx | 12 | ||||
| -rw-r--r-- | libbackend-elements/backend-elements/indentation/cxx.hxx | 1016 | ||||
| -rw-r--r-- | libbackend-elements/backend-elements/indentation/cxx.txx | 12 | ||||
| -rw-r--r-- | libbackend-elements/backend-elements/indentation/idl.hxx | 290 | ||||
| -rw-r--r-- | libbackend-elements/backend-elements/indentation/idl.txx | 11 | ||||
| -rw-r--r-- | libbackend-elements/backend-elements/indentation/sloc.hxx | 277 | ||||
| -rw-r--r-- | libbackend-elements/backend-elements/makefile | 63 | ||||
| -rw-r--r-- | libbackend-elements/backend-elements/regex.hxx | 208 | ||||
| -rw-r--r-- | libbackend-elements/backend-elements/regex.txx | 52 | ||||
| -rw-r--r-- | libbackend-elements/backend-elements/types.hxx | 16 | 
13 files changed, 2203 insertions, 0 deletions
| diff --git a/libbackend-elements/backend-elements/indentation/buffer.hxx b/libbackend-elements/backend-elements/indentation/buffer.hxx new file mode 100644 index 0000000..7058814 --- /dev/null +++ b/libbackend-elements/backend-elements/indentation/buffer.hxx @@ -0,0 +1,61 @@ +// file      : backend-elements/indentation/buffer.hxx +// author    : Boris Kolpackov <boris@kolpackov.net> +// copyright : Copyright (c) 2005-2010 Boris Kolpackov +// license   : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#ifndef BACKEND_ELEMENTS_INDENTATION_BUFFER_HXX +#define BACKEND_ELEMENTS_INDENTATION_BUFFER_HXX + +#include <backend-elements/types.hxx> + +#include <string> + +namespace BackendElements +{ +  namespace Indentation +  { +    template <typename C> +    class Buffer: public NonCopyable +    { +    public: +      struct Write {}; + +    public: +      virtual +      ~Buffer () +      { +      } + +    public: +      typedef +      std::char_traits<C> +      Traits; + +      typedef +      typename Traits::char_type +      AsChar; + +      typedef +      typename Traits::int_type +      AsInt; + +    public: +      virtual AsInt +      put (AsChar c) = 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 () = 0; +    }; +  } +} + +#include <backend-elements/indentation/buffer.txx> + +#endif  // BACKEND_ELEMENTS_INDENTATION_BUFFER_HXX diff --git a/libbackend-elements/backend-elements/indentation/buffer.txx b/libbackend-elements/backend-elements/indentation/buffer.txx new file mode 100644 index 0000000..57ba7ab --- /dev/null +++ b/libbackend-elements/backend-elements/indentation/buffer.txx @@ -0,0 +1,12 @@ +// file      : backend-elements/indentation/buffer.txx +// author    : Boris Kolpackov <boris@kolpackov.net> +// copyright : Copyright (c) 2005-2010 Boris Kolpackov +// license   : GNU GPL v2 + exceptions; see accompanying LICENSE file + +namespace BackendElements +{ +  namespace Indentation +  { +  } +} + diff --git a/libbackend-elements/backend-elements/indentation/clip.hxx b/libbackend-elements/backend-elements/indentation/clip.hxx new file mode 100644 index 0000000..068ed0d --- /dev/null +++ b/libbackend-elements/backend-elements/indentation/clip.hxx @@ -0,0 +1,173 @@ +// file      : backend-elements/indentation/clip.hxx +// author    : Boris Kolpackov <boris@kolpackov.net> +// copyright : Copyright (c) 2005-2010 Boris Kolpackov +// license   : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#ifndef BACKEND_ELEMENTS_INDENTATION_CLIP_HXX +#define BACKEND_ELEMENTS_INDENTATION_CLIP_HXX + +#include <backend-elements/types.hxx> + +#include <backend-elements/indentation/buffer.hxx> + +#include <ostream> + +namespace BackendElements +{ +  namespace Indentation +  { +    template <typename C> +    class ToStreambufAdapter: public std::basic_streambuf<C>, +                              public NonCopyable +    { +    public: +      typedef +      typename std::basic_streambuf<C>::traits_type +      Traits; + +      typedef +      typename std::basic_streambuf<C>::char_type +      AsChar; + +      typedef +      typename std::basic_streambuf<C>::int_type +      AsInt; + +    public: +      ToStreambufAdapter (Buffer<C>& buffer) +          : buffer_ (buffer) +      { +      } + +      virtual AsInt +      overflow (AsInt ch) +      { +        return buffer_.put (Traits::to_char_type (ch)); +      } + +      virtual Int +      sync () +      { +        return 0; +      } + +    private: +      Buffer<C>& buffer_; +    }; + + +    template <typename C> +    class FromStreambufAdapter: public Buffer<C> +    { +    public: +      typedef +      typename Buffer<C>::Traits +      Traits; + +      typedef +      typename Buffer<C>::AsChar +      AsChar; + +      typedef +      typename Buffer<C>::AsInt +      AsInt; + +      typedef +      typename Buffer<C>::Write +      Write; + +    public: +      FromStreambufAdapter (std::basic_streambuf<C>& b) +          : buffer_ (b) +      { +      } + +      virtual AsInt +      put (AsChar ch) +      { +        return buffer_.sputc (ch); +      } + +      virtual Void +      unbuffer () +      { +        try +        { +          if (buffer_.pubsync () == 0) return; +        } +        catch (std::ios_base::failure const&) +        { +        } + +        throw Write (); +      } + +    private: +      std::basic_streambuf<C>& buffer_; +    }; + + +    template <template <typename> class Buffer, typename C = Char> +    class Clip: public NonCopyable +    { +    public: +      Clip (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> +      Clip (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_); +      } +      */ + +      ~Clip () +      { +        try +        { +          buffer_.unbuffer (); +        } +        catch (...) +        { +          os_.rdbuf (prev_); +          throw; +        } + +        os_.rdbuf (prev_); +      } + +      Buffer<C>& +      buffer () +      { +        return buffer_; +      } + +    private: +      std::basic_ostream<C>& os_; +      std::basic_streambuf<C>* prev_; + +      FromStreambufAdapter<C> from_adapter_; + +      Buffer<C> buffer_; + +      ToStreambufAdapter<C> to_adapter_; +    }; +  } +} + +#include <backend-elements/indentation/clip.txx> + +#endif  // BACKEND_ELEMENTS_INDENTATION_CLIP_HXX diff --git a/libbackend-elements/backend-elements/indentation/clip.txx b/libbackend-elements/backend-elements/indentation/clip.txx new file mode 100644 index 0000000..58112f1 --- /dev/null +++ b/libbackend-elements/backend-elements/indentation/clip.txx @@ -0,0 +1,12 @@ +// file      : backend-elements/indentation/clip.txx +// author    : Boris Kolpackov <boris@kolpackov.net> +// copyright : Copyright (c) 2005-2010 Boris Kolpackov +// license   : GNU GPL v2 + exceptions; see accompanying LICENSE file + +namespace BackendElements +{ +  namespace Indentation +  { +  } +} + diff --git a/libbackend-elements/backend-elements/indentation/cxx.hxx b/libbackend-elements/backend-elements/indentation/cxx.hxx new file mode 100644 index 0000000..f10341a --- /dev/null +++ b/libbackend-elements/backend-elements/indentation/cxx.hxx @@ -0,0 +1,1016 @@ +// file      : backend-elements/indentation/cxx.hxx +// author    : Boris Kolpackov <boris@kolpackov.net> +// copyright : Copyright (c) 2005-2010 Boris Kolpackov +// license   : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#ifndef BACKEND_ELEMENTS_INDENTATION_CXX_HXX +#define BACKEND_ELEMENTS_INDENTATION_CXX_HXX + +#include <backend-elements/types.hxx> +#include <backend-elements/indentation/buffer.hxx> + +#include <cult/containers/set.hxx> +#include <cult/containers/stack.hxx> +#include <cult/containers/deque.hxx> + +#include <locale> + +// #include <iostream> // @@ tmp + +namespace BackendElements +{ +  namespace Indentation +  { +    template <typename C> +    class CXX: public Buffer<C>/*, public NonCopyable*/ +    { +    public: +      typedef +      typename Buffer<C>::Traits +      Traits; + +      typedef +      typename Buffer<C>::AsChar +      AsChar; + +      typedef +      typename Buffer<C>::AsInt +      AsInt; + +      typedef +      typename Buffer<C>::Write +      Write; + +    public: +      CXX (Buffer<C>& out) +          : out_ (out), +            buffering_ (false), +            position_ (0), +            paren_balance_ (0), +            spaces_ (2), +            construct_ (Construct::other), +            lbrace_ ("{"), +            rbrace_ ("}") +        // locale_ ("C") +      { +        indentation_.push (0); + +        single_line_blocks_.insert ("if"); +        single_line_blocks_.insert ("do"); +        single_line_blocks_.insert ("for"); +        single_line_blocks_.insert ("else"); +        single_line_blocks_.insert ("case"); +        single_line_blocks_.insert ("while"); + +        follow_blocks_.insert ("else"); +        follow_blocks_.insert ("case"); +        follow_blocks_.insert ("catch"); +        follow_blocks_.insert ("default"); +      } + +    public: +      virtual AsInt +      put (AsChar c) +      { +        AsInt result (Traits::to_int_type (c)); + +        try +        { +          // First determine what kind of construct we are in. +          // +          typename Construct::Value new_construct (construct_); +          typename Construct::Value old_construct (construct_); + +          switch (c) +          { +          case '\n': +            { +              if (construct_ == Construct::pp_directive || +                  construct_ == Construct::cxx_comment) +                construct_ = new_construct = Construct::other; + +              break; +            } +          case '#': +            { +              if (construct_ == Construct::other) +                construct_ = new_construct = Construct::pp_directive; + +              break; +            } +          case '\"': +            { +              if (construct_ != Construct::pp_directive && +                  construct_ != Construct::c_comment && +                  construct_ != Construct::cxx_comment && +                  construct_ != Construct::char_literal) +              { +                // We might be in an escape sequence. +                // +                Boolean es (!hold_.empty () && hold_.back () == '\\'); + +                if (es) +                { +                  // Scan the hold sequence backwards to figure out if this +                  // backslash is part of this escape sequence or a preceding +                  // one. +                  // +                  for (typename Hold::ReverseIterator i (hold_.rbegin () + 1), +                         e (hold_.rend ()); i != e && *i == '\\'; ++i) +                    es = !es; +                } + +                if (!es) +                { +                  // Not an escape sequence. +                  // +                  if (construct_ == Construct::string_literal) +                    new_construct = Construct::other; +                  else +                    construct_ = new_construct = Construct::string_literal; +                } +              } + +              break; +            } +          case '\'': +            { +              if (construct_ != Construct::pp_directive && +                  construct_ != Construct::c_comment && +                  construct_ != Construct::cxx_comment && +                  construct_ != Construct::string_literal) +              { +                // We might be in an escape sequence. +                // +                Boolean es (!hold_.empty () && hold_.back () == '\\'); + +                if (es) +                { +                  // Scan the hold sequence backwards to figure out if this +                  // backslash is part of this escape sequence or a preceding +                  // one. +                  // +                  for (typename Hold::ReverseIterator i (hold_.rbegin () + 1), +                         e (hold_.rend ()); i != e && *i == '\\'; ++i) +                    es = !es; +                } + +                if (!es) +                { +                  if (construct_ == Construct::char_literal) +                    new_construct = Construct::other; +                  else +                    construct_ = new_construct = Construct::char_literal; +                } +              } + +              break; +            } +          case '/': +            { +              if (construct_ == Construct::other) +              { +                if (!hold_.empty () && hold_.back () == '/') +                  construct_ = new_construct = Construct::cxx_comment; +              } + +              if (construct_ == Construct::c_comment) +              { +                if (!hold_.empty () && hold_.back () == '*') +                  construct_ = new_construct = Construct::other; +              } + +              break; +            } +          case '*': +            { +              if (construct_ == Construct::other) +              { +                if (!hold_.empty () && hold_.back () == '/') +                  construct_ = new_construct = Construct::c_comment; +              } + +              break; +            } +          default: +            { +              break; +            } +          } + +          // Special handling of CPP directives. +          // +          if (construct_ == Construct::pp_directive) +          { +            result = write (c); +            position_++; +            return result; +          } + +          // +          // +          tokenize (c, old_construct); + + +          // Indentation in parenthesis. We don't need to make sure +          // we are not in a comments, etc. because we make sure we +          // don't hold anything in those states. +          // +          if (!hold_.empty () && hold_.back () == '(') +          { +            unbuffer (); // We don't need to hold it anymore. + +            if (c == '\n') +              indentation_.push (indentation_.top () + spaces_); +            else +              indentation_.push (position_); +          } + + +          // +          // +          Boolean defaulting (false); + +          switch (c) +          { +          case '\n': +            { +              if (!indent_block_.empty () && construct_ == Construct::other) +                indent_block_.top ().newline_ = true; + +              hold_.push_back (c); +              position_ = 0; // Starting a new line. + +              break; +            } +          case '{': +            { +              if (construct_ == Construct::other) +              { +                if (!indent_block_.empty ()) +                { +                  // Pop all the blocks until the one that was indented. +                  // +                  while (!indent_block_.top ().indented_) +                    indent_block_.pop (); + +                  if (indentation_.size () > 1) +                    indentation_.pop (); + +                  indent_block_.pop (); +                } + +                ensure_new_line (); +                output_indentation (); +                result = write (c); +                ensure_new_line (); + +                indentation_.push (indentation_.top () + spaces_); +              } +              else +                defaulting = true; + +              break; +            } +          case '}': +            { +              if (construct_ == Construct::other) +              { +                if (indentation_.size () > 1) +                  indentation_.pop (); + +                // Reduce multiple newlines to one. +                // +                while (hold_.size () > 1) +                { +                  typename Hold::ReverseIterator 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; + +                buffering_ = true; +              } +              else +                defaulting = true; + +              break; +            } +          case ';': +            { +              if (construct_ == Construct::other) +              { +                // for (;;) +                // +                if (!indent_block_.empty () && paren_balance_ == 0) +                { +                  // Pop all the blocks until the one that was indented. +                  // +                  while (!indent_block_.top ().indented_) +                    indent_block_.pop (); + +                  if (indentation_.size () > 1) +                    indentation_.pop (); + +                  indent_block_.pop (); +                } + +                if (paren_balance_ != 0) +                { +                  // We are inside for (;;) statement. Nothing to do here. +                  // +                  defaulting = true; +                } +                else +                { +                  // Handling '};' case. +                  // + +                  Boolean brace (false); + +                  if (hold_.size () > 1 && hold_.back () == '\n') +                  { +                    Boolean pop_nl (false); + +                    for (typename Hold::ReverseIterator +                           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'); +                  } + +                  ensure_new_line (); +                } +              } +              else +                defaulting = true; + +              break; +            } +          case ' ': +            { +              if (construct_ == Construct::other) +              { +                // Handling '} foo_;' case. +                // +                if (hold_.size () > 1 && hold_.back () == '\n') +                { +                  Boolean pop_nl (false); + +                  for (typename Hold::ReverseIterator +                         i (hold_.rbegin ()), e (hold_.rend ()); +                       i != e; ++i) +                  { +                    if (*i != '\n') +                    { +                      if (*i == '}') +                        pop_nl = true; + +                      break; +                    } +                  } + +                  if (pop_nl) +                    while (hold_.back () == '\n') +                      hold_.pop_back (); +                } +              } + +              defaulting = true; +              break; +            } +          case '\\': +            { +              if (construct_ != Construct::pp_directive && +                  construct_ != Construct::c_comment && +                  construct_ != Construct::cxx_comment) +              { +                output_indentation (); +                hold_.push_back (c); +                position_++; +              } +              else +                defaulting = true; + +            break; + +            } +          case '(': +            { +              if (construct_ == 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_ == Construct::other) +              { +                if (indentation_.size () > 1) +                  indentation_.pop (); + +                if (paren_balance_ > 0) +                  paren_balance_--; +              } + +              defaulting = true; +              break; +            } +          case '/': +            { +              if (construct_ == Construct::other) +              { +                output_indentation (); +                hold_.push_back (c); +                position_++; +              } +              else +                defaulting = true; + +              break; +            } +          case '*': +            { +              if (construct_ == Construct::c_comment) +              { +                output_indentation (); +                hold_.push_back (c); +                position_++; +              } +              else +                defaulting = true; + +              break; +            } +          default: +            { +              defaulting = true; +              break; +            } +          } + + +          if (defaulting) +          { +            output_indentation (); +            result = write (c); +            position_++; +          } + +          construct_ = new_construct; +        } +        catch (Write const&) +        { +          result = Traits::eof (); +        } + +        return result; +      } + +    private: +      typedef Cult::StringTemplate<C> String; + +      Void +      next_token (String const& old, AsChar c) +      { +        //std::cerr << "next token: " << token_ +        //          << "; old token: " << old << std::endl; + +        // Handle one line indentation blocks (if, else, etc). +        // +        if (single_line_blocks_.find (token_) != single_line_blocks_.end ()) +        { +          // Only indent sub-blocks if we are on a new line. +          // +          Boolean indent (indent_block_.empty () || +                          indent_block_.top ().newline_); + +          indent_block_.push (IndentBlockInfo (c == '\n', indent)); + +          if (indent) +            indentation_.push (indentation_.top () + spaces_); +        } + +        // Keep track of the do ... while construct in order to suppress +        // the newline after } and before while. +        // +        if (old == String ("do") && token_ == lbrace_) +        { +          do_while_state_.push (0); +        } + +        if (!do_while_state_.empty ()) +        { +          if (token_ == lbrace_) +            do_while_state_.top ()++; + +          if (token_ == rbrace_) +            do_while_state_.top ()--; +        } + +        // Suppress double newline in the "}else", etc., cases. +        // +        if (old == rbrace_) +        { +          Boolean dw (!do_while_state_.empty () && +                      do_while_state_.top () == 0); + +          if (follow_blocks_.find (token_) != follow_blocks_.end () || dw) +          { +            if (dw) +              do_while_state_.pop (); + +            // Reduce double newline after "}" into a single one. +            // +            typename Hold::Iterator i (hold_.end ()), b (hold_.begin ()); + +            for (--i; i != b; --i) +            { +              // See if this is the end of the "}\n\n" sequence. +              // +              if (*i == '\n') +              { +                --i; +                if (i != b && *i == '\n') +                { +                  --i; +                  if (*i == '}') +                  { +                    ++i; +                    hold_.erase (i); +                    break; +                  } +                } +              } +            } +          } +          else if (token_ != rbrace_) +          { +            buffering_ = false; +          } +        } +      } + +    public: +      virtual Void +      unbuffer () +      { +        AsInt result; + +        while (!hold_.empty ()) +        { +          result = out_.put (hold_.front ()); + +          //@@ failed +          if (result == Traits::eof ()) +            throw Write (); + +          hold_.pop_front (); +        } +      } + +    private: +      Void +      ensure_new_line () +      { +        if (hold_.empty () || hold_.back () != '\n') +        { +          hold_.push_back ('\n'); +          position_ = 0; // Starting a new line. +        } +      } + + +      Void +      output_indentation () +      { +        if (!hold_.empty () && hold_.back () == '\n') +        { +          for (UnsignedLong i (0); i < indentation_.top (); ++i) +            write (' '); + +          position_ += indentation_.top (); +        } +      } + +      AsInt +      write (AsChar c) +      { +        hold_.push_back (c); + +        if (!buffering_) +        { +          AsInt result (Traits::eof ()); + +          while (!hold_.empty ()) +          { +            result = out_.put (hold_.front ()); + +            if (result == Traits::eof ()) +              throw Write (); + +            hold_.pop_front (); +          } + +          return result; +        } +        else +          return c; +      } + +    private: +      struct Construct +      { +        enum Value +        { +          other, +          pp_directive, +          c_comment, +          cxx_comment, +          string_literal, +          char_literal +        }; +      }; + +      Void +      tokenize (AsChar c, typename Construct::Value old) +      { +        // +        // +        switch (construct_) +        { +        case Construct::pp_directive: +          { +            if (old == Construct::other) // Start PP directive +              retire (c); + +            return; +          } +        case Construct::c_comment: +          { +            if (old == Construct::other) // Start C comment. +              lexeme_.clear (); + +            return; +          } +        case Construct::cxx_comment: +          { +            if (old == Construct::other) // Start C++ comment. +              lexeme_.clear (); + +            return; +          } +        case Construct::string_literal: +          { +            if (old == Construct::other) // Start string literal +              retire (c); + +            lexeme_ += c; +            return; +          } +        case Construct::char_literal: +          { +            if (old == Construct::other) // Start char literal +              retire (c); + +            lexeme_ += c; +            return; +          } +        default: +          break; +        } + +        // construct_ == other +        // +        switch (old) +        { +        case Construct::pp_directive: +          { +            // End  PP directive (newline). +            // +            return; +          } +        case Construct::c_comment: +          { +            // End  C comment. +            // +            return; +          } +        case Construct::cxx_comment: +          { +            // End  C++ comment (newline). +            // +            return; +          } +        case Construct::string_literal: +          { +            // End string literal ("). +            // +            lexeme_ += c; +            return; +          } +        case Construct::char_literal: +          { +            // End char literal ('). +            // +            lexeme_ += c; +            return; +          } +        default: +          break; +        } + + +        // construct_ == old == other +        // + +        /* + +        The code below is equivalent to this (simpler) code which is +        unfortunately not fast enough. + +        using std::isalpha; +        using std::isalnum; +        using std::isdigit; +        using std::isspace; + +        if (c == '_' || isalpha (c, locale_)) +        { +          if (lexeme_.empty () || +              lexeme_[0] == '_' || isalpha (lexeme_[0], locale_)) +            lexeme_ += c; +          else +          { +            retire (c); +            lexeme_ += c; +          } +        } +        else if (isdigit (c, locale_)) +        { +          if (lexeme_.empty () || +              lexeme_[0] == '_' || isalnum (lexeme_[0], locale_)) +            lexeme_ += c; +          else +          { +            retire (c); +            lexeme_ += c; +          } +        } +        else // Delimiters +        { +          retire (c); + +          if (!isspace (c, locale_)) +            lexeme_ += c; +        } +        */ + +        switch (char_class (c)) +        { +        case CharClass::alpha: +          { +            if (lexeme_.empty () || +                char_class (lexeme_[0]) == CharClass::alpha) +              lexeme_ += c; +            else +            { +              retire (c); +              lexeme_ += c; +            } +            break; +          } +        case CharClass::digit: +          { +            if (lexeme_.empty ()) +              lexeme_ += c; +            else +            { +              typename CharClass::Value cc (char_class (lexeme_[0])); + +              if (cc == CharClass::alpha || cc == CharClass::digit) +                lexeme_ += c; +              else +              { +                retire (c); +                lexeme_ += c; +              } +            } +            break; +          } +        case CharClass::op_punc: +          { +            retire (c); +            lexeme_ += c; +            break; +          } +        case CharClass::space: +          { +            retire (c); +            break; +          } +        } +      } + +      struct CharClass +      { +        enum Value +        { +          alpha,   // Alpha + '_'. +          digit, +          op_punc, // Operator or punctuation. +          space +        }; + +      }; + +      typename CharClass::Value +      char_class (C c) +      { +        switch (c) +        { +        case '0': +        case '1': +        case '2': +        case '3': +        case '4': +        case '5': +        case '6': +        case '7': +        case '8': +        case '9': +          return CharClass::digit; + +        case '!': +        case '%': +        case '^': +        case '&': +        case '*': +        case '(': +        case ')': +        case '-': +        case '+': +        case '=': +        case '{': +        case '}': +        case '|': +        case '~': +        case '[': +        case ']': +        case '\\': +        case ';': +        case '\'': +        case ':': +        case '"': +        case '<': +        case '>': +        case '?': +        case ',': +        case '.': +        case '/': +          return CharClass::op_punc; + +        case ' ': +        case '\n': +        case '\t': +        case '\f': +        case '\r': +        case '\v': +          return CharClass::space; + +        default: +          return CharClass::alpha; +        } +      } + + +      Void +      retire (AsChar c) +      { +        if (!lexeme_.empty ()) +        { +          token_.swap (lexeme_); +          next_token (lexeme_, c); +          lexeme_.clear (); +        } +      } + +    private: +      Buffer<C>& out_; +      Boolean buffering_; // True if write() should buffer the char. +      UnsignedLong position_; // Current position on the line. +      UnsignedLong paren_balance_; // ( ) balance. +      Cult::Containers::Stack<UnsignedLong> indentation_; +      UnsignedLong spaces_; + +      Boolean suppress_nl_; + +      //@@ gcc bug# 18304 +      // +      typename Construct::Value construct_; + +      // Special state stach for the do-while construct. The presence +      // of an element in the stack indicates that we are in a braced +      // do-while construct. The value of the element is the brace +      // balance. +      Cult::Containers::Stack<UnsignedLong> do_while_state_; + +      typedef +      Cult::Containers::Deque<AsInt> +      Hold; + +      Hold hold_; + +    private: +      String token_;  // previously fully recognized token +      String lexeme_; // current lexeme (accumulator) + +      // std::locale locale_; + +      // Keywords that may be folowed by a single-line block, e.g., if, +      // else, etc. +      // +      Cult::Containers::Set<String> single_line_blocks_; + +      // Keywords that may follow (and be related) to a previous block, +      // e.g., else, case, catch. +      // +      Cult::Containers::Set<String> follow_blocks_; + +      String lbrace_; +      String rbrace_; + +    private: +      // Single-line indented blocks such as if, else, while, etc. The +      // newline flag indicates whether a new line has been seen after +      // the keyword. This is needed to properly distinguish cases such +      // as: +      // +      // else if (...) +      //   foo (); +      // +      // else +      //   if (...) +      //     foo (); +      // +      struct IndentBlockInfo +      { +        IndentBlockInfo (Boolean newline, Boolean indented) +            : newline_ (newline), indented_ (indented) +        { +        } + +        Boolean newline_; +        Boolean indented_; +      }; + +      Cult::Containers::Stack<IndentBlockInfo> indent_block_; +    }; +  } +} + +#include <backend-elements/indentation/cxx.txx> + +#endif  // BACKEND_ELEMENTS_INDENTATION_CXX_HXX diff --git a/libbackend-elements/backend-elements/indentation/cxx.txx b/libbackend-elements/backend-elements/indentation/cxx.txx new file mode 100644 index 0000000..9acff37 --- /dev/null +++ b/libbackend-elements/backend-elements/indentation/cxx.txx @@ -0,0 +1,12 @@ +// file      : backend-elements/indentation/cxx.txx +// author    : Boris Kolpackov <boris@kolpackov.net> +// copyright : Copyright (c) 2005-2010 Boris Kolpackov +// license   : GNU GPL v2 + exceptions; see accompanying LICENSE file + +namespace BackendElements +{ +  namespace Indentation +  { +  } +} + diff --git a/libbackend-elements/backend-elements/indentation/idl.hxx b/libbackend-elements/backend-elements/indentation/idl.hxx new file mode 100644 index 0000000..e5a234f --- /dev/null +++ b/libbackend-elements/backend-elements/indentation/idl.hxx @@ -0,0 +1,290 @@ +// file      : backend-elements/indentation/idl.hxx +// author    : Boris Kolpackov <boris@kolpackov.net> +// copyright : Copyright (c) 2005-2010 Boris Kolpackov +// license   : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#ifndef BACKEND_ELEMENTS_INDENTATION_IDL_HXX +#define BACKEND_ELEMENTS_INDENTATION_IDL_HXX + +#include <backend-elements/types.hxx> +#include <backend-elements/indentation/buffer.hxx> + +#include <cult/containers/deque.hxx> + +namespace BackendElements +{ +  namespace Indentation +  { +    template <typename C> +    class IDL: public Buffer<C>, public NonCopyable +    { +    public: +      typedef +      typename Buffer<C>::Traits +      Traits; + +      typedef +      typename Buffer<C>::AsChar +      AsChar; + +      typedef +      typename Buffer<C>::AsInt +      AsInt; + +      typedef +      typename Buffer<C>::Write +      Write; + +    public: +      IDL (Buffer<C>& out) +          : out_ (out), +            indentation_ (0), +            spaces_ (2), +            construct_ (Construct::other) +      { +      } + +    public: +      virtual AsInt +      put (AsChar c) +      { +        AsInt result (Traits::to_int_type (c)); + +        try +        { +          Boolean 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::ReverseIterator 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'); + + +              break; +            } +          case ';': +            { +              // Handling '};' case. +              // + +              Boolean brace (false); + +              if (hold_.size () > 1 && hold_.back () == '\n') +              { +                Boolean pop_nl (false); + +                for (typename Hold::ReverseIterator +                       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_ != Construct::string_literal && +                  construct_ != Construct::char_literal) +              { +                ensure_new_line (); +              } +              break; +            } +          case '\\': +            { +              hold_.push_back (c); +              break; +            } +          case '\"': +            { +              if (hold_.empty () || hold_.back () != '\\') +              { +                // not escape sequence +                if (construct_ == Construct::string_literal) +                { +                  construct_ = Construct::other; +                } +                else construct_ = Construct::string_literal; +              } + +              defaulting = true; +              break; +            } +          case '\'': +            { +              if (hold_.empty () || hold_.back () != '\\') +              { +                // not escape sequence +                if (construct_ == Construct::char_literal) +                { +                  construct_ = Construct::other; +                } +                else construct_ = Construct::char_literal; +              } + +              defaulting = true; +              break; +            } +          default: +            { +              defaulting = true; +              break; +            } +          } + +          if (defaulting) +          { +            output_indentation (); +            result = write (c); +          } +        } +        catch (Write const&) +        { +          result = Traits::eof (); +        } + +        return result; +      } + +      virtual Void +      unbuffer () +      { +        AsInt result; + +        while (!hold_.empty ()) +        { +          result = out_.put (hold_.front ()); + +          //@@ failed +          if (result == Traits::eof ()) +            throw Write (); + +          hold_.pop_front (); +        } +      } + +    private: +      Void +      ensure_new_line () +      { +        if (hold_.empty () || hold_.back () != '\n') +          hold_.push_back ('\n'); +      } + + +      Void +      output_indentation () +      { +        if (!hold_.empty () && hold_.back () == '\n') +          for (UnsignedLong i (0); i < indentation_ * spaces_; ++i) +            write (' '); +      } + +      AsInt +      write (AsChar c) +      { +        hold_.push_back (c); + +        AsInt result (Traits::eof ()); + +        while (!hold_.empty ()) +        { +          result = out_.put (hold_.front ()); + +          if (result == Traits::eof ()) +            throw Write (); + +          hold_.pop_front (); +        } + +        return result; +      } + + +    private: + +      Buffer<C>& out_; +      UnsignedLong indentation_; +      UnsignedLong spaces_; + +      Boolean suppress_nl_; + +      struct Construct +      { +        enum Value +        { +          other, +          string_literal, +          char_literal +        }; +      }; + +      //@@ gcc bug# 18304 +      // +      typename Construct::Value construct_; + +      typedef +      Cult::Containers::Deque<AsInt> +      Hold; + +      Hold hold_; +    }; +  } +} + +#include <backend-elements/indentation/idl.txx> + +#endif  // BACKEND_ELEMENTS_INDENTATION_IDL_HXX diff --git a/libbackend-elements/backend-elements/indentation/idl.txx b/libbackend-elements/backend-elements/indentation/idl.txx new file mode 100644 index 0000000..6ddc63e --- /dev/null +++ b/libbackend-elements/backend-elements/indentation/idl.txx @@ -0,0 +1,11 @@ +// file      : backend-elements/indentation/idl.txx +// author    : Boris Kolpackov <boris@kolpackov.net> +// copyright : Copyright (c) 2005-2010 Boris Kolpackov +// license   : GNU GPL v2 + exceptions; see accompanying LICENSE file + +namespace BackendElements +{ +  namespace Indentation +  { +  } +} diff --git a/libbackend-elements/backend-elements/indentation/sloc.hxx b/libbackend-elements/backend-elements/indentation/sloc.hxx new file mode 100644 index 0000000..57e6989 --- /dev/null +++ b/libbackend-elements/backend-elements/indentation/sloc.hxx @@ -0,0 +1,277 @@ +// file      : backend-elements/indentation/sloc.hxx +// author    : Boris Kolpackov <boris@kolpackov.net> +// copyright : Copyright (c) 2005-2010 Boris Kolpackov +// license   : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#ifndef BACKEND_ELEMENTS_INDENTATION_SLOC_HXX +#define BACKEND_ELEMENTS_INDENTATION_SLOC_HXX + +#include <backend-elements/types.hxx> +#include <backend-elements/indentation/buffer.hxx> + +#include <cctype> +#include <iostream> //@@ tmp + +namespace BackendElements +{ +  namespace Indentation +  { +    template <typename C> +    class SLOC: public Buffer<C>/*, public NonCopyable*/ +    { +    public: +      typedef +      typename Buffer<C>::Traits +      Traits; + +      typedef +      typename Buffer<C>::AsChar +      AsChar; + +      typedef +      typename Buffer<C>::AsInt +      AsInt; + +      typedef +      typename Buffer<C>::Write +      Write; + +    public: +      SLOC (Buffer<C>& out) +          : out_ (out), +            count_ (0), +            prev_ ('\0'), +            code_counted_ (false), +            construct_ (Construct::code) +      { +      } + +      UnsignedLong +      count () const +      { +        return count_; +      } + +    public: +      virtual AsInt +      put (AsChar c) +      { +        typename Construct::Value old (construct_); + +        switch (construct_) +        { +        case Construct::code: +          { +            code (c); +            break; +          } +        case Construct::c_comment: +          { +            c_comment (c); +            break; +          } +        case Construct::cxx_comment: +          { +            cxx_comment (c); +            break; +          } +        case Construct::char_literal: +          { +            char_literal (c); +            break; +          } +        case Construct::string_literal: +          { +            string_literal (c); +            break; +          } +        } + +        // There are cases when a previous character has been already +        // 'used' and therefore can not be used again. Good example +        // would be '/* *//'. Here, the second slash doesn't start +        // C++ comment since it was already used by C comment. +        // +        // To account for this we are going to set prev_ to '\0' when +        // the mode changes. +        // + +        prev_ = (old == construct_) ? c : '\0'; + +        return out_.put (c); +      } + +      virtual Void +      unbuffer () +      { +      } + +    private: +      Void +      code (AsChar c) +      { +        bool count (true); + +        switch (c) +        { +        case '/': +          { +            if (prev_ == '/') +            { +              construct_ = Construct::cxx_comment; +              count = false; +            } +            else +            { +              // This slash can be a beginning of a comment but we +              // yet have no way to know. Will have to examine it later +              // (see below). +              // +              count = false; +            } + +            break; +          } +        case '*': +          { +            if (prev_ == '/') +            { +              construct_ = Construct::c_comment; +              count = false; +            } +            break; +          } +        case '\'': +          { +            construct_ = Construct::char_literal; +            break; +          } +        case '"': +          { +            construct_ = Construct::string_literal; +            break; +          } +        case '\n': +          { +            code_counted_ = false; // reset for a new line +            count = false; +            break; +          } +        default: +          { +            if (std::isspace (c)) +              count = false; +            break; +          } +        } + +        // The second condition here accounts for the fact that we cannot +        // count '/' right away since it can be a beginning of a comment. +        // +        if (!code_counted_ && +            (count || (prev_ == '/' && construct_ == Construct::code))) +        { +          //std::wcerr << "detected code @ " << c << std::endl; +          count_++; +          code_counted_ = true; +        } +      } + +      Void +      c_comment (AsChar c) +      { +        switch (c) +        { +        case '/': +          { +            if (prev_ == '*') +              construct_ = Construct::code; +            break; +          } +        case '\n': +          { +            code_counted_ = false; // reset for a new line +            break; +          } +        } +      } + +      Void +      cxx_comment (AsChar c) +      { +        switch (c) +        { +        case '\n': +          { +            construct_ = Construct::code; +            code_counted_ = false; // reset for a new line +            break; +          } +        } +      } + +      Void +      char_literal (AsChar c) +      { +        switch (c) +        { +        case '\'': +          { +            if (prev_ != '\\') +              construct_ = Construct::code; +            break; +          } +        } +      } + +      Void +      string_literal (AsChar c) +      { +        switch (c) +        { +        case '"': +          { +            if (prev_ != '\\') +              construct_ = Construct::code; +            break; +          } +        case '\n': +          { +            /*@@ Should I count multi-line string literal as multiple SLOC? */ +            break; +          } +        } +      } + +    private: +      Buffer<C>& out_; +      UnsignedLong count_; + +      AsChar prev_; // previous character or '\0' + +      struct Construct +      { +        enum Value +        { +          code, +          c_comment, +          cxx_comment, +          char_literal, +          string_literal +        }; +      }; + +      // code +      // +      bool code_counted_; + +      //@@ gcc bug# 18304 +      // +      typename Construct::Value construct_; +    }; +  } +} + +//#include <backend-elements/indentation/sloc.txx> + +#endif  // BACKEND_ELEMENTS_INDENTATION_SLOC_HXX diff --git a/libbackend-elements/backend-elements/makefile b/libbackend-elements/backend-elements/makefile new file mode 100644 index 0000000..70a3e4a --- /dev/null +++ b/libbackend-elements/backend-elements/makefile @@ -0,0 +1,63 @@ +# file      : backend-elements/makefile +# author    : Boris Kolpackov <boris@kolpackov.net> +# copyright : Copyright (c) 2005-2010 Boris Kolpackov +# license   : GNU GPL v2; see accompanying LICENSE file + +include $(dir $(lastword $(MAKEFILE_LIST)))../build/bootstrap.make + +cxx_tun   := +cxx_obj   := $(addprefix $(out_base)/,$(cxx_tun:.cxx=.o)) +cxx_od    := $(cxx_obj:.o=.o.d) + +backend_elements.l             := #$(out_base)/backend-elements.l +backend_elements.l.cpp-options := $(out_base)/backend-elements.l.cpp-options + +clean     := $(out_base)/.clean + + +# Secure default target. +# +$(backend_elements.l.cpp-options): +#$(backend_elements.l): + + +# Imports. +# +$(call import,\ +  $(scf_root)/import/libcult/stub.make,\ +  l: cult.l,cpp-options: cult.l.cpp-options) + +$(call import,\ +  $(scf_root)/import/libboost/regex/stub.make,\ +  l: re.l,cpp-options: re.l.cpp-options) + + +# Build. +# +#$(backend_elements.l): $(cxx_obj) $(cult.l) + +#$(cxx_obj): $(backend_elements.l.cpp-options) + +$(backend_elements.l.cpp-options): value := -I$(src_root) +$(backend_elements.l.cpp-options): $(re.l.cpp-options) $(cult.l.cpp-options) + +#$(call include-dep,$(cxx_od)) + + +# Convenience alias for default target. +# +$(out_base)/: $(backend_elements.l.cpp-options) + + +# Clean. +# +#$(BackendElements.l).clean \ + +$(clean): $(addsuffix .cxx.clean,$(cxx_obj)) \ +          $(backend_elements.l.cpp-options).clean + + +# How to. +# +$(call include,$(bld_root)/cxx/o-l.make) +$(call include,$(bld_root)/cxx/cxx-o.make) diff --git a/libbackend-elements/backend-elements/regex.hxx b/libbackend-elements/backend-elements/regex.hxx new file mode 100644 index 0000000..9dc6024 --- /dev/null +++ b/libbackend-elements/backend-elements/regex.hxx @@ -0,0 +1,208 @@ +// file      : backend-elements/regex.hxx +// author    : Boris Kolpackov <boris@kolpackov.net> +// copyright : Copyright (c) 2005-2010 Boris Kolpackov +// license   : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#ifndef BACKEND_ELEMENTS_REGEX_HXX +#define BACKEND_ELEMENTS_REGEX_HXX + +#include <ostream> + +#include <boost/regex.hpp> + +#include <backend-elements/types.hxx> + +namespace BackendElements +{ +  namespace Regex +  { +    template <typename C> +    struct Format +    { +      Format (StringTemplate<C> const& expression, +              StringTemplate<C> const& description) +          : expression_ (expression), description_ (description) +      { +      } + +      StringTemplate<C> const& +      expression () const +      { +        return expression_; +      } + +      StringTemplate<C> const& +      description () const +      { +        return description_; +      } + +    private: +      StringTemplate<C> expression_; +      StringTemplate<C> description_; +    }; + +    // Regex pattern. +    // +    template <typename C> +    struct Pattern +    { +      Pattern () +      { +      } + +      Pattern (Char const* p) +      { +        init (StringTemplate<C> (p)); +      } + +      Pattern (StringTemplate<C> const& p) +      { +        init (p); +      } + +      Pattern& +      operator= (Char const* p) +      { +        init (StringTemplate<C> (p)); +        return *this; +      } + +      Pattern& +      operator= (StringTemplate<C> const& p) +      { +        init (p); +        return *this; +      } + +    public: +      Boolean +      match (StringTemplate<C> const& s) const +      { +        return regex_match (s, pat_, boost::format_all); +      } + +      StringTemplate<C> +      merge (StringTemplate<C> const& sub, +             StringTemplate<C> const& s, +             Boolean first_only = false) const +      { +        if (first_only) +          return regex_merge ( +            s, pat_, sub, boost::format_all | boost::format_first_only); +        else +          return regex_merge ( s, pat_, sub, boost::format_all); +      } + +    public: +      Boolean +      empty () const +      { +        return pat_.empty (); +      } + +    public: +      boost::basic_regex<C> const& +      impl_pattern () const +      { +        return pat_; +      } + +    private: +      Void +      init (StringTemplate<C> const& r); + +    private: +      boost::basic_regex<C> pat_; +    }; + +    template <typename C1, typename C2> +    inline std::basic_ostream<C1>& +    operator<< (std::basic_ostream<C1>& os, Pattern<C2> const& p) +    { +      return os << p.impl_pattern ().str ().c_str (); +    } + +    // Regex expression: '/pattern/substitution/'. +    // +    template <typename C> +    struct Expression +    { +      Expression () +      { +      } + +      // Expression is of the form /regex/format/ where '/' can be +      // replaced with any delimiter. +      // +      Expression (Char const* e) +      { +        init (StringTemplate<C> (e)); +      } + +      Expression (StringTemplate<C> const& e) +      { +        init (e); +      } + +      Expression& +      operator= (Char const* e) +      { +        init (StringTemplate<C> (e)); +        return *this; +      } + +      Expression& +      operator= (StringTemplate<C> const& e) +      { +        init (e); +        return *this; +      } + +    public: +      Boolean +      match (StringTemplate<C> const& s) const +      { +        return pat_.match (s); +      } + +      StringTemplate<C> +      merge (StringTemplate<C> const& s, Boolean first_only = false) const +      { +        return pat_.merge (sub_, s, first_only); +      } + +    public: +      const Pattern<C>& +      pattern () const +      { +        return pat_; +      } + +      const StringTemplate<C>& +      substitution () const +      { +        return sub_; +      } + +    public: +      Boolean +      empty () const +      { +        return pat_.empty () && sub_.empty (); +      } + +    private: +      Void +      init (StringTemplate<C> const& r); + +    private: +      Pattern<C> pat_; +      StringTemplate<C> sub_; +    }; +  } +} + +#include <backend-elements/regex.txx> + +#endif  // BACKEND_ELEMENTS_REGEX_HXX diff --git a/libbackend-elements/backend-elements/regex.txx b/libbackend-elements/backend-elements/regex.txx new file mode 100644 index 0000000..897e0e8 --- /dev/null +++ b/libbackend-elements/backend-elements/regex.txx @@ -0,0 +1,52 @@ +// file      : backend-elements/regex.txx +// author    : Boris Kolpackov <boris@kolpackov.net> +// copyright : Copyright (c) 2005-2010 Boris Kolpackov +// license   : GNU GPL v2 + exceptions; see accompanying LICENSE file + +namespace BackendElements +{ +  namespace Regex +  { +    template <typename C> +    Void Pattern<C>:: +    init (StringTemplate<C> const& r) +    { +      try +      { +        pat_ = r; +      } +      catch (boost::regex_error const& e) +      { +        throw Format<C> (r, e.what ()); +      } +    } + +    // +    // +    template <typename C> +    Void Expression<C>:: +    init (StringTemplate<C> const& r) +    { +      typedef StringTemplate<C> String; + +      if (r.empty ()) +        throw Format<C> (r, "empty expression"); + +      C d (r[0]); + +      Size first (0); +      Size middle (r.find (d, first + 1)); + +      if (middle == String::npos) +        throw Format<C> (r, "missing second pattern-substitution separator"); + +      Size last (r.find (d, middle + 1)); + +      if (last == String::npos) +        throw Format<C> (r, "missing third pattern-substitution separator"); + +      pat_ = String (r, first + 1, middle - first - 1); +      sub_.assign (r, middle + 1, last - middle - 1); +    } +  } +} diff --git a/libbackend-elements/backend-elements/types.hxx b/libbackend-elements/backend-elements/types.hxx new file mode 100644 index 0000000..f309f5d --- /dev/null +++ b/libbackend-elements/backend-elements/types.hxx @@ -0,0 +1,16 @@ +// file      : backend-elements/types.hxx +// author    : Boris Kolpackov <boris@kolpackov.net> +// copyright : Copyright (c) 2005-2010 Boris Kolpackov +// license   : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#ifndef BACKEND_ELEMENTS_TYPES_HXX +#define BACKEND_ELEMENTS_TYPES_HXX + +#include <cult/types.hxx> + +namespace BackendElements +{ +  using namespace Cult::Types; +} + +#endif  // BACKEND_ELEMENTS_TYPES_HXX | 
