2 /*+-----------------------------------------------------------------**
4 **-----------------------------------------------------------------**
6 **-----------------------------------------------------------------**
7 ** First version: 08/10/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 *****************************************************************************/
67 # include <osl/util.h>
70 /*+***************************************************************************
72 *****************************************************************************/
76 * osl_util_skip_blank_and_comments internal function.
77 * This function reads the open file 'file' line by line and skips
78 * blank/comment lines and spaces. The first line where there is some
79 * useful information is stored at the address 'str' (the memory to
80 * store the line must be allocated before the call to this function
81 * and must be at least OSL_MAX_STRING*sizeof(char)). The pointer
82 * to the first useful information in this line is returned by the
84 * \param file The (opened) file to read.
85 * \param str Address of an allocated space to store the first line
86 * that contains useful information.
87 * \return The address of the the first useful digit in str.
89 char * osl_util_skip_blank_and_comments(FILE * file
, char * str
) {
93 start
= fgets(str
, OSL_MAX_STRING
, file
);
94 while ((start
!= NULL
) && isspace(*start
) && (*start
!= '\n'))
97 while (start
!= NULL
&& (*start
== '#' || *start
== '\n'));
104 * osl_util_read_int internal function.
105 * Read an int on the input 'file' or the input string 'str' depending on
106 * which one is not NULL (exactly one of them must not be NULL).
107 * \param file The file where to read an int (if not NULL).
108 * \param str The string where to read an int (if not NULL). This pointer
109 * is updated to reflect the read and points after the int.
110 * \return The int that have been read.
112 int osl_util_read_int(FILE * file
, char ** str
) {
113 char s
[OSL_MAX_STRING
], * start
;
118 if ((file
!= NULL
&& str
!= NULL
) || (file
== NULL
&& str
== NULL
))
119 OSL_error("one and only one of the two parameters"
120 " of util_read_int can be non-NULL");
123 // Parse from a file.
124 start
= osl_util_skip_blank_and_comments(file
, s
);
125 if (sscanf(start
, " %d", &res
) != 1)
126 OSL_error("an int was expected");
129 // Parse from a string.
130 // Skip blank/commented lines.
132 while (*str
&& **str
&& isspace(**str
))
135 while (**str
&& **str
!= '\n')
139 // Build the chain to analyze.
140 while (**str
&& !isspace(**str
) && **str
!= '\n')
141 s
[i
++] = *((*str
)++);
143 if (sscanf(s
, "%d", &res
) != 1)
144 OSL_error("an int was expected");
156 * osl_util_read_uptotag function:
157 * this function reads a file up to a given tag (the tag is read) or the
158 * end of file. It puts everything it reads in a string which is returned.
159 * \param[in] file The file where to read the tail.
160 * \param[in] tag The tag which, when reached, stops the file reading.
161 * \return The string that has been read from the file.
163 char * osl_util_read_uptotag(FILE * file
, char * tag
) {
164 int high_water_mark
= OSL_MAX_STRING
;
166 int lentag
= strlen(tag
);
170 OSL_malloc(res
, char *, high_water_mark
* sizeof(char));
172 // - Copy everything else to the res string.
173 while (!feof(file
)) {
174 res
[nb_chars
] = fgetc(file
);
177 if ((nb_chars
>= lentag
) &&
178 (!strncmp(&res
[nb_chars
- lentag
], tag
, lentag
))) {
183 if (nb_chars
>= high_water_mark
) {
184 high_water_mark
+= high_water_mark
;
185 OSL_realloc(res
, char *, high_water_mark
* sizeof(char));
190 OSL_info("tag was not found, end of file reached");
192 // - 0-terminate the string.
193 OSL_realloc(res
, char *, (nb_chars
+ 1) * sizeof(char));
194 res
[nb_chars
] = '\0';
201 * osl_util_tag_content function:
202 * This function returns a freshly allocated string containing the
203 * content, in the given string 'str', between the tag 'tag' and
204 * the tag 'endtag'. If the tag 'tag' is not found, returns NULL.
205 * \param str The string where to find a given content.
206 * \param tag The string that marks the beginning of the content.
207 * \param endtag The string that marks the end of the content.
208 * \return The string between 'tag' and 'endtag' in 'str'.
210 char * osl_util_tag_content(char * str
, char * tag
, char * endtag
) {
220 lentag
= strlen(tag
);
221 for (; start
&& *start
&& strncmp(start
, tag
, lentag
); ++start
)
224 // The tag 'tag' was not found.
229 lentag
= strlen(endtag
);
230 for (size
= 0; *stop
&& strncmp(stop
, endtag
, lentag
); ++stop
, ++size
)
233 // the tag 'endtag' was not found.
236 OSL_malloc(res
, char *, (size
+ 1) * sizeof(char));
238 // Copy the chain between the two tags.
239 for (++start
, i
= 0; start
!= stop
; ++start
, ++i
)
249 * osl_util_safe_strcat function:
250 * this function concatenates the string src to the string *dst
251 * and reallocates *dst if necessary. The current size of the
252 * *dst buffer must be *hwm (high water mark), if there is some
253 * reallocation, this value is updated.
254 * \param dst pointer to the destination string (may be reallocated).
255 * \param src string to concatenate to dst.
256 * \param hwm pointer to the size of the *dst buffer (may be updated).
257 * TODO: This function is not that safe, improve it !
259 void osl_util_safe_strcat(char ** dst
, char * src
, int * hwm
) {
261 if (strlen(src
) >= OSL_MAX_STRING
)
262 OSL_error("string to concatenate is too long");
264 if (strlen(*dst
) + strlen(src
) >= *hwm
) {
265 *hwm
+= OSL_MAX_STRING
;
266 OSL_realloc(*dst
, char *, *hwm
* sizeof(char));
274 * osl_util_get_precision function:
275 * this function returns the precision defined by the precision environment
276 * variable or the highest available precision if it is not defined.
277 * \return environment precision if defined or highest available precision.
279 int osl_util_get_precision() {
280 int precision
= OSL_PRECISION_DP
;
281 char * precision_env
;
283 #ifdef OSL_GMP_IS_HERE
284 precision
= OSL_PRECISION_MP
;
287 precision_env
= getenv(OSL_PRECISION_ENV
);
288 if (precision_env
!= NULL
) {
289 if (!strcmp(precision_env
, OSL_PRECISION_ENV_SP
))
290 precision
= OSL_PRECISION_SP
;
291 else if (!strcmp(precision_env
, OSL_PRECISION_ENV_DP
))
292 precision
= OSL_PRECISION_DP
;
293 else if (!strcmp(precision_env
, OSL_PRECISION_ENV_MP
))
294 precision
= OSL_PRECISION_MP
;
296 OSL_warning("bad precision environment value");
304 * osl_util_print_provided function:
305 * this function prints a "provided" boolean in a file (file, possibly stdout),
306 * with a comment title according to the OpenScop specification.
307 * \param[in] file File where the information has to be printed.
308 * \param[in] provided The provided boolean to print.
309 * \param[in] title A string to use as a title for the provided booblean.
311 void osl_util_print_provided(FILE * file
, int provided
, char * title
) {
313 fprintf(file
, "# %s provided\n", title
);
314 fprintf(file
, "1\n");
317 fprintf(file
, "# %s not provided\n", title
);
318 fprintf(file
, "0\n\n");