aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2011-12-05 14:37:08 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2011-12-05 14:37:08 +0200
commitbe1d586b7582a6b54b06719a4a1d6958d86c1851 (patch)
treeedcfd751dce1e5cbf5d40707408a2133abc6271c
parenta4a6915ffe5fef5da7e4d421d56d1e3a0bbd5f1e (diff)
C++ indenter fixes
-rw-r--r--cutl/compiler/cxx-indenter.hxx10
-rw-r--r--cutl/compiler/cxx-indenter.txx54
-rw-r--r--tests/compiler/cxx-indenter/driver.cxx54
-rw-r--r--tests/compiler/cxx-indenter/output.std7
-rw-r--r--version2
5 files changed, 111 insertions, 16 deletions
diff --git a/cutl/compiler/cxx-indenter.hxx b/cutl/compiler/cxx-indenter.hxx
index 0988438..a436da7 100644
--- a/cutl/compiler/cxx-indenter.hxx
+++ b/cutl/compiler/cxx-indenter.hxx
@@ -108,7 +108,7 @@ namespace cutl
bool suppress_nl_;
construct construct_;
- // Special state stach for the do-while construct. The presence
+ // Special state stack 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.
@@ -150,13 +150,15 @@ namespace cutl
//
struct indent_block
{
- indent_block (bool newline, bool indented)
- : newline_ (newline), indented_ (indented)
+ indent_block (bool newline, std::size_t indentation)
+ : newline_ (newline), indentation_ (indentation)
{
}
bool newline_;
- bool indented_;
+ std::size_t indentation_; // Size of the indentation_ stack
+ // corresponding to this block, or
+ // 0 if it is not indented.
};
std::stack<indent_block> indent_stack_;
diff --git a/cutl/compiler/cxx-indenter.txx b/cutl/compiler/cxx-indenter.txx
index ab5b5a8..3ebb2c9 100644
--- a/cutl/compiler/cxx-indenter.txx
+++ b/cutl/compiler/cxx-indenter.txx
@@ -212,9 +212,11 @@ namespace cutl
{
// Pop all the blocks until the one that was indented.
//
- while (!indent_stack_.top ().indented_)
+ while (indent_stack_.top ().indentation_ == 0)
indent_stack_.pop ();
+ // Pop the indented block and one level of indentation.
+ //
if (indentation_.size () > 1)
indentation_.pop ();
@@ -257,13 +259,35 @@ namespace cutl
hold_.push_back (c);
-
// Add double newline after '}'.
//
hold_.push_back ('\n');
hold_.push_back ('\n');
position_ = 0;
+ if (!indent_stack_.empty ())
+ {
+ // Pop all the blocks until the one that was indented.
+ //
+ while (indent_stack_.top ().indentation_ == 0)
+ indent_stack_.pop ();
+
+ // Now pop all the indented blocks while also popping the
+ // indentation stack. Do it only if the indentation match.
+ // If it doesn't then that means this inden_stack entry is
+ // for some other, outer block.
+ //
+ while (!indent_stack_.empty () &&
+ indent_stack_.top ().indentation_ ==
+ indentation_.size ())
+ {
+ if (indentation_.size () > 1)
+ indentation_.pop ();
+
+ indent_stack_.pop ();
+ }
+ }
+
buffering_ = true;
}
else
@@ -281,13 +305,23 @@ namespace cutl
{
// Pop all the blocks until the one that was indented.
//
- while (!indent_stack_.top ().indented_)
+ while (indent_stack_.top ().indentation_ == 0)
indent_stack_.pop ();
- if (indentation_.size () > 1)
- indentation_.pop ();
+ // Now pop all the indented blocks while also popping the
+ // indentation stack. Do it only if the indentation match.
+ // If they don't then it means we are inside a block and
+ // the stack should be popped after seeing '}', not ';'.
+ //
+ while (!indent_stack_.empty () &&
+ indent_stack_.top ().indentation_ ==
+ indentation_.size ())
+ {
+ if (indentation_.size () > 1)
+ indentation_.pop ();
- indent_stack_.pop ();
+ indent_stack_.pop ();
+ }
}
if (paren_balance_ != 0)
@@ -453,7 +487,6 @@ namespace cutl
}
}
-
if (defaulting)
{
output_indentation ();
@@ -485,10 +518,11 @@ namespace cutl
bool indent (indent_stack_.empty () ||
indent_stack_.top ().newline_);
- indent_stack_.push (indent_block (c == '\n', indent));
-
if (indent)
indentation_.push (indentation_.top () + spaces_);
+
+ indent_stack_.push (
+ indent_block (c == '\n', (indent ? indentation_.size () : 0)));
}
// Keep track of the do ... while construct in order to suppress
@@ -545,9 +579,7 @@ namespace cutl
// Stop buffering unless we have another closing brace.
//
if (token_ != rbrace_)
- {
buffering_ = false;
- }
}
}
diff --git a/tests/compiler/cxx-indenter/driver.cxx b/tests/compiler/cxx-indenter/driver.cxx
index 180187a..3a8ce30 100644
--- a/tests/compiler/cxx-indenter/driver.cxx
+++ b/tests/compiler/cxx-indenter/driver.cxx
@@ -32,6 +32,14 @@ main ()
<< "b ();"
<< "}";
+ os << "if (true)" << endl
+ << "// Hello there" << endl
+ << "//" << endl
+ << "a ();"
+ << "else" << endl
+ << "b ();"
+ << endl;
+
os << "if (false)"
<< "{"
<< "if (true)"
@@ -107,4 +115,50 @@ main ()
<< "\"'id',\"" << endl
<< "\"'name')\");"
<< "}";
+
+/*
+ @@ TODO: still misindents (if-else association problem)
+
+ os << "{"
+ << "if (foo != bar)" << endl
+ << "if (foo (bar))" << endl
+ << "baz = true;"
+ << "else" << endl
+ << "baz = false;"
+ << "else" << endl
+ << "biz = true;"
+ << endl
+ << "biz = false;"
+ << "}";
+
+ os << "{"
+ << "if (foo != bar)" << endl
+ << "if (foo (bar))"
+ << "{"
+ << "baz = true;"
+
+ << "if (x)" << endl
+ << "test ();"
+ << "else" << endl
+ << "test ();"
+ << endl
+
+ << "if (x)" << endl
+ << "if (y)"
+ << "{"
+ << "test ();"
+ << "}"
+ << "else"
+ << "{"
+ << "test ();"
+ << "}"
+
+ << "}"
+ << "else"
+ << "{"
+ << "test ();"
+ << "}"
+ << "biz = false;"
+ << "}";
+*/
}
diff --git a/tests/compiler/cxx-indenter/output.std b/tests/compiler/cxx-indenter/output.std
index f90f365..0e59a26 100644
--- a/tests/compiler/cxx-indenter/output.std
+++ b/tests/compiler/cxx-indenter/output.std
@@ -9,6 +9,13 @@ else
b ();
}
+if (true)
+ // Hello there
+ //
+ a ();
+else
+ b ();
+
if (false)
{
if (true)
diff --git a/version b/version
index dc1e644..9c6d629 100644
--- a/version
+++ b/version
@@ -1 +1 @@
-1.6.0
+1.6.1