OpenScop  0.9.0
strings.c
Go to the documentation of this file.
00001 
00002     /*+-----------------------------------------------------------------**
00003      **                       OpenScop Library                          **
00004      **-----------------------------------------------------------------**
00005      **                           strings.c                             **
00006      **-----------------------------------------------------------------**
00007      **                   First version: 13/07/2011                     **
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 <ctype.h>
00066 # include <string.h>
00067 
00068 # include <osl/macros.h>
00069 # include <osl/util.h>
00070 # include <osl/interface.h>
00071 # include <osl/strings.h>
00072 
00073 
00074 /*+***************************************************************************
00075  *                          Structure display function                       *
00076  *****************************************************************************/
00077 
00078 
00089 void osl_strings_idump(FILE * file, osl_strings_p strings, int level) {
00090   int i, nb_strings;
00091   
00092   for (i = 0; i < level; i++)
00093     fprintf(file, "|\t");
00094   
00095   if (strings != NULL) {
00096     nb_strings = osl_strings_size(strings);
00097     fprintf(file, "+-- osl_strings_t:");
00098     for (i = 0; i < nb_strings; i++)
00099       fprintf(file, " %s", strings->string[i]);
00100     fprintf(file, "\n");
00101   }
00102   else
00103     fprintf(file, "+-- NULL strings\n");
00104 
00105   // A blank line.
00106   for (i = 0; i <= level; i++)
00107     fprintf(file, "|\t");
00108   fprintf(file, "\n");
00109 }
00110 
00111 
00119 void osl_strings_dump(FILE * file, osl_strings_p strings) {
00120   osl_strings_idump(file, strings, 0);
00121 }
00122 
00123 
00131 char * osl_strings_sprint(osl_strings_p strings) {
00132   size_t i;
00133   int high_water_mark = OSL_MAX_STRING;
00134   char * string = NULL;
00135   char buffer[OSL_MAX_STRING];
00136 
00137   OSL_malloc(string, char *, high_water_mark * sizeof(char));
00138   string[0] = '\0';
00139    
00140   if (strings != NULL) {
00141     for (i = 0; i < osl_strings_size(strings); i++) {
00142       sprintf(buffer, "%s", strings->string[i]);
00143       osl_util_safe_strcat(&string, buffer, &high_water_mark);
00144       if (i < osl_strings_size(strings) - 1)
00145         osl_util_safe_strcat(&string, " ", &high_water_mark);
00146     }
00147     sprintf(buffer, "\n");
00148     osl_util_safe_strcat(&string, buffer, &high_water_mark);
00149   }
00150   else {
00151     sprintf(buffer, "# NULL strings\n");
00152     osl_util_safe_strcat(&string, buffer, &high_water_mark);
00153   }
00154 
00155   return string;
00156 }
00157 
00158 
00166 void osl_strings_print(FILE * file, osl_strings_p strings) {
00167   char * string;
00168   
00169   string = osl_strings_sprint(strings);
00170   if (string != NULL) {
00171     fprintf(file, "%s", string);
00172     free(string);
00173   }
00174 }
00175 
00176 
00177 /*+***************************************************************************
00178  *                          Structure display function                       *
00179  *****************************************************************************/
00180 
00181 
00194 osl_strings_p osl_strings_sread(char ** input) {
00195   char tmp[OSL_MAX_STRING];
00196   char * s;
00197   char ** string = NULL;
00198   int nb_strings;
00199   int i, count;
00200   osl_strings_p strings = NULL;
00201 
00202   // Skip blank/commented lines and spaces before the strings.
00203   osl_util_sskip_blank_and_comments(input);
00204   
00205   // Count the actual number of strings.
00206   nb_strings = 0;
00207   s = *input;
00208   while (1) {
00209     for (count = 0; *s && !isspace(*s) && *s != '#'; count++)
00210       s++;
00211     
00212     if (count != 0)
00213       nb_strings++;
00214 
00215     if ((!*s) || (*s == '#') || (*s == '\n'))
00216       break;
00217     else
00218       s++;
00219   }
00220 
00221   if (nb_strings > 0) {
00222     // Allocate the array of strings. Make it NULL-terminated.
00223     OSL_malloc(string, char **, sizeof(char *) * (nb_strings + 1));
00224     string[nb_strings] = NULL;
00225 
00226     // Read the desired number of strings.
00227     s = *input;
00228     for (i = 0; i < nb_strings; i++) {
00229       for (count = 0; *s && !isspace(*s) && *s != '#'; count++)
00230         tmp[count] = *(s++);
00231       tmp[count] = '\0';
00232       OSL_strdup(string[i], tmp);
00233       if (*s != '#')
00234         s++;
00235     }
00236 
00237     // Update the input pointer to the end of the strings structure.
00238     *input = s;
00239 
00240     // Build the strings structure
00241     strings = osl_strings_malloc();
00242     strings->string = string;
00243   }
00244 
00245   return strings;
00246 }
00247 
00248 
00258 osl_strings_p osl_strings_read(FILE * file) {
00259   char buffer[OSL_MAX_STRING], * start;
00260   osl_strings_p strings;
00261 
00262   start = osl_util_skip_blank_and_comments(file, buffer);
00263   strings = osl_strings_sread(&start);
00264 
00265   return strings;
00266 }
00267   
00268 
00269 /*+***************************************************************************
00270  *                    Memory allocation/deallocation function                *
00271  *****************************************************************************/
00272 
00273 
00282 osl_strings_p osl_strings_malloc() {
00283   osl_strings_p strings;
00284 
00285   OSL_malloc(strings, osl_strings_p, sizeof(osl_strings_t));
00286   OSL_malloc(strings->string, char**, sizeof(char*));
00287   strings->string[0] = NULL;
00288 
00289   return strings;
00290 }
00291 
00292 
00298 void osl_strings_free(osl_strings_p strings) {
00299   int i;
00300 
00301   if (strings != NULL) {
00302     if (strings->string != NULL) {
00303       i = 0;
00304       while (strings->string[i] != NULL) {
00305         free(strings->string[i]);
00306         i++;
00307       }
00308       free(strings->string);
00309     }
00310     free(strings);
00311   }
00312 }
00313 
00314 
00315 /*+***************************************************************************
00316  *                            Processing functions                           *
00317  *****************************************************************************/
00318 
00319 
00327 osl_strings_p osl_strings_clone(osl_strings_p strings) {
00328   int i, nb_strings;
00329   osl_strings_p clone = NULL;
00330   
00331   if (strings == NULL)
00332     return NULL;
00333 
00334   clone = osl_strings_malloc();
00335   if ((nb_strings = osl_strings_size(strings)) == 0)
00336     return clone;
00337 
00338   OSL_malloc(clone->string, char **, (nb_strings + 1) * sizeof(char *));
00339   clone->string[nb_strings] = NULL;
00340   for (i = 0; i < nb_strings; i++)
00341     OSL_strdup(clone->string[i], strings->string[i]);
00342 
00343   return clone;
00344 }
00345 
00353 size_t osl_strings_find(osl_strings_p strings, char const * const string) {
00354   size_t i;
00355   for (i = 0; i < osl_strings_size(strings); ++i) {
00356     if (strcmp(strings->string[i], string) == 0) { return i; }
00357   }
00358   return i;
00359 }
00360 
00361 
00368 void osl_strings_add(osl_strings_p strings, char const * const string) {
00369   size_t original_size = osl_strings_size(strings);
00370   OSL_realloc(strings->string, char**, sizeof(char*) * (original_size + 1 + 1));
00371   strings->string[original_size + 1] = NULL;
00372   strings->string[original_size] = malloc(sizeof(char) * (strlen(string) + 1));
00373   strcpy(strings->string[original_size], string);
00374 }
00375 
00376 
00385 int osl_strings_equal(osl_strings_p s1, osl_strings_p s2) {
00386   size_t i, nb_s1;
00387   
00388   if (s1 == s2)
00389     return 1;
00390 
00391   if (((s1 == NULL) && (s2 != NULL)) ||
00392       ((s1 != NULL) && (s2 == NULL)) ||
00393       ((nb_s1 = osl_strings_size(s1)) != osl_strings_size(s2)))
00394     return 0;
00395 
00396   for (i = 0; i < nb_s1; i++)
00397     if (strcmp(s1->string[i], s2->string[i]) != 0)
00398       return 0;
00399 
00400   return 1;
00401 }
00402 
00403 
00411 size_t osl_strings_size(osl_const_strings_const_p strings) {
00412   size_t size = 0;
00413 
00414   if ((strings != NULL) && (strings->string != NULL)) {
00415     while (strings->string[size] != NULL) {
00416       size++;
00417     }
00418   }
00419 
00420   return size;
00421 }
00422 
00423 
00431 osl_strings_p osl_strings_encapsulate(char * string) {
00432   osl_strings_p capsule = osl_strings_malloc();
00433   
00434   OSL_malloc(capsule->string, char **, 2 * sizeof(char *));
00435   capsule->string[0] = string;
00436   capsule->string[1] = NULL;
00437   
00438   return capsule;
00439 }
00440 
00441 
00448 osl_interface_p osl_strings_interface() {
00449   osl_interface_p interface = osl_interface_malloc();
00450   
00451   OSL_strdup(interface->URI, OSL_URI_STRINGS);
00452   interface->idump  = (osl_idump_f)osl_strings_idump;
00453   interface->sprint = (osl_sprint_f)osl_strings_sprint;
00454   interface->sread  = (osl_sread_f)osl_strings_sread;
00455   interface->malloc = (osl_malloc_f)osl_strings_malloc;
00456   interface->free   = (osl_free_f)osl_strings_free;
00457   interface->clone  = (osl_clone_f)osl_strings_clone;
00458   interface->equal  = (osl_equal_f)osl_strings_equal;
00459 
00460   return interface;
00461 }
00462 
00463 
00473 osl_strings_p osl_strings_generate(char * prefix, int nb_strings) {
00474   char ** strings = NULL;
00475   char buff[strlen(prefix) + 16]; // TODO: better (log10(INT_MAX) ?) :-D.
00476   int i;
00477   osl_strings_p generated;
00478 
00479   if (nb_strings) {
00480     OSL_malloc(strings, char **, sizeof(char *) * (nb_strings + 1));
00481     strings[nb_strings] = NULL;
00482     for (i = 0; i < nb_strings; i++) {
00483       sprintf(buff, "%s%d", prefix, i + 1);
00484       OSL_strdup(strings[i], buff);
00485       if (strings[i] == NULL)
00486         OSL_error("memory overflow");
00487     }
00488   }
00489 
00490   generated = osl_strings_malloc();
00491   generated->string = strings;
00492   return generated;
00493 }