Fixups after merge
[official-gcc.git] / gcc / testsuite / objc.dg / foreach-4.m
blobfaee73b82234d8f3abd2e4957abf1273daee60e2
1 /* Test basic Objective-C foreach syntax.  This tests iterations, with
2    the declaration syntax 'for (id object in array) statements'
3 */
4 /* { dg-do run } */
5 /* { dg-skip-if "No NeXT fast enum. pre-Darwin9" { *-*-darwin[5-8]* } { "-fnext-runtime" } { "" } } */
6 /* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */
7 /* { dg-options "-mno-constant-cfstrings" { target *-*-darwin* } } */
8 /* { dg-additional-sources "../objc-obj-c++-shared/nsconstantstring-class-impl.m" } */
10 #import "../objc-obj-c++-shared/TestsuiteObject.m"
11 #ifndef __NEXT_RUNTIME__
12 #include <objc/NXConstStr.h>
13 #else
14 #include "../objc-obj-c++-shared/nsconstantstring-class.h"
15 #endif
17 extern int printf (const char *, ...);
18 #include <stdlib.h>
21 struct __objcFastEnumerationState
23   unsigned long state;
24   id            *itemsPtr;
25   unsigned long *mutationsPtr;
26   unsigned long extra[5];
30  /* A mini-array implementation that can be used to test fast
31     enumeration.  You create the array with some objects; you can
32     mutate the array, and you can fast-enumerate it.
33  */
34 @interface MyArray : TestsuiteObject
36   unsigned int length;
37   id *objects;
38   unsigned long mutated;
40 - (id) initWithLength: (unsigned int)l  objects: (id *)o;
41 - (void) mutate;
42 - (unsigned long)countByEnumeratingWithState: (struct __objcFastEnumerationState *)state
43                                      objects:(id *)stackbuf 
44                                        count:(unsigned long)len;
45 @end
47 @implementation MyArray : TestsuiteObject
48 - (id) initWithLength: (unsigned int)l
49               objects: (id *)o
51   length = l;
52   objects = o;
53   mutated = 0;
54   return self;
56 - (void) mutate
58   mutated = 1;
60 - (unsigned long)countByEnumeratingWithState: (struct __objcFastEnumerationState*)state 
61                                      objects: (id*)stackbuf
62                                        count: (unsigned long)len
64   unsigned long i, batch_size;
66   /* We keep how many objects we served in the state->state counter.  So the next batch
67      will contain up to length - state->state objects.  */
68   batch_size = length - state->state;
70   /* Make obvious adjustments.  */
71   if (batch_size < 0)
72     batch_size = 0;
74   if (batch_size > len)
75     batch_size = len;
77   /* Copy the objects.  */
78   for (i = 0; i < batch_size; i++)
79     stackbuf[i] = objects[i];
81   state->state += batch_size;
82   state->itemsPtr = stackbuf;
83   state->mutationsPtr = &mutated;
85   return batch_size;
87 @end
89 int main (void)
91   MyArray *array;
92   int test_variable, counter, i;
93   id *objects;
95   array = [[MyArray alloc] initWithLength: 0
96                            objects: NULL];
98   /* Test that an empty array does nothing.  */
99   for (id object in array)
100     abort ();
102   /* Test iterating over 1 object.  */
103   objects = malloc (sizeof (id) * 1);
104   objects[0] = @"One Object";
106   array = [[MyArray alloc] initWithLength: 1
107                            objects: objects];
108   
109   for (id object in array)
110     printf ("%p\n", object);
111   
112   /* Test iterating over 20 objects.  */
113   objects = malloc (sizeof (id) * 20);
114   for (i = 0; i < 20; i++)
115     objects[i] = @"object";
116   
117   array = [[MyArray alloc] initWithLength: 20
118                            objects: objects];
119   
120   for (id object in array)
121     printf ("%p\n", object);
123   /* Test iterating over 200 objects.  */
124   objects = malloc (sizeof (id) * 200);
125   for (i = 0; i < 200; i++)
126     objects[i] = @"object";
127   
128   array = [[MyArray alloc] initWithLength: 200
129                            objects: objects];
130   
131   counter = 0;
132   for (id object in array)
133     {
134       if (object != nil)
135         counter++;
136     }
138   if (counter != 200)
139     abort ();
141   printf ("Counter was %d (should be 200)\n", counter);
143   /* Test iterating again over the same array.  */
144   counter = 0;
145   for (id object in array)
146     {
147       if (object != nil)
148         counter++;
149     }
151   if (counter != 200)
152     abort ();
154   printf ("Counter was %d (should be 200)\n", counter);
156   /* Test nested iterations.  */
157   objects = malloc (sizeof (id) * 20);
158   for (i = 0; i < 20; i++)
159     objects[i] = @"object";
160   
161   array = [[MyArray alloc] initWithLength: 20
162                            objects: objects];
163   counter = 0;
164   for (id object in array)
165     {
166       for (id another_object in array)
167         if (another_object != nil)
168           counter++;
169     }
171   printf ("Counter was %d (should be 400)\n", counter);
173   if (counter != 400)
174     abort ();
176   /* Test 'continue'.  */
177   objects = malloc (sizeof (id) * 20);
178   for (i = 0; i < 20; i++)
179     objects[i] = @"object";
180   
181   array = [[MyArray alloc] initWithLength: 20
182                            objects: objects];
183   counter = 0;
184   for (id object in array)
185     {
186       if (counter == 15)
187         continue;
189       counter++;
190     }
192   printf ("Counter was %d (should be 15)\n", counter);
194   if (counter != 15)
195     abort ();
197   /* Test 'break'.  */
198   objects = malloc (sizeof (id) * 20);
199   for (i = 0; i < 20; i++)
200     objects[i] = @"object";
201   
202   array = [[MyArray alloc] initWithLength: 20
203                            objects: objects];
204   counter = 0;
205   for (id object in array)
206     {
207       counter++;
209       if (counter == 15)
210         break;
211     }
213   printf ("Counter was %d (should be 15)\n", counter);
215   if (counter != 15)
216     abort ();
218   /* Test 'break' and 'continue' in nested iterations.  */
219   objects = malloc (sizeof (id) * 20);
220   for (i = 0; i < 20; i++)
221     objects[i] = @"object";
222   
223   array = [[MyArray alloc] initWithLength: 20
224                            objects: objects];
225   counter = 0;
226   for (id object in array)
227     {
228       int local_counter = 0;
230       /* Each internal loop should increase counter by 24.  */
231       for (id another_object in array)
232         {
233           local_counter++;
234           
235           if (local_counter == 10)
236             {
237               counter = counter + 20;
238               break;
239             }
241           if (local_counter >= 5)
242             continue;
244           counter++;
245         }
247       /* Exit after 4 iterations.  */
248       if (counter == 96)
249         break;
250     }
252   printf ("Counter was %d (should be 96)\n", counter);
254   if (counter != 96)
255     abort ();
257   /* Test that C for loops still work.  */
258   test_variable = 0;
260   for (counter = 0; counter < 4; counter++)
261     test_variable++;
263   if (test_variable != 4)
264     abort ();
266   return 0;