summaryrefslogtreecommitdiff
path: root/libbackend-elements/backend-elements/indentation/sloc.hxx
diff options
context:
space:
mode:
authorJörg Frings-Fürst <jff@merkur>2014-05-18 16:08:14 +0200
committerJörg Frings-Fürst <jff@merkur>2014-05-18 16:08:14 +0200
commita15cf65c44d5c224169c32ef5495b68c758134b7 (patch)
tree3419f58fc8e1b315ba8171910ee044c5d467c162 /libbackend-elements/backend-elements/indentation/sloc.hxx
Imported Upstream version 3.3.0.2upstream/3.3.0.2
Diffstat (limited to 'libbackend-elements/backend-elements/indentation/sloc.hxx')
-rw-r--r--libbackend-elements/backend-elements/indentation/sloc.hxx277
1 files changed, 277 insertions, 0 deletions
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