From be1d586b7582a6b54b06719a4a1d6958d86c1851 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Mon, 5 Dec 2011 14:37:08 +0200 Subject: C++ indenter fixes --- cutl/compiler/cxx-indenter.hxx | 10 ++++--- cutl/compiler/cxx-indenter.txx | 54 +++++++++++++++++++++++++++------- tests/compiler/cxx-indenter/driver.cxx | 54 ++++++++++++++++++++++++++++++++++ tests/compiler/cxx-indenter/output.std | 7 +++++ version | 2 +- 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_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 -- cgit v1.1