1 #include <stdlib.h>
2 #include <stdio.h>
3 
4 #include <ISO_Fortran_binding.h>
5 #include "dump-descriptors.h"
6 
7 struct m {
8   int x, y;
9 };
10 
11 extern void ctest (CFI_cdesc_t *a, int lb0, int lb1,
12 		   int ub0, int ub1, int s0, int s1, CFI_cdesc_t *r);
13 
14 /* Take a section of array A.  OFF is the start index of A on the Fortran
15    side and the bounds LB and UB for the section to take are relative to
16    that base index.  Store the result in R, which is supposed to be a pointer
17    array with lower bound 1.  */
18 
19 void
ctest(CFI_cdesc_t * a,int lb0,int lb1,int ub0,int ub1,int s0,int s1,CFI_cdesc_t * r)20 ctest (CFI_cdesc_t *a, int lb0, int lb1,
21 		   int ub0, int ub1, int s0, int s1, CFI_cdesc_t *r)
22 {
23   CFI_index_t lb_array[2], ub_array[2], s_array[2];
24   int i0, i1, o0, o1;
25 
26   /* Dump the descriptor contents to test that we can access the fields
27      correctly, etc.  */
28   fprintf (stderr, "\n%s: lb0=%d  lb1=%d  ub0=%d  ub1=%d  s0=%d  s1=%d\n",
29 	   (a->attribute == CFI_attribute_other) ? "non-pointer" : "pointer",
30 	   lb0, lb1, ub0, ub1, s0, s1);
31   if (! (lb0 == ub0 || lb1 == ub1))
32     abort ();
33   dump_CFI_cdesc_t (a);
34   dump_CFI_cdesc_t (r);
35 
36   /* Make sure we got a valid input descriptor.  */
37   if (!a->base_addr)
38     abort ();
39   if (a->elem_len != sizeof(struct m))
40     abort ();
41   if (a->rank != 2)
42     abort ();
43   if (a->type != CFI_type_struct)
44     abort ();
45   if (a->attribute == CFI_attribute_other)
46     {
47       if (a->dim[0].lower_bound != 0)
48 	abort ();
49       /* Adjust the 1-based bounds.  */
50       lb0 = lb0 - 1;
51       lb1 = lb1 - 1;
52       ub0 = ub0 - 1;
53       ub1 = ub1 - 1;
54     }
55   /* For pointer arrays, the bounds use the same indexing as the lower
56      bound in the array descriptor.  */
57 
58   /* Make sure we got a valid output descriptor.  */
59   if (r->base_addr)
60     abort ();
61   if (r->elem_len != sizeof(struct m))
62     abort ();
63   if (r->rank != 1)
64     abort ();
65   if (r->type != CFI_type_struct)
66     abort ();
67   if (r->attribute != CFI_attribute_pointer)
68     abort ();
69 
70   /* Create an array section.  */
71   lb_array[0] = lb0;
72   lb_array[1] = lb1;
73   ub_array[0] = ub0;
74   ub_array[1] = ub1;
75   s_array[0] = s0;
76   s_array[1] = s1;
77 
78   check_CFI_status ("CFI_section",
79 		    CFI_section (r, a, lb_array, ub_array, s_array));
80 
81   /* Check that the output descriptor is correct.  */
82   dump_CFI_cdesc_t (r);
83   if (!r->base_addr)
84     abort ();
85   if (r->elem_len != sizeof(struct m))
86     abort ();
87   if (r->rank != 1)
88     abort ();
89   if (r->type != CFI_type_struct)
90     abort ();
91   if (r->attribute != CFI_attribute_pointer)
92     abort ();
93 
94   /* Check the contents of the output array.  */
95 #if 0
96   if (lb1 == ub1)
97     {
98       /* Output is 1-d array that varies in dimension 0.  */
99       for (o0 = r->dim[0].lower_bound, i0 = lb0;
100 	   (s0 > 0 ? i0 <= ub0 : i0 >= ub0);
101 	   o0++, i0 += s0)
102 	{
103 	  CFI_index_t index[2];
104 	  struct m *input, *output;
105 	  index[0] = i0;
106 	  index[1] = lb1;
107 	  input = (struct m *) CFI_address (a, index);
108 	  index[0] = o0;
109 	  output = (struct m *) CFI_address (r, index);
110 	  fprintf (stderr, "a(%d,%d) = (%d,%d), r(%d) = (%d,%d)\n",
111 		   i0, lb1, input->x, input->y, o0, output->x, output->y);
112 	}
113     }
114   else if (lb0 == ub0)
115     {
116       /* Output is 1-d array that varies in dimension 1.  */
117       for (o1 = r->dim[0].lower_bound, i1 = lb1;
118 	   (s1 > 0 ? i1 <= ub1 : i1 >= ub1);
119 	   o1++, i1 += s1)
120 	{
121 	  CFI_index_t index[2];
122 	  struct m *input, *output;
123 	  index[0] = lb0;
124 	  index[1] = i1;
125 	  input = (struct m *) CFI_address (a, index);
126 	  index[0] = o1;
127 	  output = (struct m *) CFI_address (r, index);
128 	  fprintf (stderr, "a(%d,%d) = (%d,%d), r(%d) = (%d,%d)\n",
129 		   lb0, i1, input->x, input->y, o1, output->x, output->y);
130 	}
131     }
132   else
133     abort ();
134 #endif
135   if (lb1 == ub1)
136     {
137       /* Output is 1-d array that varies in dimension 0.  */
138       for (o0 = r->dim[0].lower_bound, i0 = lb0;
139 	   (s0 > 0 ? i0 <= ub0 : i0 >= ub0);
140 	   o0++, i0 += s0)
141 	{
142 	  CFI_index_t index[2];
143 	  struct m *input, *output;
144 	  index[0] = i0;
145 	  index[1] = lb1;
146 	  input = (struct m *) CFI_address (a, index);
147 	  index[0] = o0;
148 	  output = (struct m *) CFI_address (r, index);
149 	  if (input->x != output->x || input->y != output->y)
150 	    abort ();
151 	}
152     }
153   else if (lb0 == ub0)
154     {
155       /* Output is 1-d array that varies in dimension 1.  */
156       for (o1 = r->dim[0].lower_bound, i1 = lb1;
157 	   (s1 > 0 ? i1 <= ub1 : i1 >= ub1);
158 	   o1++, i1 += s1)
159 	{
160 	  CFI_index_t index[2];
161 	  struct m *input, *output;
162 	  index[0] = lb0;
163 	  index[1] = i1;
164 	  input = (struct m *) CFI_address (a, index);
165 	  index[0] = o1;
166 	  output = (struct m *) CFI_address (r, index);
167 	  if (input->x != output->x || input->y != output->y)
168 	    abort ();
169 	}
170     }
171   else
172     abort ();
173 
174   /* Force the output array to be 1-based.  */
175   lb_array[0] = 1;
176   lb_array[1] = 1;
177   check_CFI_status ("CFI_setpointer", CFI_setpointer (r, r, lb_array));
178   /* Check that the output descriptor is correct.  */
179   dump_CFI_cdesc_t (r);
180   if (!r->base_addr)
181     abort ();
182   if (r->elem_len != sizeof(struct m))
183     abort ();
184   if (r->rank != 1)
185     abort ();
186   if (r->type != CFI_type_struct)
187     abort ();
188   if (r->attribute != CFI_attribute_pointer)
189     abort ();
190   if (r->dim[0].lower_bound != 1)
191     abort ();
192 
193   /* Check the contents of the output array again.  */
194   if (lb1 == ub1)
195     {
196       /* Output is 1-d array that varies in dimension 0.  */
197       for (o0 = r->dim[0].lower_bound, i0 = lb0;
198 	   (s0 > 0 ? i0 <= ub0 : i0 >= ub0);
199 	   o0++, i0 += s0)
200 	{
201 	  CFI_index_t index[2];
202 	  struct m *input, *output;
203 	  index[0] = i0;
204 	  index[1] = lb1;
205 	  input = (struct m *) CFI_address (a, index);
206 	  index[0] = o0;
207 	  output = (struct m *) CFI_address (r, index);
208 	  if (input->x != output->x || input->y != output->y)
209 	    abort ();
210 	}
211     }
212   else if (lb0 == ub0)
213     {
214       /* Output is 1-d array that varies in dimension 1.  */
215       for (o1 = r->dim[0].lower_bound, i1 = lb1;
216 	   (s1 > 0 ? i1 <= ub1 : i1 >= ub1);
217 	   o1++, i1 += s1)
218 	{
219 	  CFI_index_t index[2];
220 	  struct m *input, *output;
221 	  index[0] = lb0;
222 	  index[1] = i1;
223 	  input = (struct m *) CFI_address (a, index);
224 	  index[0] = o1;
225 	  output = (struct m *) CFI_address (r, index);
226 	  if (input->x != output->x || input->y != output->y)
227 	    abort ();
228 	}
229     }
230   else
231     abort ();
232 }
233 
234 
235 
236