/* Test basic Objective-C foreach syntax.  This tests iterations, with
   the basic syntax 'for (object in array) statements'
*/
/* { dg-do run } */
/* { dg-skip-if "No NeXT fast enum. pre-Darwin9" { *-*-darwin[5-8]* } { "-fnext-runtime" } { "" } } */
/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */
/* { dg-options "-mno-constant-cfstrings" { target *-*-darwin* } } */
/* { dg-additional-sources "../objc-obj-c++-shared/nsconstantstring-class-impl.m" } */
/* { dg-additional-options "-Wno-objc-root-class" } */

#include "../objc-obj-c++-shared/TestsuiteObject.m"
#ifndef __NEXT_RUNTIME__
#include <objc/NXConstStr.h>
#else
#include "../objc-obj-c++-shared/nsconstantstring-class.h"
#endif

extern int printf (const char *, ...);
#include <stdlib.h>

/*
struct __objcFastEnumerationState
{
  unsigned long state;
  id            *itemsPtr;
  unsigned long *mutationsPtr;
  unsigned long extra[5];
};
*/

 /* A mini-array implementation that can be used to test fast
    enumeration.  You create the array with some objects; you can
    mutate the array, and you can fast-enumerate it.
 */
@interface MyArray : TestsuiteObject
{
  unsigned int length;
  id *objects;
  unsigned long mutated;
}
- (id) initWithLength: (unsigned int)l  objects: (id *)o;
- (void) mutate;
- (unsigned long)countByEnumeratingWithState: (struct __objcFastEnumerationState *)state
                                     objects:(id *)stackbuf 
                                       count:(unsigned long)len;
@end

@implementation MyArray : TestsuiteObject
- (id) initWithLength: (unsigned int)l
	      objects: (id *)o
{
  length = l;
  objects = o;
  mutated = 0;
  return self;
}
- (void) mutate
{
  mutated = 1;
}
- (unsigned long)countByEnumeratingWithState: (struct __objcFastEnumerationState*)state 
		  		     objects: (id*)stackbuf
			 	       count: (unsigned long)len
{
  unsigned long i, batch_size;

  /* We keep how many objects we served in the state->state counter.  So the next batch
     will contain up to length - state->state objects.  */
  batch_size = length - state->state;

  /* Make obvious adjustments.  */
  if (batch_size < 0)
    batch_size = 0;

  if (batch_size > len)
    batch_size = len;

  /* Copy the objects.  */
  for (i = 0; i < batch_size; i++)
    stackbuf[i] = objects[i];

  state->state += batch_size;
  state->itemsPtr = stackbuf;
  state->mutationsPtr = &mutated;

  return batch_size;
}
@end

int main (void)
{
  MyArray *array;
  TestsuiteObject *object;
  int test_variable, counter, i;
  id *objects;

  array = [[MyArray alloc] initWithLength: 0
			   objects: NULL];

  /* Test that an empty array does nothing.  */
  for (object in array)
    abort ();

  if (object != nil)
    abort ();

  /* Test iterating over 1 object.  */
  objects = malloc (sizeof (id) * 1);
  objects[0] = @"One Object";

  array = [[MyArray alloc] initWithLength: 1
			   objects: objects];
  
  for (object in array)
    printf ("%p\n", object);
  
  /* Test iterating over 20 objects.  */
  objects = malloc (sizeof (id) * 20);
  for (i = 0; i < 20; i++)
    objects[i] = @"object";
  
  array = [[MyArray alloc] initWithLength: 20
			   objects: objects];
  
  for (object in array)
    printf ("%p\n", object);

  /* Test iterating over 200 objects.  */
  objects = malloc (sizeof (id) * 200);
  for (i = 0; i < 200; i++)
    objects[i] = @"object";
  
  array = [[MyArray alloc] initWithLength: 200
			   objects: objects];
  
  counter = 0;
  for (object in array)
    {
      if (object != nil)
	counter++;
    }

  if (counter != 200)
    abort ();

  printf ("Counter was %d (should be 200)\n", counter);

  /* Test iterating again over the same array.  */
  counter = 0;
  for (object in array)
    {
      if (object != nil)
	counter++;
    }

  if (counter != 200)
    abort ();

  printf ("Counter was %d (should be 200)\n", counter);

  /* Test nested iterations.  */
  objects = malloc (sizeof (id) * 20);
  for (i = 0; i < 20; i++)
    objects[i] = @"object";
  
  array = [[MyArray alloc] initWithLength: 20
			   objects: objects];
  counter = 0;
  for (object in array)
    {
      id another_object;
      for (another_object in array)
	if (another_object != nil)
	  counter++;
    }

  printf ("Counter was %d (should be 400)\n", counter);

  if (counter != 400)
    abort ();

  /* Test 'continue'.  */
  objects = malloc (sizeof (id) * 20);
  for (i = 0; i < 20; i++)
    objects[i] = @"object";
  
  array = [[MyArray alloc] initWithLength: 20
			   objects: objects];
  counter = 0;
  for (object in array)
    {
      if (counter == 15)
	continue;

      counter++;
    }

  printf ("Counter was %d (should be 15)\n", counter);

  if (counter != 15)
    abort ();

  /* Test 'break'.  */
  objects = malloc (sizeof (id) * 20);
  for (i = 0; i < 20; i++)
    objects[i] = @"object";
  
  array = [[MyArray alloc] initWithLength: 20
			   objects: objects];
  counter = 0;
  for (object in array)
    {
      counter++;

      if (counter == 15)
	break;
    }

  printf ("Counter was %d (should be 15)\n", counter);

  if (counter != 15)
    abort ();

  /* Test 'break' and 'continue' in nested iterations.  */
  objects = malloc (sizeof (id) * 20);
  for (i = 0; i < 20; i++)
    objects[i] = @"object";
  
  array = [[MyArray alloc] initWithLength: 20
			   objects: objects];
  counter = 0;
  for (object in array)
    {
      int local_counter = 0;
      id another_object;

      /* Each internal loop should increase counter by 24.  */
      for (another_object in array)
	{
	  local_counter++;
	  
	  if (local_counter == 10)
	    {
	      counter = counter + 20;
	      break;
	    }

	  if (local_counter >= 5)
	    continue;

	  counter++;
	}

      /* Exit after 4 iterations.  */
      if (counter == 96)
	break;
    }

  printf ("Counter was %d (should be 96)\n", counter);

  if (counter != 96)
    abort ();

  /* Test that if we 'break', the object is set to the last one, while
     if we run out of objects, it is set to 'nil'.  */
  for (object in array)
    ;

  if (object != nil)
    abort ();

  for (object in array)
    break;

  if (object == nil)
    abort ();

  /* Test that C for loops still work.  */
  test_variable = 0;

  for (counter = 0; counter < 4; counter++)
    test_variable++;

  if (test_variable != 4)
    abort ();

  return 0;
}
