2 /*+-----------------------------------------------------------------**
4 **-----------------------------------------------------------------**
6 **-----------------------------------------------------------------**
7 ** First version: 13/07/2011 **
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>
69 # include <osl/util.h>
70 # include <osl/interface.h>
71 # include <osl/strings.h>
74 /*+***************************************************************************
75 * Structure display function *
76 *****************************************************************************/
80 * osl_strings_idump function:
81 * this function displays an array of strings into a file (file, possibly
82 * stdout) in a way that trends to be understandable. It includes an
83 * indentation level (level) in order to work with others
85 * \param[in] file The file where the information has to be printed.
86 * \param[in] strings The array of strings that has to be printed.
87 * \param[in] level Number of spaces before printing, for each line.
89 void osl_strings_idump(FILE * file
, osl_strings_p strings
, int level
) {
92 for (i
= 0; i
< level
; i
++)
95 if (strings
!= NULL
) {
96 nb_strings
= osl_strings_size(strings
);
97 fprintf(file
, "+-- osl_strings_t:");
98 for (i
= 0; i
< nb_strings
; i
++)
99 fprintf(file
, " %s", strings
->string
[i
]);
103 fprintf(file
, "+-- NULL strings\n");
106 for (i
= 0; i
<= level
; i
++)
107 fprintf(file
, "|\t");
113 * osl_strings_dump function:
114 * this function prints the content of an osl_strings_t structure
115 * (*strings) into a file (file, possibly stdout).
116 * \param[in] file The file where the information has to be printed.
117 * \param[in] strings The strings structure which has to be printed.
119 void osl_strings_dump(FILE * file
, osl_strings_p strings
) {
120 osl_strings_idump(file
, strings
, 0);
125 * osl_strings_sprint function:
126 * this function prints the content of an osl_strings_t structure
127 * (*strings) into a string (returned) in the OpenScop textual format.
128 * \param[in] strings The strings structure which has to be printed.
129 * \return A string containing the OpenScop dump of the strings structure.
131 char * osl_strings_sprint(osl_strings_p strings
) {
133 int high_water_mark
= OSL_MAX_STRING
;
134 char * string
= NULL
;
135 char buffer
[OSL_MAX_STRING
];
137 OSL_malloc(string
, char *, high_water_mark
* sizeof(char));
140 if (strings
!= NULL
) {
141 for (i
= 0; i
< osl_strings_size(strings
); i
++) {
142 sprintf(buffer
, "%s", strings
->string
[i
]);
143 osl_util_safe_strcat(&string
, buffer
, &high_water_mark
);
144 if (i
< osl_strings_size(strings
) - 1)
145 osl_util_safe_strcat(&string
, " ", &high_water_mark
);
147 sprintf(buffer
, "\n");
148 osl_util_safe_strcat(&string
, buffer
, &high_water_mark
);
151 sprintf(buffer
, "# NULL strings\n");
152 osl_util_safe_strcat(&string
, buffer
, &high_water_mark
);
160 * osl_strings_print function:
161 * this function prints the content of an osl_strings_t structure
162 * (*body) into a file (file, possibly stdout) in the OpenScop format.
163 * \param[in] file File where informations are printed.
164 * \param[in] strings The strings whose information has to be printed.
166 void osl_strings_print(FILE * file
, osl_strings_p strings
) {
169 string
= osl_strings_sprint(strings
);
170 if (string
!= NULL
) {
171 fprintf(file
, "%s", string
);
177 /*+***************************************************************************
178 * Structure display function *
179 *****************************************************************************/
183 * osl_strings_sread function:
184 * this function reads a strings structure from a string complying to the
185 * OpenScop textual format and returns a pointer to this strings structure.
186 * The input string should only contain the list of strings this function
187 * has to read (comments at the end of the line are accepted). The input
188 * parameter is updated to the position in the input string this function
189 * reach right after reading the strings structure.
190 * \param[in,out] input The input string where to find a strings structure.
191 * Updated to the position after what has been read.
192 * \return A pointer to the strings structure that has been read.
194 osl_strings_p
osl_strings_sread(char ** input
) {
195 char tmp
[OSL_MAX_STRING
];
197 char ** string
= NULL
;
200 osl_strings_p strings
= NULL
;
202 // Skip blank/commented lines and spaces before the strings.
203 osl_util_sskip_blank_and_comments(input
);
205 // Count the actual number of strings.
209 for (count
= 0; *s
&& !isspace(*s
) && *s
!= '#'; count
++)
215 if ((!*s
) || (*s
== '#') || (*s
== '\n'))
221 if (nb_strings
> 0) {
222 // Allocate the array of strings. Make it NULL-terminated.
223 OSL_malloc(string
, char **, sizeof(char *) * (nb_strings
+ 1));
224 string
[nb_strings
] = NULL
;
226 // Read the desired number of strings.
228 for (i
= 0; i
< nb_strings
; i
++) {
229 for (count
= 0; *s
&& !isspace(*s
) && *s
!= '#'; count
++)
232 OSL_strdup(string
[i
], tmp
);
237 // Update the input pointer to the end of the strings structure.
240 // Build the strings structure
241 strings
= osl_strings_malloc();
242 free(strings
->string
);
243 strings
->string
= string
;
251 * osl_strings_read function.
252 * this function reads a strings structure from a file (possibly stdin)
253 * complying to the OpenScop textual format and returns a pointer to this
255 * parameter nb_strings).
256 * \param[in] file The file where to read the strings structure.
257 * \return The strings structure that has been read.
259 osl_strings_p
osl_strings_read(FILE * file
) {
260 char buffer
[OSL_MAX_STRING
], * start
;
261 osl_strings_p strings
;
263 start
= osl_util_skip_blank_and_comments(file
, buffer
);
264 strings
= osl_strings_sread(&start
);
270 /*+***************************************************************************
271 * Memory allocation/deallocation function *
272 *****************************************************************************/
276 * osl_strings_malloc function:
277 * This function allocates the memory space for an osl_strings_t
278 * structure and sets its fields with default values. Then it returns a
279 * pointer to the allocated space.
280 * \return A pointer to an empty strings structure with fields set to
283 osl_strings_p
osl_strings_malloc() {
284 osl_strings_p strings
;
286 OSL_malloc(strings
, osl_strings_p
, sizeof(osl_strings_t
));
287 OSL_malloc(strings
->string
, char**, sizeof(char*));
288 strings
->string
[0] = NULL
;
295 * osl_strings_free function:
296 * this function frees the allocated memory for a strings data structure.
297 * \param[in] strings The strings structure we want to free.
299 void osl_strings_free(osl_strings_p strings
) {
302 if (strings
!= NULL
) {
303 if (strings
->string
!= NULL
) {
305 while (strings
->string
[i
] != NULL
) {
306 free(strings
->string
[i
]);
309 free(strings
->string
);
316 /*+***************************************************************************
317 * Processing functions *
318 *****************************************************************************/
322 * osl_strings_clone function.
323 * this function builds and return a "hard copy" (not a pointer copy) of an
324 * strings structure provided as parameter.
325 * \param[in] strings The strings structure to clone.
326 * \return The clone of the strings structure.
328 osl_strings_p
osl_strings_clone(osl_strings_p strings
) {
330 osl_strings_p clone
= NULL
;
335 clone
= osl_strings_malloc();
336 if ((nb_strings
= osl_strings_size(strings
)) == 0)
340 OSL_malloc(clone
->string
, char **, (nb_strings
+ 1) * sizeof(char *));
341 clone
->string
[nb_strings
] = NULL
;
342 for (i
= 0; i
< nb_strings
; i
++)
343 OSL_strdup(clone
->string
[i
], strings
->string
[i
]);
349 * osl_strings_find function.
350 * this function finds the string in the strings.
351 * \param[in,out] strings The strings structure.
352 * \param[in] string The string to find in strings.
353 * \return the index where is the string, osl_strings_size if not found
355 size_t osl_strings_find(osl_strings_p strings
, char const * const string
) {
357 for (i
= 0; i
< osl_strings_size(strings
); ++i
) {
358 if (strcmp(strings
->string
[i
], string
) == 0) { return i
; }
365 * osl_strings_add function.
366 * this function adds a copy of the string in the strings.
367 * \param[in,out] strings The strings structure.
368 * \param[in] string The string to add in strings.
370 void osl_strings_add(osl_strings_p strings
, char const * const string
) {
371 size_t original_size
= osl_strings_size(strings
);
372 OSL_realloc(strings
->string
, char**, sizeof(char*) * (original_size
+ 1 + 1));
373 strings
->string
[original_size
+ 1] = NULL
;
374 strings
->string
[original_size
] = malloc(sizeof(char) * (strlen(string
) + 1));
375 strcpy(strings
->string
[original_size
], string
);
380 * osl_strings_equal function:
381 * this function returns true if the two strings structures are the same
382 * (content-wise), false otherwise.
383 * \param[in] s1 The first strings structure.
384 * \param[in] s2 The second strings structure.
385 * \return 1 if s1 and s2 are the same (content-wise), 0 otherwise.
387 int osl_strings_equal(osl_strings_p s1
, osl_strings_p s2
) {
393 if (((s1
== NULL
) && (s2
!= NULL
)) ||
394 ((s1
!= NULL
) && (s2
== NULL
)) ||
395 ((nb_s1
= osl_strings_size(s1
)) != osl_strings_size(s2
)))
398 for (i
= 0; i
< nb_s1
; i
++)
399 if (strcmp(s1
->string
[i
], s2
->string
[i
]) != 0)
407 * osl_strings_size function:
408 * this function returns the number of elements in the NULL-terminated
409 * strings array of the strings structure.
410 * \param[in] strings The strings structure we need to know the size.
411 * \return The number of strings in the strings structure.
413 size_t osl_strings_size(osl_const_strings_const_p strings
) {
416 if ((strings
!= NULL
) && (strings
->string
!= NULL
)) {
417 while (strings
->string
[size
] != NULL
) {
427 * osl_strings_encapsulate function:
428 * this function builds a new strings structure to encapsulate the string
429 * provided as a parameter (the reference to this string is used directly).
430 * \param[in] string The string to encapsulate in a strings structure.
431 * \return A new strings structure containing only the provided string.
433 osl_strings_p
osl_strings_encapsulate(char * string
) {
434 osl_strings_p capsule
= osl_strings_malloc();
435 free(capsule
->string
);
436 OSL_malloc(capsule
->string
, char **, 2 * sizeof(char *));
437 capsule
->string
[0] = string
;
438 capsule
->string
[1] = NULL
;
445 * osl_strings_interface function:
446 * this function creates an interface structure corresponding to the strings
447 * structure and returns it).
448 * \return An interface structure for the strings structure.
450 osl_interface_p
osl_strings_interface() {
451 osl_interface_p interface
= osl_interface_malloc();
453 OSL_strdup(interface
->URI
, OSL_URI_STRINGS
);
454 interface
->idump
= (osl_idump_f
)osl_strings_idump
;
455 interface
->sprint
= (osl_sprint_f
)osl_strings_sprint
;
456 interface
->sread
= (osl_sread_f
)osl_strings_sread
;
457 interface
->malloc
= (osl_malloc_f
)osl_strings_malloc
;
458 interface
->free
= (osl_free_f
)osl_strings_free
;
459 interface
->clone
= (osl_clone_f
)osl_strings_clone
;
460 interface
->equal
= (osl_equal_f
)osl_strings_equal
;
467 * osl_strings_generate function:
468 * this function generates a new strings structure containing
469 * 'nb_strings' strings of the form "prefixXX" where XX goes from 1 to
471 * \param[in] prefix The prefix of the generated strings.
472 * \param[in] nb_strings The number of strings to generate.
473 * \return A new strings structure containing generated strings.
475 osl_strings_p
osl_strings_generate(char * prefix
, int nb_strings
) {
476 char ** strings
= NULL
;
477 char buff
[strlen(prefix
) + 16]; // TODO: better (log10(INT_MAX) ?) :-D.
479 osl_strings_p generated
;
482 OSL_malloc(strings
, char **, sizeof(char *) * (nb_strings
+ 1));
483 strings
[nb_strings
] = NULL
;
484 for (i
= 0; i
< nb_strings
; i
++) {
485 sprintf(buff
, "%s%d", prefix
, i
+ 1);
486 OSL_strdup(strings
[i
], buff
);
487 if (strings
[i
] == NULL
)
488 OSL_error("memory overflow");
492 generated
= osl_strings_malloc();
493 free(generated
->string
);
494 generated
->string
= strings
;
499 * \brief Concatenate two osl_strings into one. The parameter are cloned and not modified.
501 * \param dest[out] A pointer to the destination osl_strings.
502 * \param str1[in] The first osl_strings.
503 * \param str2[in] The second osl_strings.
505 void osl_strings_add_strings(
506 osl_strings_p
* dest
,
508 osl_strings_p str2
) {
509 struct osl_strings
* res
= NULL
;
512 res
= osl_strings_clone(str1
);
513 while (str2
->string
[i
] != NULL
) {
514 osl_strings_add(res
, str2
->string
[i
]);