PIPS
tabulated.c
Go to the documentation of this file.
1 /*
2 
3  $Id: tabulated.c 1357 2016-03-02 08:18:50Z coelho $
4 
5  Copyright 1989-2016 MINES ParisTech
6 
7  This file is part of NewGen.
8 
9  NewGen is free software: you can redistribute it and/or modify it under the
10  terms of the GNU General Public License as published by the Free Software
11  Foundation, either version 3 of the License, or any later version.
12 
13  NewGen is distributed in the hope that it will be useful, but WITHOUT ANY
14  WARRANTY; without even the implied warranty of MERCHANTABILITY or
15  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
16  License for more details.
17 
18  You should have received a copy of the GNU General Public License along with
19  NewGen. If not, see <http://www.gnu.org/licenses/>.
20 
21 */
22 /*
23  management of tabulated domains.
24 */
25 #ifdef HAVE_CONFIG_H
26  #include "config.h"
27 #endif
28 
29 #include <stdio.h>
30 #include <string.h>
31 #include <stdarg.h>
32 #include <stdlib.h>
33 #include <stdint.h>
34 #include <setjmp.h>
35 
36 #include "genC.h"
37 #include "newgen_include.h"
38 
39 /*********************************************************** TABULATED STUFF */
40 
41 /* table of tabulated elements.
42 
43  I guess it could be stored directly in the gen_binding,
44  and the index could be dropped.
45  */
46 
47 #define TABULATED_ELEMENTS_SIZE (500)
48 #define TABULATED_ELEMENTS_INCR (10000)
49 
50 struct _gtp
51 {
52  int domain; /* domain number */
53  int size; /* current allocated size */
54  int used; /* how many are used */
55  gen_chunk * table; /* actual table */
56  hash_table names; /* names to index for fast search */
57 };
58 
60 {
62  message_assert("domain is tabulated", IS_TABULATED(Domains+domain));
63  return Domains[domain].tabulated;
64 }
65 
67 {
68  int i;
69  gen_chunk * t;
70  gen_tabulated_p gtp;
71 
72  gtp = (gen_tabulated_p) alloc(sizeof(struct _gtp));
73 
75  gtp->used = 0;
76  gtp->domain = domain;
78 
79  for (i=0; i<TABULATED_ELEMENTS_SIZE; i++)
80  t[i].p = gen_chunk_undefined;
81 
82  gtp->table = t;
84 
85  return gtp;
86 }
87 
89 {
90  register int nsize, i;
91  gen_chunk * t;
92 
93  nsize = gtp->size + TABULATED_ELEMENTS_INCR;
94 
95  t = (gen_chunk*) realloc(gtp->table, sizeof(gen_chunk)*nsize);
96 
97  message_assert("realloc ok", t);
98 
99  for (i=gtp->size; i<nsize; i++)
100  t[i].p = gen_chunk_undefined;
101 
102  gtp->size = nsize;
103  gtp->table = t;
104 }
105 
106 /* WARNING: it is not reentrant... */
108 {
109  static gen_chunk c[2];
110  static struct intlist il;
111 
113 
114  c[0].i = Tabulated_bp-Domains;
115  c[1].p = gtp->table;
116 
117  il.val = gtp->size; /* max_tabulated_elements() */
118  il.cdr = (struct intlist *) NULL;
119 
122 
123  return c;
124 }
125 
126 /* apply fp to domain... */
127 void gen_mapc_tabulated(void (*fp)(gen_chunk*), int domain)
128 {
130  register int i, size = gtp->size;
131 
132  for (i=0; i<size; i++)
133  {
134  gen_chunk e = gtp->table[i];
135  if (e.p && e.p != gen_chunk_undefined)
136  {
137  message_assert("tabulated ok", e.p->i==domain);
138  fp(e.p);
139  }
140  }
141 }
142 
143 /* returns the list of entities with this caracteristics. */
145 {
147  register int i, size = gtp->size;
148  list l;
149 
150  for (l=NIL, i=0; i<size; i++) {
151  gen_chunk * o = gtp->table[i].p;
152  if (o && o != gen_chunk_undefined) {
153  if (filter(o)) l = CONS(CHUNK, o, l);
154  }
155  }
156 
157  return l;
158 }
159 
160 /* add tabulated in table. returns its index.
161  */
162 static int gen_put_tabulated(int domain, gen_chunk * gc)
163 {
165  register int i, size = gtp->size;
166 
167  if (gtp->used + 10 > gtp->size) {
168  extends_tabulated(gtp);
169  }
170 
171  message_assert("large enough", gtp->used+10 <= gtp->size);
172 
173  for (i = gtp->used? gtp->used: 1; i != gtp->used-1 ; i%=(size-1), i++)
174  {
175  if (gtp->table[i].p == gen_chunk_undefined)
176  {
177  gtp->table[i].p = gc;
178  gtp->used++;
179  return i;
180  }
181  }
182 
183  /* should not get there */
184  fatal("cannot put tabulated dom=%d... no space available!", domain);
185  return 0;
186 }
187 
188 static void gen_put_tabulated_name(int domain, char * id, _int number)
189 {
191  message_assert("positive tabulated number", number>0);
192  hash_put(gtp->names, id, (void *) number);
193 }
194 
195 
196 /* deletes obj from the tabulated names...
197  */
199 {
200  char * key = (obj+2)->s;
201  void * okey, * val;
202  int domain = obj->i;
204 
205  val = hash_delget(gtp->names, key, &okey);
206  if (val == HASH_UNDEFINED_VALUE)
207  fatal("gen_delete_tabulated_name: clearing unexisting (%s)\n", key);
208 
209  // free(okey);
210 }
211 
212 static _int gen_get_tabulated_name_basic(int domain, const char * id)
213 {
215  return (_int) hash_get(gtp->names, id);
216 }
217 
218 void * gen_find_tabulated(const char * key, int domain)
219 {
221 
222  if (number == (_int) HASH_UNDEFINED_VALUE)
223  {
224  return gen_chunk_undefined;
225  }
226  else
227  {
229  message_assert("valid tabulated number", number>=0 && number<gtp->size);
230  return gtp->table[number].p;
231  }
232 }
233 
234 static void positive_number(gen_chunk * o)
235 {
236  message_assert("positive tabulated number", (o+1)->i>0);
237 }
238 
239 int gen_read_and_check_tabulated(FILE *file, int create_p)
240 {
241  int domain = gen_read_tabulated(file, create_p);
243  return domain;
244 }
245 
246 /******************************************************************** IN/OUT */
247 
248 /* GEN_CLEAR_TABULATED_ELEMENT only clears the entry for object OBJ in the
249  gen_tabulated_ and gen_tabulated_names tables. */
250 
252 {
253  register int domain = quick_domain_index(obj);
255  int number = (obj+1)->i;
256 
257  message_assert("correct object to delete", gtp->table[number].p == obj);
258 
260  gtp->table[number].p = gen_chunk_undefined;
261  gtp->used--;
262 }
263 
264 gen_chunk *
265 gen_do_enter_tabulated(int domain, string id, gen_chunk * cp, bool is_a_ref)
266 {
267  int number = gen_put_tabulated(domain, cp);
268  (cp+1)->i = is_a_ref? -number: number; /* stores - if ref */
269  message_assert("name pointer ok", (cp+2)->s == id);
270  gen_put_tabulated_name(domain, id, number);
271  return cp;
272 }
273 
274 /* ENTER_TABULATED_DEF enters a new definition (previous refs are allowed if
275  ALLOW_REF) in the INDEX tabulation table of the DOMAIN, with the unique
276  ID and value CHUNKP.
277  */
278 gen_chunk *
279 gen_enter_tabulated(int domain, string id, gen_chunk * cp, bool allow_ref)
280 {
281  gen_chunk * gp = gen_find_tabulated(id, domain);
282 
283  if (gp==gen_chunk_undefined)
284  {
285  cp = gen_do_enter_tabulated(domain, id, cp, false);
286  }
287  else /* already in, redefine */
288  {
289  register int i, size, number = (gp+1)->i;
290 
291  if (number>0)
292  fprintf(stderr, "warning: '%s' of %d redefined\n", id, domain);
293  else
294  number = -number;
295 
296  if (!allow_ref)
297  fprintf(stderr, "unexpected reference to '%s' of %d\n", id, domain);
298 
299  size = gen_size(domain);
300 
301  message_assert("same name", same_string_p((gp+2)->s, (cp+2)->s));
302  message_assert("same domain", gp->i == cp->i);
303 
304  for (i=3; i<size; i++)
305  gp[i] = cp[i];
306 
307  free((cp+2)->s), free(cp), cp = gp;
308  (cp+1)->i = number;
309  }
310 
311  return cp;
312 }
313 
314 
315 
char * alloc(int size)
ALLOC is an "iron-clad" version of malloc(3).
Definition: build.c:501
int gen_size(int domain)
GEN_SIZE returns the size (in gen_chunks) of an object of type defined by the BP type.
Definition: genC.c:71
#define CHUNK(x)
Definition: genC.h:90
#define gen_chunk_undefined
Definition: genC.h:74
int gen_read_tabulated(FILE *file, int create_p)
GEN_READ_TABULATED reads FILE to update the Gen_tabulated_ table.
Definition: genClib.c:2334
struct gen_binding * Tabulated_bp
pointer to tabulated domain hack
Definition: genClib.c:58
void free(void *)
struct gen_binding Domains[MAX_DOMAIN]
in build.c
Definition: genspec_yacc.c:114
#define NIL
The empty list (nil in Lisp)
Definition: newgen_list.h:47
#define CONS(_t_, _i_, _l_)
List element cell constructor (insert an element at the beginning of a list)
Definition: newgen_list.h:150
hash_table hash_table_make(hash_key_type key_type, size_t size)
Definition: hash.c:294
void * hash_get(const hash_table htp, const void *key)
this function retrieves in the hash table pointed to by htp the couple whose key is equal to key.
Definition: hash.c:449
void hash_put(hash_table htp, const void *key, const void *val)
This functions stores a couple (key,val) in the hash table pointed to by htp.
Definition: hash.c:364
void * hash_delget(hash_table htp, const void *key, void **pkey)
deletes key from the hash table.
Definition: hash.c:398
#define message_assert(msg, ex)
Definition: newgen_assert.h:47
@ hash_string
Definition: newgen_hash.h:32
#define HASH_UNDEFINED_VALUE
value returned by hash_get() when the key is not found; could also be called HASH_KEY_NOT_FOUND,...
Definition: newgen_hash.h:56
#define quick_domain_index(obj)
inlined version of domain_index.
#define check_domain(dom)
void fatal(char *,...)
#define IS_TABULATED(bp)
#define same_string_p(s1, s2)
struct _gtp * gen_tabulated_p
actually defined in tabulated.c
intptr_t _int
_INT
Definition: newgen_types.h:53
Pvecteur cp
pointeur sur l'egalite ou l'inegalite courante
Definition: sc_read.c:87
int fprintf()
test sc_min : ce test s'appelle par : programme fichier1.data fichier2.data ...
Definition: tabulated.c:51
int used
current allocated size
Definition: tabulated.c:54
gen_chunk * table
how many are used
Definition: tabulated.c:55
int domain
Definition: tabulated.c:52
hash_table names
actual table
Definition: tabulated.c:56
int size
domain number
Definition: tabulated.c:53
The structure used to build lists in NewGen.
Definition: newgen_list.h:41
union domain * domain
gen_tabulated_p tabulated
number of chunks to hold this data.
#define TABULATED_ELEMENTS_SIZE
table of tabulated elements.
Definition: tabulated.c:47
gen_chunk * gen_do_enter_tabulated(int domain, string id, gen_chunk *cp, bool is_a_ref)
Definition: tabulated.c:265
static int gen_put_tabulated(int domain, gen_chunk *gc)
add tabulated in table.
Definition: tabulated.c:162
static void extends_tabulated(gen_tabulated_p gtp)
Definition: tabulated.c:88
gen_chunk * gen_tabulated_fake_object_hack(int domain)
WARNING: it is not reentrant...
Definition: tabulated.c:107
static void gen_delete_tabulated_name(gen_chunk *obj)
deletes obj from the tabulated names...
Definition: tabulated.c:198
void * gen_find_tabulated(const char *key, int domain)
Definition: tabulated.c:218
#define TABULATED_ELEMENTS_INCR
Definition: tabulated.c:48
void gen_mapc_tabulated(void(*fp)(gen_chunk *), int domain)
apply fp to domain...
Definition: tabulated.c:127
gen_chunk * gen_enter_tabulated(int domain, string id, gen_chunk *cp, bool allow_ref)
ENTER_TABULATED_DEF enters a new definition (previous refs are allowed if ALLOW_REF) in the INDEX tab...
Definition: tabulated.c:279
list gen_filter_tabulated(bool(*filter)(gen_chunk *), int domain)
returns the list of entities with this caracteristics.
Definition: tabulated.c:144
gen_tabulated_p gen_init_tabulated(int domain)
Definition: tabulated.c:66
static void gen_put_tabulated_name(int domain, char *id, _int number)
Definition: tabulated.c:188
void gen_clear_tabulated_element(gen_chunk *obj)
GEN_CLEAR_TABULATED_ELEMENT only clears the entry for object OBJ in the gen_tabulated_ and gen_tabula...
Definition: tabulated.c:251
static _int gen_get_tabulated_name_basic(int domain, const char *id)
Definition: tabulated.c:212
static void positive_number(gen_chunk *o)
Definition: tabulated.c:234
static gen_tabulated_p get_tabulated_from_domain(int domain)
Definition: tabulated.c:59
int gen_read_and_check_tabulated(FILE *file, int create_p)
Definition: tabulated.c:239
A DOMAIN union describes the structure of a user type.
struct gen_binding * element
struct intlist * dimensions
struct domain::@6 ar
A gen_chunk is used to store every object.
Definition: genC.h:58
_int i
Definition: genC.h:62
union gen_chunk * p
Definition: genC.h:69