OpenScop
0.9.0
|
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 #include <osl/extensions/arrays.h> 00072 00073 00074 /*+*************************************************************************** 00075 * Structure display function * 00076 *****************************************************************************/ 00077 00078 00089 void osl_generic_idump(FILE * file, osl_generic_p generic, int level) { 00090 int j, first = 1; 00091 00092 // Go to the right level. 00093 for (j = 0; j < level; j++) 00094 fprintf(file,"|\t"); 00095 00096 if (generic != NULL) 00097 fprintf(file, "+-- osl_generic_t\n"); 00098 else 00099 fprintf(file, "+-- NULL generic\n"); 00100 00101 while (generic != NULL) { 00102 if (!first) { 00103 // Go to the right level. 00104 for (j = 0; j < level; j++) 00105 fprintf(file, "|\t"); 00106 fprintf(file, "| osl_generic_t\n"); 00107 } 00108 else { 00109 first = 0; 00110 } 00111 00112 // A blank line 00113 for(j = 0; j <= level + 1; j++) 00114 fprintf(file, "|\t"); 00115 fprintf(file, "\n"); 00116 00117 osl_interface_idump(file, generic->interface, level + 1); 00118 00119 if (generic->interface != NULL) 00120 generic->interface->idump(file, generic->data, level + 1); 00121 00122 generic = generic->next; 00123 00124 // Next line. 00125 if (generic != NULL) { 00126 for (j = 0; j <= level; j++) 00127 fprintf(file, "|\t"); 00128 fprintf(file, "V\n"); 00129 } 00130 } 00131 00132 // The last line. 00133 for (j = 0; j <= level; j++) 00134 fprintf(file, "|\t"); 00135 fprintf(file, "\n"); 00136 } 00137 00138 00146 void osl_generic_dump(FILE * file, osl_generic_p generic) { 00147 osl_generic_idump(file, generic, 0); 00148 } 00149 00150 00158 char * osl_generic_sprint(osl_generic_p generic) { 00159 int high_water_mark = OSL_MAX_STRING; 00160 char * string = NULL, * content; 00161 char buffer[OSL_MAX_STRING]; 00162 00163 OSL_malloc(string, char *, high_water_mark * sizeof(char)); 00164 string[0] = '\0'; 00165 00166 while (generic != NULL) { 00167 if (generic->interface != NULL) { 00168 content = generic->interface->sprint(generic->data); 00169 if (content != NULL) { 00170 sprintf(buffer, "<%s>\n", generic->interface->URI); 00171 osl_util_safe_strcat(&string, buffer, &high_water_mark); 00172 osl_util_safe_strcat(&string, content, &high_water_mark); 00173 free(content); 00174 sprintf(buffer, "</%s>\n", generic->interface->URI); 00175 osl_util_safe_strcat(&string, buffer, &high_water_mark); 00176 } 00177 } 00178 generic = generic->next; 00179 if (generic != NULL) { 00180 sprintf(buffer, "\n"); 00181 osl_util_safe_strcat(&string, buffer, &high_water_mark); 00182 } 00183 } 00184 00185 return string; 00186 } 00187 00188 00196 void osl_generic_print(FILE * file, osl_generic_p generic) { 00197 char * string; 00198 00199 string = osl_generic_sprint(generic); 00200 if (string != NULL) { 00201 fprintf(file, "%s", string); 00202 free(string); 00203 } 00204 } 00205 00206 00214 void osl_generic_print_options_scoplib(FILE * file, osl_generic_p generic) { 00215 char * string; 00216 00217 osl_generic_p arrays = osl_generic_lookup(generic, OSL_URI_ARRAYS); 00218 00219 string = osl_arrays_sprint((osl_arrays_p) arrays); 00220 if (string != NULL) { 00221 fprintf(file, "<arrays>\n%s</arrays>\n", string); 00222 free(string); 00223 } 00224 } 00225 00226 00227 /***************************************************************************** 00228 * Reading function * 00229 *****************************************************************************/ 00230 00231 00243 osl_generic_p osl_generic_sread(char ** input, osl_interface_p registry) { 00244 osl_generic_p generic = NULL, new; 00245 00246 while (**input != '\0') { 00247 new = osl_generic_sread_one(input, registry); 00248 osl_generic_add(&generic, new); 00249 } 00250 00251 return generic; 00252 } 00253 00254 00266 osl_generic_p osl_generic_sread_one(char ** input, osl_interface_p registry) { 00267 char * tag; 00268 char * content, * temp; 00269 osl_generic_p generic = NULL; 00270 osl_interface_p interface; 00271 00272 tag = osl_util_read_tag(NULL, input); 00273 if ((tag == NULL) || (strlen(tag) < 1) || (tag[0] == '/')) { 00274 OSL_debug("empty tag name or closing tag instead of an opening one"); 00275 return NULL; 00276 } 00277 00278 content = osl_util_read_uptoendtag(NULL, input, tag); 00279 interface = osl_interface_lookup(registry, tag); 00280 00281 temp = content; 00282 if (interface == NULL) { 00283 OSL_warning("unsupported generic"); 00284 fprintf(stderr, "[osl] Warning: unknown URI \"%s\".\n", tag); 00285 } 00286 else { 00287 generic = osl_generic_malloc(); 00288 generic->interface = osl_interface_nclone(interface, 1); 00289 generic->data = interface->sread(&temp); 00290 } 00291 00292 free(content); 00293 free(tag); 00294 return generic; 00295 } 00296 00297 00309 osl_generic_p osl_generic_read_one(FILE * file, osl_interface_p registry) { 00310 char * tag; 00311 char * content, * temp; 00312 osl_generic_p generic = NULL; 00313 osl_interface_p interface; 00314 00315 tag = osl_util_read_tag(file, NULL); 00316 if ((tag == NULL) || (strlen(tag) < 1) || (tag[0] == '/')) { 00317 OSL_debug("empty tag name or closing tag instead of an opening one"); 00318 return NULL; 00319 } 00320 00321 content = osl_util_read_uptoendtag(file, NULL, tag); 00322 interface = osl_interface_lookup(registry, tag); 00323 00324 temp = content; 00325 if (interface == NULL) { 00326 OSL_warning("unsupported generic"); 00327 fprintf(stderr, "[osl] Warning: unknown URI \"%s\".\n", tag); 00328 } 00329 else { 00330 generic = osl_generic_malloc(); 00331 generic->interface = osl_interface_nclone(interface, 1); 00332 generic->data = interface->sread(&temp); 00333 } 00334 00335 free(content); 00336 free(tag); 00337 return generic; 00338 } 00339 00340 00350 osl_generic_p osl_generic_read(FILE * file, osl_interface_p registry) { 00351 char * generic_string, * temp; 00352 osl_generic_p generic_list; 00353 00354 generic_string = osl_util_read_uptoendtag(file, NULL, OSL_URI_SCOP); 00355 temp = generic_string; 00356 generic_list = osl_generic_sread(&temp, registry); 00357 free(generic_string); 00358 return generic_list; 00359 } 00360 00361 00362 /*+*************************************************************************** 00363 * Memory allocation/deallocation function * 00364 *****************************************************************************/ 00365 00366 00375 void osl_generic_add(osl_generic_p * list, osl_generic_p generic) { 00376 osl_generic_p tmp = *list, check; 00377 00378 if (generic != NULL) { 00379 // First, check that the generic list is OK. 00380 check = generic; 00381 while (check != NULL) { 00382 if ((check->interface == NULL) || (check->interface->URI == NULL)) 00383 OSL_error("no interface or URI in a generic to add to a list"); 00384 00385 // TODO: move this to the integrity check. 00386 if (osl_generic_lookup(*list, check->interface->URI) != NULL) 00387 OSL_error("only one generic with a given URI is allowed"); 00388 check = check->next; 00389 } 00390 00391 if (*list != NULL) { 00392 while (tmp->next != NULL) 00393 tmp = tmp->next; 00394 tmp->next = generic; 00395 } 00396 else { 00397 *list = generic; 00398 } 00399 } 00400 } 00401 00409 void osl_generic_remove_node(osl_generic_p * list, osl_generic_p generic) { 00410 00411 osl_generic_p tmp = NULL; 00412 00413 if (generic != NULL) { 00414 00415 if (*list != NULL) { 00416 //target is the first element of list 00417 if(*list==generic){ 00418 *list = generic->next; 00419 generic->next=NULL; //free below removes the whole list! 00420 osl_generic_free(generic); 00421 return; 00422 } 00423 00424 //find target 00425 tmp = *list; 00426 while (tmp->next!=generic && tmp->next != NULL) 00427 tmp = tmp->next; 00428 00429 if(tmp->next==generic){ 00430 tmp->next = generic->next; 00431 generic->next=NULL; //free below removes the whole list! 00432 osl_generic_free(generic); 00433 } 00434 else //target not found 00435 OSL_warning("generic not found in the list\n"); 00436 } 00437 00438 } 00439 } 00440 00447 void osl_generic_remove(osl_generic_p *list, char * URI){ 00448 00449 osl_generic_p tmp = *list; 00450 00451 while(tmp != NULL){ 00452 if(osl_generic_has_URI(tmp, URI)) 00453 break; 00454 tmp = tmp->next; 00455 } 00456 00457 if(tmp!=NULL){ 00458 osl_generic_remove_node(list, tmp); 00459 } 00460 00461 } 00462 00463 00472 osl_generic_p osl_generic_malloc() { 00473 osl_generic_p generic; 00474 00475 OSL_malloc(generic, osl_generic_p, sizeof(osl_generic_t)); 00476 generic->interface = NULL; 00477 generic->data = NULL; 00478 generic->next = NULL; 00479 00480 return generic; 00481 } 00482 00483 00489 void osl_generic_free(osl_generic_p generic) { 00490 osl_generic_p next; 00491 00492 while (generic != NULL) { 00493 next = generic->next; 00494 if (generic->interface != NULL) { 00495 generic->interface->free(generic->data); 00496 osl_interface_free(generic->interface); 00497 } 00498 else { 00499 if (generic->data != NULL) { 00500 OSL_warning("unregistered interface, memory leaks are possible"); 00501 free(generic->data); 00502 } 00503 } 00504 free(generic); 00505 generic = next; 00506 } 00507 } 00508 00509 00510 /*+*************************************************************************** 00511 * Processing functions * 00512 *****************************************************************************/ 00513 00514 00522 int osl_generic_number(osl_generic_p generic) { 00523 int number = 0; 00524 00525 while (generic != NULL) { 00526 number++; 00527 generic = generic->next; 00528 } 00529 return number; 00530 } 00531 00532 00540 osl_generic_p osl_generic_clone(osl_generic_p generic) { 00541 osl_generic_p clone = NULL, new; 00542 osl_interface_p interface; 00543 void * x; 00544 00545 while (generic != NULL) { 00546 if (generic->interface != NULL) { 00547 x = generic->interface->clone(generic->data); 00548 interface = osl_interface_clone(generic->interface); 00549 new = osl_generic_malloc(); 00550 new->interface = interface; 00551 new->data = x; 00552 osl_generic_add(&clone, new); 00553 } 00554 else { 00555 OSL_warning("unregistered interface, cloning ignored"); 00556 } 00557 generic = generic->next; 00558 } 00559 00560 return clone; 00561 } 00562 00563 00571 int osl_generic_count(osl_generic_p x) { 00572 int generic_number = 0; 00573 00574 while (x != NULL) { 00575 generic_number++; 00576 x = x->next; 00577 } 00578 00579 return generic_number; 00580 } 00581 00582 00592 int osl_generic_equal(osl_generic_p x1, osl_generic_p x2) { 00593 int x1_generic_number, x2_generic_number; 00594 int found, equal; 00595 osl_generic_p backup_x2 = x2; 00596 00597 if (x1 == x2) 00598 return 1; 00599 00600 // Check whether the number of generics is the same or not. 00601 x1_generic_number = osl_generic_count(x1); 00602 x2_generic_number = osl_generic_count(x2); 00603 if (x1_generic_number != x2_generic_number) 00604 return 0; 00605 00606 // Check that for each generic in x1 a similar generic is in x2. 00607 while (x1 != NULL) { 00608 x2 = backup_x2; 00609 found = 0; 00610 while ((x2 != NULL) && (found != 1)) { 00611 if (osl_interface_equal(x1->interface, x2->interface)) { 00612 if (x1->interface != NULL) { 00613 equal = x1->interface->equal(x1->data, x2->data); 00614 } 00615 else { 00616 OSL_warning("unregistered generic, " 00617 "cannot state generic equality"); 00618 equal = 0; 00619 } 00620 00621 if (equal == 0) 00622 return 0; 00623 else 00624 found = 1; 00625 } 00626 00627 x2 = x2->next; 00628 } 00629 00630 if (found != 1) 00631 return 0; 00632 00633 x1 = x1->next; 00634 } 00635 00636 return 1; 00637 } 00638 00639 00648 int osl_generic_has_URI(osl_const_generic_const_p x, char const * const URI) { 00649 00650 if ((x == NULL) || 00651 (x->interface == NULL) || 00652 (x->interface->URI == NULL) || 00653 (strcmp(x->interface->URI, URI))) 00654 return 0; 00655 00656 return 1; 00657 } 00658 00659 00669 void * osl_generic_lookup(osl_generic_p x, char const * const URI) { 00670 while (x != NULL) { 00671 if (osl_generic_has_URI(x, URI)) 00672 return x->data; 00673 00674 x = x->next; 00675 } 00676 00677 return NULL; 00678 } 00679 00680 00689 osl_generic_p osl_generic_shell(void * data, osl_interface_p interface) { 00690 osl_generic_p generic = NULL; 00691 00692 if ((data == NULL) || (interface == NULL)) 00693 OSL_warning("shell created with some empty elements inside"); 00694 00695 generic = osl_generic_malloc(); 00696 generic->data = data; 00697 generic->interface = interface; 00698 return generic; 00699 }