OpenScop 0.8.1
|
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 }