OpenScop 0.8.1

arrays.c

Go to the documentation of this file.
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