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/sloc.hxx | 277 +++++++++++++++++++++ 1 file changed, 277 insertions(+) create mode 100644 libbackend-elements/backend-elements/indentation/sloc.hxx (limited to 'libbackend-elements/backend-elements/indentation/sloc.hxx') 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 +// 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 +#include + +#include +#include //@@ tmp + +namespace BackendElements +{ + namespace Indentation + { + template + class SLOC: 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: + SLOC (Buffer& 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& 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 + +#endif // BACKEND_ELEMENTS_INDENTATION_SLOC_HXX -- cgit v1.2.3