Return type of osl_relation_list_count function is size_t
[openscop.git] / source / strings.c
blob0a4c2bd48af6597dd0ab42f5b1e4965b91eb9eb2
2 /*+-----------------------------------------------------------------**
3 ** OpenScop Library **
4 **-----------------------------------------------------------------**
5 ** strings.c **
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 * '---'-'---'---'---'---'-'---'-'---'---'---'-'---'-'---' '--' *
29 * *
30 * Copyright (C) 2008 University Paris-Sud 11 and INRIA *
31 * *
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 *
35 * are met: *
36 * *
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. *
44 * *
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. *
55 * *
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> *
60 * *
61 *****************************************************************************/
63 # include <stdlib.h>
64 # include <stdio.h>
65 # include <ctype.h>
66 # include <string.h>
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 *****************************************************************************/
79 /**
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
84 * idump functions.
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) {
90 int i, nb_strings;
92 for (i = 0; i < level; i++)
93 fprintf(file, "|\t");
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]);
100 fprintf(file, "\n");
102 else
103 fprintf(file, "+-- NULL strings\n");
105 // A blank line.
106 for (i = 0; i <= level; i++)
107 fprintf(file, "|\t");
108 fprintf(file, "\n");
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) {
132 size_t i;
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));
138 string[0] = '\0';
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);
150 else {
151 sprintf(buffer, "# NULL strings\n");
152 osl_util_safe_strcat(&string, buffer, &high_water_mark);
155 return string;
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) {
167 char * string;
169 string = osl_strings_sprint(strings);
170 if (string != NULL) {
171 fprintf(file, "%s", string);
172 free(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];
196 char * s;
197 char ** string = NULL;
198 int nb_strings;
199 int i, count;
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.
206 nb_strings = 0;
207 s = *input;
208 while (1) {
209 for (count = 0; *s && !isspace(*s) && *s != '#'; count++)
210 s++;
212 if (count != 0)
213 nb_strings++;
215 if ((!*s) || (*s == '#') || (*s == '\n'))
216 break;
217 else
218 s++;
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.
227 s = *input;
228 for (i = 0; i < nb_strings; i++) {
229 for (count = 0; *s && !isspace(*s) && *s != '#'; count++)
230 tmp[count] = *(s++);
231 tmp[count] = '\0';
232 OSL_strdup(string[i], tmp);
233 if (*s != '#')
234 s++;
237 // Update the input pointer to the end of the strings structure.
238 *input = s;
240 // Build the strings structure
241 strings = osl_strings_malloc();
242 strings->string = string;
245 return strings;
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
253 * structure.
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);
265 return strings;
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
280 * default values.
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;
289 return strings;
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) {
299 int i;
301 if (strings != NULL) {
302 if (strings->string != NULL) {
303 i = 0;
304 while (strings->string[i] != NULL) {
305 free(strings->string[i]);
306 i++;
308 free(strings->string);
310 free(strings);
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) {
328 int i, nb_strings;
329 osl_strings_p clone = NULL;
331 if (strings == NULL)
332 return NULL;
334 clone = osl_strings_malloc();
335 if ((nb_strings = osl_strings_size(strings)) == 0)
336 return clone;
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]);
343 return clone;
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) {
354 size_t i;
355 for (i = 0; i < osl_strings_size(strings); ++i) {
356 if (strcmp(strings->string[i], string) == 0) { return i; }
358 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) {
386 size_t i, nb_s1;
388 if (s1 == s2)
389 return 1;
391 if (((s1 == NULL) && (s2 != NULL)) ||
392 ((s1 != NULL) && (s2 == NULL)) ||
393 ((nb_s1 = osl_strings_size(s1)) != osl_strings_size(s2)))
394 return 0;
396 for (i = 0; i < nb_s1; i++)
397 if (strcmp(s1->string[i], s2->string[i]) != 0)
398 return 0;
400 return 1;
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) {
412 size_t size = 0;
414 if ((strings != NULL) && (strings->string != NULL)) {
415 while (strings->string[size] != NULL) {
416 size++;
420 return size;
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;
438 return capsule;
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;
460 return interface;
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
468 * nb_strings.
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.
476 int i;
477 osl_strings_p generated;
479 if (nb_strings) {
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;
492 return generated;