/* vim: set cin ts=4 sw=4 : */

Test for 'cindent'

STARTTEST
:so small.vim
:set nocompatible viminfo+=nviminfo
:edit                " read modeline
/start of AUTO
=/end of AUTO
ENDTEST

/* start of AUTO matically checked */
{
	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
};

{
	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
}

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)
{
}

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 incoreectly 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;
}

/* end of AUTO */

STARTTEST
:set tw=0 wm=60 columns=80 noai fo=croq
/serious/e
a about life, the universe, and the rest
ENDTEST

{

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

STARTTEST
:set nocin
/comments
joabout life/happens
jothere/below
oline/this
Ohello
ENDTEST

{
	/*
	 * Testing for comments, without 'cin' set
	 */

/*
* what happens here?
*/

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

		/* how about
		                this one */
}

STARTTEST
:set cin
/vec2
==
ENDTEST

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

STARTTEST
:set cin
:set cino=}4
/testing1
k2==/testing2
k2==
ENDTEST

{
		asdf asdflkajds f;
	if (tes & ting) {
		asdf asdf asdf ;
		asdfa sdf asdf;
		}
	testing1;
	if (tes & ting)
	{
		asdf asdf asdf ;
		asdfa sdf asdf;
		}
	testing2;
}

STARTTEST
:set cin
:set cino=(0,)20
/main
=][
ENDTEST

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
                      */
        );

}

STARTTEST
:set cin
:set cino=
]]=][
ENDTEST

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

STARTTEST
]]=][
ENDTEST

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

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

    n();
}

STARTTEST
:set cino={s,e-s
]]=][
ENDTEST

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

STARTTEST
:set cino={s,fs
]]=/ foo
ENDTEST

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 */

STARTTEST
:set cino=
/while
ohere
ENDTEST

a()
{
  do {
    a = a +
      a;
  } while ( a );		/* add text under this line */
    if ( a )
      a;
}

STARTTEST
:set cino= com=
/comment
olabel2: b();
label3 /* post */:
/* pre */ label4:
f(/*com*/);
if (/*com*/)
cmd();
ENDTEST

a()
{
label1:
            /* hmm */
            // comment
}

STARTTEST
:set comments& comments^=s:/*,m:**,ex:*/
/simple
=5j
ENDTEST

/*
  * A simple comment
   */

/*
  ** A different comment
   */

STARTTEST
:set cino=c0
:set comments& comments-=s1:/* comments^=s0:/*
2kdd]]=][
ENDTEST

void f()
{

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

STARTTEST
:set cino=c0,C1
:set comments& comments-=s1:/* comments^=s0:/*
2kdd]]=][
ENDTEST

void f()
{

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

STARTTEST
:set cino=
]]=][
ENDTEST

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

STARTTEST
:set cino=(s
2kdd]]=][
ENDTEST

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

STARTTEST
:set cino=(s,U1  
2kdd]]=][
ENDTEST

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

STARTTEST
:set cino=(0
2kdd]]=][
ENDTEST

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

STARTTEST
:set cino=(0,w1  
2kdd]]=][
ENDTEST

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

STARTTEST
:set cino=(s
2kdd]]=][
ENDTEST

void f()
{
	c = c1 && (
	c2 ||
	c3
	) && c4;
	if (
	c1 && c2
	)
	foo;
}

STARTTEST
:set cino=(s,m1  
2kdd]]=][
ENDTEST

void f()
{
	c = c1 && (
	c2 ||
	c3
	) && c4;
	if (
	c1 && c2
	)
	foo;
}

STARTTEST
:set cino=b1
2kdd]]=][
ENDTEST

void f()
{
	switch (x)
	{
		case 1:
			a = b;
			break;
		default:
			a = 0;
			break;
	}
}

STARTTEST
:set cino=(0,W5
2kdd]]=][
ENDTEST

void f()
{
	invokeme(
	argu,
	ment);
	invokeme(
	argu,
	ment
	);
	invokeme(argu,
	ment
	);
}

STARTTEST
:set cino=/6
2kdd]]=][
ENDTEST

void f()
{
	statement;
		// comment 1
	// comment 2
}

STARTTEST
:set cino=
2kdd]]/comment 1/+1
==
ENDTEST

void f()
{
	statement;
	   // comment 1
	// comment 2
}

STARTTEST
:set cino=g0
2kdd]]=][
ENDTEST

class CAbc
{
   int Test() { return FALSE; }

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

STARTTEST
:set cino=(0,W2s
2kdd]]=][
ENDTEST

{
   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
         );
}

STARTTEST
:g/^STARTTEST/.,/^ENDTEST/d
:1;/start of AUTO/,$wq! test.out
ENDTEST
