1 2 /*+-----------------------------------------------------------------** 3 ** OpenScop Library ** 4 **-----------------------------------------------------------------** 5 ** extensions/arrays.c ** 6 **-----------------------------------------------------------------** 7 ** First version: 07/12/2010 ** 8 **-----------------------------------------------------------------** 9 10 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 *****************************************************************************/ 62 63#include <stdlib.h> 64#include <stdio.h> 65#include <string.h> 66#include <ctype.h> 67 68#include <osl/macros.h> 69#include <osl/util.h> 70#include <osl/strings.h> 71#include <osl/interface.h> 72#include <osl/extensions/arrays.h> 73 74 75/*+*************************************************************************** 76 * Structure display function * 77 *****************************************************************************/ 78 79 80/** 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 85 * idump functions. 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. 89 */ 90void osl_arrays_idump(FILE * file, osl_arrays_p arrays, int level) { 91 int i, j; 92 93 // Go to the right level. 94 for (j = 0; j < level; j++) 95 fprintf(file, "|\t"); 96 97 if (arrays != NULL) 98 fprintf(file, "+-- osl_arrays_t\n"); 99 else 100 fprintf(file, "+-- NULL arrays\n"); 101 102 if (arrays != NULL) { 103 // Go to the right level. 104 for(j = 0; j <= level; j++) 105 fprintf(file, "|\t"); 106 107 // Display the number of names. 108 fprintf(file, "nb_names: %d\n", arrays->nb_names); 109 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"); 115 116 fprintf(file, "id: %2d, name: %s\n", arrays->id[i], arrays->names[i]); 117 } 118 } 119 120 // The last line. 121 for (j = 0; j <= level; j++) 122 fprintf(file, "|\t"); 123 fprintf(file, "\n"); 124} 125 126 127/** 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. 133 */ 134void osl_arrays_dump(FILE * file, osl_arrays_p arrays) { 135 osl_arrays_idump(file, arrays, 0); 136} 137 138 139/** 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. 145 */ 146char * osl_arrays_sprint(osl_arrays_p arrays) { 147 int i; 148 int high_water_mark = OSL_MAX_STRING; 149 char * string = NULL; 150 char buffer[OSL_MAX_STRING]; 151 152 if (arrays != NULL) { 153 OSL_malloc(string, char *, high_water_mark * sizeof(char)); 154 string[0] = '\0'; 155 156 sprintf(buffer, "# Number of arrays\n"); 157 osl_util_safe_strcat(&string, buffer, &high_water_mark); 158 159 sprintf(buffer, "%d\n", arrays->nb_names); 160 osl_util_safe_strcat(&string, buffer, &high_water_mark); 161 162 if (arrays->nb_names) { 163 sprintf(buffer, "# Mapping array-identifiers/array-names\n"); 164 osl_util_safe_strcat(&string, buffer, &high_water_mark); 165 } 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); 169 } 170 171 OSL_realloc(string, char *, (strlen(string) + 1) * sizeof(char)); 172 } 173 174 return string; 175} 176 177 178/***************************************************************************** 179 * Reading function * 180 *****************************************************************************/ 181 182 183/** 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. 193 */ 194osl_arrays_p osl_arrays_sread(char ** input) { 195 int i, k; 196 int nb_names; 197 osl_arrays_p arrays; 198 199 if (input == NULL) { 200 OSL_debug("no arrays optional tag"); 201 return NULL; 202 } 203 204 // Find the number of names provided. 205 nb_names = osl_util_read_int(NULL, input); 206 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; 214 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); 219 220 // Get the array name string. 221 arrays->names[k] = osl_util_read_string(NULL, input); 222 } 223 224 return arrays; 225} 226 227 228/*+*************************************************************************** 229 * Memory allocation/deallocation function * 230 *****************************************************************************/ 231 232 233/** 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 239 * default values. 240 */ 241osl_arrays_p osl_arrays_malloc() { 242 osl_arrays_p arrays; 243 244 OSL_malloc(arrays, osl_arrays_p, sizeof(osl_arrays_t)); 245 arrays->nb_names = 0; 246 arrays->id = NULL; 247 arrays->names = NULL; 248 249 return arrays; 250} 251 252 253/** 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. 257 */ 258void osl_arrays_free(osl_arrays_p arrays) { 259 int i; 260 261 if (arrays != NULL) { 262 free(arrays->id); 263 for (i = 0; i < arrays->nb_names; i++) 264 free(arrays->names[i]); 265 free(arrays->names); 266 free(arrays); 267 } 268} 269 270 271/*+*************************************************************************** 272 * Processing functions * 273 *****************************************************************************/ 274 275 276/** 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. 282 */ 283osl_arrays_p osl_arrays_clone(osl_arrays_p arrays) { 284 int i; 285 osl_arrays_p clone; 286 287 if (arrays == NULL) 288 return NULL; 289 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*)); 294 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]); 298 } 299 300 return clone; 301} 302 303 304/** 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. 313 */ 314int osl_arrays_equal(osl_arrays_p a1, osl_arrays_p a2) { 315 int i, j, found; 316 317 if (a1 == a2) 318 return 1; 319 320 if (((a1 == NULL) && (a2 != NULL)) || ((a1 != NULL) && (a2 == NULL))) 321 return 0; 322 323 // Check whether the number of names is the same. 324 if (a1->nb_names != a2->nb_names) 325 return 0; 326 327 // We accept a different order of the names, as long as the identifiers 328 // are the same. 329 for (i = 0; i < a1->nb_names; i++) { 330 found = 0; 331 for (j = 0; j < a2->nb_names; j++) { 332 if ((a1->id[i] == a2->id[j]) && (!strcmp(a1->names[i], a2->names[j]))) { 333 found = 1; 334 break; 335 } 336 } 337 if (found != 1) 338 return 0; 339 } 340 341 return 1; 342} 343 344 345/** 346 * osl_arrays_to_strings function: 347 * this function creates a strings structure containing the textual names 348 * contained in a names structure. Each name is placed according to its 349 * id in the strings array. The "empty" strings cells are filled with 350 * dummy names. 351 * \param[in] arrays The arrays structure to convert to a strings. 352 * \return A strings structure containing all the array names. 353 */ 354osl_strings_p osl_arrays_to_strings(osl_arrays_p arrays) { 355 int i, max_id = 0; 356 osl_strings_p strings = NULL; 357 358 if (arrays == NULL) 359 return NULL; 360 361 // Find the maximum array id. 362 if (arrays->nb_names >= 1) { 363 max_id = arrays->id[0]; 364 for (i = 1; i < arrays->nb_names; i++) 365 if (arrays->id[i] > max_id) 366 max_id = arrays->id[i]; 367 } 368 369 // Build a strings structure for this number of ids. 370 strings = osl_strings_generate("Dummy", max_id); 371 for (i = 0; i < arrays->nb_names; i++) { 372 free(strings->string[arrays->id[i] - 1]); 373 OSL_strdup(strings->string[arrays->id[i] - 1], arrays->names[i]); 374 } 375 376 return strings; 377} 378 379 380/** 381 * osl_arrays_interface function: 382 * this function creates an interface structure corresponding to the arrays 383 * extension and returns it). 384 * \return An interface structure for the arrays extension. 385 */ 386osl_interface_p osl_arrays_interface() { 387 osl_interface_p interface = osl_interface_malloc(); 388 389 interface->URI = strdup(OSL_URI_ARRAYS); 390 interface->idump = (osl_idump_f)osl_arrays_idump; 391 interface->sprint = (osl_sprint_f)osl_arrays_sprint; 392 interface->sread = (osl_sread_f)osl_arrays_sread; 393 interface->malloc = (osl_malloc_f)osl_arrays_malloc; 394 interface->free = (osl_free_f)osl_arrays_free; 395 interface->clone = (osl_clone_f)osl_arrays_clone; 396 interface->equal = (osl_equal_f)osl_arrays_equal; 397 398 return interface; 399} 400 401 402