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 strings
->string
= string
;
250 * osl_strings_read function.
251 * this function reads a strings structure from a file (possibly stdin)
252 * complying to the OpenScop textual format and returns a pointer to this
254 * parameter nb_strings).
255 * \param[in] file The file where to read the strings structure.
256 * \return The strings structure that has been read.
258 osl_strings_p
osl_strings_read(FILE * file
) {
259 char buffer
[OSL_MAX_STRING
], * start
;
260 osl_strings_p strings
;
262 start
= osl_util_skip_blank_and_comments(file
, buffer
);
263 strings
= osl_strings_sread(&start
);
269 /*+***************************************************************************
270 * Memory allocation/deallocation function *
271 *****************************************************************************/
275 * osl_strings_malloc function:
276 * This function allocates the memory space for an osl_strings_t
277 * structure and sets its fields with default values. Then it returns a
278 * pointer to the allocated space.
279 * \return A pointer to an empty strings structure with fields set to
282 osl_strings_p
osl_strings_malloc() {
283 osl_strings_p strings
;
285 OSL_malloc(strings
, osl_strings_p
, sizeof(osl_strings_t
));
286 OSL_malloc(strings
->string
, char**, sizeof(char*));
287 strings
->string
[0] = NULL
;
294 * osl_strings_free function:
295 * this function frees the allocated memory for a strings data structure.
296 * \param[in] strings The strings structure we want to free.
298 void osl_strings_free(osl_strings_p strings
) {
301 if (strings
!= NULL
) {
302 if (strings
->string
!= NULL
) {
304 while (strings
->string
[i
] != NULL
) {
305 free(strings
->string
[i
]);
308 free(strings
->string
);
315 /*+***************************************************************************
316 * Processing functions *
317 *****************************************************************************/
321 * osl_strings_clone function.
322 * this function builds and return a "hard copy" (not a pointer copy) of an
323 * strings structure provided as parameter.
324 * \param[in] strings The strings structure to clone.
325 * \return The clone of the strings structure.
327 osl_strings_p
osl_strings_clone(osl_strings_p strings
) {
329 osl_strings_p clone
= NULL
;
334 clone
= osl_strings_malloc();
335 if ((nb_strings
= osl_strings_size(strings
)) == 0)
338 OSL_malloc(clone
->string
, char **, (nb_strings
+ 1) * sizeof(char *));
339 clone
->string
[nb_strings
] = NULL
;
340 for (i
= 0; i
< nb_strings
; i
++)
341 OSL_strdup(clone
->string
[i
], strings
->string
[i
]);
347 * osl_strings_find function.
348 * this function finds the string in the strings.
349 * \param[in,out] strings The strings structure.
350 * \param[in] string The string to find in strings.
351 * \return the index where is the string, osl_strings_size if not found
353 size_t osl_strings_find(osl_strings_p strings
, char const * const string
) {
355 for (i
= 0; i
< osl_strings_size(strings
); ++i
) {
356 if (strcmp(strings
->string
[i
], string
) == 0) { return i
; }
363 * osl_strings_add function.
364 * this function adds a copy of the string in the strings.
365 * \param[in,out] strings The strings structure.
366 * \param[in] string The string to add in strings.
368 void osl_strings_add(osl_strings_p strings
, char const * const string
) {
369 size_t original_size
= osl_strings_size(strings
);
370 OSL_realloc(strings
->string
, char**, sizeof(char*) * (original_size
+ 1 + 1));
371 strings
->string
[original_size
+ 1] = NULL
;
372 strings
->string
[original_size
] = malloc(sizeof(char) * (strlen(string
) + 1));
373 strcpy(strings
->string
[original_size
], string
);
378 * osl_strings_equal function:
379 * this function returns true if the two strings structures are the same
380 * (content-wise), false otherwise.
381 * \param[in] s1 The first strings structure.
382 * \param[in] s2 The second strings structure.
383 * \return 1 if s1 and s2 are the same (content-wise), 0 otherwise.
385 int osl_strings_equal(osl_strings_p s1
, osl_strings_p s2
) {
391 if (((s1
== NULL
) && (s2
!= NULL
)) ||
392 ((s1
!= NULL
) && (s2
== NULL
)) ||
393 ((nb_s1
= osl_strings_size(s1
)) != osl_strings_size(s2
)))
396 for (i
= 0; i
< nb_s1
; i
++)
397 if (strcmp(s1
->string
[i
], s2
->string
[i
]) != 0)
405 * osl_strings_size function:
406 * this function returns the number of elements in the NULL-terminated
407 * strings array of the strings structure.
408 * \param[in] strings The strings structure we need to know the size.
409 * \return The number of strings in the strings structure.
411 size_t osl_strings_size(osl_const_strings_const_p strings
) {
414 if ((strings
!= NULL
) && (strings
->string
!= NULL
)) {
415 while (strings
->string
[size
] != NULL
) {
425 * osl_strings_encapsulate function:
426 * this function builds a new strings structure to encapsulate the string
427 * provided as a parameter (the reference to this string is used directly).
428 * \param[in] string The string to encapsulate in a strings structure.
429 * \return A new strings structure containing only the provided string.
431 osl_strings_p
osl_strings_encapsulate(char * string
) {
432 osl_strings_p capsule
= osl_strings_malloc();
434 OSL_malloc(capsule
->string
, char **, 2 * sizeof(char *));
435 capsule
->string
[0] = string
;
436 capsule
->string
[1] = NULL
;
443 * osl_strings_interface function:
444 * this function creates an interface structure corresponding to the strings
445 * structure and returns it).
446 * \return An interface structure for the strings structure.
448 osl_interface_p
osl_strings_interface() {
449 osl_interface_p interface
= osl_interface_malloc();
451 OSL_strdup(interface
->URI
, OSL_URI_STRINGS
);
452 interface
->idump
= (osl_idump_f
)osl_strings_idump
;
453 interface
->sprint
= (osl_sprint_f
)osl_strings_sprint
;
454 interface
->sread
= (osl_sread_f
)osl_strings_sread
;
455 interface
->malloc
= (osl_malloc_f
)osl_strings_malloc
;
456 interface
->free
= (osl_free_f
)osl_strings_free
;
457 interface
->clone
= (osl_clone_f
)osl_strings_clone
;
458 interface
->equal
= (osl_equal_f
)osl_strings_equal
;
465 * osl_strings_generate function:
466 * this function generates a new strings structure containing
467 * 'nb_strings' strings of the form "prefixXX" where XX goes from 1 to
469 * \param[in] prefix The prefix of the generated strings.
470 * \param[in] nb_strings The number of strings to generate.
471 * \return A new strings structure containing generated strings.
473 osl_strings_p
osl_strings_generate(char * prefix
, int nb_strings
) {
474 char ** strings
= NULL
;
475 char buff
[strlen(prefix
) + 16]; // TODO: better (log10(INT_MAX) ?) :-D.
477 osl_strings_p generated
;
480 OSL_malloc(strings
, char **, sizeof(char *) * (nb_strings
+ 1));
481 strings
[nb_strings
] = NULL
;
482 for (i
= 0; i
< nb_strings
; i
++) {
483 sprintf(buff
, "%s%d", prefix
, i
+ 1);
484 OSL_strdup(strings
[i
], buff
);
485 if (strings
[i
] == NULL
)
486 OSL_error("memory overflow");
490 generated
= osl_strings_malloc();
491 generated
->string
= strings
;