~ubuntu-branches/ubuntu/trusty/cloog/trusty

« back to all changes in this revision

Viewing changes to osl/source/generic.c

  • Committer: Package Import Robot
  • Author(s): Matthias Klose
  • Date: 2011-12-15 18:39:17 UTC
  • mfrom: (1.1.1)
  • Revision ID: package-import@ubuntu.com-20111215183917-uqggmujou8wna9js
Tags: 0.17.0-1
New upstream version.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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
 
 
72
 
 
73
/*+***************************************************************************
 
74
 *                          Structure display function                       *
 
75
 *****************************************************************************/
 
76
 
 
77
 
 
78
/**
 
79
 * osl_generic_idump function:
 
80
 * this function displays an osl_generic_t structure (*generic) into
 
81
 * a file (file, possibly stdout) in a way that trends to be understandable.
 
82
 * It includes an indentation level (level) in order to work with others
 
83
 * idump functions.
 
84
 * \param[in] file    File where informations are printed.
 
85
 * \param[in] generic The generic whose information has to be printed.
 
86
 * \param[in] level   Number of spaces before printing, for each line.
 
87
 */
 
88
void osl_generic_idump(FILE * file, osl_generic_p generic, int level) {
 
89
  int j, first = 1;
 
90
  
 
91
  // Go to the right level.
 
92
  for (j = 0; j < level; j++)
 
93
    fprintf(file,"|\t");
 
94
 
 
95
  if (generic != NULL)
 
96
    fprintf(file, "+-- osl_generic_t\n");
 
97
  else
 
98
    fprintf(file, "+-- NULL generic\n");
 
99
 
 
100
  while (generic != NULL) {
 
101
    if (!first) {
 
102
      // Go to the right level.
 
103
      for (j = 0; j < level; j++)
 
104
        fprintf(file, "|\t");
 
105
      fprintf(file, "|   osl_generic_t\n");
 
106
    }
 
107
    else {
 
108
      first = 0;
 
109
    }
 
110
 
 
111
    // A blank line
 
112
    for(j = 0; j <= level + 1; j++)
 
113
      fprintf(file, "|\t");
 
114
    fprintf(file, "\n");
 
115
 
 
116
    osl_interface_idump(file, generic->interface, level + 1);
 
117
   
 
118
    if (generic->interface != NULL)
 
119
      generic->interface->idump(file, generic->data, level + 1);
 
120
    
 
121
    generic = generic->next;
 
122
 
 
123
    // Next line.
 
124
    if (generic != NULL) {
 
125
      for (j = 0; j <= level; j++)
 
126
        fprintf(file, "|\t");
 
127
      fprintf(file, "V\n");
 
128
    }
 
129
  }
 
130
  
 
131
  // The last line.
 
132
  for (j = 0; j <= level; j++)
 
133
    fprintf(file, "|\t");
 
134
  fprintf(file, "\n");
 
135
}
 
136
 
 
137
 
 
138
/**
 
139
 * osl_generic_dump function:
 
140
 * this function prints the content of an osl_generic_t structure
 
141
 * (*generic) into a file (file, possibly stdout).
 
142
 * \param[in] file    File where the information has to be printed.
 
143
 * \param[in] generic The generic structure to print.
 
144
 */
 
145
void osl_generic_dump(FILE * file, osl_generic_p generic) {
 
146
  osl_generic_idump(file, generic, 0); 
 
147
}
 
148
 
 
149
 
 
150
/**
 
151
 * osl_generic_print function:
 
152
 * this function prints the content of an osl_generic_t structure
 
153
 * (*generic) into a string (returned) in the OpenScop format.
 
154
 * \param[in] file    File where the information has to be printed.
 
155
 * \param[in] generic The generic structure to print.
 
156
 */
 
157
void osl_generic_print(FILE * file, osl_generic_p generic) {
 
158
  char * string;
 
159
  
 
160
  if (generic == NULL)
 
161
    return;
 
162
 
 
163
  while (generic != NULL) {
 
164
    if (generic->interface != NULL) {
 
165
      string = generic->interface->sprint(generic->data);
 
166
      if (string != NULL) {
 
167
        fprintf(file, "<%s>\n", generic->interface->URI);
 
168
        fprintf(file, "%s", string);
 
169
        fprintf(file, "</%s>\n", generic->interface->URI);
 
170
        free(string);
 
171
      }
 
172
    }
 
173
    generic = generic->next;
 
174
  }
 
175
}
 
176
 
 
177
 
 
178
/*****************************************************************************
 
179
 *                               Reading function                            *
 
180
 *****************************************************************************/
 
181
 
 
182
 
 
183
/**
 
184
 * osl_generic_sread function:
 
185
 * this function reads a list of generics from a string complying to the
 
186
 * OpenScop textual format and a list of known interfaces. It returns a
 
187
 * pointer to the corresponding list of generic structures.
 
188
 * \param[in] string   The string where to read a list of data.
 
189
 * \param[in] registry The list of known interfaces (others are ignored).
 
190
 * \return A pointer to the generic information list that has been read.
 
191
 */
 
192
osl_generic_p osl_generic_sread(char * string, osl_interface_p registry) {
 
193
  osl_generic_p generic = NULL, new;
 
194
  char * content, * start;
 
195
  void * data;
 
196
 
 
197
  while (registry != NULL) {
 
198
    content = osl_util_tag_content(string, registry->URI);
 
199
    if (content != NULL) {
 
200
      start = content;
 
201
      data = registry->sread(&content);
 
202
      if (data != NULL) {
 
203
        new = osl_generic_malloc();
 
204
        new->interface = osl_interface_nclone(registry, 1);
 
205
        new->data = data;
 
206
        osl_generic_add(&generic, new);
 
207
      }
 
208
      free(start);
 
209
    }
 
210
    registry = registry->next;
 
211
  }
 
212
  
 
213
  return generic;
 
214
}
 
215
 
 
216
 
 
217
/**
 
218
 * osl_generic_read_one function:
 
219
 * this function reads one generic from a file (possibly stdin)
 
220
 * complying to the OpenScop textual format and a list of known interfaces.
 
221
 * It returns a pointer to the corresponding generic structure. If no
 
222
 * tag is found, an error is reported, in the case of an empty or closing tag
 
223
 * name the function returns the NULL pointer.
 
224
 * \param[in] file     The input file where to read a list of data.
 
225
 * \param[in] registry The list of known interfaces (others are ignored).
 
226
 * \return A pointer to the generic that has been read.
 
227
 */
 
228
osl_generic_p osl_generic_read_one(FILE * file, osl_interface_p registry) {
 
229
  char * tag;
 
230
  char * content, * temp;
 
231
  osl_generic_p generic = NULL;
 
232
  osl_interface_p interface;
 
233
 
 
234
  tag = osl_util_read_tag(file, NULL);
 
235
  if ((tag == NULL) || (strlen(tag) < 1) || (tag[0] == '/')) {
 
236
    OSL_debug("empty tag name or closing tag instead of an opening one");
 
237
    return NULL;
 
238
  }
 
239
 
 
240
  content = osl_util_read_uptoendtag(file, tag);
 
241
  interface = osl_interface_lookup(registry, tag);
 
242
 
 
243
  temp = content;
 
244
  if (interface == NULL) {
 
245
    OSL_warning("unsupported generic");
 
246
    fprintf(stderr, "[osl] Warning: unknown URI \"%s\".\n", tag);
 
247
  }
 
248
  else {
 
249
    generic = osl_generic_malloc();
 
250
    generic->interface = osl_interface_nclone(interface, 1);
 
251
    generic->data = interface->sread(&temp);
 
252
  }
 
253
 
 
254
  free(content);
 
255
  free(tag);
 
256
  return generic;
 
257
}
 
258
 
 
259
 
 
260
/**
 
261
 * osl_generic_read function:
 
262
 * this function reads a list of generics from a file (possibly stdin)
 
263
 * complying to the OpenScop textual format and a list of known interfaces.
 
264
 * It returns a pointer to the list of corresponding generic structures.
 
265
 * \param[in] file     The input file where to read a list of data.
 
266
 * \param[in] registry The list of known interfaces (others are ignored).
 
267
 * \return A pointer to the generic information list that has been read.
 
268
 */
 
269
osl_generic_p osl_generic_read(FILE * file, osl_interface_p registry) {
 
270
  char * generic_string;
 
271
  osl_generic_p generic_list;
 
272
 
 
273
  generic_string = osl_util_read_uptotag(file, OSL_TAG_END_SCOP);
 
274
  generic_list = osl_generic_sread(generic_string, registry);
 
275
  free(generic_string);
 
276
  return generic_list;
 
277
}
 
278
 
 
279
 
 
280
/*+***************************************************************************
 
281
 *                    Memory allocation/deallocation function                *
 
282
 *****************************************************************************/
 
283
 
 
284
 
 
285
/**
 
286
 * osl_generic_add function:
 
287
 * this function adds a generic node (it may be a list as well) to a list
 
288
 * of generics provided as parameter (list). The new node is inserted at
 
289
 * the end of the list. 
 
290
 * \param[in] list    The list of generics to add a node (NULL if empty).
 
291
 * \param[in] generic The generic list to add to the initial list.
 
292
 */
 
293
void osl_generic_add(osl_generic_p * list, osl_generic_p generic) {
 
294
  osl_generic_p tmp = *list, check;
 
295
  
 
296
  if (generic != NULL) {
 
297
    // First, check that the generic list is OK.
 
298
    check = generic;
 
299
    while (check != NULL) {
 
300
      if ((check->interface == NULL) || (check->interface->URI == NULL))
 
301
        OSL_error("no interface or URI in a generic to add to a list");
 
302
 
 
303
      // TODO: move this to the integrity check.
 
304
      if (osl_generic_lookup(*list, check->interface->URI) != NULL)
 
305
        OSL_error("only one generic with a given URI is allowed");
 
306
      check = check->next;
 
307
    }
 
308
 
 
309
    if (*list != NULL) {
 
310
      while (tmp->next != NULL)
 
311
        tmp = tmp->next;
 
312
      tmp->next = generic;
 
313
    }
 
314
    else {
 
315
      *list = generic;
 
316
    }
 
317
  }
 
318
}
 
319
 
 
320
 
 
321
/**
 
322
 * osl_generic_malloc function:
 
323
 * This function allocates the memory space for an osl_generic_t
 
324
 * structure and sets its fields with default values. Then it returns a
 
325
 * pointer to the allocated space.
 
326
 * \return A pointer to an empty generic structure with fields set to
 
327
 *         default values.
 
328
 */
 
329
osl_generic_p osl_generic_malloc() {
 
330
  osl_generic_p generic;
 
331
 
 
332
  OSL_malloc(generic, osl_generic_p, sizeof(osl_generic_t));
 
333
  generic->interface = NULL;
 
334
  generic->data      = NULL;
 
335
  generic->next      = NULL;
 
336
 
 
337
  return generic;
 
338
}
 
339
 
 
340
 
 
341
/**
 
342
 * osl_generic_free function:
 
343
 * This function frees the allocated memory for a generic structure.
 
344
 * \param[in] generic The pointer to the generic structure we want to free.
 
345
 */
 
346
void osl_generic_free(osl_generic_p generic) {
 
347
  osl_generic_p next;
 
348
 
 
349
  while (generic != NULL) {
 
350
    next = generic->next;
 
351
    if (generic->interface != NULL) {
 
352
      generic->interface->free(generic->data);
 
353
      osl_interface_free(generic->interface);
 
354
    }
 
355
    else {
 
356
      if (generic->data != NULL) {
 
357
        OSL_warning("unregistered interface, memory leaks are possible");
 
358
        free(generic->data);
 
359
      }
 
360
    }
 
361
    free(generic);
 
362
    generic = next;
 
363
  }
 
364
}
 
365
 
 
366
 
 
367
/*+***************************************************************************
 
368
 *                            Processing functions                           *
 
369
 *****************************************************************************/
 
370
 
 
371
 
 
372
/**
 
373
 * osl_generic_clone function:
 
374
 * This function builds and returns a "hard copy" (not a pointer copy) of an
 
375
 * osl_generic_t data structure.
 
376
 * \param[in] generic The pointer to the generic structure we want to clone.
 
377
 * \return A pointer to the clone of the input generic structure.
 
378
 */
 
379
osl_generic_p osl_generic_clone(osl_generic_p generic) {
 
380
  osl_generic_p clone = NULL, new;
 
381
  osl_interface_p interface;
 
382
  void * x;
 
383
 
 
384
  while (generic != NULL) { 
 
385
    if (generic->interface != NULL) {
 
386
      x = generic->interface->clone(generic->data);
 
387
      interface = osl_interface_clone(generic->interface);
 
388
      new = osl_generic_malloc();
 
389
      new->interface = interface;
 
390
      new->data = x;
 
391
      osl_generic_add(&clone, new);
 
392
    }
 
393
    else {
 
394
      OSL_warning("unregistered interface, cloning ignored");
 
395
    }
 
396
    generic = generic->next;
 
397
  }
 
398
 
 
399
  return clone;
 
400
}
 
401
 
 
402
 
 
403
/**
 
404
 * osl_generic_count function:
 
405
 * this function counts the number of elements in the generic list provided
 
406
 * as parameter (x) and returns this number.
 
407
 * \param[in] x The list of generics.
 
408
 * \return  The number of elements in the list.
 
409
 */
 
410
int osl_generic_count(osl_generic_p x) {
 
411
  int generic_number = 0;
 
412
 
 
413
  while (x != NULL) {
 
414
    generic_number++;
 
415
    x = x->next;
 
416
  }
 
417
 
 
418
  return generic_number;
 
419
}
 
420
 
 
421
 
 
422
/**
 
423
 * osl_generic_equal function:
 
424
 * this function returns true if the two generic structures are the same,
 
425
 * false otherwise. This functions considers two generic structures as equal
 
426
 * independently of the order of the nodes. TODO: make it dependent on the
 
427
 * order.
 
428
 * \param x1 The first generic structure.
 
429
 * \param x2 The second generic structure.
 
430
 * \return 1 if x1 and x2 are the same (content-wise), 0 otherwise.
 
431
 */
 
432
int osl_generic_equal(osl_generic_p x1, osl_generic_p x2) {
 
433
  int x1_generic_number, x2_generic_number;
 
434
  int found, equal;
 
435
  osl_generic_p backup_x2 = x2;
 
436
 
 
437
  if (x1 == x2)
 
438
    return 1;
 
439
 
 
440
  // Check whether the number of generics is the same or not.
 
441
  x1_generic_number = osl_generic_count(x1);
 
442
  x2_generic_number = osl_generic_count(x2);
 
443
  if (x1_generic_number != x2_generic_number)
 
444
    return 0;
 
445
 
 
446
  // Check that for each generic in x1 a similar generic is in x2.
 
447
  while (x1 != NULL) {
 
448
    x2 = backup_x2;
 
449
    found = 0;
 
450
    while ((x2 != NULL) && (found != 1)) {
 
451
      if (osl_interface_equal(x1->interface, x2->interface)) {
 
452
        if (x1->interface != NULL) {
 
453
          equal = x1->interface->equal(x1->data, x2->data);
 
454
        }
 
455
        else {
 
456
          OSL_warning("unregistered generic, "
 
457
                      "cannot state generic equality");
 
458
          equal = 0;
 
459
        }
 
460
 
 
461
        if (equal == 0)
 
462
          return 0;
 
463
        else
 
464
          found = 1;
 
465
      }
 
466
 
 
467
      x2 = x2->next;
 
468
    }
 
469
 
 
470
    if (found != 1)
 
471
      return 0;
 
472
 
 
473
    x1 = x1->next;
 
474
  }
 
475
 
 
476
  return 1;
 
477
}
 
478
 
 
479
 
 
480
/**
 
481
 * osl_generic_has_URI function:
 
482
 * this function returns 1 if the generic provided as parameter has
 
483
 * a given URI, 0 other wise.
 
484
 * \param x   The generic structure to test.
 
485
 * \param URI The URI value to test.
 
486
 * \return 1 if x has the provided URI, 0 otherwise.
 
487
 */
 
488
int osl_generic_has_URI(osl_generic_p x, char * URI) {
 
489
 
 
490
  if ((x == NULL) ||
 
491
      (x->interface == NULL) ||
 
492
      (x->interface->URI == NULL) ||
 
493
      (strcmp(x->interface->URI, URI)))
 
494
    return 0;
 
495
 
 
496
  return 1;
 
497
}
 
498
 
 
499
 
 
500
/**
 
501
 * osl_generic_lookup function:
 
502
 * this function returns the first generic with a given URI in the
 
503
 * generic list provided as parameter and NULL if it doesn't find such
 
504
 * a generic.
 
505
 * \param x   The generic list where to search a given generic URI.
 
506
 * \param URI The URI of the generic we are looking for.
 
507
 * \return The first generic of the requested URI in the list.
 
508
 */
 
509
void * osl_generic_lookup(osl_generic_p x, char * URI) {
 
510
  while (x != NULL) {
 
511
    if (osl_generic_has_URI(x, URI))
 
512
      return x->data;
 
513
 
 
514
    x = x->next;
 
515
  }
 
516
 
 
517
  return NULL;
 
518
}