From a15cf65c44d5c224169c32ef5495b68c758134b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Frings-F=C3=BCrst?= Date: Sun, 18 May 2014 16:08:14 +0200 Subject: Imported Upstream version 3.3.0.2 --- .../backend-elements/indentation/idl.hxx | 290 +++++++++++++++++++++ 1 file changed, 290 insertions(+) create mode 100644 libbackend-elements/backend-elements/indentation/idl.hxx (limited to 'libbackend-elements/backend-elements/indentation/idl.hxx') 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 +// 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 +#include + +#include + +namespace BackendElements +{ + namespace Indentation + { + template + class IDL: public Buffer, public NonCopyable + { + public: + typedef + typename Buffer::Traits + Traits; + + typedef + typename Buffer::AsChar + AsChar; + + typedef + typename Buffer::AsInt + AsInt; + + typedef + typename Buffer::Write + Write; + + public: + IDL (Buffer& 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& 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 + Hold; + + Hold hold_; + }; + } +} + +#include + +#endif // BACKEND_ELEMENTS_INDENTATION_IDL_HXX -- cgit v1.2.3