2 /*+-----------------------------------------------------------------**
4 **-----------------------------------------------------------------**
5 ** extensions/arrays.c **
6 **-----------------------------------------------------------------**
7 ** First version: 07/12/2010 **
8 **-----------------------------------------------------------------**
11 *****************************************************************************
12 * OpenScop: Structures and formats for polyhedral tools to talk together *
13 *****************************************************************************
14 * ,___,,_,__,,__,,__,,__,,_,__,,_,__,,__,,___,_,__,,_,__, *
15 * / / / // // // // / / / // // / / // / /|,_, *
16 * / / / // // // // / / / // // / / // / / / /\ *
17 * |~~~|~|~~~|~~~|~~~|~~~|~|~~~|~|~~~|~~~|~~~|~|~~~|~|~~~|/_/ \ *
18 * | G |C| P | = | L | P |=| = |C| = | = | = |=| = |=| C |\ \ /\ *
19 * | R |l| o | = | e | l |=| = |a| = | = | = |=| = |=| L | \# \ /\ *
20 * | A |a| l | = | t | u |=| = |n| = | = | = |=| = |=| o | |\# \ \ *
21 * | P |n| l | = | s | t |=| = |d| = | = | = | | |=| o | | \# \ \ *
22 * | H | | y | | e | o | | = |l| | | = | | | | G | | \ \ \ *
23 * | I | | | | e | | | | | | | | | | | | | \ \ \ *
24 * | T | | | | | | | | | | | | | | | | | \ \ \ *
25 * | E | | | | | | | | | | | | | | | | | \ \ \ *
26 * | * |*| * | * | * | * |*| * |*| * | * | * |*| * |*| * | / \* \ \ *
27 * | O |p| e | n | S | c |o| p |-| L | i | b |r| a |r| y |/ \ \ / *
28 * '---'-'---'---'---'---'-'---'-'---'---'---'-'---'-'---' '--' *
30 * Copyright (C) 2008 University Paris-Sud 11 and INRIA *
32 * (3-clause BSD license) *
33 * Redistribution and use in source and binary forms, with or without *
34 * modification, are permitted provided that the following conditions *
37 * 1. Redistributions of source code must retain the above copyright notice, *
38 * this list of conditions and the following disclaimer. *
39 * 2. Redistributions in binary form must reproduce the above copyright *
40 * notice, this list of conditions and the following disclaimer in the *
41 * documentation and/or other materials provided with the distribution. *
42 * 3. The name of the author may not be used to endorse or promote products *
43 * derived from this software without specific prior written permission. *
45 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR *
46 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES *
47 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. *
48 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, *
49 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT *
50 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, *
51 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY *
52 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT *
53 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF *
54 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
56 * OpenScop Library, a library to manipulate OpenScop formats and data *
57 * structures. Written by: *
58 * Cedric Bastoul <Cedric.Bastoul@u-psud.fr> and *
59 * Louis-Noel Pouchet <Louis-Noel.pouchet@inria.fr> *
61 *****************************************************************************/
68 #include <osl/macros.h>
70 #include <osl/strings.h>
71 #include <osl/interface.h>
72 #include <osl/extensions/arrays.h>
75 /*+***************************************************************************
76 * Structure display function *
77 *****************************************************************************/
81 * osl_arrays_idump function:
82 * this function displays an osl_arrays_t structure (*arrays) into a file
83 * (file, possibly stdout) in a way that trends to be understandable. It
84 * includes an indentation level (level) in order to work with others
86 * \param[in] file The file where the information has to be printed.
87 * \param[in] arrays The arrays structure to print.
88 * \param[in] level Number of spaces before printing, for each line.
90 void osl_arrays_idump(FILE * file
, osl_arrays_p arrays
, int level
) {
93 // Go to the right level.
94 for (j
= 0; j
< level
; j
++)
98 fprintf(file
, "+-- osl_arrays_t\n");
100 fprintf(file
, "+-- NULL arrays\n");
102 if (arrays
!= NULL
) {
103 // Go to the right level.
104 for(j
= 0; j
<= level
; j
++)
105 fprintf(file
, "|\t");
107 // Display the number of names.
108 fprintf(file
, "nb_names: %d\n", arrays
->nb_names
);
110 // Display the id/name.
111 for(i
= 0; i
< arrays
->nb_names
; i
++) {
112 // Go to the right level.
113 for(j
= 0; j
<= level
; j
++)
114 fprintf(file
, "|\t");
116 fprintf(file
, "id: %2d, name: %s\n", arrays
->id
[i
], arrays
->names
[i
]);
121 for (j
= 0; j
<= level
; j
++)
122 fprintf(file
, "|\t");
128 * osl_arrays_dump function:
129 * this function prints the content of an osl_arrays_t structure
130 * (*arrays) into a file (file, possibly stdout).
131 * \param[in] file The file where the information has to be printed.
132 * \param[in] arrays The arrays structure to print.
134 void osl_arrays_dump(FILE * file
, osl_arrays_p arrays
) {
135 osl_arrays_idump(file
, arrays
, 0);
140 * osl_arrays_sprint function:
141 * this function prints the content of an osl_arrays_t structure
142 * (*arrays) into a string (returned) in the OpenScop textual format.
143 * \param[in] arrays The arrays structure to print.
144 * \return A string containing the OpenScop dump of the arrays structure.
146 char * osl_arrays_sprint(osl_arrays_p arrays
) {
148 int high_water_mark
= OSL_MAX_STRING
;
149 char * string
= NULL
;
150 char buffer
[OSL_MAX_STRING
];
152 if (arrays
!= NULL
) {
153 OSL_malloc(string
, char *, high_water_mark
* sizeof(char));
156 sprintf(buffer
, "# Number of arrays\n");
157 osl_util_safe_strcat(&string
, buffer
, &high_water_mark
);
159 sprintf(buffer
, "%d\n", arrays
->nb_names
);
160 osl_util_safe_strcat(&string
, buffer
, &high_water_mark
);
162 if (arrays
->nb_names
) {
163 sprintf(buffer
, "# Mapping array-identifiers/array-names\n");
164 osl_util_safe_strcat(&string
, buffer
, &high_water_mark
);
166 for (i
= 0; i
< arrays
->nb_names
; i
++) {
167 sprintf(buffer
, "%d %s\n", arrays
->id
[i
], arrays
->names
[i
]);
168 osl_util_safe_strcat(&string
, buffer
, &high_water_mark
);
171 OSL_realloc(string
, char *, (strlen(string
) + 1) * sizeof(char));
178 /*****************************************************************************
180 *****************************************************************************/
184 * osl_arrays_sread function:
185 * this function reads an arrays structure from a string complying to the
186 * OpenScop textual format and returns a pointer to this arrays structure.
187 * The string should contain only one textual format of an arrays structure.
188 * The input parameter is updated to the position in the input string this
189 * function reach right after reading the comment structure.
190 * \param[in,out] input The input string where to find an arrays structure.
191 * Updated to the position after what has been read.
192 * \return A pointer to the arrays structure that has been read.
194 osl_arrays_p
osl_arrays_sread(char ** input
) {
200 OSL_debug("no arrays optional tag");
204 // Find the number of names provided.
205 nb_names
= osl_util_read_int(NULL
, input
);
207 // Allocate the array of id and names.
208 arrays
= osl_arrays_malloc();
209 OSL_malloc(arrays
->id
, int *, nb_names
* sizeof(int));
210 OSL_malloc(arrays
->names
, char **, nb_names
* sizeof(char *));
211 arrays
->nb_names
= nb_names
;
212 for (i
= 0; i
< nb_names
; i
++)
213 arrays
->names
[i
] = NULL
;
215 // Get each array id/name.
216 for (k
= 0; k
< nb_names
; k
++) {
217 // Get the array name id.
218 arrays
->id
[k
] = osl_util_read_int(NULL
, input
);
220 // Get the array name string.
221 arrays
->names
[k
] = osl_util_read_string(NULL
, input
);
228 /*+***************************************************************************
229 * Memory allocation/deallocation function *
230 *****************************************************************************/
234 * osl_arrays_malloc function:
235 * this function allocates the memory space for an osl_arrays_t
236 * structure and sets its fields with default values. Then it returns a
237 * pointer to the allocated space.
238 * \return A pointer to an empty arrays structure with fields set to
241 osl_arrays_p
osl_arrays_malloc() {
244 OSL_malloc(arrays
, osl_arrays_p
, sizeof(osl_arrays_t
));
245 arrays
->nb_names
= 0;
247 arrays
->names
= NULL
;
254 * osl_arrays_free function:
255 * this function frees the allocated memory for an arrays structure.
256 * \param[in,out] arrays The pointer to the arrays structure we want to free.
258 void osl_arrays_free(osl_arrays_p arrays
) {
261 if (arrays
!= NULL
) {
263 for (i
= 0; i
< arrays
->nb_names
; i
++)
264 free(arrays
->names
[i
]);
271 /*+***************************************************************************
272 * Processing functions *
273 *****************************************************************************/
277 * osl_arrays_clone function:
278 * this function builds and returns a "hard copy" (not a pointer copy) of an
279 * osl_arrays_t data structure.
280 * \param[in] arrays The pointer to the arrays structure to clone.
281 * \return A pointer to the clone of the arrays structure.
283 osl_arrays_p
osl_arrays_clone(osl_arrays_p arrays
) {
290 clone
= osl_arrays_malloc();
291 clone
->nb_names
= arrays
->nb_names
;
292 OSL_malloc(clone
->id
, int *, arrays
->nb_names
* sizeof(int));
293 OSL_malloc(clone
->names
, char **, arrays
->nb_names
* sizeof(char*));
295 for (i
= 0; i
< arrays
->nb_names
; i
++) {
296 clone
->id
[i
] = arrays
->id
[i
];
297 OSL_strdup(clone
->names
[i
], arrays
->names
[i
]);
305 * osl_arrays_equal function:
306 * this function returns true if the two arrays structures are the same
307 * (content-wise), false otherwise. This functions considers two arrays
308 * structures as equal if the order of the array names differ, however the
309 * identifiers and names must be the same.
310 * \param[in] a1 The first arrays structure.
311 * \param[in] a2 The second arrays structure.
312 * \return 1 if a1 and a2 are the same (content-wise), 0 otherwise.
314 int osl_arrays_equal(osl_arrays_p a1
, osl_arrays_p a2
) {
320 if (((a1
== NULL
) && (a2
!= NULL
)) || ((a1
!= NULL
) && (a2
== NULL
))) {
321 OSL_info("arrays are not the same");
325 // Check whether the number of names is the same.
326 if (a1
->nb_names
!= a2
->nb_names
) {
327 OSL_info("arrays are not the same");
331 // We accept a different order of the names, as long as the identifiers
333 for (i
= 0; i
< a1
->nb_names
; i
++) {
335 for (j
= 0; j
< a2
->nb_names
; j
++) {
336 if ((a1
->id
[i
] == a2
->id
[j
]) && (!strcmp(a1
->names
[i
], a2
->names
[j
]))) {
342 OSL_info("arrays are not the same");
352 * osl_arrays_to_strings function:
353 * this function creates a strings structure containing the textual names
354 * contained in a names structure. Each name is placed according to its
355 * id in the strings array. The "empty" strings cells are filled with
357 * \param[in] arrays The arrays structure to convert to a strings.
358 * \return A strings structure containing all the array names.
360 osl_strings_p
osl_arrays_to_strings(osl_arrays_p arrays
) {
362 osl_strings_p strings
= NULL
;
367 // Find the maximum array id.
368 if (arrays
->nb_names
>= 1) {
369 max_id
= arrays
->id
[0];
370 for (i
= 1; i
< arrays
->nb_names
; i
++)
371 if (arrays
->id
[i
] > max_id
)
372 max_id
= arrays
->id
[i
];
375 // Build a strings structure for this number of ids.
376 strings
= osl_strings_generate("Dummy", max_id
);
377 for (i
= 0; i
< arrays
->nb_names
; i
++) {
378 free(strings
->string
[arrays
->id
[i
] - 1]);
379 OSL_strdup(strings
->string
[arrays
->id
[i
] - 1], arrays
->names
[i
]);
387 * osl_arrays_interface function:
388 * this function creates an interface structure corresponding to the arrays
389 * extension and returns it).
390 * \return An interface structure for the arrays extension.
392 osl_interface_p
osl_arrays_interface() {
393 osl_interface_p interface
= osl_interface_malloc();
395 OSL_strdup(interface
->URI
, OSL_URI_ARRAYS
);
396 interface
->idump
= (osl_idump_f
)osl_arrays_idump
;
397 interface
->sprint
= (osl_sprint_f
)osl_arrays_sprint
;
398 interface
->sread
= (osl_sread_f
)osl_arrays_sread
;
399 interface
->malloc
= (osl_malloc_f
)osl_arrays_malloc
;
400 interface
->free
= (osl_free_f
)osl_arrays_free
;
401 interface
->clone
= (osl_clone_f
)osl_arrays_clone
;
402 interface
->equal
= (osl_equal_f
)osl_arrays_equal
;