OpenScop 0.8.1
|
00001 00002 /*+-----------------------------------------------------------------** 00003 ** OpenScop Library ** 00004 **-----------------------------------------------------------------** 00005 ** extensions/arrays.c ** 00006 **-----------------------------------------------------------------** 00007 ** First version: 07/12/2010 ** 00008 **-----------------------------------------------------------------** 00009 00010 00011 ***************************************************************************** 00012 * OpenScop: Structures and formats for polyhedral tools to talk together * 00013 ***************************************************************************** 00014 * ,___,,_,__,,__,,__,,__,,_,__,,_,__,,__,,___,_,__,,_,__, * 00015 * / / / // // // // / / / // // / / // / /|,_, * 00016 * / / / // // // // / / / // // / / // / / / /\ * 00017 * |~~~|~|~~~|~~~|~~~|~~~|~|~~~|~|~~~|~~~|~~~|~|~~~|~|~~~|/_/ \ * 00018 * | G |C| P | = | L | P |=| = |C| = | = | = |=| = |=| C |\ \ /\ * 00019 * | R |l| o | = | e | l |=| = |a| = | = | = |=| = |=| L | \# \ /\ * 00020 * | A |a| l | = | t | u |=| = |n| = | = | = |=| = |=| o | |\# \ \ * 00021 * | P |n| l | = | s | t |=| = |d| = | = | = | | |=| o | | \# \ \ * 00022 * | H | | y | | e | o | | = |l| | | = | | | | G | | \ \ \ * 00023 * | I | | | | e | | | | | | | | | | | | | \ \ \ * 00024 * | T | | | | | | | | | | | | | | | | | \ \ \ * 00025 * | E | | | | | | | | | | | | | | | | | \ \ \ * 00026 * | * |*| * | * | * | * |*| * |*| * | * | * |*| * |*| * | / \* \ \ * 00027 * | O |p| e | n | S | c |o| p |-| L | i | b |r| a |r| y |/ \ \ / * 00028 * '---'-'---'---'---'---'-'---'-'---'---'---'-'---'-'---' '--' * 00029 * * 00030 * Copyright (C) 2008 University Paris-Sud 11 and INRIA * 00031 * * 00032 * (3-clause BSD license) * 00033 * Redistribution and use in source and binary forms, with or without * 00034 * modification, are permitted provided that the following conditions * 00035 * are met: * 00036 * * 00037 * 1. Redistributions of source code must retain the above copyright notice, * 00038 * this list of conditions and the following disclaimer. * 00039 * 2. Redistributions in binary form must reproduce the above copyright * 00040 * notice, this list of conditions and the following disclaimer in the * 00041 * documentation and/or other materials provided with the distribution. * 00042 * 3. The name of the author may not be used to endorse or promote products * 00043 * derived from this software without specific prior written permission. * 00044 * * 00045 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * 00046 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * 00047 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * 00048 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * 00049 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * 00050 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * 00051 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * 00052 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * 00053 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * 00054 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * 00055 * * 00056 * OpenScop Library, a library to manipulate OpenScop formats and data * 00057 * structures. Written by: * 00058 * Cedric Bastoul <Cedric.Bastoul@u-psud.fr> and * 00059 * Louis-Noel Pouchet <Louis-Noel.pouchet@inria.fr> * 00060 * * 00061 *****************************************************************************/ 00062 00063 #include <stdlib.h> 00064 #include <stdio.h> 00065 #include <string.h> 00066 #include <ctype.h> 00067 00068 #include <osl/macros.h> 00069 #include <osl/util.h> 00070 #include <osl/strings.h> 00071 #include <osl/interface.h> 00072 #include <osl/extensions/arrays.h> 00073 00074 00075 /*+*************************************************************************** 00076 * Structure display function * 00077 *****************************************************************************/ 00078 00079 00090 void osl_arrays_idump(FILE * file, osl_arrays_p arrays, int level) { 00091 int i, j; 00092 00093 // Go to the right level. 00094 for (j = 0; j < level; j++) 00095 fprintf(file, "|\t"); 00096 00097 if (arrays != NULL) 00098 fprintf(file, "+-- osl_arrays_t\n"); 00099 else 00100 fprintf(file, "+-- NULL arrays\n"); 00101 00102 if (arrays != NULL) { 00103 // Go to the right level. 00104 for(j = 0; j <= level; j++) 00105 fprintf(file, "|\t"); 00106 00107 // Display the number of names. 00108 fprintf(file, "nb_names: %d\n", arrays->nb_names); 00109 00110 // Display the id/name. 00111 for(i = 0; i < arrays->nb_names; i++) { 00112 // Go to the right level. 00113 for(j = 0; j <= level; j++) 00114 fprintf(file, "|\t"); 00115 00116 fprintf(file, "id: %2d, name: %s\n", arrays->id[i], arrays->names[i]); 00117 } 00118 } 00119 00120 // The last line. 00121 for (j = 0; j <= level; j++) 00122 fprintf(file, "|\t"); 00123 fprintf(file, "\n"); 00124 } 00125 00126 00134 void osl_arrays_dump(FILE * file, osl_arrays_p arrays) { 00135 osl_arrays_idump(file, arrays, 0); 00136 } 00137 00138 00146 char * osl_arrays_sprint(osl_arrays_p arrays) { 00147 int i; 00148 int high_water_mark = OSL_MAX_STRING; 00149 char * string = NULL; 00150 char * buffer; 00151 00152 if (arrays != NULL) { 00153 OSL_malloc(string, char *, high_water_mark * sizeof(char)); 00154 OSL_malloc(buffer, char *, OSL_MAX_STRING * sizeof(char)); 00155 string[0] = '\0'; 00156 00157 sprintf(buffer, OSL_TAG_ARRAYS_START); 00158 osl_util_safe_strcat(&string, buffer, &high_water_mark); 00159 00160 sprintf(buffer, "\n%d\n", arrays->nb_names); 00161 osl_util_safe_strcat(&string, buffer, &high_water_mark); 00162 00163 for (i = 0; i < arrays->nb_names; i++) { 00164 sprintf(buffer, "%d %s\n", arrays->id[i], arrays->names[i]); 00165 osl_util_safe_strcat(&string, buffer, &high_water_mark); 00166 } 00167 sprintf(buffer, OSL_TAG_ARRAYS_STOP"\n"); 00168 osl_util_safe_strcat(&string, buffer, &high_water_mark); 00169 00170 OSL_realloc(string, char *, (strlen(string) + 1) * sizeof(char)); 00171 free(buffer); 00172 } 00173 00174 return string; 00175 } 00176 00177 00178 /***************************************************************************** 00179 * Reading function * 00180 *****************************************************************************/ 00181 00182 00191 osl_arrays_p osl_arrays_sread(char ** extensions_fixme) { 00192 int i, k, array_id; 00193 int nb_names; 00194 int * id; 00195 char ** names; 00196 char * content, * content_backup; 00197 char buff[OSL_MAX_STRING]; 00198 osl_arrays_p arrays; 00199 00200 // FIXME: this is a quick and dirty thing to accept char ** instead 00201 // of char * in the parameter: really do it and update the 00202 // pointer to after what has been read. 00203 content = *extensions_fixme; 00204 00205 if (content == NULL) { 00206 OSL_debug("no arrays optional tag"); 00207 return NULL; 00208 } 00209 content_backup = content; 00210 00211 // Find the number of names provided. 00212 nb_names = osl_util_read_int(NULL, &content); 00213 00214 // Allocate the array of id and names. 00215 id = (int *)malloc(nb_names * sizeof(int)); 00216 names = (char **)malloc(nb_names * sizeof(char *)); 00217 for (i = 0; i < nb_names; i++) 00218 names[i] = NULL; 00219 00220 // Get each array name. 00221 for (k = 0; k < nb_names; k++) { 00222 // Skip blank or commented lines. 00223 while (*content == '#' || *content == '\n') { 00224 for (; *content != '\n'; ++content) 00225 continue; 00226 ++content; 00227 } 00228 00229 // Get the array name id. 00230 for (i = 0; *content && ! isspace(*content); ++i, ++content) 00231 buff[i] = *content; 00232 buff[i] = '\0'; 00233 sscanf(buff, "%d", &array_id); 00234 if (array_id <= 0) 00235 OSL_error("array id must be > 0"); 00236 id[k] = array_id; 00237 00238 // Get the array name string. 00239 while (*content && isspace(*content)) 00240 ++content; 00241 for (i = 0; *content && ! isspace(*content); ++i, ++content) 00242 buff[i] = *content; 00243 buff[i] = '\0'; 00244 names[k] = strdup(buff); 00245 00246 // Go to the end of line. 00247 while (*content && *content != '\n') 00248 ++content; 00249 } 00250 free(content_backup); 00251 00252 arrays = osl_arrays_malloc(); 00253 arrays->nb_names = nb_names; 00254 arrays->id = id; 00255 arrays->names = names; 00256 00257 return arrays; 00258 } 00259 00260 00261 /*+*************************************************************************** 00262 * Memory allocation/deallocation function * 00263 *****************************************************************************/ 00264 00265 00274 osl_arrays_p osl_arrays_malloc() { 00275 osl_arrays_p arrays; 00276 00277 OSL_malloc(arrays, osl_arrays_p, sizeof(osl_arrays_t)); 00278 arrays->nb_names = 0; 00279 arrays->id = NULL; 00280 arrays->names = NULL; 00281 00282 return arrays; 00283 } 00284 00285 00291 void osl_arrays_free(osl_arrays_p arrays) { 00292 int i; 00293 00294 if (arrays != NULL) { 00295 if (arrays->names != NULL) { 00296 free(arrays->id); 00297 for (i = 0; i < arrays->nb_names; i++) 00298 free(arrays->names[i]); 00299 free(arrays->names); 00300 } 00301 00302 free(arrays); 00303 } 00304 } 00305 00306 00307 /*+*************************************************************************** 00308 * Processing functions * 00309 *****************************************************************************/ 00310 00311 00319 osl_arrays_p osl_arrays_clone(osl_arrays_p arrays) { 00320 osl_arrays_p copy; 00321 int i; 00322 00323 if (arrays == NULL) 00324 return NULL; 00325 00326 copy = osl_arrays_malloc(); 00327 if (copy != NULL) { 00328 copy->nb_names = arrays->nb_names; 00329 copy->id = (int *)malloc(arrays->nb_names * sizeof(int)); 00330 OSL_malloc(copy->names, char **, arrays->nb_names * sizeof(char*)); 00331 00332 for (i = 0; i < arrays->nb_names; i++) { 00333 copy->id[i] = arrays->id[i]; 00334 copy->names[i] = strdup(arrays->names[i]); 00335 if ((copy->names[i] == NULL) && (arrays->names[i] != NULL)) 00336 OSL_error("memory overflow"); 00337 } 00338 } 00339 00340 return copy; 00341 } 00342 00343 00354 int osl_arrays_equal(osl_arrays_p a1, osl_arrays_p a2) { 00355 int i, j, found; 00356 00357 if (a1 == a2) 00358 return 1; 00359 00360 if (((a1 == NULL) && (a2 != NULL)) || ((a1 != NULL) && (a2 == NULL))) 00361 return 0; 00362 00363 // Check whether the number of names is the same. 00364 if (a1->nb_names != a2->nb_names) 00365 return 0; 00366 00367 // We accept a different order of the names, as long as the identifiers 00368 // are the same. 00369 for (i = 0; i < a1->nb_names; i++) { 00370 found = 0; 00371 for (j = 0; j < a2->nb_names; j++) { 00372 if ((a1->id[i] == a2->id[j]) && (!strcmp(a1->names[i], a2->names[j]))) { 00373 found = 1; 00374 break; 00375 } 00376 } 00377 if (found != 1) 00378 return 0; 00379 } 00380 00381 return 1; 00382 } 00383 00384 00396 char ** osl_arrays_generate_names(osl_arrays_p arrays, int * nb_names) { 00397 char ** names = NULL; 00398 char ** tmpnames; 00399 int i; 00400 00401 *nb_names = 0; 00402 00403 if (arrays != NULL) { 00404 // Get the maximum id (it will be nb_names). 00405 for (i = 0; i < arrays->nb_names; i++) 00406 if (arrays->id[i] > *nb_names) 00407 *nb_names = arrays->id[i]; 00408 00409 // Allocate the array of names and store the existing names. 00410 OSL_malloc(names, char **, *nb_names * sizeof(char *)); 00411 for (i = 0; i < arrays->nb_names; i++) { 00412 names[arrays->id[i] - 1] = strdup(arrays->names[i]); 00413 if (names[arrays->id[i] - 1] == NULL) 00414 OSL_error("memory overflow"); 00415 } 00416 00417 // Fill the missing names. 00418 // TODO : update this with the new osl_strings_t 00419 /* 00420 tmpnames = osl_strings_generate("A_", *nb_names); 00421 for (i = 0; i < *nb_names; i++) { 00422 if (names[i] == NULL || names[i][0] == '\0') 00423 names[i] = tmpnames[i]; // Use a generated name. 00424 else 00425 free(tmpnames[i]); // Use a read name. 00426 } 00427 free(tmpnames); 00428 */ 00429 } 00430 00431 return names; 00432 } 00433 00434 00441 osl_interface_p osl_arrays_interface() { 00442 osl_interface_p interface = osl_interface_malloc(); 00443 00444 interface->URI = strdup(OSL_URI_ARRAYS); 00445 interface->idump = (osl_idump_f)osl_arrays_idump; 00446 interface->sprint = (osl_sprint_f)osl_arrays_sprint; 00447 interface->sread = (osl_sread_f)osl_arrays_sread; 00448 interface->malloc = (osl_malloc_f)osl_arrays_malloc; 00449 interface->free = (osl_free_f)osl_arrays_free; 00450 interface->clone = (osl_clone_f)osl_arrays_clone; 00451 interface->equal = (osl_equal_f)osl_arrays_equal; 00452 00453 return interface; 00454 } 00455 00456