view src/testdir/test_cindent.vim @ 33811:06219b3bdaf3 v9.0.2121

patch 9.0.2121: [security]: use-after-free in ex_substitute Commit: https://github.com/vim/vim/commit/26c11c56888d01e298cd8044caf860f3c26f57bb Author: Christian Brabandt <cb@256bit.org> Date: Wed Nov 22 21:26:41 2023 +0100 patch 9.0.2121: [security]: use-after-free in ex_substitute Problem: [security]: use-after-free in ex_substitute Solution: always allocate memory closes: #13552 A recursive :substitute command could cause a heap-use-after free in Vim (CVE-2023-48706). The whole reproducible test is a bit tricky, I can only reproduce this reliably when no previous substitution command has been used yet (which is the reason, the test needs to run as first one in the test_substitute.vim file) and as a combination of the `:~` command together with a :s command that contains the special substitution atom `~\=` which will make use of a sub-replace special atom and calls a vim script function. There was a comment in the existing :s code, that already makes the `sub` variable allocate memory so that a recursive :s call won't be able to cause any issues here, so this was known as a potential problem already. But for the current test-case that one does not work, because the substitution does not start with `\=` but with `~\=` (and since there does not yet exist a previous substitution atom, Vim will simply increment the `sub` pointer (which then was not allocated dynamically) and later one happily use a sub-replace special expression (which could then free the `sub` var). The following commit fixes this, by making the sub var always using allocated memory, which also means we need to free the pointer whenever we leave the function. Since sub is now always an allocated variable, we also do no longer need the sub_copy variable anymore, since this one was used to indicated when sub pointed to allocated memory (and had therefore to be freed on exit) and when not. Github Security Advisory: https://github.com/vim/vim/security/advisories/GHSA-c8qm-x72m-q53q Signed-off-by: Christian Brabandt <cb@256bit.org>
author Christian Brabandt <cb@256bit.org>
date Wed, 22 Nov 2023 22:15:05 +0100
parents 73489b6c4a02
children
line wrap: on
line source

" Test for cinoptions and cindent

def Test_cino_hash()
  # Test that curbuf->b_ind_hash_comment is correctly reset
  new
  setlocal cindent cinoptions=#1
  setlocal cinoptions=
  setline(1, ["#include <iostream>"])
  cursor(1, 1)
  norm! o#include
  assert_equal(["#include <iostream>", "#include"], getline(1, 2))

  bwipe!
enddef

def Test_cino_extern_c()
  # Test for cino-E

  var without_ind =<< trim [CODE]
    #ifdef __cplusplus
    extern "C" {
    #endif
    int func_a(void);
    #ifdef __cplusplus
    }
    #endif
  [CODE]

  var with_ind =<< trim [CODE]
    #ifdef __cplusplus
    extern "C" {
    #endif
    	int func_a(void);
    #ifdef __cplusplus
    }
    #endif
  [CODE]
  new
  setlocal cindent cinoptions=E0
  setline(1, without_ind)
  feedkeys("gg=G", 'tx')
  assert_equal(with_ind, getline(1, '$'))

  setlocal cinoptions=E-s
  setline(1, with_ind)
  feedkeys("gg=G", 'tx')
  assert_equal(without_ind, getline(1, '$'))

  setlocal cinoptions=Es
  var tests = [
        \ ['recognized', ['extern "C" {'], "\t\t;"],
        \ ['recognized', ['extern "C++" {'], "\t\t;"],
        \ ['recognized', ['extern /* com */ "C"{'], "\t\t;"],
        \ ['recognized', ['extern"C"{'], "\t\t;"],
        \ ['recognized', ['extern "C"', '{'], "\t\t;"],
        \ ['not recognized', ['extern {'], "\t;"],
        \ ['not recognized', ['extern /*"C"*/{'], "\t;"],
        \ ['not recognized', ['extern "C" //{'], ";"],
        \ ['not recognized', ['extern "C" /*{*/'], ";"],
        \ ]

  for pair in tests
    var lines = pair[1]
    setline(1, lines)
    feedkeys(len(lines) .. "Go;", 'tx')
    assert_equal(pair[2], getline(len(lines) + 1),
                    'Failed for "' .. string(lines) .. '"')
  endfor

  bwipe!
enddef

def Test_cindent_rawstring()
  new
  setl cindent
  feedkeys("i" ..
          \ "int main() {\<CR>" ..
          \ "R\"(\<CR>" ..
          \ ")\";\<CR>" ..
          \ "statement;\<Esc>", "x")
  assert_equal("\tstatement;", getline(line('.')))

  bwipe!
enddef

def Test_cindent_expr()
  new
  def g:MyIndentFunction(): number
    return v:lnum == 1 ? shiftwidth() : 0
  enddef
  setl expandtab sw=8 indentkeys+=; indentexpr=g:MyIndentFunction()
  var testinput =<< trim [CODE]
    var_a = something()
    b = something()
  [CODE]
  setline(1, testinput)
  cursor(1, 1)
  feedkeys("^\<c-v>j$A;\<esc>", 'tnix')
  var expected =<< [CODE]
        var_a = something();
b = something();
[CODE]
  assert_equal(expected, getline(1, '$'))

  :%d
  testinput =<< [CODE]
                var_a = something()
                b = something()
[CODE]
  setline(1, testinput)
  cursor(1, 1)
  feedkeys("^\<c-v>j$A;\<esc>", 'tnix')
  expected =<< [CODE]
        var_a = something();
                b = something()
[CODE]
  assert_equal(expected, getline(1, '$'))

  delfunc g:MyIndentFunction

  bwipe!
enddef

def Test_cindent_func()
  new
  setlocal cindent
  setline(1, ['int main(void)', '{', 'return 0;', '}'])
  assert_equal(-1, cindent(0))
  assert_equal(&sw, 3->cindent())
  assert_equal(-1, cindent(line('$') + 1))

  bwipe!
enddef

def Test_cindent_1()
  new
  setl cindent ts=4 sw=4
  setl cino& sts&

  var code =<< trim [CODE]
  /* start of AUTO matically checked vim: set ts=4 : */
  {
  	if (test)
  		cmd1;
  	cmd2;
  }

  {
  	if (test)
  		cmd1;
  	else
  		cmd2;
  }

  {
  	if (test)
  	{
  		cmd1;
  		cmd2;
  	}
  }

  {
  	if (test)
  	{
  		cmd1;
  		else
  	}
  }

  {
  	while (this)
  		if (test)
  			cmd1;
  	cmd2;
  }

  {
  	while (this)
  		if (test)
  			cmd1;
  		else
  			cmd2;
  }

  {
  	if (test)
  	{
  		cmd;
  	}

  	if (test)
  		cmd;
  }

  {
  	if (test) {
  		cmd;
  	}

  	if (test) cmd;
  }

  {
  	cmd1;
  	for (blah)
  		while (this)
  			if (test)
  				cmd2;
  	cmd3;
  }

  {
  	cmd1;
  	for (blah)
  		while (this)
  			if (test)
  				cmd2;
  	cmd3;

  	if (test)
  	{
  		cmd1;
  		cmd2;
  		cmd3;
  	}
  }


  /* Test for 'cindent' do/while mixed with if/else: */

  {
  	do
  		if (asdf)
  			asdfasd;
  	while (cond);

  	do
  		if (asdf)
  			while (asdf)
  				asdf;
  	while (asdf);
  }

  /* Test for 'cindent' with two ) on a continuation line */
  {
  	if (asdfasdf;asldkfj asdlkfj as;ldkfj sal;d
  			aal;sdkjf  ( ;asldfkja;sldfk
  					al;sdjfka ;slkdf ) sa;ldkjfsa dlk;)
  		line up here;
  }


  /* C++ tests: */

  // foo()		these three lines should remain in column 0
  // {
  // }

  /* Test for continuation and unterminated lines: */
  {
  	i = 99 + 14325 +
  		21345 +
  		21345 +
  		21345 + ( 21345 +
  				21345) +
  		2345 +
  		1234;
  	c = 1;
  }

  /*
     testje for indent with empty line

     here */

  {
  	if (testing &&
  			not a joke ||
  			line up here)
  		hay;
  	if (testing &&
  			(not a joke || testing
  			)line up here)
  		hay;
  	if (testing &&
  			(not a joke || testing
  			 line up here))
  		hay;
  }


  {
  	switch (c)
  	{
  		case xx:
  			do
  				if (asdf)
  					do
  						asdfasdf;
  					while (asdf);
  				else
  					asdfasdf;
  			while (cond);
  		case yy:
  		case xx:
  		case zz:
  			testing;
  	}
  }

  {
  	if (cond) {
  		foo;
  	}
  	else
  	{
  		bar;
  	}
  }

  {
  	if (alskdfj ;alsdkfjal;skdjf (;sadlkfsa ;dlkf j;alksdfj ;alskdjf
  			alsdkfj (asldk;fj
  					awith cino=(0 ;lf this one goes to below the paren with ==
  							;laksjfd ;lsakdjf ;alskdf asd)
  					asdfasdf;)))
  		asdfasdf;
  }

  	int
  func(a, b)
  	int a;
  	int c;
  {
  	if (c1 && (c2 ||
  			c3))
  		foo;
  	if (c1 &&
  			(c2 || c3)
  	   )
  }

  {
  	while (asd)
  	{
  		if (asdf)
  			if (test)
  				if (that)
  				{
  					if (asdf)
  						do
  							cdasd;
  						while (as
  								df);
  				}
  				else
  					if (asdf)
  						asdf;
  					else
  						asdf;
  		asdf;
  	}
  }

  {
  	s = "/*"; b = ';'
  		s = "/*"; b = ';';
  	a = b;
  }

  {
  	switch (a)
  	{
  		case a:
  			switch (t)
  			{
  				case 1:
  					cmd;
  					break;
  				case 2:
  					cmd;
  					break;
  			}
  			cmd;
  			break;
  		case b:
  			{
  				int i;
  				cmd;
  			}
  			break;
  		case c: {
  					int i;
  					cmd;
  				}
  		case d: if (cond &&
  						test) {		/* this line doesn't work right */
  					int i;
  					cmd;
  				}
  				break;
  	}
  }

  {
  	if (!(vim_strchr(p_cpo, CPO_BUFOPTGLOB) != NULL && entering) &&
  			(bp_to->b_p_initialized ||
  			 (!entering && vim_strchr(p_cpo, CPO_BUFOPT) != NULL)))
  		return;
  label :
  	asdf = asdf ?
  		asdf : asdf;
  	asdf = asdf ?
  		asdf: asdf;
  }

  /* Special Comments	: This function has the added complexity (compared  */
  /*					: to addtolist) of having to check for a detail     */
  /*					: texture and add that to the list first.	 	    */

  char *(array[100]) = {
  	"testje",
  	"foo",
  	"bar",
  }

  enum soppie
  {
  yes = 0,
  no,
  maybe
  };

  typedef enum soppie
  {
  yes = 0,
  no,
  maybe
  };

  static enum
  {
  yes = 0,
  no,
  maybe
  } soppie;

  public static enum
  {
  yes = 0,
  no,
  maybe
  } soppie;

  static private enum
  {
  yes = 0,
  no,
  maybe
  } soppie;

  {
  	int a,
  		b;
  }

  {
  	struct Type
  	{
  		int i;
  		char *str;
  	} var[] =
  	{
  		0, "zero",
  		1, "one",
  		2, "two",
  		3, "three"
  	};

  	float matrix[3][3] =
  	{
  		{
  			0,
  			1,
  			2
  		},
  		{
  			3,
  			4,
  			5
  		},
  		{
  			6,
  			7,
  			8
  		}
  	};
  }

  {
  	/* blah ( blah */
  	/* where does this go? */

  	/* blah ( blah */
  	cmd;

  	func(arg1,
  			/* comment */
  			arg2);
  	a;
  	{
  		b;
  		{
  			c; /* Hey, NOW it indents?! */
  		}
  	}

  	{
  		func(arg1,
  				arg2,
  				arg3);
  		/* Hey, what am I doing here?  Is this coz of the ","? */
  	}
  }

  main ()
  {
  	if (cond)
  	{
  		a = b;
  	}
  	if (cond) {
  		a = c;
  	}
  	if (cond)
  		a = d;
  	return;
  }

  {
  	case 2: if (asdf &&
  					asdfasdf)
  				aasdf;
  			a = 9;
  	case 3: if (asdf)
  				aasdf;
  			a = 9;
  	case 4:    x = 1;
  			   y = 2;

  label:	if (asdf)
  			here;

  label:  if (asdf &&
  				asdfasdf)
  		{
  		}

  label:  if (asdf &&
  				asdfasdf) {
  			there;
  		}

  label:  if (asdf &&
  				asdfasdf)
  			there;
  }

  {
  	/*
  	   hello with ":set comments= cino=c5"
  	 */

  	/*
  	   hello with ":set comments= cino="
  	 */
  }


  {
  	if (a < b) {
  		a = a + 1;
  	} else
  		a = a + 2;

  	if (a)
  		do {
  			testing;
  		} while (asdfasdf);
  	a = b + 1;
  	asdfasdf
  }

  {
  for ( int i = 0;
  	i < 10; i++ )
  {
  }
  	i = 0;
  }

  class bob
  {
  	int foo() {return 1;}
  		int bar;
  }

  main()
  {
  while(1)
  if (foo)
  {
  bar;
  }
  else {
  asdf;
  }
  misplacedline;
  }

  {
  	if (clipboard.state == SELECT_DONE
  	&& ((row == clipboard.start.lnum
  	&& col >= clipboard.start.col)
  	|| row > clipboard.start.lnum))
  }

  {
  if (1) {i += 4;}
  where_am_i;
  return 0;
  }

  {
  {
  } // sdf(asdf
  if (asdf)
  asd;
  }

  {
  label1:
  label2:
  }

  {
  int fooRet = foo(pBar1, false /*fKB*/,
  	true /*fPTB*/, 3 /*nT*/, false /*fDF*/);
  f() {
  for ( i = 0;
  	i < m;
  	/* c */ i++ ) {
  a = b;
  }
  }
  }

  {
  	f1(/*comment*/);
  	f2();
  }

  {
  do {
  if (foo) {
  } else
  ;
  } while (foo);
  foo();	// was wrong
  }

  int x;	    // no extra indent because of the ;
  void func()
  {
  }

  char *tab[] = {"aaa",
  	"};", /* }; */ NULL}
  	int indented;
  {}

  char *a[] = {"aaa", "bbb",
  	"ccc", NULL};
  // here

  char *tab[] = {"aaa",
  	"xx", /* xx */};    /* asdf */
  int not_indented;

  {
  	do {
  		switch (bla)
  		{
  			case 1: if (foo)
  						bar;
  		}
  	} while (boo);
  					wrong;
  }

  int	foo,
  	bar;
  int foo;

  #if defined(foo) \
  	&& defined(bar)
  char * xx = "asdf\
  	foo\
  	bor";
  int x;

  char    *foo = "asdf\
  	asdf\
  	asdf",
  	*bar;

  void f()
  {
  #if defined(foo) \
  	&& defined(bar)
  char    *foo = "asdf\
  	asdf\
  	asdf",
  	*bar;
  	{
  	int i;
  char    *foo = "asdf\
  	asdf\
  	asdf",
  	*bar;
  	}
  #endif
  }
  #endif

  int y;		// comment
  		// comment

  	// comment

  {
  	Constructor(int a,
  			int b )  : BaseClass(a)
  	{
  	}
  }

  void foo()
  {
  	char one,
  	two;
  	struct bla piet,
  	jan;
  	enum foo kees,
  	jannie;
  	static unsigned sdf,
  	krap;
  	unsigned int piet,
  	jan;
  	int
  	kees,
  	jan;
  }

  {
  	t(int f,
  			int d);		// )
  	d();
  }

  Constructor::Constructor(int a,
                           int b 
                          )  : 
     BaseClass(a,
               b,
               c),
     mMember(b),
  {
  }

  Constructor::Constructor(int a,
                           int b )  : 
     BaseClass(a)
  {
  }

  Constructor::Constructor(int a,
                           int b ) /*x*/ : /*x*/ BaseClass(a),
                                                 member(b)
  {
  }

  A::A(int a, int b)
  : aa(a),
  bb(b),
  cc(c)
  {
  }

  class CAbc :
     public BaseClass1,
     protected BaseClass2
  {
     int Test() { return FALSE; }
     int Test1() { return TRUE; }

     CAbc(int a, int b )  : 
        BaseClass(a)
     { 
        switch(xxx)
        {
           case abc:
              asdf();
              break;

           case 999:
              baer();
              break;
        }
     }

  public: // <-- this was incorrectly indented before!!
     void testfall();
  protected:
     void testfall();
  };

  class CAbc : public BaseClass1,
               protected BaseClass2
  {
  };

  static struct
  {
      int a;
      int b;
  } variable[COUNT] =
  {
      {
          123,
          456
      },
  	{
          123,
          456
      }
  };

  static struct
  {
      int a;
      int b;
  } variable[COUNT] =
  {
      { 123, 456 },
  	{ 123, 456 }
  };

  void asdf()		/* ind_maxparen may cause trouble here */
  {
  	if ((0
  				&& 1
  				&& 1
  				&& 1
  				&& 1
  				&& 1
  				&& 1
  				&& 1
  				&& 1
  				&& 1
  				&& 1
  				&& 1
  				&& 1
  				&& 1
  				&& 1
  				&& 1
  				&& 1
  				&& 1
  				&& 1
  				&& 1
  				&& 1
  				&& 1
  				&& 1
  				&& 1
  				&& 1
  				&& 1)) break;
  }

  foo()
  {
  	a = cond ? foo() : asdf
  					   + asdf;

  	a = cond ?
  		foo() : asdf
  				+ asdf;
  }

  int  main(void)
  {
  	if (a)
  		if (b)
  			2;
  		else 3;
  	next_line_of_code();
  }

  barry()
  {
  	Foo::Foo (int one,
  			int two)
  		: something(4)
  	{}
  }

  barry()
  {
  	Foo::Foo (int one, int two)
  		: something(4)
  	{}
  }

  Constructor::Constructor(int a,
  		int b 
  		)  : 
  	BaseClass(a,
  			b,
  			c),
  	mMember(b)
  {
  }
         int main ()
         {
  	 if (lala)
  	   do
  	     ++(*lolo);
  	   while (lili
  		  && lele);
  	   lulu;
         }

  int main ()
  {
  switch (c)
  {
  case 'c': if (cond)
  {
  }
  }
  }

  main()
  {
  	(void) MyFancyFuasdfadsfnction(
  			argument);
  }

  main()
  {
  	char	foo[] = "/*";
  	/* as
  	df */
  		hello
  }

  /* valid namespaces with normal indent */
  namespace
  {
  {
    111111111111;
  }
  }
  namespace /* test */
  {
    11111111111111111;
  }
  namespace // test
  {
    111111111111111111;
  }
  namespace
  {
    111111111111111111;
  }
  namespace test
  {
    111111111111111111;
  }
  namespace{
    111111111111111111;
  }
  namespace test{
    111111111111111111;
  }
  namespace {
    111111111111111111;
  }
  namespace test {
    111111111111111111;
  namespace test2 {
    22222222222222222;
  }
  }
  inline namespace {
    111111111111111111;
  }
  inline /* test */ namespace {
    111111111111111111;
  }
  inline/* test */namespace {
    111111111111111111;
  }

  /* invalid namespaces use block indent */
  namespace test test2 {
    111111111111111111111;
  }
  namespace11111111111 {
    111111111111;
  }
  namespace() {
    1111111111111;
  }
  namespace()
  {
    111111111111111111;
  }
  namespace test test2
  {
    1111111111111111111;
  }
  namespace111111111
  {
    111111111111111111;
  }
  inlinenamespace {
    111111111111111111;
  }

  void getstring() {
  /* Raw strings */
  const char* s = R"(
    test {
      # comment
      field: 123
    }
   )";
       }

  void getstring() {
  const char* s = R"foo(
    test {
      # comment
      field: 123
    }
      )foo";
       }

  {
  int a[4] = {
  [0] = 0,
  [1] = 1,
  [2] = 2,
  [3] = 3,
  };
  }

  {
  a = b[2]
  + 3;
  }

  {
  if (1)
  /* aaaaa
  * bbbbb
  */
  a = 1;
  }

  void func()
  {
  switch (foo)
  {
  case (bar):
  if (baz())
  quux();
  break;
  case (shmoo):
  if (!bar)
  {
  }
  case (foo1):
  switch (bar)
  {
  case baz:
  baz_f();
  break;
  }
  break;
  default:
  baz();
  baz();
  break;
  }
  }

  /* end of AUTO */
  [CODE]

  append(0, code)
  normal gg
  search('start of AUTO')
  exe "normal =/end of AUTO\<CR>"

  var expected =<< trim [CODE]
  /* start of AUTO matically checked vim: set ts=4 : */
  {
  	if (test)
  		cmd1;
  	cmd2;
  }

  {
  	if (test)
  		cmd1;
  	else
  		cmd2;
  }

  {
  	if (test)
  	{
  		cmd1;
  		cmd2;
  	}
  }

  {
  	if (test)
  	{
  		cmd1;
  		else
  	}
  }

  {
  	while (this)
  		if (test)
  			cmd1;
  	cmd2;
  }

  {
  	while (this)
  		if (test)
  			cmd1;
  		else
  			cmd2;
  }

  {
  	if (test)
  	{
  		cmd;
  	}

  	if (test)
  		cmd;
  }

  {
  	if (test) {
  		cmd;
  	}

  	if (test) cmd;
  }

  {
  	cmd1;
  	for (blah)
  		while (this)
  			if (test)
  				cmd2;
  	cmd3;
  }

  {
  	cmd1;
  	for (blah)
  		while (this)
  			if (test)
  				cmd2;
  	cmd3;

  	if (test)
  	{
  		cmd1;
  		cmd2;
  		cmd3;
  	}
  }


  /* Test for 'cindent' do/while mixed with if/else: */

  {
  	do
  		if (asdf)
  			asdfasd;
  	while (cond);

  	do
  		if (asdf)
  			while (asdf)
  				asdf;
  	while (asdf);
  }

  /* Test for 'cindent' with two ) on a continuation line */
  {
  	if (asdfasdf;asldkfj asdlkfj as;ldkfj sal;d
  			aal;sdkjf  ( ;asldfkja;sldfk
  				al;sdjfka ;slkdf ) sa;ldkjfsa dlk;)
  		line up here;
  }


  /* C++ tests: */

  // foo()		these three lines should remain in column 0
  // {
  // }

  /* Test for continuation and unterminated lines: */
  {
  	i = 99 + 14325 +
  		21345 +
  		21345 +
  		21345 + ( 21345 +
  				21345) +
  		2345 +
  		1234;
  	c = 1;
  }

  /*
     testje for indent with empty line

     here */

  {
  	if (testing &&
  			not a joke ||
  			line up here)
  		hay;
  	if (testing &&
  			(not a joke || testing
  			)line up here)
  		hay;
  	if (testing &&
  			(not a joke || testing
  			 line up here))
  		hay;
  }


  {
  	switch (c)
  	{
  		case xx:
  			do
  				if (asdf)
  					do
  						asdfasdf;
  					while (asdf);
  				else
  					asdfasdf;
  			while (cond);
  		case yy:
  		case xx:
  		case zz:
  			testing;
  	}
  }

  {
  	if (cond) {
  		foo;
  	}
  	else
  	{
  		bar;
  	}
  }

  {
  	if (alskdfj ;alsdkfjal;skdjf (;sadlkfsa ;dlkf j;alksdfj ;alskdjf
  				alsdkfj (asldk;fj
  					awith cino=(0 ;lf this one goes to below the paren with ==
  						;laksjfd ;lsakdjf ;alskdf asd)
  					asdfasdf;)))
  		asdfasdf;
  }

  	int
  func(a, b)
  	int a;
  	int c;
  {
  	if (c1 && (c2 ||
  				c3))
  		foo;
  	if (c1 &&
  			(c2 || c3)
  	   )
  }

  {
  	while (asd)
  	{
  		if (asdf)
  			if (test)
  				if (that)
  				{
  					if (asdf)
  						do
  							cdasd;
  						while (as
  								df);
  				}
  				else
  					if (asdf)
  						asdf;
  					else
  						asdf;
  		asdf;
  	}
  }

  {
  	s = "/*"; b = ';'
  		s = "/*"; b = ';';
  	a = b;
  }

  {
  	switch (a)
  	{
  		case a:
  			switch (t)
  			{
  				case 1:
  					cmd;
  					break;
  				case 2:
  					cmd;
  					break;
  			}
  			cmd;
  			break;
  		case b:
  			{
  				int i;
  				cmd;
  			}
  			break;
  		case c: {
  					int i;
  					cmd;
  				}
  		case d: if (cond &&
  						test) {		/* this line doesn't work right */
  					int i;
  					cmd;
  				}
  				break;
  	}
  }

  {
  	if (!(vim_strchr(p_cpo, CPO_BUFOPTGLOB) != NULL && entering) &&
  			(bp_to->b_p_initialized ||
  			 (!entering && vim_strchr(p_cpo, CPO_BUFOPT) != NULL)))
  		return;
  label :
  	asdf = asdf ?
  		asdf : asdf;
  	asdf = asdf ?
  		asdf: asdf;
  }

  /* Special Comments	: This function has the added complexity (compared  */
  /*					: to addtolist) of having to check for a detail     */
  /*					: texture and add that to the list first.	 	    */

  char *(array[100]) = {
  	"testje",
  	"foo",
  	"bar",
  }

  enum soppie
  {
  	yes = 0,
  	no,
  	maybe
  };

  typedef enum soppie
  {
  	yes = 0,
  	no,
  	maybe
  };

  static enum
  {
  	yes = 0,
  	no,
  	maybe
  } soppie;

  public static enum
  {
  	yes = 0,
  	no,
  	maybe
  } soppie;

  static private enum
  {
  	yes = 0,
  	no,
  	maybe
  } soppie;

  {
  	int a,
  		b;
  }

  {
  	struct Type
  	{
  		int i;
  		char *str;
  	} var[] =
  	{
  		0, "zero",
  		1, "one",
  		2, "two",
  		3, "three"
  	};

  	float matrix[3][3] =
  	{
  		{
  			0,
  			1,
  			2
  		},
  		{
  			3,
  			4,
  			5
  		},
  		{
  			6,
  			7,
  			8
  		}
  	};
  }

  {
  	/* blah ( blah */
  	/* where does this go? */

  	/* blah ( blah */
  	cmd;

  	func(arg1,
  			/* comment */
  			arg2);
  	a;
  	{
  		b;
  		{
  			c; /* Hey, NOW it indents?! */
  		}
  	}

  	{
  		func(arg1,
  				arg2,
  				arg3);
  		/* Hey, what am I doing here?  Is this coz of the ","? */
  	}
  }

  main ()
  {
  	if (cond)
  	{
  		a = b;
  	}
  	if (cond) {
  		a = c;
  	}
  	if (cond)
  		a = d;
  	return;
  }

  {
  	case 2: if (asdf &&
  					asdfasdf)
  				aasdf;
  			a = 9;
  	case 3: if (asdf)
  				aasdf;
  			a = 9;
  	case 4:    x = 1;
  			   y = 2;

  label:	if (asdf)
  			here;

  label:  if (asdf &&
  				asdfasdf)
  		{
  		}

  label:  if (asdf &&
  				asdfasdf) {
  			there;
  		}

  label:  if (asdf &&
  				asdfasdf)
  			there;
  }

  {
  	/*
  	   hello with ":set comments= cino=c5"
  	 */

  	/*
  	   hello with ":set comments= cino="
  	 */
  }


  {
  	if (a < b) {
  		a = a + 1;
  	} else
  		a = a + 2;

  	if (a)
  		do {
  			testing;
  		} while (asdfasdf);
  	a = b + 1;
  	asdfasdf
  }

  {
  	for ( int i = 0;
  			i < 10; i++ )
  	{
  	}
  	i = 0;
  }

  class bob
  {
  	int foo() {return 1;}
  	int bar;
  }

  main()
  {
  	while(1)
  		if (foo)
  		{
  			bar;
  		}
  		else {
  			asdf;
  		}
  	misplacedline;
  }

  {
  	if (clipboard.state == SELECT_DONE
  			&& ((row == clipboard.start.lnum
  					&& col >= clipboard.start.col)
  				|| row > clipboard.start.lnum))
  }

  {
  	if (1) {i += 4;}
  	where_am_i;
  	return 0;
  }

  {
  	{
  	} // sdf(asdf
  	if (asdf)
  		asd;
  }

  {
  label1:
  label2:
  }

  {
  	int fooRet = foo(pBar1, false /*fKB*/,
  			true /*fPTB*/, 3 /*nT*/, false /*fDF*/);
  	f() {
  		for ( i = 0;
  				i < m;
  				/* c */ i++ ) {
  			a = b;
  		}
  	}
  }

  {
  	f1(/*comment*/);
  	f2();
  }

  {
  	do {
  		if (foo) {
  		} else
  			;
  	} while (foo);
  	foo();	// was wrong
  }

  int x;	    // no extra indent because of the ;
  void func()
  {
  }

  char *tab[] = {"aaa",
  	"};", /* }; */ NULL}
  	int indented;
  {}

  char *a[] = {"aaa", "bbb",
  	"ccc", NULL};
  // here

  char *tab[] = {"aaa",
  	"xx", /* xx */};    /* asdf */
  int not_indented;

  {
  	do {
  		switch (bla)
  		{
  			case 1: if (foo)
  						bar;
  		}
  	} while (boo);
  	wrong;
  }

  int	foo,
  	bar;
  int foo;

  #if defined(foo) \
  	&& defined(bar)
  char * xx = "asdf\
  			 foo\
  			 bor";
  int x;

  char    *foo = "asdf\
  				asdf\
  				asdf",
  		*bar;

  void f()
  {
  #if defined(foo) \
  	&& defined(bar)
  	char    *foo = "asdf\
  					asdf\
  					asdf",
  			*bar;
  	{
  		int i;
  		char    *foo = "asdf\
  						asdf\
  						asdf",
  				*bar;
  	}
  #endif
  }
  #endif

  int y;		// comment
			// comment

			// comment

  {
  	Constructor(int a,
  			int b )  : BaseClass(a)
  	{
  	}
  }

  void foo()
  {
  	char one,
  		 two;
  	struct bla piet,
  			   jan;
  	enum foo kees,
  			 jannie;
  	static unsigned sdf,
  					krap;
  	unsigned int piet,
  				 jan;
  	int
  		kees,
  		jan;
  }

  {
  	t(int f,
  			int d);		// )
  	d();
  }

  Constructor::Constructor(int a,
  		int b 
  		)  : 
  	BaseClass(a,
  			b,
  			c),
  	mMember(b),
  {
  }

  Constructor::Constructor(int a,
  		int b )  : 
  	BaseClass(a)
  {
  }

  Constructor::Constructor(int a,
  		int b ) /*x*/ : /*x*/ BaseClass(a),
  	member(b)
  {
  }

  A::A(int a, int b)
  	: aa(a),
  	bb(b),
  	cc(c)
  {
  }

  class CAbc :
  	public BaseClass1,
  	protected BaseClass2
  {
  	int Test() { return FALSE; }
  	int Test1() { return TRUE; }

  	CAbc(int a, int b )  : 
  		BaseClass(a)
  	{ 
  		switch(xxx)
  		{
  			case abc:
  				asdf();
  				break;

  			case 999:
  				baer();
  				break;
  		}
  	}

  	public: // <-- this was incorrectly indented before!!
  	void testfall();
  	protected:
  	void testfall();
  };

  class CAbc : public BaseClass1,
  	protected BaseClass2
  {
  };

  static struct
  {
  	int a;
  	int b;
  } variable[COUNT] =
  {
  	{
  		123,
  		456
  	},
  	{
  		123,
  		456
  	}
  };

  static struct
  {
  	int a;
  	int b;
  } variable[COUNT] =
  {
  	{ 123, 456 },
  	{ 123, 456 }
  };

  void asdf()		/* ind_maxparen may cause trouble here */
  {
  	if ((0
  				&& 1
  				&& 1
  				&& 1
  				&& 1
  				&& 1
  				&& 1
  				&& 1
  				&& 1
  				&& 1
  				&& 1
  				&& 1
  				&& 1
  				&& 1
  				&& 1
  				&& 1
  				&& 1
  				&& 1
  				&& 1
  				&& 1
  				&& 1
  				&& 1
  				&& 1
  				&& 1
  				&& 1
  				&& 1)) break;
  }

  foo()
  {
  	a = cond ? foo() : asdf
  		+ asdf;

  	a = cond ?
  		foo() : asdf
  		+ asdf;
  }

  int  main(void)
  {
  	if (a)
  		if (b)
  			2;
  		else 3;
  	next_line_of_code();
  }

  barry()
  {
  	Foo::Foo (int one,
  			int two)
  		: something(4)
  	{}
  }

  barry()
  {
  	Foo::Foo (int one, int two)
  		: something(4)
  	{}
  }

  Constructor::Constructor(int a,
  		int b 
  		)  : 
  	BaseClass(a,
  			b,
  			c),
  	mMember(b)
  {
  }
  int main ()
  {
  	if (lala)
  		do
  			++(*lolo);
  		while (lili
  				&& lele);
  	lulu;
  }

  int main ()
  {
  	switch (c)
  	{
  		case 'c': if (cond)
  				  {
  				  }
  	}
  }

  main()
  {
  	(void) MyFancyFuasdfadsfnction(
  			argument);
  }

  main()
  {
  	char	foo[] = "/*";
  	/* as
  	   df */
  	hello
  }

  /* valid namespaces with normal indent */
  namespace
  {
  	{
  		111111111111;
  	}
  }
  namespace /* test */
  {
  	11111111111111111;
  }
  namespace // test
  {
  	111111111111111111;
  }
  namespace
  {
  	111111111111111111;
  }
  namespace test
  {
  	111111111111111111;
  }
  namespace{
  	111111111111111111;
  }
  namespace test{
  	111111111111111111;
  }
  namespace {
  	111111111111111111;
  }
  namespace test {
  	111111111111111111;
  	namespace test2 {
  		22222222222222222;
  	}
  }
  inline namespace {
  	111111111111111111;
  }
  inline /* test */ namespace {
  	111111111111111111;
  }
  inline/* test */namespace {
  	111111111111111111;
  }

  /* invalid namespaces use block indent */
  namespace test test2 {
  	111111111111111111111;
  }
  namespace11111111111 {
  	111111111111;
  }
  namespace() {
  	1111111111111;
  }
  namespace()
  {
  	111111111111111111;
  }
  namespace test test2
  {
  	1111111111111111111;
  }
  namespace111111111
  {
  	111111111111111111;
  }
  inlinenamespace {
  	111111111111111111;
  }

  void getstring() {
  	/* Raw strings */
  	const char* s = R"(
    test {
      # comment
      field: 123
    }
   )";
  }

  void getstring() {
  	const char* s = R"foo(
    test {
      # comment
      field: 123
    }
      )foo";
  }

  {
  	int a[4] = {
  		[0] = 0,
  		[1] = 1,
  		[2] = 2,
  		[3] = 3,
  	};
  }

  {
  	a = b[2]
  		+ 3;
  }

  {
  	if (1)
  		/* aaaaa
  		 * bbbbb
  		 */
  		a = 1;
  }

  void func()
  {
  	switch (foo)
  	{
  		case (bar):
  			if (baz())
  				quux();
  			break;
  		case (shmoo):
  			if (!bar)
  			{
  			}
  		case (foo1):
  			switch (bar)
  			{
  				case baz:
  					baz_f();
  					break;
  			}
  			break;
  		default:
  			baz();
  			baz();
  			break;
  	}
  }

  /* end of AUTO */

  [CODE]

  assert_equal(expected, getline(1, '$'))

  bwipe!
enddef

def Test_cindent_2()
  new
  setl cindent ts=4 sw=4
  setl tw=0 noai fo=croq
  &wm = &columns - 20

  var code =<< trim [CODE]
    {
  
    /* this is
     * a real serious important big
     * comment
     */
    	/* insert " about life, the universe, and the rest" after "serious" */
    }
  [CODE]

  append(0, code)
  normal gg
  search('serious', 'e')
  normal a about life, the universe, and the rest

  var expected =<< trim [CODE]
  {

  /* this is
   * a real serious
   * about life, the
   * universe, and the
   * rest important big
   * comment
   */
  	/* insert " about life, the universe, and the rest" after "serious" */
  }

  [CODE]

  assert_equal(expected, getline(1, '$'))
  set wm&

  bwipe!
enddef

def Test_cindent_3()
  new
  setl nocindent ts=4 sw=4

  var code =<< trim [CODE]
  {
  	/*
  	 * Testing for comments, without 'cin' set
  	 */

  /*
  * what happens here?
  */

  	/*
  	   the end of the comment, try inserting a line below */

  		/* how about
  		                this one */
  }
  [CODE]

  append(0, code)
  normal gg
  search('comments')
  normal joabout life
  search('happens')
  normal jothere
  search('below')
  normal oline
  search('this')
  normal Ohello

  var expected =<< trim [CODE]
  {
  	/*
  	 * Testing for comments, without 'cin' set
  	 */
  about life

  /*
  * what happens here?
  */
  there

  	/*
  	   the end of the comment, try inserting a line below */
  line

  		/* how about
  hello
  		                this one */
  }

  [CODE]

  assert_equal(expected, getline(1, '$'))

  bwipe!
enddef

def Test_cindent_4()
  new
  setl cindent ts=4 sw=4

  var code =<< trim [CODE]
  {
      var = this + that + vec[0] * vec[0]
  				      + vec[1] * vec[1]
  					  + vec2[2] * vec[2];
  }
  [CODE]

  append(0, code)
  normal gg
  search('vec2')
  normal ==

  var expected =<< trim [CODE]
  {
      var = this + that + vec[0] * vec[0]
  				      + vec[1] * vec[1]
  					  + vec2[2] * vec[2];
  }

  [CODE]

  assert_equal(expected, getline(1, '$'))

  bwipe!
enddef

def Test_cindent_5()
  new
  setl cindent ts=4 sw=4
  setl cino=}4

  var code =<< trim [CODE]
  {
  		asdf asdflkajds f;
  	if (tes & ting) {
  		asdf asdf asdf ;
  		asdfa sdf asdf;
  		}
  	testing1;
  	if (tes & ting)
  	{
  		asdf asdf asdf ;
  		asdfa sdf asdf;
  		}
  	testing2;
  }
  [CODE]

  append(0, code)
  normal gg
  search('testing1')
  exe "normal k2==/testing2\<CR>"
  normal k2==

  var expected =<< trim [CODE]
  {
  		asdf asdflkajds f;
  	if (tes & ting) {
  		asdf asdf asdf ;
  		asdfa sdf asdf;
  		}
  	testing1;
  	if (tes & ting)
  	{
  		asdf asdf asdf ;
  		asdfa sdf asdf;
  		}
  	testing2;
  }

  [CODE]

  assert_equal(expected, getline(1, '$'))

  bwipe!
enddef

def Test_cindent_6()
  new
  setl cindent ts=4 sw=4
  setl cino=(0,)20

  var code =<< trim [CODE]
  main ( int first_par, /*
                         * Comment for
                         * first par
                         */
            int second_par /*
                         * Comment for
                         * second par
                         */
       )
  {
  	func( first_par, /*
                        * Comment for
                        * first par
                        */
      second_par /*
                        * Comment for
                        * second par
                        */
          );

  }
  [CODE]

  append(0, code)
  normal gg
  search('main')
  normal =][

  var expected =<< trim [CODE]
  main ( int first_par, /*
  					   * Comment for
  					   * first par
  					   */
  	   int second_par /*
  					   * Comment for
  					   * second par
  					   */
  	 )
  {
  	func( first_par, /*
  					  * Comment for
  					  * first par
  					  */
  		  second_par /*
  					  * Comment for
  					  * second par
  					  */
  		);

  }

  [CODE]

  assert_equal(expected, getline(1, '$'))

  bwipe!
enddef

def Test_cindent_7()
  new
  setl cindent ts=4 sw=4
  setl cino=es,n0s

  var code =<< trim [CODE]
  main(void)
  {
  	/* Make sure that cino=X0s is not parsed like cino=Xs. */
  	if (cond)
  		foo();
  	else
  	{
  		bar();
  	}
  }
  [CODE]

  append(0, code)
  normal gg
  search('main')
  normal =][

  var expected =<< trim [CODE]
  main(void)
  {
  	/* Make sure that cino=X0s is not parsed like cino=Xs. */
  	if (cond)
  		foo();
  	else
  	{
  		bar();
  	}
  }

  [CODE]
  assert_equal(expected, getline(1, '$'))

  bwipe!
enddef

def Test_cindent_8()
  new
  setl cindent ts=4 sw=4
  setl cino=

  var code =<< trim [CODE]

  {
  	do
  	{
  		if ()
  		{
  			if ()
  				asdf;
  			else
  				asdf;
  		}
  	} while ();
  			cmd;		/* this should go under the } */
  }
  [CODE]

  append(0, code)
  normal gg
  normal ]]=][

  var expected =<< trim [CODE]

  {
  	do
  	{
  		if ()
  		{
  			if ()
  				asdf;
  			else
  				asdf;
  		}
  	} while ();
  	cmd;		/* this should go under the } */
  }

  [CODE]

  assert_equal(expected, getline(1, '$'))

  bwipe!
enddef

def Test_cindent_9()
  new
  setl cindent ts=4 sw=4

  var code =<< trim [CODE]

  void f()
  {
      if ( k() ) {
          l();

      } else { /* Start (two words) end */
          m();
      }

      n();
  }
  [CODE]

  append(0, code)
  normal gg
  normal ]]=][

  var expected =<< trim [CODE]

  void f()
  {
  	if ( k() ) {
  		l();

  	} else { /* Start (two words) end */
  		m();
  	}

  	n();
  }

  [CODE]

  assert_equal(expected, getline(1, '$'))

  bwipe!
enddef

def Test_cindent_10()
  new
  setl cindent ts=4 sw=4
  setl cino={s,e-s

  var code =<< trim [CODE]

  void f()
  {
      if ( k() )
  	{
          l();
      } else { /* Start (two words) end */
          m();
      }
  		n();	/* should be under the if () */
  }
  [CODE]

  append(0, code)
  normal gg
  normal ]]=][

  var expected =<< trim [CODE]

  void f()
  {
  	if ( k() )
  		{
  		l();
  		} else { /* Start (two words) end */
  		m();
  		}
  	n();	/* should be under the if () */
  }

  [CODE]

  assert_equal(expected, getline(1, '$'))

  bwipe!
enddef

def Test_cindent_11()
  new
  setl cindent ts=4 sw=4
  setl cino={s,fs

  var code =<< trim [CODE]
  void bar(void)
  {
  	static array[2][2] =
  	{
  		{ 1, 2 },
  		{ 3, 4 },
  	}

  	while (a)
  	{
  		foo(&a);
  	}

  	{
  		int a;
  		{
  			a = a + 1;
  		}
  	}
  	b = a;
  	}

  void func(void)
  	{
  	a = 1;
  	{
  		b = 2;
  	}
  	c = 3;
  	d = 4;
  	}
  /* foo */
  [CODE]

  append(0, code)
  normal gg
  exe "normal ]]=/ foo\<CR>"

  var expected =<< trim [CODE]
  void bar(void)
  	{
  	static array[2][2] =
  		{
  			{ 1, 2 },
  			{ 3, 4 },
  		}

  	while (a)
  		{
  		foo(&a);
  		}

  		{
  		int a;
  			{
  			a = a + 1;
  			}
  		}
  	b = a;
  	}

  void func(void)
  	{
  	a = 1;
  		{
  		b = 2;
  		}
  	c = 3;
  	d = 4;
  	}
  /* foo */

  [CODE]
  assert_equal(expected, getline(1, '$'))

  bwipe!
enddef

def Test_cindent_12()
  new
  setl cindent ts=4 sw=4
  setl cino=

  var code =<< trim [CODE]
  a()
  {
    do {
      a = a +
        a;
    } while ( a );		/* add text under this line */
      if ( a )
        a;
  }
  [CODE]

  append(0, code)
  normal gg
  search('while')
  normal ohere

  var expected =<< trim [CODE]
  a()
  {
    do {
      a = a +
        a;
    } while ( a );		/* add text under this line */
    here
      if ( a )
        a;
  }

  [CODE]
  assert_equal(expected, getline(1, '$'))

  bwipe!
enddef

def Test_cindent_13()
  new
  setl cindent ts=4 sw=4
  setl cino= com=

  var code =<< trim [CODE]
  a()
  {
  label1:
              /* hmm */
              // comment
  }
  [CODE]

  append(0, code)
  normal gg
  search('comment')
  exe "normal olabel2: b();\rlabel3 /* post */:\r/* pre */ label4:\r"
        .. "f(/*com*/);\rif (/*com*/)\rcmd();"

  var expected =<< trim [CODE]
  a()
  {
  label1:
              /* hmm */
              // comment
  label2: b();
  label3 /* post */:
  /* pre */ label4:
  		f(/*com*/);
  		if (/*com*/)
  			cmd();
  }

  [CODE]
  assert_equal(expected, getline(1, '$'))

  bwipe!
enddef

def Test_cindent_14()
  new
  setl cindent ts=4 sw=4
  setl comments& comments^=s:/*,m:**,ex:*/

  var code =<< trim [CODE]
  /*
    * A simple comment
     */

  /*
    ** A different comment
     */
  [CODE]

  append(0, code)
  normal gg
  search('simple')
  normal =5j

  var expected =<< trim [CODE]
  /*
   * A simple comment
   */

  /*
  ** A different comment
  */

  [CODE]
  assert_equal(expected, getline(1, '$'))

  bwipe!
enddef

def Test_cindent_15()
  new
  setl cindent ts=4 sw=4
  setl cino=c0
  setl comments& comments-=s1:/* comments^=s0:/*

  var code =<< trim [CODE]
  void f()
  {

  	/*********
    A comment.
  *********/
  }
  [CODE]

  append(0, code)
  normal gg
  normal ]]=][

  var expected =<< trim [CODE]
  void f()
  {

  	/*********
  	  A comment.
  	*********/
  }

  [CODE]
  assert_equal(expected, getline(1, '$'))

  bwipe!
enddef

def Test_cindent_16()
  new
  setl cindent ts=4 sw=4
  setl cino=c0,C1
  setl comments& comments-=s1:/* comments^=s0:/*

  var code =<< trim [CODE]
  void f()
  {

  	/*********
    A comment.
  *********/
  }
  [CODE]

  append(0, code)
  normal gg
  normal ]]=][

  var expected =<< trim [CODE]
  void f()
  {

  	/*********
  	A comment.
  	*********/
  }

  [CODE]
  assert_equal(expected, getline(1, '$'))

  bwipe!
enddef

def Test_cindent_17()
  new
  setl cindent ts=4 sw=4
  setl cino=

  var code =<< trim [CODE]
  void f()
  {
  	c = c1 &&
  	(
  	c2 ||
  	c3
  	) && c4;
  }
  [CODE]

  append(0, code)
  normal gg
  normal ]]=][

  var expected =<< trim [CODE]
  void f()
  {
  	c = c1 &&
  		(
  		 c2 ||
  		 c3
  		) && c4;
  }

  [CODE]
  call assert_equal(expected, getline(1, '$'))

  bwipe!
enddef

def Test_cindent_18()
  new
  setl cindent ts=4 sw=4
  setl cino=(s

  var code =<< trim [CODE]
  void f()
  {
  	c = c1 &&
  	(
  	c2 ||
  	c3
  	) && c4;
  }
  [CODE]

  append(0, code)
  normal gg
  normal ]]=][

  var expected =<< trim [CODE]
  void f()
  {
  	c = c1 &&
  		(
  		 c2 ||
  		 c3
  		) && c4;
  }

  [CODE]
  assert_equal(expected, getline(1, '$'))

  bwipe!
enddef

def Test_cindent_19()
  new
  setl cindent ts=4 sw=4
  set cino=(s,U1

  var code =<< trim [CODE]
  void f()
  {
  	c = c1 &&
  	(
  	c2 ||
  	c3
  	) && c4;
  }
  [CODE]

  append(0, code)
  normal gg
  normal ]]=][

  var expected =<< trim [CODE]
  void f()
  {
  	c = c1 &&
  		(
  			c2 ||
  			c3
  		) && c4;
  }

  [CODE]
  assert_equal(expected, getline(1, '$'))

  bwipe!
enddef

def Test_cindent_20()
  new
  setl cindent ts=4 sw=4
  setl cino=(0

  var code =<< trim [CODE]
  void f()
  {
  	if (   c1
  	&& (   c2
  	|| c3))
  	foo;
  }
  [CODE]

  append(0, code)
  normal gg
  normal ]]=][

  var expected =<< trim [CODE]
  void f()
  {
  	if (   c1
  		   && (   c2
  				  || c3))
  		foo;
  }

  [CODE]
  assert_equal(expected, getline(1, '$'))

  bwipe!
enddef

def Test_cindent_21()
  new
  setl cindent ts=4 sw=4
  setl cino=(0,w1

  var code =<< trim [CODE]
  void f()
  {
  	if (   c1
  	&& (   c2
  	|| c3))
  	foo;
  }
  [CODE]

  append(0, code)
  normal gg
  normal ]]=][

  var expected =<< trim [CODE]
  void f()
  {
  	if (   c1
  		&& (   c2
  			|| c3))
  		foo;
  }

  [CODE]
  assert_equal(expected, getline(1, '$'))

  bwipe!
enddef

def Test_cindent_22()
  new
  setl cindent ts=4 sw=4
  setl cino=(s

  var code =<< trim [CODE]
  void f()
  {
  	c = c1 && (
  	c2 ||
  	c3
  	) && c4;
  	if (
  	c1 && c2
  	)
  	foo;
  }
  [CODE]

  append(0, code)
  normal gg
  normal ]]=][

  var expected =<< trim [CODE]
  void f()
  {
  	c = c1 && (
  		c2 ||
  		c3
  		) && c4;
  	if (
  		c1 && c2
  	   )
  		foo;
  }

  [CODE]
  assert_equal(expected, getline(1, '$'))

  bwipe!
enddef

def Test_cindent_23()
  new
  setl cindent ts=4 sw=4
  setl cino=(s,m1

  var code =<< trim [CODE]
  void f()
  {
  	c = c1 && (
  	c2 ||
  	c3
  	) && c4;
  	if (
  	c1 && c2
  	)
  	foo;
  }
  [CODE]

  append(0, code)
  normal gg
  normal ]]=][

  var expected =<< trim [CODE]
  void f()
  {
  	c = c1 && (
  		c2 ||
  		c3
  	) && c4;
  	if (
  		c1 && c2
  	)
  		foo;
  }

  [CODE]
  assert_equal(expected, getline(1, '$'))

  bwipe!
enddef

def Test_cindent_24()
  new
  setl cindent ts=4 sw=4
  setl cino=b1

  var code =<< trim [CODE]
  void f()
  {
  	switch (x)
  	{
  		case 1:
  			a = b;
  			break;
  		default:
  			a = 0;
  			break;
  	}
  }
  [CODE]

  append(0, code)
  normal gg
  normal ]]=][

  var expected =<< trim [CODE]
  void f()
  {
  	switch (x)
  	{
  		case 1:
  			a = b;
  		break;
  		default:
  			a = 0;
  		break;
  	}
  }

  [CODE]
  assert_equal(expected, getline(1, '$'))

  bwipe!
enddef

def Test_cindent_25()
  new
  setl cindent ts=4 sw=4
  setl cino=(0,W5

  var code =<< trim [CODE]
  void f()
  {
  	invokeme(
  	argu,
  	ment);
  	invokeme(
  	argu,
  	ment
  	);
  	invokeme(argu,
  	ment
  	);
  }
  [CODE]

  append(0, code)
  normal gg
  normal ]]=][

  var expected =<< trim [CODE]
  void f()
  {
  	invokeme(
  		 argu,
  		 ment);
  	invokeme(
  		 argu,
  		 ment
  		 );
  	invokeme(argu,
  			 ment
  			);
  }

  [CODE]
  assert_equal(expected, getline(1, '$'))

  bwipe!
enddef

def Test_cindent_26()
  new
  setl cindent ts=4 sw=4
  setl cino=/6

  var code =<< trim [CODE]
  void f()
  {
  	statement;
  		// comment 1
  	// comment 2
  }
  [CODE]

  append(0, code)
  normal gg
  normal ]]=][

  var expected =<< trim [CODE]
  void f()
  {
  	statement;
  		  // comment 1
  		  // comment 2
  }

  [CODE]
  assert_equal(expected, getline(1, '$'))

  bwipe!
enddef

def Test_cindent_27()
  new
  setl cindent ts=4 sw=4
  setl cino=

  var code =<< trim [CODE]
  void f()
  {
  	statement;
  	   // comment 1
  	// comment 2
  }
  [CODE]

  append(0, code)
  normal gg
  exe "normal ]]/comment 1/+1\<CR>=="

  var expected =<< trim [CODE]
  void f()
  {
  	statement;
  	   // comment 1
  	   // comment 2
  }

  [CODE]
  assert_equal(expected, getline(1, '$'))

  bwipe!
enddef

def Test_cindent_28()
  new
  setl cindent ts=4 sw=4
  setl cino=g0

  var code =<< trim [CODE]
  class CAbc
  {
     int Test() { return FALSE; }

  public: // comment
     void testfall();
  protected:
     void testfall();
  };
  [CODE]

  append(0, code)
  normal gg
  normal ]]=][

  var expected =<< trim [CODE]
  class CAbc
  {
  	int Test() { return FALSE; }

  public: // comment
  	void testfall();
  protected:
  	void testfall();
  };

  [CODE]
  assert_equal(expected, getline(1, '$'))

  bwipe!
enddef

def Test_cindent_29()
  new
  setl cindent ts=4 sw=4
  setl cino=(0,gs,hs

  var code =<< trim [CODE]
  class Foo : public Bar
  {
  public:
  virtual void method1(void) = 0;
  virtual void method2(int arg1,
  int arg2,
  int arg3) = 0;
  };
  [CODE]

  append(0, code)
  normal gg
  normal ]]=][

  var expected =<< trim [CODE]
  class Foo : public Bar
  {
  	public:
  		virtual void method1(void) = 0;
  		virtual void method2(int arg1,
  							 int arg2,
  							 int arg3) = 0;
  };

  [CODE]
  assert_equal(expected, getline(1, '$'))

  bwipe!
enddef

def Test_cindent_30()
  new
  setl cindent ts=4 sw=4
  setl cino=+20

  var code =<< [CODE]
	void
foo()
{
	if (a)
	{
	} else
		asdf;
}
[CODE]

  append(0, code)
  normal gg
  normal ]]=][

  var expected =<< [CODE]
	void
foo()
{
	if (a)
	{
	} else
		asdf;
}

[CODE]
  assert_equal(expected, getline(1, '$'))

  bwipe!
enddef

def Test_cindent_31()
  new
  setl cindent ts=4 sw=4
  setl cino=(0,W2s

  var code =<< trim [CODE]

  {
     averylongfunctionnamelongfunctionnameaverylongfunctionname()->asd(
           asdasdf,
           func(asdf,
                asdfadsf),
           asdfasdf
           );

     /* those are ugly, but consequent */

     func()->asd(asdasdf,
                 averylongfunctionname(
                       abc,
                       dec)->averylongfunctionname(
                             asdfadsf,
                             asdfasdf,
                             asdfasdf,
                             ),
                 func(asdfadf,
                      asdfasdf
                     ),
                 asdasdf
                );

     averylongfunctionnameaverylongfunctionnameavery()->asd(fasdf(
                 abc,
                 dec)->asdfasdfasdf(
                       asdfadsf,
                       asdfasdf,
                       asdfasdf,
                       ),
           func(asdfadf,
                asdfasdf),
           asdasdf
           );
  }
  [CODE]

  append(0, code)
  normal gg
  normal ]]=][

  var expected =<< trim [CODE]

  {
  	averylongfunctionnamelongfunctionnameaverylongfunctionname()->asd(
  			asdasdf,
  			func(asdf,
  				 asdfadsf),
  			asdfasdf
  			);

  	/* those are ugly, but consequent */

  	func()->asd(asdasdf,
  				averylongfunctionname(
  						abc,
  						dec)->averylongfunctionname(
  								asdfadsf,
  								asdfasdf,
  								asdfasdf,
  								),
  				func(asdfadf,
  					 asdfasdf
  					),
  				asdasdf
  			   );

  	averylongfunctionnameaverylongfunctionnameavery()->asd(fasdf(
  					abc,
  					dec)->asdfasdfasdf(
  							asdfadsf,
  							asdfasdf,
  							asdfasdf,
  							),
  			func(asdfadf,
  				 asdfasdf),
  			asdasdf
  			);
  }

  [CODE]
  assert_equal(expected, getline(1, '$'))

  bwipe!
enddef

def Test_cindent_32()
  new
  setl cindent ts=4 sw=4
  setl cino=M1

  var code =<< trim [CODE]
  int main ()
  {
  	if (cond1 &&
  			cond2
  			)
  		foo;
  }
  [CODE]

  append(0, code)
  normal gg
  normal ]]=][

  var expected =<< trim [CODE]
  int main ()
  {
  	if (cond1 &&
  			cond2
  			)
  		foo;
  }

  [CODE]
  assert_equal(expected, getline(1, '$'))

  bwipe!
enddef

def Test_cindent_33()
  new
  setl cindent ts=4 sw=4
  setl cino=(0,ts

  var code =<< trim [CODE]
  void func(int a
  #if defined(FOO)
  		  , int b
  		  , int c
  #endif
  		 )
  {
  }
  [CODE]

  append(0, code)
  normal gg
  normal 2j=][

  var expected =<< trim [CODE]
  void func(int a
  #if defined(FOO)
  		  , int b
  		  , int c
  #endif
  		 )
  {
  }

  [CODE]
  assert_equal(expected, getline(1, '$'))

  bwipe!
enddef

def Test_cindent_34()
  new
  setl cindent ts=4 sw=4
  setl cino=(0

  var code =<< trim [CODE]

  void
  func(int a
  #if defined(FOO)
  		  , int b
  		  , int c
  #endif
  		 )
  {
  }
  [CODE]

  append(0, code)
  normal gg
  normal =][

  var expected =<< trim [CODE]
  
  	void
  func(int a
  #if defined(FOO)
  	 , int b
  	 , int c
  #endif
  	)
  {
  }

  [CODE]
  assert_equal(expected, getline(1, '$'))

  bwipe!
enddef

def Test_cindent_35()
  new
  setl cindent ts=4 sw=4
  setl cino&

  var code =<< trim [CODE]
  void func(void)
  {
  	if(x==y)
  		if(y==z)
  			foo=1;
  		else { bar=1;
  			baz=2;
  		}
  	printf("Foo!\n");
  }

  void func1(void)
  {
  	char* tab[] = {"foo", "bar",
  		"baz", "quux",
  			"this line used", "to be indented incorrectly"};
  	foo();
  }

  void func2(void)
  {
  	int tab[] =
  	{1, 2,
  		3, 4,
  		5, 6};

  		printf("This line used to be indented incorrectly.\n");
  }

  int foo[]
  #ifdef BAR

  = { 1, 2, 3,
  	4, 5, 6 }

  #endif
  ;
  	int baz;

  void func3(void)
  {
  	int tab[] = {
  	1, 2,
  	3, 4,
  	5, 6};

  printf("Don't you dare indent this line incorrectly!\n");
  }

  void
  func4(a, b,
  		c)
  int a;
  int b;
  int c;
  {
  }

  void
  func5(
  		int a,
  		int b)
  {
  }

  void
  func6(
  		int a)
  {
  }
  [CODE]

  append(0, code)
  normal gg
  normal ]]=7][

  var expected =<< trim [CODE]
  void func(void)
  {
  	if(x==y)
  		if(y==z)
  			foo=1;
  		else { bar=1;
  			baz=2;
  		}
  	printf("Foo!\n");
  }

  void func1(void)
  {
  	char* tab[] = {"foo", "bar",
  		"baz", "quux",
  		"this line used", "to be indented incorrectly"};
  	foo();
  }

  void func2(void)
  {
  	int tab[] =
  	{1, 2,
  		3, 4,
  		5, 6};

  	printf("This line used to be indented incorrectly.\n");
  }

  int foo[]
  #ifdef BAR

  = { 1, 2, 3,
  	4, 5, 6 }

  #endif
  	;
  int baz;

  void func3(void)
  {
  	int tab[] = {
  		1, 2,
  		3, 4,
  		5, 6};

  	printf("Don't you dare indent this line incorrectly!\n");
  }

  	void
  func4(a, b,
  		c)
  	int a;
  	int b;
  	int c;
  {
  }

  	void
  func5(
  		int a,
  		int b)
  {
  }

  	void
  func6(
  		int a)
  {
  }

  [CODE]
  assert_equal(expected, getline(1, '$'))

  bwipe!
enddef

def Test_cindent_36()
  new
  setl cindent ts=4 sw=4
  setl cino&
  setl cino+=l1

  var code =<< trim [CODE]
  void func(void)
  {
  	int tab[] =
  	{
  		1, 2, 3,
  		4, 5, 6};

  	printf("Indent this line correctly!\n");

  	switch (foo)
  	{
  		case bar:
  			printf("bar");
  			break;
  		case baz: {
  			printf("baz");
  			break;
  		}
  		case quux:
  printf("But don't break the indentation of this instruction\n");
  break;
  	}
  }
  [CODE]

  append(0, code)
  normal gg
  normal ]]=][

  var expected =<< trim [CODE]
  void func(void)
  {
  	int tab[] =
  	{
  		1, 2, 3,
  		4, 5, 6};

  	printf("Indent this line correctly!\n");

  	switch (foo)
  	{
  		case bar:
  			printf("bar");
  			break;
  		case baz: {
  			printf("baz");
  			break;
  		}
  		case quux:
  			printf("But don't break the indentation of this instruction\n");
  			break;
  	}
  }

  [CODE]
  assert_equal(expected, getline(1, '$'))

  bwipe!
enddef

def Test_cindent_37()
  new
  setl cindent ts=4 sw=4
  setl cino&

  var code =<< trim [CODE]
  void func(void)
  {
  	cout << "a"
  	<< "b"
  	<< ") :"
  	<< "c";
  }
  [CODE]

  append(0, code)
  normal gg
  normal ]]=][

  var expected =<< trim [CODE]
  void func(void)
  {
  	cout << "a"
  		<< "b"
  		<< ") :"
  		<< "c";
  }

  [CODE]
  assert_equal(expected, getline(1, '$'))

  bwipe!
enddef

def Test_cindent_38()
  new
  setl cindent ts=4 sw=4
  setl com=s1:/*,m:*,ex:*/

  var code =<< trim [CODE]
  void func(void)
  {
  	/*
  	 * This is a comment.
  	 */
  }
  [CODE]

  append(0, code)
  normal gg
  normal ]]3jofoo();

  var expected =<< trim [CODE]
  void func(void)
  {
  	/*
  	 * This is a comment.
  	 */
  	foo();
  }

  [CODE]
  assert_equal(expected, getline(1, '$'))

  bwipe!
enddef

def Test_cindent_39()
  new
  setl cindent ts=4 sw=4
  setl cino&

  var code =<< trim [CODE]
  void func(void)
  {
  	for (int i = 0; i < 10; ++i)
  		if (i & 1) {
  			foo(1);
  		} else
  			foo(0);
  baz();
  }
  [CODE]

  append(0, code)
  normal gg
  normal ]]=][

  var expected =<< trim [CODE]
  void func(void)
  {
  	for (int i = 0; i < 10; ++i)
  		if (i & 1) {
  			foo(1);
  		} else
  			foo(0);
  	baz();
  }

  [CODE]
  assert_equal(expected, getline(1, '$'))

  bwipe!
enddef

def Test_cindent_40()
  new
  setl cindent ts=4 sw=4
  setl cino=k2s,(0

  var code =<< trim [CODE]
  void func(void)
  {
  	if (condition1
  	&& condition2)
  	action();
  	function(argument1
  	&& argument2);

  	if (c1 && (c2 ||
  	c3))
  	foo;
  	if (c1 &&
  	(c2 || c3))
  	{
  	}

  	if (   c1
  	&& (      c2
  	|| c3))
  	foo;
  	func( c1
  	&& (     c2
  	|| c3))
  	foo;
  }
  [CODE]

  append(0, code)
  normal gg
  normal ]]=][

  var expected =<< trim [CODE]
  void func(void)
  {
  	if (condition1
  			&& condition2)
  		action();
  	function(argument1
  			 && argument2);

  	if (c1 && (c2 ||
  				c3))
  		foo;
  	if (c1 &&
  			(c2 || c3))
  	{
  	}

  	if (   c1
  			&& (      c2
  					  || c3))
  		foo;
  	func( c1
  		  && (     c2
  				   || c3))
  		foo;
  }

  [CODE]
  assert_equal(expected, getline(1, '$'))

  bwipe!
enddef

def Test_cindent_41()
  new
  setl cindent ts=4 sw=4
  setl cino=k2s,(s

  var code =<< trim [CODE]
  void func(void)
  {
  	if (condition1
  	&& condition2)
  	action();
  	function(argument1
  	&& argument2);

  	if (c1 && (c2 ||
  	c3))
  	foo;
  	if (c1 &&
  	(c2 || c3))
  	{
  	}

  	if (   c1
  	&& (      c2
  	|| c3))
  	foo;
  	func(   c1
  	&& (      c2
  	|| c3))
  	foo;
  }
  [CODE]

  append(0, code)
  normal gg
  normal ]]=][

  var expected =<< trim [CODE]
  void func(void)
  {
  	if (condition1
  			&& condition2)
  		action();
  	function(argument1
  		&& argument2);

  	if (c1 && (c2 ||
  				c3))
  		foo;
  	if (c1 &&
  			(c2 || c3))
  	{
  	}

  	if (   c1
  			&& (      c2
  				|| c3))
  		foo;
  	func(   c1
  		&& (      c2
  			|| c3))
  		foo;
  }

  [CODE]
  assert_equal(expected, getline(1, '$'))

  bwipe!
enddef

def Test_cindent_42()
  new
  setl cindent ts=4 sw=4
  setl cino=k2s,(s,U1

  var code =<< trim [CODE]
  void func(void)
  {
  	if (condition1
  	&& condition2)
  	action();
  	function(argument1
  	&& argument2);

  	if (c1 && (c2 ||
  	c3))
  	foo;
  	if (c1 &&
  	(c2 || c3))
  	{
  	}
  	if (c123456789
  	&& (c22345
  	|| c3))
  	printf("foo\n");

  	c = c1 &&
  	(
  	c2 ||
  	c3
  	) && c4;
  }
  [CODE]

  append(0, code)
  normal gg
  normal ]]=][

  var expected =<< trim [CODE]
  void func(void)
  {
  	if (condition1
  			&& condition2)
  		action();
  	function(argument1
  		&& argument2);

  	if (c1 && (c2 ||
  				c3))
  		foo;
  	if (c1 &&
  			(c2 || c3))
  	{
  	}
  	if (c123456789
  			&& (c22345
  				|| c3))
  		printf("foo\n");

  	c = c1 &&
  		(
  			c2 ||
  			c3
  		) && c4;
  }

  [CODE]
  assert_equal(expected, getline(1, '$'))

  bwipe!
enddef

def Test_cindent_43()
  new
  setl cindent ts=4 sw=4
  setl cino=k2s,(0,W4

  var code =<< trim [CODE]
  void func(void)
  {
  	if (condition1
  	&& condition2)
  	action();
  	function(argument1
  	&& argument2);

  	if (c1 && (c2 ||
  	c3))
  	foo;
  	if (c1 &&
  	(c2 || c3))
  	{
  	}
  	if (c123456789
  	&& (c22345
  	|| c3))
  	printf("foo\n");

  	if (   c1
  	&& (   c2
  	|| c3))
  	foo;

  	a_long_line(
  	argument,
  	argument);
  	a_short_line(argument,
  	argument);
  }
  [CODE]

  append(0, code)
  normal gg
  normal ]]=][

  var expected =<< trim [CODE]
  void func(void)
  {
  	if (condition1
  			&& condition2)
  		action();
  	function(argument1
  			 && argument2);

  	if (c1 && (c2 ||
  				c3))
  		foo;
  	if (c1 &&
  			(c2 || c3))
  	{
  	}
  	if (c123456789
  			&& (c22345
  				|| c3))
  		printf("foo\n");

  	if (   c1
  			&& (   c2
  				   || c3))
  		foo;

  	a_long_line(
  		argument,
  		argument);
  	a_short_line(argument,
  				 argument);
  }

  [CODE]
  assert_equal(expected, getline(1, '$'))

  bwipe!
enddef

def Test_cindent_44()
  new
  setl cindent ts=4 sw=4
  setl cino=k2s,u2

  var code =<< trim [CODE]
  void func(void)
  {
  	if (condition1
  	&& condition2)
  	action();
  	function(argument1
  	&& argument2);

  	if (c1 && (c2 ||
  	c3))
  	foo;
  	if (c1 &&
  	(c2 || c3))
  	{
  	}
  	if (c123456789
  	&& (c22345
  	|| c3))
  	printf("foo\n");
  }
  [CODE]

  append(0, code)
  normal gg
  normal ]]=][

  var expected =<< trim [CODE]
  void func(void)
  {
  	if (condition1
  			&& condition2)
  		action();
  	function(argument1
  			&& argument2);

  	if (c1 && (c2 ||
  			  c3))
  		foo;
  	if (c1 &&
  			(c2 || c3))
  	{
  	}
  	if (c123456789
  			&& (c22345
  			  || c3))
  		printf("foo\n");
  }

  [CODE]
  assert_equal(expected, getline(1, '$'))

  bwipe!
enddef

def Test_cindent_45()
  new
  setl cindent ts=4 sw=4
  setl cino=k2s,(0,w1

  var code =<< trim [CODE]
  void func(void)
  {
  	if (condition1
  	&& condition2)
  	action();
  	function(argument1
  	&& argument2);

  	if (c1 && (c2 ||
  	c3))
  	foo;
  	if (c1 &&
  	(c2 || c3))
  	{
  	}
  	if (c123456789
  	&& (c22345
  	|| c3))
  	printf("foo\n");

  	if (   c1
  	&& (      c2
  	|| c3))
  	foo;
  	func(   c1
  	&& (      c2
  	|| c3))
  	foo;
  }
  [CODE]

  append(0, code)
  normal gg
  normal ]]=][

  var expected =<< trim [CODE]
  void func(void)
  {
  	if (condition1
  			&& condition2)
  		action();
  	function(argument1
  			 && argument2);

  	if (c1 && (c2 ||
  				c3))
  		foo;
  	if (c1 &&
  			(c2 || c3))
  	{
  	}
  	if (c123456789
  			&& (c22345
  				|| c3))
  		printf("foo\n");

  	if (   c1
  			&& (      c2
  				|| c3))
  		foo;
  	func(   c1
  		 && (      c2
  			 || c3))
  		foo;
  }

  [CODE]
  assert_equal(expected, getline(1, '$'))

  bwipe!
enddef

def Test_cindent_46()
  new
  setl cindent ts=4 sw=4
  setl cino=k2,(s

  var code =<< trim [CODE]
  void func(void)
  {
  	if (condition1
  	  && condition2)
  		action();
  	function(argument1
  		&& argument2);

  	if (c1 && (c2 ||
  		  c3))
  		foo;
  	if (c1 &&
  	  (c2 || c3))
  	{
  	}
  }
  [CODE]

  append(0, code)
  normal gg
  normal ]]=][

  var expected =<< trim [CODE]
  void func(void)
  {
  	if (condition1
  	  && condition2)
  		action();
  	function(argument1
  		&& argument2);

  	if (c1 && (c2 ||
  		  c3))
  		foo;
  	if (c1 &&
  	  (c2 || c3))
  	{
  	}
  }

  [CODE]
  assert_equal(expected, getline(1, '$'))

  bwipe!
enddef

def Test_cindent_47()
  new
  setl cindent ts=4 sw=4
  setl cino=N-s

  var code =<< trim [CODE]
  NAMESPACESTART
  /* valid namespaces with normal indent */
  namespace
  {
     {
  	111111111111;
  }
  }
  namespace /* test */
  {
    11111111111111111;
  }
  namespace // test
  {
    111111111111111111;
  }
  namespace
  {
    111111111111111111;
  }
  namespace test
  {
    111111111111111111;
  }
  namespace test::cpp17
  {
    111111111111111111;
  }
  namespace ::incorrectcpp17
  {
    111111111111111111;
  }
  namespace test::incorrectcpp17::
  {
    111111111111111111;
  }
  namespace test:incorrectcpp17
  {
    111111111111111111;
  }
  namespace test:::incorrectcpp17
  {
    111111111111111111;
  }
  namespace{
    111111111111111111;
  }
  namespace test{
    111111111111111111;
  }
  namespace {
    111111111111111111;
  }
  namespace test {
    111111111111111111;
  namespace test2 {
    22222222222222222;
  }
  }
  inline namespace {
    111111111111111111;
  }
  inline /* test */ namespace {
    111111111111111111;
  }
  inline/* test */namespace {
    111111111111111111;
  }
  export namespace {
    111111111111111111;
  }
  export inline namespace {
    111111111111111111;
  }
  export/* test */inline namespace {
    111111111111111111;
  }
  inline export namespace {
    111111111111111111;
  }

  /* invalid namespaces use block indent */
  namespace test test2 {
    111111111111111111111;
  }
  namespace11111111111 {
    111111111111;
  }
  namespace() {
    1111111111111;
  }
  namespace()
  {
    111111111111111111;
  }
  namespace test test2
  {
    1111111111111111111;
  }
  namespace111111111
  {
    111111111111111111;
  }
  inlinenamespace {
    111111111111111111;
  }
  NAMESPACEEND
  [CODE]

  append(0, code)
  normal gg
  call search('^NAMESPACESTART')
  exe "normal =/^NAMESPACEEND\n"

  var expected =<< trim [CODE]
  NAMESPACESTART
  /* valid namespaces with normal indent */
  namespace
  {
  {
  	111111111111;
  }
  }
  namespace /* test */
  {
  11111111111111111;
  }
  namespace // test
  {
  111111111111111111;
  }
  namespace
  {
  111111111111111111;
  }
  namespace test
  {
  111111111111111111;
  }
  namespace test::cpp17
  {
  111111111111111111;
  }
  namespace ::incorrectcpp17
  {
  	111111111111111111;
  }
  namespace test::incorrectcpp17::
  {
  	111111111111111111;
  }
  namespace test:incorrectcpp17
  {
  	111111111111111111;
  }
  namespace test:::incorrectcpp17
  {
  	111111111111111111;
  }
  namespace{
  111111111111111111;
  }
  namespace test{
  111111111111111111;
  }
  namespace {
  111111111111111111;
  }
  namespace test {
  111111111111111111;
  namespace test2 {
  22222222222222222;
  }
  }
  inline namespace {
  111111111111111111;
  }
  inline /* test */ namespace {
  111111111111111111;
  }
  inline/* test */namespace {
  111111111111111111;
  }
  export namespace {
  111111111111111111;
  }
  export inline namespace {
  111111111111111111;
  }
  export/* test */inline namespace {
  111111111111111111;
  }
  inline export namespace {
  111111111111111111;
  }

  /* invalid namespaces use block indent */
  namespace test test2 {
  	111111111111111111111;
  }
  namespace11111111111 {
  	111111111111;
  }
  namespace() {
  	1111111111111;
  }
  namespace()
  {
  	111111111111111111;
  }
  namespace test test2
  {
  	1111111111111111111;
  }
  namespace111111111
  {
  	111111111111111111;
  }
  inlinenamespace {
  	111111111111111111;
  }
  NAMESPACEEND

  [CODE]
  assert_equal(expected, getline(1, '$'))

  bwipe!
enddef

def Test_cindent_48()
  new
  setl cindent ts=4 sw=4
  setl cino=j1,J1

  var code =<< trim [CODE]
  JSSTART
  var bar = {
  foo: {
  that: this,
  some: ok,
  },
  "bar":{
  a : 2,
  b: "123abc",
  x: 4,
  "y": 5
  }
  }
  JSEND
  [CODE]

  append(0, code)
  normal gg
  search('^JSSTART')
  exe "normal =/^JSEND\n"

  var expected =<< trim [CODE]
  JSSTART
  var bar = {
  	foo: {
  		that: this,
  		some: ok,
  	},
  	"bar":{
  		a : 2,
  		b: "123abc",
  		x: 4,
  		"y": 5
  	}
  }
  JSEND

  [CODE]
  assert_equal(expected, getline(1, '$'))

  bwipe!
enddef

def Test_cindent_49()
  new
  setl cindent ts=4 sw=4
  setl cino=j1,J1

  var code =<< trim [CODE]
  JSSTART
  var foo = [
  1,
  2,
  3
  ];
  JSEND
  [CODE]

  append(0, code)
  normal gg
  search('^JSSTART')
  exe "normal =/^JSEND\n"

  var expected =<< trim [CODE]
  JSSTART
  var foo = [
  	1,
  	2,
  	3
  ];
  JSEND

  [CODE]
  assert_equal(expected, getline(1, '$'))

  bwipe!
enddef

def Test_cindent_50()
  new
  setl cindent ts=4 sw=4
  setl cino=j1,J1

  var code =<< trim [CODE]
  JSSTART
  function bar() {
  var foo = [
  1,
  2,
  3
  ];
  }
  JSEND
  [CODE]

  append(0, code)
  normal gg
  search('^JSSTART')
  exe "normal =/^JSEND\n"

  var expected =<< trim [CODE]
  JSSTART
  function bar() {
  	var foo = [
  		1,
  		2,
  		3
  	];
  }
  JSEND

  [CODE]
  assert_equal(expected, getline(1, '$'))

  bwipe!
enddef

def Test_cindent_51()
  new
  setl cindent ts=4 sw=4
  setl cino=j1,J1

  var code =<< trim [CODE]
  JSSTART
  (function($){

  if (cond &&
  cond) {
  stmt;
  }
  window.something.left =
  (width - 50 + offset) + "px";
  var class_name='myclass';

  function private_method() {
  }

  var public_method={
  method: function(options,args){
  private_method();
  }
  }

  function init(options) {

  $(this).data(class_name+'_public',$.extend({},{
  foo: 'bar',
  bar: 2,
  foobar: [
  1,
  2,
  3
  ],
  callback: function(){
  return true;
  }
  }, options||{}));
  }

  $.fn[class_name]=function() {

  var _arguments=arguments;
  return this.each(function(){

  var options=$(this).data(class_name+'_public');
  if (!options) {
  init.apply(this,_arguments);

  } else {
  var method=public_method[_arguments[0]];

  if (typeof(method)!='function') {
  console.log(class_name+' has no method "'+_arguments[0]+'"');
  return false;
  }
  _arguments[0]=options;
  method.apply(this,_arguments);
  }
  });
  }

  })(jQuery);
  JSEND
  [CODE]

  append(0, code)
  normal gg
  search('^JSSTART')
  exe "normal =/^JSEND\n"

  var expected =<< trim [CODE]
  JSSTART
  (function($){

  	if (cond &&
  			cond) {
  		stmt;
  	}
  	window.something.left =
  		(width - 50 + offset) + "px";
  	var class_name='myclass';

  	function private_method() {
  	}

  	var public_method={
  		method: function(options,args){
  			private_method();
  		}
  	}

  	function init(options) {

  		$(this).data(class_name+'_public',$.extend({},{
  			foo: 'bar',
  			bar: 2,
  			foobar: [
  				1,
  				2,
  				3
  			],
  			callback: function(){
  				return true;
  			}
  		}, options||{}));
  	}

  	$.fn[class_name]=function() {

  		var _arguments=arguments;
  		return this.each(function(){

  			var options=$(this).data(class_name+'_public');
  			if (!options) {
  				init.apply(this,_arguments);

  			} else {
  				var method=public_method[_arguments[0]];

  				if (typeof(method)!='function') {
  					console.log(class_name+' has no method "'+_arguments[0]+'"');
  					return false;
  				}
  				_arguments[0]=options;
  				method.apply(this,_arguments);
  			}
  		});
  	}

  })(jQuery);
  JSEND

  [CODE]
  assert_equal(expected, getline(1, '$'))

  bwipe!
enddef

def Test_cindent_52()
  new
  setl cindent ts=4 sw=4
  setl cino=j1,J1

  var code =<< trim [CODE]
  JSSTART
  function init(options) {
  $(this).data(class_name+'_public',$.extend({},{
  foo: 'bar',
  bar: 2,
  foobar: [
  1,
  2,
  3
  ],
  callback: function(){
  return true;
  }
  }, options||{}));
  }
  JSEND
  [CODE]

  append(0, code)
  normal gg
  search('^JSSTART')
  exe "normal =/^JSEND\n"

  var expected =<< trim [CODE]
  JSSTART
  function init(options) {
  	$(this).data(class_name+'_public',$.extend({},{
  		foo: 'bar',
  		bar: 2,
  		foobar: [
  			1,
  			2,
  			3
  		],
  		callback: function(){
  			return true;
  		}
  	}, options||{}));
  }
  JSEND

  [CODE]
  assert_equal(expected, getline(1, '$'))

  bwipe!
enddef

def Test_cindent_53()
  new
  setl cindent ts=4 sw=4
  setl cino=j1,J1

  var code =<< trim [CODE]
  JSSTART
  (function($){
  function init(options) {
  $(this).data(class_name+'_public',$.extend({},{
  foo: 'bar',
  bar: 2,
  foobar: [
  1,
  2,
  3
  ],
  callback: function(){
  return true;
  }
  }, options||{}));
  }
  })(jQuery);
  JSEND
  [CODE]

  append(0, code)
  normal gg
  search('^JSSTART')
  exe "normal =/^JSEND\n"

  var expected =<< trim [CODE]
  JSSTART
  (function($){
  	function init(options) {
  		$(this).data(class_name+'_public',$.extend({},{
  			foo: 'bar',
  			bar: 2,
  			foobar: [
  				1,
  				2,
  				3
  			],
  			callback: function(){
  				return true;
  			}
  		}, options||{}));
  	}
  })(jQuery);
  JSEND

  [CODE]
  assert_equal(expected, getline(1, '$'))

  bwipe!
enddef

def Test_cindent_54()
  new
  setl cindent ts=4 sw=4
  setl cino=j1,J1,+2

  var code =<< trim [CODE]
  JSSTART
  // Results of JavaScript indent
  // 1
  (function(){
  var a = [
  'a',
  'b',
  'c',
  'd',
  'e',
  'f',
  'g',
  'h',
  'i'
  ];
  }())

  // 2
  (function(){
  var a = [
  0 +
  5 *
  9 *
  'a',
  'b',
  0 +
  5 *
  9 *
  'c',
  'd',
  'e',
  'f',
  'g',
  'h',
  'i'
  ];
  }())

  // 3
  (function(){
  var a = [
  0 +
  // comment 1
  5 *
  /* comment 2 */
  9 *
  'a',
  'b',
  0 +
  5 *
  9 *
  'c',
  'd',
  'e',
  'f',
  'g',
  'h',
  'i'
  ];
  }())

  // 4
  {
  var a = [
  0,
  1
  ];
  var b;
  var c;
  }

  // 5
  {
  var a = [
  [
  0
  ],
  2,
  3
  ];
  }

  // 6
  {
  var a = [
  [
  0,
  1
  ],
  2,
  3
  ];
  }

  // 7
  {
  var a = [
  // [
  0,
  // 1
  // ],
  2,
  3
  ];
  }

  // 8
  var x = [
  (function(){
  var a,
  b,
  c,
  d,
  e,
  f,
  g,
  h,
  i;
  })
  ];

  // 9
  var a = [
  0 +
  5 *
  9 *
  'a',
  'b',
  0 +
  5 *
  9 *
  'c',
  'd',
  'e',
  'f',
  'g',
  'h',
  'i'
  ];

  // 10
  var a,
  b,
  c,
  d,
  e,
  f,
  g,
  h,
  i;
  JSEND
  [CODE]

  append(0, code)
  normal gg
  search('^JSSTART')
  exe "normal =/^JSEND\n"

  var expected =<< trim [CODE]
  JSSTART
  // Results of JavaScript indent
  // 1
  (function(){
  	var a = [
  	  'a',
  	  'b',
  	  'c',
  	  'd',
  	  'e',
  	  'f',
  	  'g',
  	  'h',
  	  'i'
  	];
  }())

  // 2
  (function(){
  	var a = [
  	  0 +
  		5 *
  		9 *
  		'a',
  	  'b',
  	  0 +
  		5 *
  		9 *
  		'c',
  	  'd',
  	  'e',
  	  'f',
  	  'g',
  	  'h',
  	  'i'
  	];
  }())

  // 3
  (function(){
  	var a = [
  	  0 +
  		// comment 1
  		5 *
  		/* comment 2 */
  		9 *
  		'a',
  	  'b',
  	  0 +
  		5 *
  		9 *
  		'c',
  	  'd',
  	  'e',
  	  'f',
  	  'g',
  	  'h',
  	  'i'
  	];
  }())

  // 4
  {
  	var a = [
  	  0,
  	  1
  	];
  	var b;
  	var c;
  }

  // 5
  {
  	var a = [
  	  [
  		0
  	  ],
  	  2,
  	  3
  	];
  }

  // 6
  {
  	var a = [
  	  [
  		0,
  		1
  	  ],
  	  2,
  	  3
  	];
  }

  // 7
  {
  	var a = [
  	  // [
  	  0,
  	  // 1
  	  // ],
  	  2,
  	  3
  	];
  }

  // 8
  var x = [
    (function(){
  	  var a,
  	  b,
  	  c,
  	  d,
  	  e,
  	  f,
  	  g,
  	  h,
  	  i;
    })
  ];

  // 9
  var a = [
    0 +
    5 *
    9 *
    'a',
    'b',
    0 +
    5 *
    9 *
    'c',
    'd',
    'e',
    'f',
    'g',
    'h',
    'i'
  ];

  // 10
  var a,
  	b,
  	c,
  	d,
  	e,
  	f,
  	g,
  	h,
  	i;
  JSEND

  [CODE]
  assert_equal(expected, getline(1, '$'))

  bwipe!
enddef

def Test_cindent_55()
  new
  setl cindent ts=4 sw=4
  setl cino&

  var code =<< trim [CODE]
  /* start of define */
  {
  }
  #define AAA \
  BBB\
  CCC

  #define CNT \
  1 + \
  2 + \
  4
  /* end of define */
  [CODE]

  append(0, code)
  normal gg
  search('start of define')
  exe "normal =/end of define\n"

  var expected =<< trim [CODE]
  /* start of define */
  {
  }
  #define AAA \
  	BBB\
  	CCC

  #define CNT \
  	1 + \
  	2 + \
  	4
  /* end of define */

  [CODE]
  assert_equal(expected, getline(1, '$'))

  bwipe!
enddef

def Test_cindent_56()
  new
  setl cindent ts=4 sw=4
  setl cino&

  var code =<< trim [CODE]
  {
  	a = second/*bug*/*line;
  }
  [CODE]

  append(0, code)
  normal gg
  search('a = second')
  normal ox

  var expected =<< trim [CODE]
  {
  	a = second/*bug*/*line;
  	x
  }

  [CODE]
  assert_equal(expected, getline(1, '$'))

  bwipe!
enddef

" this was going beyond the end of the line.
def Test_cindent_case()
  new
  setline(1, 'case x: // x')
  set cindent
  norm! f:a:
  assert_equal('case x:: // x', getline(1))
  set cindent&
  bwipe!
enddef

" Test for changing multiple lines (using c) with cindent
def Test_cindent_change_multline()
  new
  setlocal cindent
  setline(1, ['if (a)', '{', '    i = 1;', '}'])
  normal! jc3jm = 2;
  assert_equal("\tm = 2;", getline(2))
  bwipe!
enddef

" This was reading past the end of the line
def Test_cindent_check_funcdecl()
  new
  sil norm o0('\0=L
  bwipe!
enddef

def Test_cindent_scopedecls()
  new
  setl cindent ts=4 sw=4
  setl cino=g0
  setl cinsd+=public\ slots,signals

  var code =<< trim [CODE]
  class Foo
  {
  public:
  virtual void foo() = 0;
  public slots:
  void onBar();
  signals:
  void baz();
  private:
  int x;
  };
  [CODE]

  append(0, code)
  normal gg
  normal ]]=][

  var expected =<< trim [CODE]
  class Foo
  {
  public:
	virtual void foo() = 0;
  public slots:
	void onBar();
  signals:
	void baz();
  private:
	int x;
  };

  [CODE]
  assert_equal(expected, getline(1, '$'))

  bwipe!
enddef

def Test_cindent_pragma()
  new
  setl cindent ts=4 sw=4
  setl cino=Ps

  var code =<< trim [CODE]
  {
  #pragma omp parallel
  {
  #pragma omp task
  foo();
  # pragma omp taskwait
  }
  }
  [CODE]

  append(0, code)
  normal gg
  normal =G

  var expected =<< trim [CODE]
  {
	#pragma omp parallel
	{
		#pragma omp task
		foo();
		# pragma omp taskwait
	}
  }

  [CODE]
  assert_equal(expected, getline(1, '$'))

  bwipe!
enddef

def Test_backslash_at_end_of_line()
  new
  exe "norm v>O'\\\<C-m>-"
  exe "norm \<C-q>="
  bwipe!
enddef

def Test_find_brace_backwards()
  # this was looking beyond the end of the line
  new
  norm R/*
  norm o0{
  norm o//
  norm V{=
  assert_equal(['/*', '   0{', '//'], getline(1, 3))
  bwipe!
enddef


" vim: shiftwidth=2 sts=2 expandtab