OpenScop 0.8.1

generic.c

Go to the documentation of this file.
00001 
00002     /*+-----------------------------------------------------------------**
00003      **                       OpenScop Library                          **
00004      **-----------------------------------------------------------------**
00005      **                           generic.c                             **
00006      **-----------------------------------------------------------------**
00007      **                   First version: 26/11/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 
00067 #include <osl/macros.h>
00068 #include <osl/util.h>
00069 #include <osl/interface.h>
00070 #include <osl/generic.h>
00071 
00072 
00073 /*+***************************************************************************
00074  *                          Structure display function                       *
00075  *****************************************************************************/
00076 
00077 
00088 void osl_generic_idump(FILE * file, osl_generic_p generic, int level) {
00089   int j, first = 1;
00090   
00091   // Go to the right level.
00092   for (j = 0; j < level; j++)
00093     fprintf(file,"|\t");
00094 
00095   if (generic != NULL)
00096     fprintf(file, "+-- osl_generic_t\n");
00097   else
00098     fprintf(file, "+-- NULL generic\n");
00099  
00100   while (generic != NULL) {
00101     if (!first) {
00102       // Go to the right level.
00103       for (j = 0; j < level; j++)
00104         fprintf(file, "|\t");
00105       fprintf(file, "|   osl_generic_t\n");
00106     }
00107     else {
00108       first = 0;
00109     }
00110 
00111     // A blank line
00112     for(j = 0; j <= level + 1; j++)
00113       fprintf(file, "|\t");
00114     fprintf(file, "\n");
00115 
00116     osl_interface_idump(file, generic->interface, level + 1);
00117    
00118     if (generic->interface != NULL)
00119       generic->interface->idump(file, generic->data, level + 1);
00120     
00121     generic = generic->next;
00122 
00123     // Next line.
00124     if (generic != NULL) {
00125       for (j = 0; j <= level; j++)
00126         fprintf(file, "|\t");
00127       fprintf(file, "V\n");
00128     }
00129   }
00130   
00131   // The last line.
00132   for (j = 0; j <= level; j++)
00133     fprintf(file, "|\t");
00134   fprintf(file, "\n");
00135 }
00136 
00137 
00145 void osl_generic_dump(FILE * file, osl_generic_p generic) {
00146   osl_generic_idump(file, generic, 0); 
00147 }
00148 
00149 
00157 void osl_generic_print(FILE * file, osl_generic_p generic) {
00158   char * string;
00159   
00160   if (generic == NULL)
00161     return;
00162 
00163   while (generic != NULL) {
00164     if (generic->interface != NULL) {
00165       string = generic->interface->sprint(generic->data);
00166       if (string != NULL) {
00167         fprintf(file, "<%s>\n", generic->interface->URI);
00168         fprintf(file, "%s", string);
00169         fprintf(file, "</%s>\n", generic->interface->URI);
00170         free(string);
00171       }
00172     }
00173     generic = generic->next;
00174   }
00175 }
00176 
00177 
00178 /*****************************************************************************
00179  *                               Reading function                            *
00180  *****************************************************************************/
00181 
00182 
00192 osl_generic_p osl_generic_sread(char * string, osl_interface_p registry) {
00193   osl_generic_p generic = NULL, new;
00194   char * content, * start;
00195   void * data;
00196 
00197   while (registry != NULL) {
00198     content = osl_util_tag_content(string, registry->URI);
00199     if (content != NULL) {
00200       start = content;
00201       data = registry->sread(&content);
00202       if (data != NULL) {
00203         new = osl_generic_malloc();
00204         new->interface = osl_interface_nclone(registry, 1);
00205         new->data = data;
00206         osl_generic_add(&generic, new);
00207       }
00208       free(start);
00209     }
00210     registry = registry->next;
00211   }
00212   
00213   return generic;
00214 }
00215 
00216 
00228 osl_generic_p osl_generic_read_one(FILE * file, osl_interface_p registry) {
00229   char * tag;
00230   char * content, * temp;
00231   osl_generic_p generic = NULL;
00232   osl_interface_p interface;
00233 
00234   tag = osl_util_read_tag(file, NULL);
00235   if ((tag == NULL) || (strlen(tag) < 1) || (tag[0] == '/')) {
00236     OSL_debug("empty tag name or closing tag instead of an opening one");
00237     return NULL;
00238   }
00239 
00240   content = osl_util_read_uptoendtag(file, tag);
00241   interface = osl_interface_lookup(registry, tag);
00242 
00243   temp = content;
00244   if (interface == NULL) {
00245     OSL_warning("unsupported generic");
00246     fprintf(stderr, "[osl] Warning: unknown URI \"%s\".\n", tag);
00247   }
00248   else {
00249     generic = osl_generic_malloc();
00250     generic->interface = osl_interface_nclone(interface, 1);
00251     generic->data = interface->sread(&temp);
00252   }
00253 
00254   free(content);
00255   free(tag);
00256   return generic;
00257 }
00258 
00259 
00269 osl_generic_p osl_generic_read(FILE * file, osl_interface_p registry) {
00270   char * generic_string;
00271   osl_generic_p generic_list;
00272 
00273   generic_string = osl_util_read_uptotag(file, OSL_TAG_END_SCOP);
00274   generic_list = osl_generic_sread(generic_string, registry);
00275   free(generic_string);
00276   return generic_list;
00277 }
00278 
00279 
00280 /*+***************************************************************************
00281  *                    Memory allocation/deallocation function                *
00282  *****************************************************************************/
00283 
00284 
00293 void osl_generic_add(osl_generic_p * list, osl_generic_p generic) {
00294   osl_generic_p tmp = *list, check;
00295   
00296   if (generic != NULL) {
00297     // First, check that the generic list is OK.
00298     check = generic;
00299     while (check != NULL) {
00300       if ((check->interface == NULL) || (check->interface->URI == NULL))
00301         OSL_error("no interface or URI in a generic to add to a list");
00302 
00303       // TODO: move this to the integrity check.
00304       if (osl_generic_lookup(*list, check->interface->URI) != NULL)
00305         OSL_error("only one generic with a given URI is allowed");
00306       check = check->next;
00307     }
00308 
00309     if (*list != NULL) {
00310       while (tmp->next != NULL)
00311         tmp = tmp->next;
00312       tmp->next = generic;
00313     }
00314     else {
00315       *list = generic;
00316     }
00317   }
00318 }
00319 
00320 
00329 osl_generic_p osl_generic_malloc() {
00330   osl_generic_p generic;
00331 
00332   OSL_malloc(generic, osl_generic_p, sizeof(osl_generic_t));
00333   generic->interface = NULL;
00334   generic->data      = NULL;
00335   generic->next      = NULL;
00336 
00337   return generic;
00338 }
00339 
00340 
00346 void osl_generic_free(osl_generic_p generic) {
00347   osl_generic_p next;
00348 
00349   while (generic != NULL) {
00350     next = generic->next;
00351     if (generic->interface != NULL) {
00352       generic->interface->free(generic->data);
00353       osl_interface_free(generic->interface);
00354     }
00355     else {
00356       if (generic->data != NULL) {
00357         OSL_warning("unregistered interface, memory leaks are possible");
00358         free(generic->data);
00359       }
00360     }
00361     free(generic);
00362     generic = next;
00363   }
00364 }
00365 
00366 
00367 /*+***************************************************************************
00368  *                            Processing functions                           *
00369  *****************************************************************************/
00370 
00371 
00379 osl_generic_p osl_generic_clone(osl_generic_p generic) {
00380   osl_generic_p clone = NULL, new;
00381   osl_interface_p interface;
00382   void * x;
00383 
00384   while (generic != NULL) { 
00385     if (generic->interface != NULL) {
00386       x = generic->interface->clone(generic->data);
00387       interface = osl_interface_clone(generic->interface);
00388       new = osl_generic_malloc();
00389       new->interface = interface;
00390       new->data = x;
00391       osl_generic_add(&clone, new);
00392     }
00393     else {
00394       OSL_warning("unregistered interface, cloning ignored");
00395     }
00396     generic = generic->next;
00397   }
00398 
00399   return clone;
00400 }
00401 
00402 
00410 int osl_generic_count(osl_generic_p x) {
00411   int generic_number = 0;
00412 
00413   while (x != NULL) {
00414     generic_number++;
00415     x = x->next;
00416   }
00417 
00418   return generic_number;
00419 }
00420 
00421 
00432 int osl_generic_equal(osl_generic_p x1, osl_generic_p x2) {
00433   int x1_generic_number, x2_generic_number;
00434   int found, equal;
00435   osl_generic_p backup_x2 = x2;
00436 
00437   if (x1 == x2)
00438     return 1;
00439 
00440   // Check whether the number of generics is the same or not.
00441   x1_generic_number = osl_generic_count(x1);
00442   x2_generic_number = osl_generic_count(x2);
00443   if (x1_generic_number != x2_generic_number)
00444     return 0;
00445 
00446   // Check that for each generic in x1 a similar generic is in x2.
00447   while (x1 != NULL) {
00448     x2 = backup_x2;
00449     found = 0;
00450     while ((x2 != NULL) && (found != 1)) {
00451       if (osl_interface_equal(x1->interface, x2->interface)) {
00452         if (x1->interface != NULL) {
00453           equal = x1->interface->equal(x1->data, x2->data);
00454         }
00455         else {
00456           OSL_warning("unregistered generic, "
00457                       "cannot state generic equality");
00458           equal = 0;
00459         }
00460 
00461         if (equal == 0)
00462           return 0;
00463         else
00464           found = 1;
00465       }
00466 
00467       x2 = x2->next;
00468     }
00469 
00470     if (found != 1)
00471       return 0;
00472 
00473     x1 = x1->next;
00474   }
00475 
00476   return 1;
00477 }
00478 
00479 
00488 int osl_generic_has_URI(osl_generic_p x, char * URI) {
00489 
00490   if ((x == NULL) ||
00491       (x->interface == NULL) ||
00492       (x->interface->URI == NULL) ||
00493       (strcmp(x->interface->URI, URI)))
00494     return 0;
00495 
00496   return 1;
00497 }
00498 
00499 
00509 void * osl_generic_lookup(osl_generic_p x, char * URI) {
00510   while (x != NULL) {
00511     if (osl_generic_has_URI(x, URI))
00512       return x->data;
00513 
00514     x = x->next;
00515   }
00516 
00517   return NULL;
00518 }