OpenScop  0.9.0
generic.c
Go to the documentation of this file.
1 
2  /*+-----------------------------------------------------------------**
3  ** OpenScop Library **
4  **-----------------------------------------------------------------**
5  ** generic.c **
6  **-----------------------------------------------------------------**
7  ** First version: 26/11/2010 **
8  **-----------------------------------------------------------------**
9 
10 
11  *****************************************************************************
12  * OpenScop: Structures and formats for polyhedral tools to talk together *
13  *****************************************************************************
14  * ,___,,_,__,,__,,__,,__,,_,__,,_,__,,__,,___,_,__,,_,__, *
15  * / / / // // // // / / / // // / / // / /|,_, *
16  * / / / // // // // / / / // // / / // / / / /\ *
17  * |~~~|~|~~~|~~~|~~~|~~~|~|~~~|~|~~~|~~~|~~~|~|~~~|~|~~~|/_/ \ *
18  * | G |C| P | = | L | P |=| = |C| = | = | = |=| = |=| C |\ \ /\ *
19  * | R |l| o | = | e | l |=| = |a| = | = | = |=| = |=| L | \# \ /\ *
20  * | A |a| l | = | t | u |=| = |n| = | = | = |=| = |=| o | |\# \ \ *
21  * | P |n| l | = | s | t |=| = |d| = | = | = | | |=| o | | \# \ \ *
22  * | H | | y | | e | o | | = |l| | | = | | | | G | | \ \ \ *
23  * | I | | | | e | | | | | | | | | | | | | \ \ \ *
24  * | T | | | | | | | | | | | | | | | | | \ \ \ *
25  * | E | | | | | | | | | | | | | | | | | \ \ \ *
26  * | * |*| * | * | * | * |*| * |*| * | * | * |*| * |*| * | / \* \ \ *
27  * | O |p| e | n | S | c |o| p |-| L | i | b |r| a |r| y |/ \ \ / *
28  * '---'-'---'---'---'---'-'---'-'---'---'---'-'---'-'---' '--' *
29  * *
30  * Copyright (C) 2008 University Paris-Sud 11 and INRIA *
31  * *
32  * (3-clause BSD license) *
33  * Redistribution and use in source and binary forms, with or without *
34  * modification, are permitted provided that the following conditions *
35  * are met: *
36  * *
37  * 1. Redistributions of source code must retain the above copyright notice, *
38  * this list of conditions and the following disclaimer. *
39  * 2. Redistributions in binary form must reproduce the above copyright *
40  * notice, this list of conditions and the following disclaimer in the *
41  * documentation and/or other materials provided with the distribution. *
42  * 3. The name of the author may not be used to endorse or promote products *
43  * derived from this software without specific prior written permission. *
44  * *
45  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR *
46  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES *
47  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. *
48  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, *
49  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT *
50  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, *
51  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY *
52  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT *
53  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF *
54  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
55  * *
56  * OpenScop Library, a library to manipulate OpenScop formats and data *
57  * structures. Written by: *
58  * Cedric Bastoul <Cedric.Bastoul@u-psud.fr> and *
59  * Louis-Noel Pouchet <Louis-Noel.pouchet@inria.fr> *
60  * *
61  *****************************************************************************/
62 
63 #include <stdlib.h>
64 #include <stdio.h>
65 #include <string.h>
66 
67 #include <osl/macros.h>
68 #include <osl/util.h>
69 #include <osl/interface.h>
70 #include <osl/generic.h>
71 #include <osl/extensions/arrays.h>
72 
73 
74 /*+***************************************************************************
75  * Structure display function *
76  *****************************************************************************/
77 
78 
89 void osl_generic_idump(FILE * file, osl_generic_p generic, int level) {
90  int j, first = 1;
91 
92  // Go to the right level.
93  for (j = 0; j < level; j++)
94  fprintf(file,"|\t");
95 
96  if (generic != NULL)
97  fprintf(file, "+-- osl_generic_t\n");
98  else
99  fprintf(file, "+-- NULL generic\n");
100 
101  while (generic != NULL) {
102  if (!first) {
103  // Go to the right level.
104  for (j = 0; j < level; j++)
105  fprintf(file, "|\t");
106  fprintf(file, "| osl_generic_t\n");
107  }
108  else {
109  first = 0;
110  }
111 
112  // A blank line
113  for(j = 0; j <= level + 1; j++)
114  fprintf(file, "|\t");
115  fprintf(file, "\n");
116 
117  osl_interface_idump(file, generic->interface, level + 1);
118 
119  if (generic->interface != NULL)
120  generic->interface->idump(file, generic->data, level + 1);
121 
122  generic = generic->next;
123 
124  // Next line.
125  if (generic != NULL) {
126  for (j = 0; j <= level; j++)
127  fprintf(file, "|\t");
128  fprintf(file, "V\n");
129  }
130  }
131 
132  // The last line.
133  for (j = 0; j <= level; j++)
134  fprintf(file, "|\t");
135  fprintf(file, "\n");
136 }
137 
138 
146 void osl_generic_dump(FILE * file, osl_generic_p generic) {
147  osl_generic_idump(file, generic, 0);
148 }
149 
150 
159  int high_water_mark = OSL_MAX_STRING;
160  char * string = NULL, * content;
161  char buffer[OSL_MAX_STRING];
162 
163  OSL_malloc(string, char *, high_water_mark * sizeof(char));
164  string[0] = '\0';
165 
166  while (generic != NULL) {
167  if (generic->interface != NULL) {
168  content = generic->interface->sprint(generic->data);
169  if (content != NULL) {
170  sprintf(buffer, "<%s>\n", generic->interface->URI);
171  osl_util_safe_strcat(&string, buffer, &high_water_mark);
172  osl_util_safe_strcat(&string, content, &high_water_mark);
173  free(content);
174  sprintf(buffer, "</%s>\n", generic->interface->URI);
175  osl_util_safe_strcat(&string, buffer, &high_water_mark);
176  }
177  }
178  generic = generic->next;
179  if (generic != NULL) {
180  sprintf(buffer, "\n");
181  osl_util_safe_strcat(&string, buffer, &high_water_mark);
182  }
183  }
184 
185  return string;
186 }
187 
188 
196 void osl_generic_print(FILE * file, osl_generic_p generic) {
197  char * string;
198 
199  string = osl_generic_sprint(generic);
200  if (string != NULL) {
201  fprintf(file, "%s", string);
202  free(string);
203  }
204 }
205 
206 
215  char * string;
216 
217  osl_generic_p arrays = osl_generic_lookup(generic, OSL_URI_ARRAYS);
218 
219  string = osl_arrays_sprint((osl_arrays_p) arrays);
220  if (string != NULL) {
221  fprintf(file, "<arrays>\n%s</arrays>\n", string);
222  free(string);
223  }
224 }
225 
226 
227 /*****************************************************************************
228  * Reading function *
229  *****************************************************************************/
230 
231 
244  osl_generic_p generic = NULL, new;
245 
246  while (**input != '\0') {
247  new = osl_generic_sread_one(input, registry);
248  osl_generic_add(&generic, new);
249  }
250 
251  return generic;
252 }
253 
254 
267  char * tag;
268  char * content, * temp;
269  osl_generic_p generic = NULL;
270  osl_interface_p interface;
271 
272  tag = osl_util_read_tag(NULL, input);
273  if ((tag == NULL) || (strlen(tag) < 1) || (tag[0] == '/')) {
274  OSL_debug("empty tag name or closing tag instead of an opening one");
275  return NULL;
276  }
277 
278  content = osl_util_read_uptoendtag(NULL, input, tag);
279  interface = osl_interface_lookup(registry, tag);
280 
281  temp = content;
282  if (interface == NULL) {
283  OSL_warning("unsupported generic");
284  fprintf(stderr, "[osl] Warning: unknown URI \"%s\".\n", tag);
285  }
286  else {
287  generic = osl_generic_malloc();
288  generic->interface = osl_interface_nclone(interface, 1);
289  generic->data = interface->sread(&temp);
290  }
291 
292  free(content);
293  free(tag);
294  return generic;
295 }
296 
297 
310  char * tag;
311  char * content, * temp;
312  osl_generic_p generic = NULL;
313  osl_interface_p interface;
314 
315  tag = osl_util_read_tag(file, NULL);
316  if ((tag == NULL) || (strlen(tag) < 1) || (tag[0] == '/')) {
317  OSL_debug("empty tag name or closing tag instead of an opening one");
318  return NULL;
319  }
320 
321  content = osl_util_read_uptoendtag(file, NULL, tag);
322  interface = osl_interface_lookup(registry, tag);
323 
324  temp = content;
325  if (interface == NULL) {
326  OSL_warning("unsupported generic");
327  fprintf(stderr, "[osl] Warning: unknown URI \"%s\".\n", tag);
328  }
329  else {
330  generic = osl_generic_malloc();
331  generic->interface = osl_interface_nclone(interface, 1);
332  generic->data = interface->sread(&temp);
333  }
334 
335  free(content);
336  free(tag);
337  return generic;
338 }
339 
340 
351  char * generic_string, * temp;
352  osl_generic_p generic_list;
353 
354  generic_string = osl_util_read_uptoendtag(file, NULL, OSL_URI_SCOP);
355  temp = generic_string;
356  generic_list = osl_generic_sread(&temp, registry);
357  free(generic_string);
358  return generic_list;
359 }
360 
361 
362 /*+***************************************************************************
363  * Memory allocation/deallocation function *
364  *****************************************************************************/
365 
366 
376  osl_generic_p tmp = *list, check;
377 
378  if (generic != NULL) {
379  // First, check that the generic list is OK.
380  check = generic;
381  while (check != NULL) {
382  if ((check->interface == NULL) || (check->interface->URI == NULL))
383  OSL_error("no interface or URI in a generic to add to a list");
384 
385  // TODO: move this to the integrity check.
386  if (osl_generic_lookup(*list, check->interface->URI) != NULL)
387  OSL_error("only one generic with a given URI is allowed");
388  check = check->next;
389  }
390 
391  if (*list != NULL) {
392  while (tmp->next != NULL)
393  tmp = tmp->next;
394  tmp->next = generic;
395  }
396  else {
397  *list = generic;
398  }
399  }
400 }
401 
410 
411  osl_generic_p tmp = NULL;
412 
413  if (generic != NULL) {
414 
415  if (*list != NULL) {
416  //target is the first element of list
417  if(*list==generic){
418  *list = generic->next;
419  generic->next=NULL; //free below removes the whole list!
420  osl_generic_free(generic);
421  return;
422  }
423 
424  //find target
425  tmp = *list;
426  while (tmp->next!=generic && tmp->next != NULL)
427  tmp = tmp->next;
428 
429  if(tmp->next==generic){
430  tmp->next = generic->next;
431  generic->next=NULL; //free below removes the whole list!
432  osl_generic_free(generic);
433  }
434  else //target not found
435  OSL_warning("generic not found in the list\n");
436  }
437 
438  }
439 }
440 
447 void osl_generic_remove(osl_generic_p *list, char * URI){
448 
449  osl_generic_p tmp = *list;
450 
451  while(tmp != NULL){
452  if(osl_generic_has_URI(tmp, URI))
453  break;
454  tmp = tmp->next;
455  }
456 
457  if(tmp!=NULL){
458  osl_generic_remove_node(list, tmp);
459  }
460 
461 }
462 
463 
473  osl_generic_p generic;
474 
475  OSL_malloc(generic, osl_generic_p, sizeof(osl_generic_t));
476  generic->interface = NULL;
477  generic->data = NULL;
478  generic->next = NULL;
479 
480  return generic;
481 }
482 
483 
490  osl_generic_p next;
491 
492  while (generic != NULL) {
493  next = generic->next;
494  if (generic->interface != NULL) {
495  generic->interface->free(generic->data);
496  osl_interface_free(generic->interface);
497  }
498  else {
499  if (generic->data != NULL) {
500  OSL_warning("unregistered interface, memory leaks are possible");
501  free(generic->data);
502  }
503  }
504  free(generic);
505  generic = next;
506  }
507 }
508 
509 
510 /*+***************************************************************************
511  * Processing functions *
512  *****************************************************************************/
513 
514 
523  int number = 0;
524 
525  while (generic != NULL) {
526  number++;
527  generic = generic->next;
528  }
529  return number;
530 }
531 
532 
541  osl_generic_p clone = NULL, new;
542  osl_interface_p interface;
543  void * x;
544 
545  while (generic != NULL) {
546  if (generic->interface != NULL) {
547  x = generic->interface->clone(generic->data);
548  interface = osl_interface_clone(generic->interface);
549  new = osl_generic_malloc();
550  new->interface = interface;
551  new->data = x;
552  osl_generic_add(&clone, new);
553  }
554  else {
555  OSL_warning("unregistered interface, cloning ignored");
556  }
557  generic = generic->next;
558  }
559 
560  return clone;
561 }
562 
563 
572  int generic_number = 0;
573 
574  while (x != NULL) {
575  generic_number++;
576  x = x->next;
577  }
578 
579  return generic_number;
580 }
581 
582 
593  int x1_generic_number, x2_generic_number;
594  int found, equal;
595  osl_generic_p backup_x2 = x2;
596 
597  if (x1 == x2)
598  return 1;
599 
600  // Check whether the number of generics is the same or not.
601  x1_generic_number = osl_generic_count(x1);
602  x2_generic_number = osl_generic_count(x2);
603  if (x1_generic_number != x2_generic_number)
604  return 0;
605 
606  // Check that for each generic in x1 a similar generic is in x2.
607  while (x1 != NULL) {
608  x2 = backup_x2;
609  found = 0;
610  while ((x2 != NULL) && (found != 1)) {
611  if (osl_interface_equal(x1->interface, x2->interface)) {
612  if (x1->interface != NULL) {
613  equal = x1->interface->equal(x1->data, x2->data);
614  }
615  else {
616  OSL_warning("unregistered generic, "
617  "cannot state generic equality");
618  equal = 0;
619  }
620 
621  if (equal == 0)
622  return 0;
623  else
624  found = 1;
625  }
626 
627  x2 = x2->next;
628  }
629 
630  if (found != 1)
631  return 0;
632 
633  x1 = x1->next;
634  }
635 
636  return 1;
637 }
638 
639 
648 int osl_generic_has_URI(osl_const_generic_const_p x, char const * const URI) {
649 
650  if ((x == NULL) ||
651  (x->interface == NULL) ||
652  (x->interface->URI == NULL) ||
653  (strcmp(x->interface->URI, URI)))
654  return 0;
655 
656  return 1;
657 }
658 
659 
669 void * osl_generic_lookup(osl_generic_p x, char const * const URI) {
670  while (x != NULL) {
671  if (osl_generic_has_URI(x, URI))
672  return x->data;
673 
674  x = x->next;
675  }
676 
677  return NULL;
678 }
679 
680 
690  osl_generic_p generic = NULL;
691 
692  if ((data == NULL) || (interface == NULL))
693  OSL_warning("shell created with some empty elements inside");
694 
695  generic = osl_generic_malloc();
696  generic->data = data;
697  generic->interface = interface;
698  return generic;
699 }
int osl_interface_equal(osl_interface_p interface1, osl_interface_p interface2)
Definition: interface.c:328
osl_interface_p osl_interface_nclone(osl_interface_p interface, int n)
Definition: interface.c:283
char * osl_util_read_uptoendtag(FILE *file, char **str, char *name)
Definition: util.c:413
int osl_generic_number(osl_generic_p generic)
Definition: generic.c:522
void osl_interface_free(osl_interface_p interface)
Definition: interface.c:237
char * osl_arrays_sprint(osl_arrays_p arrays)
Definition: arrays.c:146
osl_equal_f equal
Definition: interface.h:97
char * osl_generic_sprint(osl_generic_p generic)
Definition: generic.c:158
osl_generic_p osl_generic_shell(void *data, osl_interface_p interface)
Definition: generic.c:689
osl_interface_p osl_interface_clone(osl_interface_p interface)
Definition: interface.c:314
osl_generic_p osl_generic_malloc()
Definition: generic.c:472
void * osl_generic_lookup(osl_generic_p x, char const *const URI)
Definition: generic.c:669
osl_interface_p osl_interface_lookup(osl_interface_p list, char *URI)
Definition: interface.c:362
void osl_generic_add(osl_generic_p *list, osl_generic_p generic)
Definition: generic.c:375
void osl_interface_idump(FILE *file, osl_interface_p interface, int level)
Definition: interface.c:100
int osl_generic_has_URI(osl_const_generic_const_p x, char const *const URI)
Definition: generic.c:648
int osl_generic_count(osl_generic_p x)
Definition: generic.c:571
void * data
Definition: generic.h:82
void osl_util_safe_strcat(char **dst, char *src, int *hwm)
Definition: util.c:483
osl_generic_p osl_generic_read(FILE *file, osl_interface_p registry)
Definition: generic.c:350
osl_generic_p osl_generic_read_one(FILE *file, osl_interface_p registry)
Definition: generic.c:309
void osl_generic_remove(osl_generic_p *list, char *URI)
Definition: generic.c:447
void osl_generic_remove_node(osl_generic_p *list, osl_generic_p generic)
Definition: generic.c:409
void osl_generic_idump(FILE *file, osl_generic_p generic, int level)
Definition: generic.c:89
osl_interface_p interface
Definition: generic.h:83
struct osl_generic * next
Definition: generic.h:84
void osl_generic_dump(FILE *file, osl_generic_p generic)
Definition: generic.c:146
osl_generic_p osl_generic_sread(char **input, osl_interface_p registry)
Definition: generic.c:243
char * URI
Definition: interface.h:90
osl_sread_f sread
Definition: interface.h:93
osl_clone_f clone
Definition: interface.h:96
osl_free_f free
Definition: interface.h:95
struct osl_generic const *const osl_const_generic_const_p
Definition: generic.h:91
void osl_generic_print_options_scoplib(FILE *file, osl_generic_p generic)
Definition: generic.c:214
osl_generic_p osl_generic_sread_one(char **input, osl_interface_p registry)
Definition: generic.c:266
char * osl_util_read_tag(FILE *file, char **str)
Definition: util.c:268
int osl_generic_equal(osl_generic_p x1, osl_generic_p x2)
Definition: generic.c:592
osl_generic_p osl_generic_clone(osl_generic_p generic)
Definition: generic.c:540
void osl_generic_print(FILE *file, osl_generic_p generic)
Definition: generic.c:196
void osl_generic_free(osl_generic_p generic)
Definition: generic.c:489