Initial version of donated sources by Avertec, 3.4p5.
[tas-yagle.git] / distrib / sources / mbk / mbk_util.c
1 /*
2 * This file is part of the Alliance CAD System
3 * Copyright (C) Laboratoire LIP6 - Département ASIM
4 * Universite Pierre et Marie Curie
5 *
6 * Home page : http://www-asim.lip6.fr/alliance/
7 * E-mail support : mailto:alliance-support@asim.lip6.fr
8 *
9 * This library is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU Library General Public License as published
11 * by the Free Software Foundation; either version 2 of the License, or (at
12 * your option) any later version.
13 *
14 * Alliance VLSI CAD System is distributed in the hope that it will be
15 * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
17 * Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License along
20 * with the GNU C Library; see the file COPYING. If not, write to the Free
21 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 */
23
24 /*
25 * Purpose : services functions and global variables
26 * Date : 06/03/92
27 * Author : Frederic Petrot <Frederic.Petrot@lip6.fr>
28 * Modified by Czo <Olivier.Sirol@lip6.fr> 1997,98
29 */
30
31 #ident "$Id: mbk_util.c,v 1.198 2009/05/07 14:33:06 fabrice Exp $"
32
33 #include <stdio.h>
34 #include <stdlib.h>
35 #include <unistd.h>
36 #include <ctype.h>
37 #include <string.h>
38 #include <signal.h>
39 #include <sys/types.h>
40 #include <sys/wait.h>
41 #include AVT_H
42 #include MUT_H
43 #include "mbk_util.h"
44 #include "../avt/avt_init_funcs.h"
45
46 #ifdef MALLOC_HISTOGRAM
47 ht_v2 *MALLOC_HISTO=NULL;
48 int MALLOC_HISTO_mutex=0;
49 unsigned long MALLOC_HOOK_TOTAL_MEM=0, MALLOC_HOOK_TOTAL_CALL=0, MALLOC_HOOK_ERRORS=0, FREE_HOOK_TOTAL_CALL=0, REALLOC_HOOK_TOTAL_CALL=0, MALLOC_HOOK_TOTAL_MEM_FROM_START=0, MALLOC_HOOK_CONSO=0;
50 void setup_malloc_hook();
51 #endif
52
53 /* Normally defined in values.h, but not available on all systems */
54 #ifndef BITS
55 #define BITS(type) (8 * (int)sizeof(type))
56 #endif
57
58 /*******************************************************************************
59 * global variables *
60 *******************************************************************************/
61 chain_list *HEAD_CHAIN = NULL; /* chain buffer head */
62 chain_list *HEAD_BLOCK_CHAIN = NULL;
63 ptype_list *HEAD_PTYPE = NULL; /* ptype buffer head */
64 num_list *HEAD_NUM = NULL; /* num buffer head */
65 char TRACE_MODE = 'N'; /* trace if 'Y' */
66 char DEBUG_MODE = 'N'; /* debug if 'Y' */
67 char FAST_MODE = 'Y'; /* no consistency check if 'Y' */
68 char SEPAR = '.'; /* char used in concatenation */
69 char *WORK_LIB = NULL; /* working directory */
70 char **CATA_LIB = NULL; /* read only directories */
71 char *CATAL = NULL; /* catalog file */
72 /* par Fabrice le 7/2/2002 */
73 char IN_PARASITICS[5] = "dspf"; /* parasitic input format */
74 int MBK_LOAD_PARA = 0; /* load parasitics enabler */
75 /* ----- le 8/2/2002 */
76 int MBK_DEVECT = 1; /* devect signal name enabler */
77 /* ----- */
78 char IN_LO[5] = "spi"; /* input logical format */
79 char IN_PH[5] = "ap"; /* input physical format */
80 char OUT_LO[5] = "spi"; /* output logical format */
81 char OUT_PH[5] = "ap"; /* output physical format */
82 long SCALE_X = 10000; /* distance scale definition */
83 char PARSER_INFO[100] = "nothing yet"; /* version number, and so on */
84 char *VDD = NULL; /* user name for power high */
85 char *VSS = NULL; /* user name for power ground */
86 char *GLOBAL_VDD = NULL; /* user name for power high */
87 char *GLOBAL_VSS = NULL; /* user name for power ground */
88 long VDD_VSS_THRESHOLD = 0; /* Threshold between VDD & VSS */
89 char *MBK_BBOX_NAME = NULL; /* blackbox list file name */
90 char *IN_FILTER = NULL ;
91 char *OUT_FILTER = NULL ;
92 char *FILTER_SFX = NULL ;
93 char *LIB_FILE = NULL ;
94 ht *LIB_CATAL = NULL ;
95
96 char **MBK_NRD = NULL;
97 char **MBK_NRS = NULL;
98 char **MBK_DELVT0 = NULL;
99 char **MBK_MULU0 = NULL;
100 char **MBK_SA = NULL;
101 char **MBK_SB = NULL;
102 char **MBK_SD = NULL;
103 char **MBK_SC = NULL;
104 char **MBK_SCA = NULL;
105 char **MBK_SCB = NULL;
106 char **MBK_SCC = NULL;
107 char **MBK_NF = NULL;
108 char **MBK_NFING = NULL;
109 char **MBK_M = NULL;
110 char **MBK_MULT = NULL;
111 char **MBK_GEOMOD = NULL;
112 char **MBK_ABSOURCE = NULL;
113 char **MBK_LSSOURCE = NULL;
114 char **MBK_LGSOURCE = NULL;
115 char **MBK_ABDRAIN = NULL;
116 char **MBK_LSDRAIN = NULL;
117 char **MBK_LGDRAIN = NULL;
118
119 static int namealloc_primes[]={103, 5023, 10007, 50047, 100003, 507077, 1000099, 1500823, 2015177};
120 static int namealloc_primes_index=4;
121 #ifdef BASE_STAT
122 long ynmsize=0;
123 long i_nbchain=0, i_nbptype=0, i_nbnum=0;
124 #endif
125
126 /* table de hash de namealloc() et namefind() */
127 static chain_list **NAME_HASHTABLE=NULL;//[HASHVAL];
128 static char buffer[BUFSIZ]; /* buffer for namealloc strcpy */
129 static char str[BUFSIZ]; /* buffer for concatname */
130 static char tolowertable[1 << BITS(char)]; /* number of chars */
131 static char touppertable[1 << BITS(char)]; /* number of chars */
132 char CASE_SENSITIVE = 'P'; /* namealloc case sensistive */
133 char MBK_DUP_PNAME_FF='Y';
134 char SPI_VECTOR[1024];
135 char FLATTEN_KEEP_ALL_NAMES=0;
136
137 /*
138 ** Added by Ludovic Jacomme (The slave)
139 ** in order to "trap" exit with Graal/Dreal etc ...
140 */
141 void (*MBK_EXIT_FUNCTION)(int) = 0;
142 char MBK_EXIT_KILL = 'N' ;
143
144 char *MBK_BULK_NAME,*MBK_GRID_NAME,*MBK_DRAIN_NAME,*MBK_SOURCE_NAME;
145
146 chain_list *CRYPTMOS=NULL;
147 chain_list *TNMOS=NULL, *TPMOS=NULL;
148 chain_list *DNMOS=NULL, *DPMOS=NULL;
149 chain_list *JFETN=NULL, *JFETP=NULL;
150
151 /* Known optional parameters */
152 static char *KNOWN_TRSPARAM[] = {"nrd", "$nrd", "nrs", "$nrs", "mulu0", "$mulu0", "delvto", "$delvto", "sa", "$sa", "sb", "$sb", "sd", "$sd", "nf", "$nf", "nfing", "$nfing", "m", "$m", "geomod", "$geomod", "sc", "$sc", "sca", "$sca", "scb", "$scb", "scc", "$scc", "absource", "$absource", "lssource", "$lssource", "lgsource", "$lgsource", "abdrain", "$abdrain", "lsdrain", "$lsdrain", "lgdrain", "$lgdrain", "mult", "$mult" };
153 static int NUM_KNOWN_TRSPARAM = 44;
154
155 static NameAllocator SENSITIVE_NAMEALLOC_ALLOCATOR;
156
157 mbk_parse_error MBK_PARSE_ERROR = { NULL, 0ul, 0ul, 0ul, 0ul, 0, 0};
158 chain_list *MBK_ALL_PARSE_ERROR=NULL;
159
160 char MBK_VECTOR_OPEN[256];
161 char MBK_VECTOR_CLOSE[256];
162 char MBK_VECTOR_SINGLE[256];
163
164 int namealloc_ok()
165 {
166 return NAME_HASHTABLE!=NULL;
167 }
168 void mbk_commit_errors(char *filename)
169 {
170 mbk_parse_error *mpr;
171 mpr=(mbk_parse_error *)mbkalloc(sizeof(mbk_parse_error));
172 memcpy(mpr, &MBK_PARSE_ERROR, sizeof(mbk_parse_error));
173 mpr->filename=sensitive_namealloc(filename);
174 MBK_ALL_PARSE_ERROR=addchain(MBK_ALL_PARSE_ERROR, mpr);
175 MBK_PARSE_ERROR.NB_RESI=MBK_PARSE_ERROR.NB_CAPA=MBK_PARSE_ERROR.NB_LOTRS=MBK_PARSE_ERROR.NB_NET=MBK_PARSE_ERROR.NB_INSTANCE=MBK_PARSE_ERROR.NB_DIODE=0;
176 }
177
178 void mbk_reset_errors()
179 {
180 chain_list *cl;
181 for (cl=MBK_ALL_PARSE_ERROR; cl!=NULL; cl=cl->NEXT) mbkfree(cl->DATA);
182 freechain(MBK_ALL_PARSE_ERROR);
183 MBK_ALL_PARSE_ERROR = NULL;
184 }
185
186 int isknowntrsparam(void *param)
187 {
188 if ((char **)param >= (char **)KNOWN_TRSPARAM && (char **)param < (char **)KNOWN_TRSPARAM + NUM_KNOWN_TRSPARAM) {
189 return 1;
190 }
191 return 0;
192 }
193
194 char **getknowntrsparam(char *name)
195 {
196 int i;
197
198 for (i = 0; i < NUM_KNOWN_TRSPARAM; i+=2) {
199 if (!strcasecmp(name, KNOWN_TRSPARAM[i])) return ((char **)KNOWN_TRSPARAM + i);
200 }
201 return NULL;
202 }
203
204 static void dflhandler(int);
205
206 /*******************************************************************************
207 * fonction handler() *
208 *******************************************************************************/
209 static void dflhandler(int sig)
210 {
211 MBK_EXIT_KILL = 'N';
212 sig=0; /* avoir warning */
213 EXIT(100);
214 }
215
216 /*******************************************************************************
217 * fonction mbkwaitpid() *
218 * Verifie parmis les processus fils termines si pid en fait partie. Si status *
219 * est non nul, le code de retour est place dans cette variable. si mode vaut *
220 * 1, cet appel est bloquant, sinon il est non bloquant. *
221 *******************************************************************************/
222 int mbkwaitpid( int pid, int mode, int *status )
223 {
224 while(1)
225 {
226 if( waitpid( pid, status, WNOHANG) != 0 )
227 return( 1 );
228
229 if( mode != 1 )
230 return( 0 );
231
232 sleep(1); /* le sleep est interruptible : on ne perd rien */
233 }
234
235 return( 0 );
236 }
237
238 int mbk_decodvectorconfig( char *env )
239 {
240 char buf[1024] ;
241 char onechar[2] ;
242 static char separ = ',';
243 char *pt ;
244 int i ;
245 char vector_open[1024];
246 char vector_close[1024];
247 char vector_single[1024];
248
249 MBK_DEVECT=1;
250 if( !env || strcasecmp(env,"yes")==0) {
251 strcpy( MBK_VECTOR_OPEN, "<[" );
252 strcpy( MBK_VECTOR_CLOSE, ">]" );
253 strcpy( MBK_VECTOR_SINGLE, "" );
254 return 1 ;
255 }
256 else if (strcasecmp(env,"no")==0)
257 {
258 MBK_DEVECT=0;
259 return 1;
260 }
261
262 pt = env ;
263 *vector_open = '\0' ;
264 *vector_close = '\0' ;
265 *vector_single = '\0' ;
266
267
268 while( *pt ) {
269
270 for( i=0 ;
271 *pt && *pt != separ ;
272 buf[i]=*pt, i++, pt++
273 );
274 buf[i]='\0';
275 if( *pt )
276 pt++;
277
278 switch( i ) {
279
280 case 0 :
281 break ;
282
283 case 1 :
284 strcat( vector_single, buf );
285 break ;
286
287 case 2 :
288 onechar[1] = '\0' ;
289
290 onechar[0] = buf[0] ;
291 strcat( vector_open, onechar );
292
293 onechar[0] = buf[1] ;
294 strcat( vector_close, onechar );
295 break ;
296
297 default :
298 return 0 ;
299 }
300 }
301
302 strcpy( MBK_VECTOR_OPEN, vector_open ) ;
303 strcpy( MBK_VECTOR_CLOSE, vector_close ) ;
304 strcpy( MBK_VECTOR_SINGLE, vector_single ) ;
305
306 return 1 ;
307 }
308
309 /*******************************************************************************
310 * fonction mbkenv() *
311 *******************************************************************************/
312 void mbkenv()
313 {
314 char *str, *env;
315 char *pttok;
316 long nchar;
317 struct sigaction sgct;
318 sigset_t ens;
319 char buf[1024];
320 int n ;
321 static int protect_mbkenv=0;
322 static char MBK_RAND_SEED[] =
323 {
324 0x62, 0x37, 0x34, 0x30, 0x30, 0x32, 0x31, 0x38, 0x61, 0x31, 0x37, 0x34,
325 0x64, 0x34, 0x64, 0x36, 0x36, 0x65, 0x32, 0x35, 0x38, 0x30, 0x34, 0x63,
326 0x31, 0x36, 0x32, 0x38, 0x34, 0x65, 0x37, 0x61
327 } ;
328
329
330 if (!protect_mbkenv)
331 {
332 #ifdef MALLOC_HISTOGRAM
333 setup_malloc_hook();
334 #endif
335 }
336 read_lib(); /* read the contents of MBK_WORK_LIB and MBK_CATA_LIB */
337
338 str = getenv("MBK_DEBUG_MODE");
339 if (str)
340 if (!strcmp(str,"yes"))
341 DEBUG_MODE = 'Y';
342
343 str = getenv("MBK_TRACE_MODE");
344 if (str)
345 if (!strcmp(str,"yes"))
346 TRACE_MODE = 'Y';
347
348 FAST_MODE = V_BOOL_TAB[__MBK_FAST_MODE].VALUE?'Y':'N';
349
350 SCALE_X = (long)V_INT_TAB[__MBK_SCALE_X].VALUE;
351
352 srand((unsigned int) MBK_RAND_SEED);
353
354 str = V_STR_TAB[__MBK_IN_LO].VALUE;
355 if (str) {
356 if (!strcmp(str, "hns"))
357 (void)strcpy(IN_LO, "hns");
358 else if (!strcmp(str, "fne"))
359 (void)strcpy(IN_LO, "fne");
360 else if (!strcmp(str, "hdn"))
361 (void)strcpy(IN_LO, "hdn");
362 else if (!strcmp(str, "fdn"))
363 (void)strcpy(IN_LO, "fdn");
364 else if (!strcmp(str, "al" ))
365 (void)strcpy(IN_LO, "al");
366 else if (!strcmp(str, "alx"))
367 (void)strcpy(IN_LO, "alx");
368 else if (!strcmp(str, "spi"))
369 (void)strcpy(IN_LO, "spi");
370 else if (!strcmp(str, "cir"))
371 (void)strcpy(IN_LO, "cir");
372 else if (!strcmp(str, "sp"))
373 (void)strcpy(IN_LO, "sp");
374 else if (!strcmp(str, "edi"))
375 (void)strcpy(IN_LO, "edi");
376 else if (!strcmp(str, "vst"))
377 (void)strcpy(IN_LO, "vst");
378 else if (!strcmp(str, "vhd"))
379 (void)strcpy(IN_LO, "vhd");
380 else if (!strcmp(str, "v"))
381 (void)strcpy(IN_LO, "v");
382 else if (!strcmp(str, "vlg"))
383 (void)strcpy(IN_LO, "vlg");
384 else {
385 (void)fflush(stdout);
386 (void)fprintf(stderr,"*** mbk error ***\n");
387 (void)fprintf(stderr,"netlist input format '%s' not supported\n",str);
388 EXIT(1);
389 }
390 }
391
392 str = V_STR_TAB[__MBK_OUT_LO].VALUE;
393 if (str) {
394 if (!strcmp(str, "hns"))
395 (void)strcpy(OUT_LO, "hns");
396 else if (!strcmp(str, "fne"))
397 (void)strcpy(OUT_LO, "fne");
398 else if (!strcmp(str, "hdn"))
399 (void)strcpy(OUT_LO, "hdn");
400 else if (!strcmp(str, "fdn"))
401 (void)strcpy(OUT_LO, "fdn");
402 else if (!strcmp(str, "al" ))
403 (void)strcpy(OUT_LO, "al");
404 else if (!strcmp(str, "alx"))
405 (void)strcpy(OUT_LO, "alx");
406 else if (!strcmp(str, "spi"))
407 (void)strcpy(OUT_LO, "spi");
408 else if (!strcmp(str, "cir"))
409 (void)strcpy(OUT_LO, "cir");
410 else if (!strcmp(str, "sp"))
411 (void)strcpy(OUT_LO, "sp");
412 else if (!strcmp(str, "edi"))
413 (void)strcpy(OUT_LO, "edi");
414 else if (!strcmp(str, "vst"))
415 (void)strcpy(OUT_LO, "vst");
416 else if (!strcmp(str, "vhd"))
417 (void)strcpy(OUT_LO, "vhd");
418 else if (!strcmp(str, "cct"))
419 (void)strcpy(OUT_LO, "cct");
420 else if (!strcmp(str, "vlg"))
421 (void)strcpy(OUT_LO, "vlg");
422 else if (!strcmp(str, "v"))
423 (void)strcpy(OUT_LO, "v");
424 else {
425 (void)fflush(stdout);
426 (void)fprintf(stderr,"*** mbk error ***\n");
427 (void)fprintf(stderr,"netlist output format '%s' not supported\n",str);
428 EXIT(1);
429 }
430 }
431
432 /* par Fabrice le 7/2/2002 */
433 MBK_LOAD_PARA=V_BOOL_TAB[__MBK_LOAD_PARASITICS].VALUE;
434
435 str = V_STR_TAB[__MBK_IN_PARASITICS].VALUE;
436 if (str) {
437 if (!strcmp(str, "spf"))
438 (void)strcpy(IN_PARASITICS, "spf");
439 else if (!strcmp(str, "dspf"))
440 (void)strcpy(IN_PARASITICS, "dspf");
441 else if (!strcmp(str, "spef"))
442 (void)strcpy(IN_PARASITICS, "spef");
443 else {
444 (void)fflush(stdout);
445 (void)fprintf(stderr,"*** mbk error ***\n");
446 (void)fprintf(stderr,"parasitic netlist input format '%s' not supported\n",str);
447 EXIT(1);
448 }
449 }
450 /* --------- le 8/2/2002 */
451 str = getenv("MBK_DEVECT");
452 if (str) {
453 if (!strcmp(str, "yes"))
454 MBK_DEVECT=1;
455 else if (!strcmp(str, "no"))
456 MBK_DEVECT=0;
457 else {
458 (void)fflush(stdout);
459 (void)fprintf(stderr,"*** mbk error ***\n");
460 (void)fprintf(stderr,"invalid value for MBK_DEVECT, should be yes or no\n");
461 EXIT(1);
462 }
463 }
464 /* ------------ */
465
466
467 str = getenv("MBK_IN_PH");
468 if (str) {
469 if (!strcmp(str, "cp"))
470 (void)strcpy(IN_PH, "cp");
471 else if (!strcmp(str, "ap"))
472 (void)strcpy(IN_PH, "ap");
473 else if (!strcmp(str, "mg"))
474 (void)strcpy(IN_PH, "mg");
475 else {
476 (void)fflush(stdout);
477 (void)fprintf(stderr,"*** mbk error ***\n");
478 (void)fprintf(stderr,"layout input format '%s' not supported\n",str);
479 EXIT(1);
480 }
481 }
482
483 str = getenv("MBK_OUT_PH");
484 if (str) {
485 if (!strcmp(str, "cp"))
486 (void)strcpy(OUT_PH, "cp");
487 else if (!strcmp(str, "ap"))
488 (void)strcpy(OUT_PH, "ap");
489 else if (!strcmp(str, "mg"))
490 (void)strcpy(OUT_PH, "mg");
491 else {
492 (void)fflush(stdout);
493 (void)fprintf(stderr,"*** mbk error ***\n");
494 (void)fprintf(stderr,"layout output format '%s' not supported\n",str);
495 EXIT(1);
496 }
497 }
498
499
500 if ((str = V_STR_TAB[__MBK_CATAL_NAME].VALUE)) CATAL = str;
501 else CATAL = "CATAL";
502
503 if ((str = V_STR_TAB[__MBK_SEPAR].VALUE)) SEPAR = *str;
504
505 if ((str = V_STR_TAB[__MBK_BLACKBOX_NAME].VALUE)) MBK_BBOX_NAME = str;
506 else MBK_BBOX_NAME = "BLACKBOX";
507
508 if((str = V_STR_TAB[__MBK_IN_FILTER].VALUE)) IN_FILTER = str;
509 else IN_FILTER = NULL;
510
511 if((str = V_STR_TAB[__MBK_OUT_FILTER].VALUE)) OUT_FILTER = str;
512 else OUT_FILTER = NULL;
513
514 if((str = V_STR_TAB[__MBK_FILTER_SFX].VALUE)) FILTER_SFX = str;
515 else FILTER_SFX = NULL;
516
517 if((str = V_STR_TAB[__MBK_LIB_FILE].VALUE)) LIB_FILE = str;
518 else LIB_FILE = NULL;
519
520 if (!protect_mbkenv)
521 {
522 if ((str = V_STR_TAB[__MBK_CASE_SENSITIVE].VALUE)) {
523 if (!strcmp(str,"yes"))
524 CASE_SENSITIVE = 'Y';
525 else if (!strcmp(str,"no"))
526 CASE_SENSITIVE = 'N';
527 else if (!strcmp(str,"preserve"))
528 CASE_SENSITIVE = 'P';
529 }
530
531 /* EXIT shall produce a real exit if not trapped */
532 signal(SIGTERM, dflhandler);
533 }
534 /* Initialize a table of lower case characters for the machine encoding */
535 for (nchar = 0; (size_t)nchar < sizeof(tolowertable); nchar++)
536 tolowertable[nchar] = isupper(nchar) ? tolower(nchar) : nchar;
537
538 /* Initialize a table of upper case characters for the machine encoding */
539 for (nchar = 0; (size_t)nchar < sizeof(touppertable); nchar++)
540 touppertable[nchar] = islower(nchar) ? toupper(nchar) : nchar;
541
542 if ((str = V_STR_TAB[__MBK_VDD].VALUE)) VDD = namealloc (str);
543 else VDD = namealloc ("");
544
545 if ((str = V_STR_TAB[__MBK_VSS].VALUE)) VSS = namealloc (str);
546 else VSS = namealloc ("");
547
548 if ((str = V_STR_TAB[__MBK_GLOBAL_VDD].VALUE)) GLOBAL_VDD = namealloc (str);
549 else GLOBAL_VDD = namealloc ("");
550
551 if ((str = V_STR_TAB[__MBK_GLOBAL_VSS].VALUE)) {
552 sprintf(buf, "0:*%c0:%s", SEPAR, str);
553 GLOBAL_VSS = namealloc (buf);
554 }
555 else {
556 sprintf(buf, "0:*%c0", SEPAR);
557 GLOBAL_VSS = namealloc (buf);
558 }
559
560 VDD_VSS_THRESHOLD = SCALE_ALIM*V_FLOAT_TAB[__MBK_VDD_VSS_THRESHOLD].VALUE;
561
562 /* zinaps was here */
563 /* prenameallocation of often used names */
564 MBK_BULK_NAME = namealloc ("bulk");
565 MBK_GRID_NAME = namealloc ("grid");
566 MBK_DRAIN_NAME = namealloc ("drain");
567 MBK_SOURCE_NAME = namealloc ("source");
568
569 MBK_NRD = (char **)KNOWN_TRSPARAM;
570 MBK_NRS = (char **)KNOWN_TRSPARAM+2;
571 MBK_MULU0 = (char **)KNOWN_TRSPARAM+4;
572 MBK_DELVT0 = (char **)KNOWN_TRSPARAM+6;
573 MBK_SA = (char **)KNOWN_TRSPARAM+8;
574 MBK_SB = (char **)KNOWN_TRSPARAM+10;
575 MBK_SD = (char **)KNOWN_TRSPARAM+12;
576 MBK_NF = (char **)KNOWN_TRSPARAM+14;
577 MBK_NFING = (char **)KNOWN_TRSPARAM+16;
578 MBK_M = (char **)KNOWN_TRSPARAM+18;
579 MBK_GEOMOD = (char **)KNOWN_TRSPARAM+20;
580 MBK_SC = (char **)KNOWN_TRSPARAM+22;
581 MBK_SCA = (char **)KNOWN_TRSPARAM+24;
582 MBK_SCB = (char **)KNOWN_TRSPARAM+26;
583 MBK_SCC = (char **)KNOWN_TRSPARAM+28;
584 MBK_ABSOURCE = (char **)KNOWN_TRSPARAM+30;
585 MBK_LSSOURCE = (char **)KNOWN_TRSPARAM+32;
586 MBK_LGSOURCE = (char **)KNOWN_TRSPARAM+34;
587 MBK_ABDRAIN = (char **)KNOWN_TRSPARAM+36;
588 MBK_LSDRAIN = (char **)KNOWN_TRSPARAM+38;
589 MBK_LGDRAIN = (char **)KNOWN_TRSPARAM+40;
590 MBK_MULT = (char **)KNOWN_TRSPARAM+42;
591
592 if (!protect_mbkenv)
593 {
594 avt_init_model(&TNMOS, V_STR_TAB[__MBK_SPI_TN].VALUE);
595 avt_init_model(&TPMOS, V_STR_TAB[__MBK_SPI_TP].VALUE);
596 avt_init_model(&DNMOS, V_STR_TAB[__MBK_SPI_DN].VALUE);
597 avt_init_model(&DPMOS, V_STR_TAB[__MBK_SPI_DP].VALUE);
598 }
599 MBK_DUP_PNAME_FF=V_BOOL_TAB[__MBK_DUP_PNAME_FOR_FLAT].VALUE?'Y':'N';
600
601 if((env = V_STR_TAB[__MBK_SPI_VECTOR].VALUE)) {
602 if (strlen(env) < 1024)
603 strcpy (SPI_VECTOR, env);
604 }
605 else strcpy (SPI_VECTOR, "_");
606
607 FLATTEN_KEEP_ALL_NAMES=V_BOOL_TAB[__MBK_KEEP_ALL_SIGNAL_NAMES].VALUE;
608
609 if( V_INT_TAB[__MBK_MAX_CACHE_FILE].VALUE <= 0 ) {
610 fflush( stdout );
611 fprintf( stderr, "*** mbk error ***\n" );
612 fprintf( stderr, "bad value for MBK_MAX_CACHE_FILE.\n" );
613 EXIT(1);
614 }
615 MBK_MAX_CACHE = V_INT_TAB[__MBK_MAX_CACHE_FILE].VALUE ;
616
617 if (!mbk_decodvectorconfig(V_STR_TAB[__MBK_INPUT_VECTOR].VALUE))
618 {
619 fprintf( stderr, "bad value for variable controlling input vectors\n" );
620 }
621
622 avt_initlog();
623
624 avt_LogConfig();
625
626 if (!protect_mbkenv)
627 {
628
629 mbkinitautoackchld();
630 /* Sous Solaris, certaines fonctions de haut niveau (fgets...) sont
631 * interruptible par la reception d'un signal. Ceci n'a jamais ete pris
632 * en compte auparavant : on conserve donc explicitement le comportement
633 * "normal" qui est que ces fonctions ne sont normalement pas
634 * interruptible. D'ou le SA_RESTART.
635 */
636
637 #ifdef SunOS
638 signal( SIGCHLD, mbkackchld );
639 #else
640 sigemptyset( &ens );
641 sgct.sa_handler = mbkackchld;
642 sgct.sa_mask = ens;
643 sgct.sa_flags = SA_RESTART;
644 sigaction( SIGCHLD, &sgct , NULL );
645 #endif
646
647 CreateNameAllocator(1024, &SENSITIVE_NAMEALLOC_ALLOCATOR, 'y');
648 }
649
650 protect_mbkenv=1;
651
652 AVT_FULLVERSION = namealloc(AVT_FULLVERSION);
653
654
655 }
656
657 /*******************************************************************************
658 * fonction readlibfile() *
659 *******************************************************************************/
660 void readlibfile(type,fonc,reload)
661 char *type ;
662 void (*fonc)(char *) ;
663 int reload ;
664 {
665 FILE *file ;
666 char buftype[64] ;
667 char buffile[1024] ;
668 int nb ;
669 int nb_input ;
670 chain_list *chain ;
671 char *pt ;
672 static chain_list *typelist = NULL ;
673
674 if(LIB_FILE == NULL)
675 return ;
676
677 for(chain = typelist ; chain != NULL ; chain = chain->NEXT)
678 {
679 if(strcmp((char *)chain->DATA,type) == 0)
680 break ;
681 }
682
683 if(chain != NULL)
684 {
685 if(reload == 0)
686 return ;
687 }
688 else
689 {
690 pt = namealloc(type) ;
691 typelist = addchain(typelist,pt) ;
692 }
693
694 file = mbkfopen(LIB_FILE,NULL,"r") ;
695
696 if(file == NULL)
697 {
698 if(TRACE_MODE == 'Y')
699 {
700 fflush(stdout);
701 (void)fprintf (stderr, "*** mbk warning ***\n");
702 (void)fprintf (stderr, "can not open lib file %s\n",LIB_FILE);
703 }
704 return ;
705 }
706
707 nb = 0;
708
709 while(!feof(file))
710 {
711 nb++;
712 nb_input = fscanf(file, "%s %s\n", buffile, buftype);
713 if(nb_input == 0) continue;
714 if(nb_input != 2)
715 {
716 (void)fflush(stdout);
717 (void)fprintf(stderr, "*** mbk error ***\n");
718 (void)fprintf(stderr, "syntax error line %d in file %s\n",nb,LIB_FILE);
719 fclose(file) ;
720 EXIT(1) ;
721 }
722 if(strcmp(buftype,type) == 0)
723 fonc(buffile) ;
724 }
725 }
726
727 /*******************************************************************************
728 * function nameindex() *
729 * return a string that is the concatenation of the name argument, the mbk *
730 * separator, and an index *
731 *******************************************************************************/
732 char *nameindex(name, index)
733 char *name;
734 long index;
735 {
736 char str[1024];
737
738 (void)sprintf(str,"%s%c%ld", name, SEPAR, index);
739 return namealloc(str);
740 }
741
742 /*******************************************************************************
743 * fonction addnum() *
744 * num list specialized allocator to avoid too many mallocs *
745 *******************************************************************************/
746 num_list *addnum(ptnum, data)
747 num_list *ptnum;
748 long data;
749 {
750 num_list *pt;
751 register int i;
752
753 #ifdef NOHEAPALLOC
754 HEAD_NUM = (num_list *)mbkalloc(sizeof(num_list));
755 HEAD_NUM->NEXT = NULL ;
756 #else
757 if (HEAD_NUM == NULL) {
758 HEAD_NUM = (num_list *)mbkalloc((1+BUFSIZE)*sizeof(num_list));
759 #ifdef BASE_STAT
760 i_nbnum+=(1+BUFSIZE);
761 #endif
762 pt = HEAD_NUM;
763 for (i = 1; i < BUFSIZE; i++) {
764 pt->NEXT = pt + 1;
765 pt++;
766 }
767 pt->NEXT = NULL;
768 }
769 #endif
770
771 pt = HEAD_NUM;
772 HEAD_NUM = HEAD_NUM->NEXT;
773 pt->NEXT = ptnum;
774 pt->DATA = data;
775 #ifdef BASE_STAT
776 i_nbnum--;
777 #endif
778 return pt;
779 }
780
781 /*******************************************************************************
782 * fonction getnum() *
783 * get pointer to num list element from data *
784 *******************************************************************************/
785 num_list *getnum(ptnum, data)
786 num_list *ptnum;
787 long data;
788 {
789 num_list *pt;
790
791 for (pt = ptnum; pt; pt = pt->NEXT) {
792 if (pt->DATA == data) return pt;
793 }
794 return NULL;
795 }
796
797 /*******************************************************************************
798 * function freenum() *
799 * gives back freed block to the num memory allocator *
800 *******************************************************************************/
801 void freenum(pt)
802 num_list *pt;
803 {
804 #ifdef BASE_STAT
805 {
806 num_list *n;
807 for (n=pt; n!=NULL; n=n->NEXT)
808 i_nbnum++;
809 }
810 #endif
811 #ifdef NOHEAPALLOC
812 {
813 num_list *next,*scan;
814 for( scan=pt ; scan ; scan=next ) {
815 next = scan->NEXT;
816 mbkfree( scan );
817 }
818 }
819 #else
820 HEAD_NUM = (num_list *)append((chain_list *)pt, (chain_list *)HEAD_NUM);
821 #endif
822 }
823
824 num_list* dupnumlst( num_list *head )
825 {
826 num_list *reversed = NULL ;
827
828 for( ; head ; head = head->NEXT )
829 reversed = addnum( reversed, head->DATA );
830 reversed = (num_list*)reverse( (chain_list*)reversed );
831
832 return reversed ;
833 }
834 /*******************************************************************************
835 * function addchain() *
836 * chain list specialized allocator to avoid too many mallocs *
837 *******************************************************************************/
838 chain_list *addchain(pthead, ptdata)
839 chain_list *pthead;
840 void *ptdata;
841 {
842 chain_list *pt;
843 register int i;
844
845 #ifdef NOHEAPALLOC
846 HEAD_CHAIN = (chain_list*)mbkalloc( sizeof( chain_list ) );
847 HEAD_CHAIN->NEXT = NULL;
848 #else
849 if (HEAD_CHAIN == NULL) {
850 pt = (chain_list *)mbkalloc(BUFSIZE*sizeof(chain_list));
851 #ifdef BASE_STAT
852 i_nbchain+=BUFSIZE;
853 #endif
854 HEAD_CHAIN = pt;
855 for (i = 1; i < BUFSIZE; i++) {
856 pt->NEXT = pt + 1;
857 pt++;
858 }
859 pt->NEXT = NULL;
860 }
861 #endif
862
863 pt = HEAD_CHAIN;
864 HEAD_CHAIN = HEAD_CHAIN->NEXT;
865 pt->NEXT = pthead;
866 pt->DATA = ptdata;
867 #ifdef BASE_STAT
868 i_nbchain--;
869 #endif
870 return pt;
871 }
872
873 chain_list *getchain(chain_list *ptchain, void *data)
874 {
875 while (ptchain!=NULL)
876 {
877 if (ptchain->DATA == data) return ptchain;
878 ptchain=ptchain->NEXT;
879 }
880 return NULL;
881 }
882
883 /*******************************************************************************
884 * function freechain() *
885 * gives back freed block or blocks to the chain_list memory allocator *
886 *******************************************************************************/
887 void freechain(pt)
888 chain_list *pt;
889 {
890 chain_list *scan;
891 #ifdef BASE_STAT
892 for( scan=pt ; scan ; scan=scan->NEXT) i_nbchain++;
893 #endif
894 #ifdef NOHEAPALLOC
895 {
896 chain_list *next;
897 for( scan=pt ; scan ; scan=next ) {
898 next = scan->NEXT;
899 mbkfree( scan );
900 }
901 }
902 #else
903 HEAD_CHAIN = append(pt, HEAD_CHAIN);
904 #endif
905 }
906
907 /*******************************************************************************
908 * function delchain() *
909 * delete a single element of a chain_list and gives it back to freechain *
910 *******************************************************************************/
911 chain_list *delchain(pthead, ptdel)
912 chain_list *pthead;
913 chain_list *ptdel;
914 {
915 chain_list *pt;
916 chain_list *ptsav = NULL; /* To make gcc -Wall silent */
917
918 if (pthead == NULL || ptdel == NULL) {
919 (void)fflush(stdout);
920 (void)fprintf(stderr,"*** mbk error ***");
921 (void)fprintf(stderr," delchain() impossible : pointer = NULL !\n");
922 EXIT(1);
923 }
924
925 if (ptdel == pthead) {
926 pt = pthead->NEXT;
927 pthead->NEXT = NULL;
928 freechain(pthead);
929 return pt;
930 } else {
931 for (pt = pthead; pt; pt = pt->NEXT) {
932 if (pt == ptdel)
933 break;
934 ptsav = pt;
935 }
936 if (pt != NULL) {
937 ptsav->NEXT = pt->NEXT;
938 ptdel->NEXT = NULL;
939 freechain(ptdel);
940 return pthead;
941 } else
942 return NULL;
943 }
944 }
945
946 /*******************************************************************************
947 * function subchain() *
948 * copy all elements from chain refchain to a new chain, exept elements that *
949 * appear in delchain. refchain and delchain must have the same order. *
950 * neither refchain nor delchain are altered. *
951 *******************************************************************************/
952 chain_list* subchain( chain_list *refchain, chain_list *delchain )
953 {
954 chain_list *chain;
955 chain_list *retchain=NULL;
956
957 for( chain = refchain ; chain ; chain = chain->NEXT ) {
958 if( !delchain || chain->DATA != delchain->DATA ) {
959 retchain = addchain( retchain, chain->DATA );
960 }
961 else {
962 if( delchain )
963 delchain = delchain->NEXT;
964 }
965 }
966
967 return reverse( retchain );
968 }
969
970 /*
971 * renvoir le nombre d'element dans une chain_list
972 */
973
974 int countchain(chain_list *doubl)
975 {
976 int count;
977 for (count=0;doubl!=NULL;doubl=doubl->NEXT,count++) ;
978 return count;
979 }
980
981 /*******************************************************************************
982 * function delchaindata() *
983 * delete a single element of a chain_list and gives it back to freechain *
984 *******************************************************************************/
985 chain_list *delchaindata(pthead, ptdeldata)
986 chain_list *pthead;
987 void *ptdeldata;
988 {
989 chain_list *pt;
990 chain_list *ptsav = NULL; /* To make gcc -Wall silent */
991
992 if (pthead == NULL || ptdeldata == NULL) {
993 (void)fflush(stdout);
994 (void)fprintf(stderr,"*** mbk error ***");
995 (void)fprintf(stderr," delchaindata() impossible : pointer = NULL !\n");
996 EXIT(1);
997 }
998
999 if (ptdeldata == pthead->DATA) {
1000 pt = pthead->NEXT;
1001 pthead->NEXT = NULL;
1002 freechain(pthead);
1003 return pt;
1004 } else {
1005 for (pt = pthead; pt; pt = pt->NEXT) {
1006 if (pt->DATA == ptdeldata)
1007 break;
1008 ptsav = pt;
1009 }
1010 if (pt != NULL) {
1011 ptsav->NEXT = pt->NEXT;
1012 pt->NEXT = NULL;
1013 freechain(pt);
1014 return pthead;
1015 }
1016 }
1017 return pthead;
1018 }
1019
1020 /*##------------------------------------------------------------------##*/
1021 /* Function : dupptypelst() */
1022 /* contents : duplicate a ptype list and return a pointer on the new */
1023 /* structure. */
1024 /* called func. : reverse(), mbkalloc(), */
1025 /*##------------------------------------------------------------------##*/
1026
1027 ptype_list *dupptypelst(ptype_ptr)
1028 ptype_list *ptype_ptr;
1029 {
1030 ptype_list *ptype_rpt = NULL; /* Returned chain pointer */
1031
1032 while(ptype_ptr != NULL)
1033 {
1034 ptype_rpt = addptype(ptype_rpt, ptype_ptr->TYPE, ptype_ptr->DATA);
1035 ptype_ptr = ptype_ptr->NEXT;
1036 }
1037 ptype_rpt = (ptype_list *)reverse((chain_list *)ptype_rpt);
1038 return(ptype_rpt);
1039 }
1040
1041 /*##------------------------------------------------------------------##*/
1042 /* Function : dupchainlst() */
1043 /* contents : duplicate a chain list and return a pointer on the new */
1044 /* structure. */
1045 /* called func. : reverse(), mbkalloc(), */
1046 /*##------------------------------------------------------------------##*/
1047
1048 chain_list *dupchainlst(chain_ptr)
1049 chain_list *chain_ptr;
1050 {
1051 chain_list *chain_rpt = NULL; /* Returned chain pointer */
1052
1053 while(chain_ptr != NULL)
1054 {
1055 chain_rpt = addchain(chain_rpt, chain_ptr->DATA);
1056 chain_ptr = chain_ptr->NEXT;
1057 }
1058 chain_rpt = reverse(chain_rpt);
1059 return(chain_rpt);
1060 }
1061
1062 /*******************************************************************************
1063 * function addptype() *
1064 *******************************************************************************/
1065 ptype_list *addptype(pthead,type,ptdata)
1066 ptype_list *pthead;
1067 long type;
1068 void *ptdata;
1069 {
1070 ptype_list *pt;
1071 register int i;
1072
1073 if (HEAD_PTYPE == NULL) {
1074 #ifdef NOHEAPALLOC
1075 pt = (ptype_list *)mbkalloc(sizeof(ptype_list));
1076 HEAD_PTYPE = pt;
1077 #else
1078 pt = (ptype_list *)mbkalloc(BUFSIZE * sizeof(ptype_list));
1079 #ifdef BASE_STAT
1080 i_nbptype+=BUFSIZE;
1081 #endif
1082 HEAD_PTYPE = pt;
1083 for (i = 1; i < BUFSIZE; i++) {
1084 pt->NEXT = pt + 1;
1085 pt++;
1086 }
1087 #endif
1088 pt->NEXT = NULL;
1089 }
1090
1091 pt = HEAD_PTYPE;
1092 HEAD_PTYPE = HEAD_PTYPE->NEXT;
1093 pt->NEXT = pthead;
1094 pt->DATA = ptdata;
1095 pt->TYPE = type;
1096 #ifdef BASE_STAT
1097 i_nbptype--;
1098 #endif
1099 return pt;
1100 }
1101
1102 /*******************************************************************************
1103 * function testanddelptype() *
1104 *******************************************************************************/
1105 ptype_list *testanddelptype(pthead, type)
1106 ptype_list *pthead;
1107 long type;
1108 {
1109 ptype_list *pt;
1110 ptype_list *ptsav = NULL; /* To make gcc -Wall silent */
1111
1112 if (pthead == NULL) return NULL;
1113
1114 if (pthead->TYPE == type) {
1115 pt = pthead->NEXT;
1116 pthead->NEXT = NULL;
1117 freeptype(pthead);
1118 return pt;
1119 } else {
1120 for (pt = pthead; pt; pt = pt->NEXT) {
1121 if (pt->TYPE == type)
1122 break;
1123 ptsav = pt;
1124 }
1125 if (pt != NULL) {
1126 ptsav->NEXT = pt->NEXT;
1127 pt->NEXT = NULL;
1128 freeptype(pt);
1129 }
1130 return pthead ;
1131 }
1132
1133 }
1134 /*******************************************************************************
1135 * function delptype() *
1136 *******************************************************************************/
1137 ptype_list *delptype(pthead, type)
1138 ptype_list *pthead;
1139 long type;
1140 {
1141 ptype_list *pt;
1142 ptype_list *ptsav = NULL; /* To make gcc -Wall silent */
1143
1144 if (pthead == NULL) {
1145 (void)fflush(stdout);
1146 (void)fprintf(stderr,"*** mbk error ***\n");
1147 (void)fprintf(stderr,"delptype() impossible : pthead = NULL !\n");
1148 EXIT(1);
1149 }
1150
1151 if (pthead->TYPE == type) {
1152 pt = pthead->NEXT;
1153 pthead->NEXT = NULL;
1154 freeptype(pthead);
1155 return pt;
1156 } else {
1157 for (pt = pthead; pt; pt = pt->NEXT) {
1158 if (pt->TYPE == type)
1159 break;
1160 ptsav = pt;
1161 }
1162 if (pt != NULL) {
1163 ptsav->NEXT = pt->NEXT;
1164 pt->NEXT = NULL;
1165 freeptype(pt);
1166 return pthead;
1167 } else
1168 #if DELAY_DEBUG_STAT
1169 avt_fprintf(stderr, "¤6delptype function called for non existing PTYPE¤.\n");
1170 exit(55);
1171 #endif
1172 return NULL;
1173 }
1174 }
1175
1176 /*******************************************************************************
1177 * function freeptype() *
1178 *******************************************************************************/
1179 void freeptype(pt)
1180 ptype_list *pt;
1181 {
1182 ptype_list *scan;
1183 #ifdef BASE_STAT
1184 for( scan = pt ; scan ; scan = scan->NEXT ) i_nbptype++;
1185 #endif
1186 #ifdef NOHEAPALLOC
1187 {
1188 ptype_list *next;
1189 for( scan = pt ; scan ; scan = next ) {
1190 next = scan->NEXT ;
1191 mbkfree( scan );
1192 }
1193 }
1194 #else
1195 HEAD_PTYPE = (ptype_list *)append((chain_list *)pt,(chain_list *)HEAD_PTYPE);
1196 #endif
1197 }
1198
1199 /*******************************************************************************
1200 * function getptype() *
1201 *******************************************************************************/
1202 ptype_list *getptype(pthead, type)
1203 ptype_list *pthead;
1204 long type;
1205 {
1206 ptype_list *pt;
1207
1208 for (pt = pthead; pt; pt = pt->NEXT)
1209 if (pt->TYPE == type)
1210 return pt;
1211 return NULL;
1212 }
1213
1214 /*******************************************************************************
1215 * function append() *
1216 *******************************************************************************/
1217 chain_list *append(pt1, pt2)
1218 chain_list *pt1,*pt2;
1219 {
1220 chain_list *pt;
1221
1222 if (pt1 == NULL)
1223 return pt2;
1224 else {
1225 for (pt = pt1; pt->NEXT; pt = pt->NEXT);
1226 pt->NEXT = pt2; /* append the list 2 at the end of list 1 */
1227 return pt1;
1228 }
1229 }
1230
1231 /*******************************************************************************
1232 * Dictonnary related functions *
1233 *******************************************************************************/
1234
1235 /* Random hash function due to Don. E. Knuth, The Stanford Graph Base.
1236 * Truly better than the previous one from my own experimentations. */
1237 #define HASH_MULT 314159
1238 #define HASH_PRIME 516595003
1239
1240 #if 0
1241 #define HASH_FUNC(inputname, name, code) \
1242 do { \
1243 while (*inputname) { \
1244 if (CASE_SENSITIVE == 'N') *name = tolowertable[(int)*inputname++]; \
1245 else *name = *inputname++; \
1246 code += (code ^ (code >> 1)) + HASH_MULT * (unsigned char) *name++; \
1247 while (code >= HASH_PRIME) \
1248 code -= HASH_PRIME; \
1249 } \
1250 *name = '\0'; \
1251 code %= HASHVAL; \
1252 } while (0)
1253 #endif
1254
1255 static inline int SUB_HASH_FUNC(char *inputname, char *name, int code, char CASE_SENSITIVE)
1256 {
1257 while (*inputname) {
1258 if (CASE_SENSITIVE == 'N') *name = tolowertable[(int)*inputname++];
1259 else *name = *inputname++;
1260 if (CASE_SENSITIVE != 'P') code += (code ^ (code >> 1)) + HASH_MULT * (unsigned char) *name++;
1261 else code += (code ^ (code >> 1)) + HASH_MULT * tolowertable[(int)*name++];
1262 while (code >= HASH_PRIME)
1263 code -= HASH_PRIME;
1264 }
1265 *name = '\0';
1266 return code;
1267 }
1268
1269 static inline int HASH_FUNC(char *inputname, char *name, int code, int HASHVAL0)
1270 {
1271 code = SUB_HASH_FUNC(inputname, name, code, CASE_SENSITIVE) % HASHVAL0;
1272 return code;
1273 }
1274
1275 /*******************************************************************************
1276 * function namealloc() *
1277 *******************************************************************************/
1278 void CreateNameAllocator(int size, NameAllocator *na, char _case)
1279 {
1280 int i;
1281 if (size==0) size=5100; // next rehash @10007
1282 na->HASHVAL0=size;
1283 na->NAME_HASHTABLE=mbkalloc(sizeof(chain_list *)*size);
1284 for (i=0; i<size; i++) na->NAME_HASHTABLE[i]=NULL;
1285
1286 if (tolower(_case)=='y') na->SENSITIVE='Y';
1287 else if (tolower(_case)=='p') na->SENSITIVE='P'; // case preserve
1288 else na->SENSITIVE='N';
1289
1290 for (na->namealloc_primes_index=0;
1291 (unsigned)na->namealloc_primes_index<(sizeof(namealloc_primes)/sizeof(*namealloc_primes))-1
1292 && namealloc_primes[na->namealloc_primes_index+1]<=size; na->namealloc_primes_index++) ;
1293
1294 na->aba=CreateAdvancedBlockAllocator(4000, 'n');
1295 #ifdef ENABLE_STATS
1296 na->__SIZE__=sizeof(chain_list *)*size;
1297 na->__NBNAMES__=0;
1298 #endif
1299 }
1300
1301 void DeleteNameAllocator(NameAllocator *na)
1302 {
1303 int i;
1304 // chain_list *cl;
1305 for (i=0; i<na->HASHVAL0; i++)
1306 {
1307 /* for (cl=na->NAME_HASHTABLE[i]; cl!=NULL; cl=cl->NEXT)
1308 mbkfree(cl->DATA);*/
1309 if (na->NAME_HASHTABLE[i]!=NULL) freechain(na->NAME_HASHTABLE[i]);
1310 }
1311 FreeAdvancedBlockAllocator(na->aba);
1312 mbkfree(na->NAME_HASHTABLE);
1313 }
1314
1315 static void NameAlloc_rehash(NameAllocator *na)
1316 {
1317 chain_list **nn, *cl;
1318 int i, code;
1319 char *name = buffer;
1320
1321 // fprintf(stdout,".rehashing name dico: %d -> %d...",na->HASHVAL0,namealloc_primes[na->namealloc_primes_index+1]); fflush(stdout);
1322
1323 nn=mbkalloc(namealloc_primes[na->namealloc_primes_index+1]*sizeof(chain_list *));
1324 for (i=0;i<namealloc_primes[na->namealloc_primes_index+1];i++)
1325 nn[i]=NULL;
1326
1327 for (i=0;i<na->HASHVAL0;i++)
1328 {
1329 for (cl=na->NAME_HASHTABLE[i]; cl!=NULL; cl=cl->NEXT)
1330 {
1331 code = HASH_FUNC((char *)cl->DATA, name, 0, namealloc_primes[na->namealloc_primes_index+1]);
1332 nn[code]=addchain(nn[code], cl->DATA);
1333 }
1334 freechain(na->NAME_HASHTABLE[i]);
1335 }
1336 mbkfree(na->NAME_HASHTABLE);
1337 na->NAME_HASHTABLE=nn;
1338 na->HASHVAL0=namealloc_primes[na->namealloc_primes_index+1];
1339 na->namealloc_primes_index++;
1340 // fprintf(stdout,"done\n");
1341 }
1342
1343 inline char *NameAlloc_sub(NameAllocator *na, char *inputname, int find)
1344 {
1345 chain_list *pt;
1346 char buffer[BUFSIZ];
1347 char *name = buffer; /* ensure no modification of parameter string */
1348 int code = 0, depth;
1349
1350 if (inputname == NULL)
1351 return NULL;
1352
1353 /* Beware, that's a define, ... */
1354 code = SUB_HASH_FUNC(inputname, name, code, na->SENSITIVE) % na->HASHVAL0;
1355
1356 for (pt = na->NAME_HASHTABLE[code], depth=0; pt; pt = pt->NEXT, depth++)
1357 {
1358 if (na->SENSITIVE != 'P')
1359 {
1360 if (!strcmp(buffer, (char *)pt->DATA))
1361 return (char *)pt->DATA;
1362 }
1363 else
1364 {
1365 if (!strcasecmp(buffer, (char *)pt->DATA))
1366 return (char *)pt->DATA;
1367 }
1368 }
1369
1370 if (find) return NULL;
1371
1372 name=(char *)AdvancedBlockAlloc(na->aba, (unsigned int)(strlen(buffer) + 1));
1373
1374 // name = (char *)mbkalloc((unsigned int)(strlen(buffer) + 1));
1375 strcpy(name, buffer);
1376 na->NAME_HASHTABLE[code] = addchain(na->NAME_HASHTABLE[code], name);
1377 #ifdef ENABLE_STATS
1378 na->__NBNAMES__++;
1379 na->__SIZE__+=sizeof(chain_list *)+strlen(buffer)+1+4;
1380 #endif
1381 if ((unsigned)na->namealloc_primes_index<(sizeof(namealloc_primes)/sizeof(*namealloc_primes))-1 && depth>32)
1382 NameAlloc_rehash(na);
1383
1384 return name;
1385 }
1386
1387 char *NameAlloc(NameAllocator *na, char *inputname)
1388 {
1389 return NameAlloc_sub(na, inputname, 0);
1390
1391 }
1392 char *NameAllocFind(NameAllocator *na, char *inputname)
1393 {
1394 return NameAlloc_sub(na, inputname, 1);
1395 }
1396
1397 void NameAllocStat(NameAllocator *na)
1398 {
1399 int i, nb, max=0,moy=0, nb0=0;
1400 int maxstr=0, moystr=0, lg, cntstr=0;
1401 chain_list *cl;
1402
1403 printf("--- Nameallocator stats:\n");
1404 for (i=0, nb=0;i<na->HASHVAL0;i++) if (na->NAME_HASHTABLE[i]==NULL) nb++;
1405 printf(" %d/%d entries unused\n",nb,na->HASHVAL0);
1406 for (i=0, max=0;i<na->HASHVAL0;i++)
1407 if (na->NAME_HASHTABLE[i]!=NULL)
1408 {
1409 nb0++;
1410 for (nb=0, cl=na->NAME_HASHTABLE[i];cl!=NULL; cl=cl->NEXT, nb++)
1411 {
1412 lg=strlen((char *)cl->DATA);
1413 if (lg>maxstr) maxstr=lg;
1414 moystr+=lg;
1415 cntstr++;
1416 }
1417 if (nb>max) max=nb;
1418 moy+=nb;
1419 }
1420 printf(" chain length: mean=%.1f max=%d\n",(float)moy/(float)nb0,max);
1421 printf(" string length: mean=%.1f max=%d\n",(float)moystr/(float)cntstr,maxstr);
1422 }
1423
1424 char *sensitive_namealloc(char *name)
1425 {
1426 return NameAlloc(&SENSITIVE_NAMEALLOC_ALLOCATOR, name);
1427 }
1428
1429 char *min_namealloc(char *name)
1430 {
1431 char buf[4096], *temp;
1432
1433 downstr(name, buf);
1434 temp=namealloc(buf);
1435 return temp;
1436 }
1437
1438 char *min_namefind(char *name)
1439 {
1440 char buf[4096], *temp;
1441
1442 downstr(name, buf);
1443 temp=namefind(buf);
1444 return temp;
1445 }
1446
1447 static void namealloc_rehash()
1448 {
1449 chain_list **nn, *cl;
1450 int i, code;
1451 char *name = buffer;
1452
1453 // fprintf(stdout,".rehashing name dico: %d -> %d...",namealloc_primes[namealloc_primes_index],namealloc_primes[namealloc_primes_index+1]); fflush(stdout);
1454
1455 nn=mbkalloc(namealloc_primes[namealloc_primes_index+1]*sizeof(chain_list *));
1456 for (i=0;i<namealloc_primes[namealloc_primes_index+1];i++)
1457 nn[i]=NULL;
1458
1459 for (i=0;i<namealloc_primes[namealloc_primes_index];i++)
1460 {
1461 for (cl=NAME_HASHTABLE[i]; cl!=NULL; cl=cl->NEXT)
1462 {
1463 code = HASH_FUNC((char *)cl->DATA, name, 0, namealloc_primes[namealloc_primes_index+1]);
1464 nn[code]=addchain(nn[code], cl->DATA);
1465 }
1466 freechain(NAME_HASHTABLE[i]);
1467 }
1468 mbkfree(NAME_HASHTABLE);
1469 NAME_HASHTABLE=nn;
1470 namealloc_primes_index++;
1471
1472 // fprintf(stdout,"done\n");
1473 }
1474
1475
1476
1477 char *namealloc(inputname)
1478 char *inputname;
1479 {
1480 chain_list *pt;
1481 char *name = buffer; /* ensure no modification of parameter string */
1482 int code = 0;
1483 int depth;
1484
1485 if (inputname == NULL)
1486 return NULL;
1487
1488 if (NAME_HASHTABLE==NULL)
1489 {
1490 int i;
1491 NAME_HASHTABLE=mbkalloc(namealloc_primes[namealloc_primes_index]*sizeof(chain_list *));
1492 for (i=0;i<namealloc_primes[namealloc_primes_index];i++)
1493 NAME_HASHTABLE[i]=NULL;
1494 }
1495
1496 /* Beware, that's a define, ... */
1497 code = HASH_FUNC(inputname, name, 0, namealloc_primes[namealloc_primes_index]);
1498
1499 for (pt = NAME_HASHTABLE[code], depth=0; pt; pt = pt->NEXT, depth++)
1500 {
1501 if (CASE_SENSITIVE != 'P')
1502 {
1503 if (!strcmp(buffer, (char *)pt->DATA))
1504 return (char *)pt->DATA;
1505 }
1506 else
1507 {
1508 if (!strcasecmp(buffer, (char *)pt->DATA))
1509 return (char *)pt->DATA;
1510 }
1511 }
1512
1513 name = (char *)mbkalloc((unsigned int)(strlen(buffer) + 1));
1514 #ifdef BASE_STAT
1515 ynmsize+=strlen(buffer) + 1+4+8;
1516 #endif
1517 (void)strcpy(name, buffer);
1518 NAME_HASHTABLE[code] = addchain(NAME_HASHTABLE[code], (void *)name);
1519
1520 if ((unsigned)namealloc_primes_index<(sizeof(namealloc_primes)/sizeof(*namealloc_primes))-1 && depth>32)
1521 namealloc_rehash();
1522
1523 return name;
1524 }
1525
1526 /*******************************************************************************
1527 * function namefind() *
1528 *******************************************************************************/
1529 char *namefind(inputname)
1530 char *inputname;
1531 {
1532 chain_list *pt;
1533 char *name = buffer; /* ensure no modification of parameter string */
1534 register int code = 0;
1535
1536 if (inputname == NULL)
1537 return NULL;
1538
1539 if (NAME_HASHTABLE==NULL) return NULL;
1540
1541 code=HASH_FUNC(inputname, name, 0, namealloc_primes[namealloc_primes_index]);
1542
1543 for (pt = NAME_HASHTABLE[code]; pt; pt = pt->NEXT)
1544 {
1545 if (CASE_SENSITIVE != 'P')
1546 {
1547 if (!strcmp(buffer, (char *)pt->DATA))
1548 return (char *)pt->DATA;
1549 }
1550 else
1551 {
1552 if (!strcasecmp(buffer, (char *)pt->DATA))
1553 return (char *)pt->DATA;
1554 }
1555 }
1556
1557 return NULL ;
1558 }
1559
1560 /*******************************************************************************
1561 * function downstr() *
1562 *******************************************************************************/
1563 void downstr(s, t)
1564 char *s, *t;
1565 {
1566 for (; *s; s++, t++)
1567 *t = tolowertable[(int)*s];
1568 *t = *s;
1569 }
1570
1571 /*******************************************************************************
1572 * function upstr() *
1573 *******************************************************************************/
1574 void upstr(s, t)
1575 char *s, *t;
1576 {
1577 for (; *s; s++, t++)
1578 *t = touppertable[(int)*s];
1579 *t = *s;
1580 }
1581
1582 /*******************************************************************************
1583 * function endstr() : match occurence of find at the end of string *
1584 *******************************************************************************/
1585
1586 char *endstr(s, find)
1587 char *s, *find ;
1588 {
1589 int ls, lf, i ;
1590
1591 if (!s || !find)
1592 return NULL;
1593
1594 lf = strlen(find);
1595 ls = strlen(s);
1596
1597 if (ls < lf)
1598 return NULL ;
1599
1600 for (i = 0 ; i < lf ; i++)
1601 if ((find[lf - i - 1] != s[ls - i - 1])
1602 && (find[lf - i - 1] != s[ls - i - 1] + 32)
1603 && (find[lf - i - 1] + 32 != s[ls - i - 1]))
1604 return NULL ;
1605
1606 return find ;
1607 }
1608
1609 /*******************************************************************************
1610 * function beginstr() : match occurence of find at the beginnig of string *
1611 *******************************************************************************/
1612
1613 char *beginstr (s, find, separ)
1614 char *s, *find, separ ;
1615 {
1616 char *t ;
1617 int lf, ls, i ;
1618
1619 if (!s || !find)
1620 return NULL;
1621 if (separ) {
1622 t = s ;
1623 if ((s = strrchr(s, separ)) == NULL)
1624 s = t ;
1625 else
1626 s++; /* skip the separator itself */
1627 }
1628 if ((find[0]) != 0) {
1629 lf = strlen (find) ;
1630 ls = strlen (s) ;
1631 if (ls < lf)
1632 return NULL ;
1633 for (i = 0 ; i < lf ; i++)
1634 if ((s[i] != find[i]) && (s[i] + 32 != find[i]) && (s[i] != find[i] + 32))
1635 return NULL ;
1636 }
1637 return s;
1638 }
1639
1640 /*******************************************************************************
1641 * function wildstrstr() : match multiple strings separated by ':' *
1642 * enabling wildcard '*' *
1643 *******************************************************************************/
1644
1645 int wildstrstr (char *s, char *find)
1646 {
1647 char buff[1024], *buf = buff;
1648 int i, j, match;
1649
1650 i = 0;
1651 while (find[i] != '\0') {
1652
1653 j = 0;
1654 while (find[i] != '\0' && find[i] != ':') buf[j++] = find[i++];
1655 buf[j] = '\0';
1656
1657 if (mbk_TestREGEX(s, buf)) return 1;
1658 if (find[i] == ':') i++;
1659 }
1660
1661 return 0;
1662
1663 }
1664
1665 /*******************************************************************************
1666 * function vectorize : builds a legal mbk vector from a name and an index *
1667 *******************************************************************************/
1668 char *vectorize(radical, index)
1669 char *radical;
1670 long index;
1671 {
1672 (void)sprintf(str,"%s %ld", radical, index);
1673 return namealloc(str);
1674 }
1675
1676 /*******************************************************************************
1677 * function vectorradical : returns the radical of an mbk vector *
1678 *******************************************************************************/
1679 char *vectorradical(name)
1680 char *name;
1681 {
1682 char *s;
1683 char t;
1684 if ((t=name[strlen(name)-1])<'0' || t>'9') return name;
1685
1686 s = strchr(name, ' ');
1687
1688 if (!s)
1689 return name;
1690
1691 strcpy(str, name);
1692 s=&str[s-name];
1693
1694 *s = '\0';
1695 return namealloc(str);
1696 }
1697
1698 char *mbk_VectorRadical(char *name, char *openb, char *closeb)
1699 {
1700 char *closebplace;
1701 char findchar;
1702 int l;
1703 char str[2048];
1704
1705 if (openb==NULL || closeb==NULL) openb="[(<", closeb="])>";
1706
1707 l=strlen(name)-1;
1708
1709 if (l<=0) return name;
1710
1711 if (isdigit((int)(unsigned char)name[l]))
1712 {
1713 findchar=' ';
1714 }
1715 else
1716 if ((closebplace=strchr(closeb, name[l]))!=NULL)
1717 {
1718 findchar=*(openb-(closebplace-closeb));
1719 }
1720 else
1721 return name;
1722
1723 l--;
1724
1725 while (l>0 && isdigit((int)(unsigned char)name[l])) l--;
1726
1727 if (l==0 || name[l]!=findchar) return name;
1728
1729 strncpy(str, name, l);
1730 str[l]='\0';
1731
1732 return namealloc(str);
1733 }
1734
1735 int mbk_VectorIndex(char *name, char *openb, char *closeb)
1736 {
1737 char *closebplace;
1738 char findchar;
1739 int l;
1740
1741 if (openb==NULL || closeb==NULL) openb="[(<", closeb="])>";
1742
1743 l=strlen(name)-1;
1744
1745 if (l<=0) return -1;
1746
1747 if (isdigit((int)(unsigned char)name[l]))
1748 {
1749 findchar=' ';
1750 }
1751 else
1752 if ((closebplace=strchr(closeb, name[l]))!=NULL)
1753 {
1754 findchar=*(openb-(closebplace-closeb));
1755 }
1756 else return -1;
1757
1758 l--;
1759
1760 while (l>0 && isdigit((int)(unsigned char)name[l])) l--;
1761
1762 if (l==0 || name[l]!=findchar) return -1;
1763
1764 return strtol(&name[l+1], NULL, 10);
1765 }
1766
1767
1768 /*******************************************************************************
1769 * function vectorindex : returns the index of an mbk vector *
1770 *******************************************************************************/
1771 int vectorindex(name)
1772 char *name;
1773 {
1774 char *s = strchr(name, ' ');
1775
1776 if (!s)
1777 return -1;
1778
1779 return atoi(s);
1780 }
1781
1782 /*******************************************************************************
1783 * generic compaison function : *
1784 * unlike strcmp, ensure that 10 > 2 for vectorized strings. *
1785 * first, check strings, then check numerical values as numbers, not strings. *
1786 *******************************************************************************/
1787 int naturalstrcmp(s, t)
1788 char *s, *t;
1789 {
1790 char *spt, *tpt , *st = s, *tt = t;
1791 int u, ls, lt;
1792
1793 spt = buffer, tpt = str;
1794
1795 while ((!isspace((int)*st)) && *st)
1796 *spt++ = *st++;
1797 *spt = '\0';
1798
1799 while ((!isspace((int)*tt)) && *tt)
1800 *tpt++ = *tt++;
1801 *tpt = '\0';
1802
1803 if ((u = strcmp(buffer, str)) != 0)
1804 return u;
1805
1806 if ((ls = strlen(s)) == (lt = strlen(t)))
1807 return strcmp(s, t);
1808
1809 return ls - lt;
1810 }
1811
1812 /*******************************************************************************
1813 * function concatname() *
1814 *******************************************************************************/
1815 char *concatname(name1, name2)
1816 char *name1, *name2;
1817 {
1818 (void)sprintf(str,"%s%c%s", name1, SEPAR, name2);
1819 return namealloc(str);
1820 }
1821
1822 /*******************************************************************************
1823 * function leftunconcatname() *
1824 * name="AAA.BBB.CCC.DDD" *
1825 * gives : *
1826 * left="AAA" or NULL *
1827 * right="BBB.CCC.DDD" *
1828 *******************************************************************************/
1829 void leftunconcatname(name, left, right)
1830 char *name, **left, **right;
1831 {
1832 int i;
1833
1834 // On recherche le premier séparateur.
1835
1836 for( i=0;
1837 name[i] != SEPAR && name[i]!= 0 ;
1838 i++ )
1839 str[i] = name[i];
1840 str[i]=0;
1841
1842 if( name[i] != SEPAR ) {
1843 // Il n'y a plus de séparateur : il ne reste donc que le right.
1844 *right = name;
1845 *left =NULL;
1846 } else {
1847 *left = namealloc( str );
1848 *right = namealloc( name+i+1 );
1849 }
1850 }
1851
1852 /*******************************************************************************
1853 * function rightunconcatname() *
1854 * name="AAA.BBB.CCC.DDD" *
1855 * gives : *
1856 * left="AAA.BBB.CCC" *
1857 * right="DDD" or NULL *
1858 *******************************************************************************/
1859 void rightunconcatname(name, left, right)
1860 char *name, **left, **right;
1861 {
1862 int i, m;
1863
1864 // Positionne sur le dernier caractère;
1865 for( i=0, m=-1 ; name[i] ; i++)
1866 if( name[i] == SEPAR )
1867 m=i;
1868
1869 if( m == -1 ) {
1870 // Il n'y a plus de séparateur : il ne reste donc que le left
1871 *right = NULL;
1872 *left = name;
1873 } else {
1874 // strlcpy( str, name, m ); pas disponible sous Solaris 5.6
1875 for( i=0 ; i < m ; i++ )
1876 str[i] = name[i];
1877 str[i] = '\0';
1878
1879 *right = namealloc( name+m+1 );
1880 *left = namealloc( str );
1881 }
1882 }
1883
1884 /*******************************************************************************
1885 * mbkstrdup : since brain damaged system we aim at do not have it *
1886 *******************************************************************************/
1887 char *mbkstrdup(s)
1888 char *s;
1889 {
1890 char *t;
1891
1892 if (s == NULL)
1893 return NULL;
1894
1895 t = (char *)mbkalloc((unsigned int)(strlen(s) + 1));
1896 return strcpy(t, s);
1897 }
1898
1899 int mbk_casestrcmp(char *orig, char *dest)
1900 {
1901 if (CASE_SENSITIVE=='Y') return strcmp(orig, dest);
1902 return strcasecmp(orig, dest);
1903 }
1904
1905 int mbk_charcmp(char orig, char dest)
1906 {
1907 if (CASE_SENSITIVE=='Y') return orig==dest;
1908 return tolower(orig)==tolower(dest);
1909 }
1910
1911 /*******************************************************************************
1912 * function reverse *
1913 *******************************************************************************/
1914 chain_list *reverse(head)
1915 chain_list *head;
1916 {
1917 chain_list *p;
1918 chain_list *q = (chain_list *)NULL;
1919
1920 if (!head)
1921 return NULL;
1922 while ((p = head->NEXT)) {
1923 head->NEXT = q;
1924 q = head;
1925 head = p;
1926 }
1927 head->NEXT = q;
1928 return head;
1929 }
1930
1931 /*******************************************************************************
1932 * function pstrcmp *
1933 * used for qsort and bsearch use for catalog sorting and acessing *
1934 *******************************************************************************/
1935 static int pstrcmp(s, t)
1936 char **s, **t;
1937 {
1938 return strcmp(*s, *t);
1939 }
1940
1941 /*******************************************************************************
1942 * function incatalogfeed *
1943 * tests if a model is present in the catalog with the F attribut *
1944 *******************************************************************************/
1945 int incatalogfeed(figname)
1946 char *figname;
1947 {
1948 static int size;
1949 static char **table;
1950
1951 if (!size)
1952 loadcatalog(&table, &size, 'F');
1953 return size ?
1954 (int)((long)bsearch(&figname, table, size, sizeof(char *), pstrcmp)) : 0;
1955 }
1956
1957 /*******************************************************************************
1958 * function incataloggds *
1959 * tests if a model is present in the catalog with the G attribut *
1960 *******************************************************************************/
1961 int incataloggds(figname)
1962 char *figname;
1963 {
1964 static int size;
1965 static char **table;
1966
1967 if (!size)
1968 loadcatalog(&table, &size, 'G');
1969 return size ?
1970 (int)((long)bsearch(&figname, table, size, sizeof(char *), pstrcmp)) : 0;
1971 }
1972
1973 /*******************************************************************************
1974 * function inlibcatalog *
1975 * tests if a model is present in the lib catalog with the C attribut *
1976 *******************************************************************************/
1977 int inlibcatalog(figname)
1978 char *figname;
1979 {
1980 if(LIB_CATAL != NULL) {
1981 if(gethtitem(LIB_CATAL,figname) != EMPTYHT)
1982 return(1) ;
1983 }
1984
1985 return(0) ;
1986 }
1987
1988 /*******************************************************************************
1989 * function incatalog *
1990 * tests if a model is present in the catalog with the C attribut *
1991 *******************************************************************************/
1992 int incatalog(figname)
1993 char *figname;
1994 {
1995 static int size;
1996 static char **table;
1997
1998 if(LIB_CATAL != NULL) {
1999 if(gethtitem(LIB_CATAL,figname) != EMPTYHT)
2000 return(1) ;
2001 }
2002
2003 if (!size)
2004 loadcatalog(&table, &size, 'C');
2005 return size ?
2006 (int)((long)bsearch(&figname, table, size, sizeof(char *), pstrcmp)) : 0;
2007 }
2008
2009 /*******************************************************************************
2010 * function incatalogdelete *
2011 * tests if a model is present in the catalog with the D attribut *
2012 *******************************************************************************/
2013 int incatalogdelete(figname)
2014 char *figname;
2015 {
2016 static int size;
2017 static char **table;
2018
2019 if (!size)
2020 loadcatalog(&table, &size, 'D');
2021 return size ?
2022 (int)((long)bsearch(&figname, table, size, sizeof(char *), pstrcmp)) : 0;
2023 }
2024
2025 /*******************************************************************************
2026 * function addcatalog *
2027 * add a cell in the catalog *
2028 *******************************************************************************/
2029 void addcatalog(figname)
2030 char *figname;
2031 {
2032 if(LIB_CATAL == NULL)
2033 {
2034 LIB_CATAL = addht(100) ;
2035 }
2036 sethtitem(LIB_CATAL,figname,(long)1) ;
2037 }
2038
2039 chain_list *getcataloglist()
2040 {
2041 if(LIB_CATAL == NULL)
2042 {
2043 LIB_CATAL = addht(100) ;
2044 }
2045 return GetAllHTKeys(LIB_CATAL);
2046 }
2047
2048 void setcataloglist(chain_list *cl)
2049 {
2050 if(LIB_CATAL != NULL)
2051 {
2052 delht(LIB_CATAL);
2053 LIB_CATAL = NULL;
2054 }
2055 while (cl!=NULL)
2056 {
2057 addcatalog(namealloc((char *)cl->DATA));
2058 cl=cl->NEXT;
2059 }
2060 }
2061
2062 /*******************************************************************************
2063 * function loadcatalog *
2064 * read the catalog from disk checking the given type *
2065 *******************************************************************************/
2066
2067 static void loadcatalog(table, size, type)
2068 char ***table;
2069 int *size;
2070 char type;
2071 {
2072 void *pt;
2073 char attrib;
2074 int nb;
2075 int nb_input;
2076 int i = 0;
2077 chain_list *files = (chain_list *)NULL;
2078 /* Tables for quick cell search :
2079 The catalog file is read only once, and sorted for speed.
2080 The later calls to loadcatalog only return the approriate table. */
2081 static chain_list *cells[4];
2082 static char **tabs[4];
2083 static int sizes[4];
2084 static int read;
2085
2086 if (!read) {
2087 read++;
2088 (void)sprintf(buffer, "%s/%s", WORK_LIB, CATAL ? CATAL : "CATAL");
2089 files = addchain(files, (void *)fopen(buffer, READ_TEXT));
2090 while (CATA_LIB[i]) {
2091 (void)sprintf(buffer, "%s/CATAL", CATA_LIB[i++]);
2092 files = addchain(files, (void *)fopen(buffer, READ_TEXT));
2093 }
2094 /* error message :
2095 To avoid malloc/free on file name, the error message is output
2096 relatively to its order. */
2097 files = reverse(files);
2098 for (i = 0, pt = (void *)files; pt;
2099 pt = (void *)((chain_list *)pt)->NEXT, i++) {
2100 if (!((chain_list *)pt)->DATA)
2101 continue;
2102 nb = 0;
2103 while (!feof((FILE *)((chain_list *)pt)->DATA)) {
2104 nb++; /* count lines */
2105 nb_input = fscanf((FILE *)((chain_list *)pt)->DATA, "%s %c\n",
2106 buffer, &attrib);
2107 if (nb_input == 0) /* skip white lines */
2108 continue;
2109 if (nb_input != 2) {
2110 (void)fflush(stdout);
2111 (void)fprintf(stderr, "*** mbk error ***\n");
2112 (void)fprintf(stderr, "loadcatalog syntax error line %d ", nb);
2113 if (i == 0)
2114 (void)fprintf(stderr, "in file %s/%s\n", WORK_LIB, CATAL);
2115 else
2116 (void)fprintf(stderr, "in file %s/CATAL\n", CATA_LIB[i - 1]);
2117 EXIT(1);
2118 }
2119 attrib = islower((int)attrib) ? (char)toupper(attrib) : attrib;
2120 switch (attrib) {
2121 case 'C' :
2122 cells[0] = addchain(cells[0], namealloc(buffer));
2123 sizes[0]++;
2124 break;
2125 case 'G' :
2126 cells[1] = addchain(cells[1], namealloc(buffer));
2127 sizes[1]++;
2128 break;
2129 case 'F' :
2130 cells[2] = addchain(cells[2], namealloc(buffer));
2131 sizes[2]++;
2132 break;
2133 case 'D' :
2134 cells[3] = addchain(cells[3], namealloc(buffer));
2135 sizes[3]++;
2136 break;
2137 default :
2138 (void)fflush(stdout);
2139 (void)fprintf(stderr, "*** mbk error ***\n");
2140 (void)fprintf(stderr, "loadcatalog syntax error line %d ",
2141 nb);
2142 if (i == 0)
2143 (void)fprintf(stderr, "in file %s/%s\n", WORK_LIB, CATAL);
2144 else
2145 (void)fprintf(stderr, "in file %s/CATAL\n",
2146 CATA_LIB[i - 1]);
2147 (void)fprintf(stderr,"unknown attribut %c\n", attrib);
2148 EXIT(1);
2149 }
2150 }
2151 (void)fclose((FILE *)((chain_list *)pt)->DATA);
2152 }
2153 freechain(files);
2154 for (nb = 0; nb < 4; nb++) {
2155 if (sizes[nb]) {
2156 tabs[nb] = (char **)mbkalloc(sizes[nb] * sizeof(char *));
2157 for (i = 0, pt = (void *)cells[nb]; pt;
2158 pt = (void *)((chain_list *)pt)->NEXT, i++)
2159 tabs[nb][i] = (char *)((chain_list *)pt)->DATA;
2160 qsort(tabs[nb], sizes[nb], sizeof(char *), pstrcmp);
2161 freechain(cells[nb]);
2162 }
2163 }
2164 }
2165
2166 switch (type) {
2167 case 'C' :
2168 *table = tabs[0];
2169 *size = sizes[0];
2170 break;
2171 case 'G' :
2172 *table = tabs[1];
2173 *size = sizes[1];
2174 break;
2175 case 'F' :
2176 *table = tabs[2];
2177 *size = sizes[2];
2178 break;
2179 case 'D' :
2180 *table = tabs[3];
2181 *size = sizes[3];
2182 break;
2183 }
2184 }
2185
2186 /*******************************************************************************
2187 * function read_lib() *
2188 * fills an array of char * in order to have a list of names as CATA_LIB *
2189 *******************************************************************************/
2190 static void read_lib()
2191 {
2192 char *str, *s, *stc, *c;
2193 int argc = 0, i;
2194
2195 if (WORK_LIB!=NULL) mbkfree(WORK_LIB);
2196 str = V_STR_TAB[__MBK_WORK_LIB].VALUE;
2197 if (str != NULL) {
2198 WORK_LIB =
2199 (char *)mbkalloc((unsigned int)(strlen(str) + 1) * sizeof(char));
2200 (void)strcpy(WORK_LIB, str);
2201 } else { /* no specific path is given */
2202 WORK_LIB = (char *)mbkalloc((unsigned int)2 * sizeof(char));
2203 (void)strcpy(WORK_LIB, ".");
2204 }
2205
2206 if (CATA_LIB!=NULL)
2207 {
2208 i=0;
2209 while (CATA_LIB[i]) { mbkfree(CATA_LIB[i]); i++; }
2210 mbkfree(CATA_LIB);
2211 }
2212
2213 str = V_STR_TAB[__MBK_CATA_LIB].VALUE;
2214 if(str != NULL) {
2215 char *savs;
2216 savs= s = (char *)mbkalloc((unsigned int)(strlen(str) + 1) * sizeof(char));
2217 (void)strcpy(s, str);
2218 str = s; /* let's not modify the environement values */
2219 stc = str; /* for counting purposes */
2220 while (1) {
2221 if ((c = strchr(stc, ':')) == NULL)
2222 break;
2223 argc++;
2224 stc = ++c;
2225 }
2226
2227
2228 CATA_LIB = (char **)mbkalloc((unsigned int)(argc + 2) * sizeof(char *));
2229 argc = 0;
2230 while (1) {
2231 if ((s = strchr(str, ':')) == NULL)
2232 break;
2233 *(s++) = '\0';
2234 CATA_LIB[argc++] = mbkstrdup(str); /* no allocation necessary */
2235 str = s;
2236 }
2237 if (s == NULL)
2238 CATA_LIB[argc++] = (str == NULL || *str == '\0') ? NULL : mbkstrdup(str);
2239 CATA_LIB[argc] = NULL;
2240 mbkfree(savs);
2241 } else { /* no specific path is given */
2242 CATA_LIB = (char **)mbkalloc((unsigned int)2 * sizeof(char *));
2243 CATA_LIB[0] = mbkstrdup(".");
2244 CATA_LIB[1] = NULL;
2245 }
2246 }
2247 /*******************************************************************************
2248 * Hash tables management functions, contributed to by Luc Burgun on 20/06/92 *
2249 *******************************************************************************/
2250 /*******************************************************************************
2251 * new dilution function for the table accesses. G. Augustins 18.XII.2001 *
2252 *******************************************************************************/
2253
2254 unsigned long hash(p)
2255 void *p;
2256 {
2257 unsigned long key ;
2258 unsigned long bit0 = (long)p & (long)0xff ;
2259 unsigned long bit1 = ((long)p >> 8) & (long)0xff ;
2260 unsigned long bit2 = ((long)p >> 16) & (long)0xff ;
2261 unsigned long bit3 = ((long)p >> 24) & (long)0xff ;
2262 unsigned long key0 ;
2263 unsigned long key1 ;
2264 unsigned long key2 ;
2265 unsigned long key3 ;
2266
2267 key3 = bit2 ^ bit0 ;
2268 key2 = bit1 ^ bit3 ;
2269 key1 = bit3 ^ bit2 ;
2270 key0 = bit1 ^ bit2 ;
2271
2272 key = (key3 << 24) | (key2 << 16) | (key1 << 8) | key0 ;
2273
2274 return (key) ;
2275 }
2276
2277 /*******************************************************************************
2278 * function addht, create a hash table *
2279 *******************************************************************************/
2280 ht *addht(len)
2281 unsigned long len;
2282 {
2283 ht *pTable;
2284 htitem *pEl;
2285 unsigned int i;
2286
2287 if( V_BOOL_TAB[__AVT_USEHT_V2].VALUE )
2288 return (ht*)addht_v2(len);
2289
2290 if (len == 0) {
2291 fflush(stdout);
2292 (void)fprintf(stderr, "*** mbk error ***\n");
2293 (void)fprintf(stderr, "addht impossible : hash table size is '0'\n");
2294 EXIT(1);
2295 }
2296 pTable = (ht *)mbkalloc(sizeof(struct htable));
2297 pTable->length = len;
2298 pEl = (htitem *)mbkalloc(len * (sizeof(struct htitem)));
2299 pTable->pElem = pEl;
2300 for (i = 0; i < len; i++) {
2301 pEl[i].key = NULL;
2302 pEl[i].value = EMPTYHT;
2303 }
2304 pTable->count = 0;
2305 return pTable;
2306 }
2307
2308 ht *dupht(ht *orig)
2309 {
2310 ht *dest;
2311 //htitem *hi;
2312 int i;
2313
2314 if( V_BOOL_TAB[__AVT_USEHT_V2].VALUE )
2315 return (ht*)dupht_v2((ht_v2*)orig);
2316
2317 dest=(ht *)mbkalloc(sizeof(ht));
2318 memcpy(dest, orig, sizeof(ht));
2319 dest->pElem=(htitem *)mbkalloc(sizeof(htitem)*orig->length);
2320 for (i=0; i<orig->length; i++)
2321 memcpy(&dest->pElem[i], &orig->pElem[i], sizeof(htitem));
2322 // memcpy(dest->pElem, orig->pElem, sizeof(htitem)*orig->length);
2323 return dest;
2324 }
2325 /*******************************************************************************
2326 * function delht, delete a hash table *
2327 *******************************************************************************/
2328 void delht(pTable)
2329 ht *pTable;
2330 {
2331 htitem * pEl;
2332
2333 if( V_BOOL_TAB[__AVT_USEHT_V2].VALUE ) {
2334 delht_v2((ht_v2*)pTable);
2335 return ;
2336 }
2337
2338 if (pTable == NULL) return;
2339 pEl = pTable->pElem;
2340 mbkfree(pEl);
2341 mbkfree(pTable);
2342 }
2343
2344 /*******************************************************************************
2345 * function gethtitem, get an element in a hash table *
2346 *******************************************************************************/
2347 long gethtitem(pTable, key)
2348 ht *pTable;
2349 void *key;
2350 {
2351 long co = 0;
2352 long indice = 0;
2353 htitem * pEl;
2354
2355 if( V_BOOL_TAB[__AVT_USEHT_V2].VALUE )
2356 return gethtitem_v2( (ht_v2*)pTable, key );
2357
2358 indice = hash(key) % pTable->length;
2359 do {
2360 if (co++ > HMAX_CALLS) {
2361 if ((pTable->count > (pTable->length) * 2 / 10) || (co >= pTable->length)) {
2362 reallocht(pTable);
2363 return gethtitem(pTable, key);
2364 }
2365 }
2366
2367 pEl = (pTable->pElem) + indice;
2368 if (pEl->value != EMPTYHT && pEl->value != DELETEHT) {
2369 if ((long) key == (long) pEl->key)
2370 return pEl->value;
2371 } else if (pEl->value == EMPTYHT)
2372 return EMPTYHT;
2373 indice = (indice + 1) % pTable->length;
2374 } while (1);
2375 }
2376
2377 /*******************************************************************************
2378 * function addhtitem, get an element in a hash table *
2379 *******************************************************************************/
2380 long addhtitem(pTable, key, value)
2381 ht *pTable;
2382 void *key;
2383 long value;
2384 {
2385 int indice = 0;
2386 htitem *pEl, *FirstDEL=NULL;
2387 int co = 0;
2388
2389 if( V_BOOL_TAB[__AVT_USEHT_V2].VALUE )
2390 return addhtitem_v2( (ht_v2*)pTable, key, value );
2391
2392 if (value == EMPTYHT || value == DELETEHT) {
2393 fflush(stdout);
2394 (void)fprintf(stderr, "*** mbk error ***\n");
2395 (void)fprintf(stderr, "addhtitem impossible : value is EMPTYHT or DELETEHT\n");
2396 EXIT(1);
2397 }
2398 if (pTable->count++ > (pTable->length) * 8 / 10) {
2399 reallocht(pTable);
2400 return addhtitem(pTable, key, value);
2401 }
2402
2403 indice = hash(key) % pTable->length;
2404 do {
2405 if (co++ > HMAX_CALLS) {
2406 if (pTable->count > (pTable->length) * 2 / 10 || (co >= pTable->length)) {
2407 reallocht(pTable);
2408 return addhtitem(pTable, key, value);
2409 } else if(TRACE_MODE == 'Y') {
2410 fflush(stdout);
2411 (void)fprintf (stderr, "*** mbk warning ***\n");
2412 (void)fprintf (stderr, "reallocht undone : density is too low\n");
2413 }
2414 }
2415 pEl = (pTable->pElem) + indice;
2416 if (FirstDEL==NULL && pEl->value == DELETEHT) FirstDEL=pEl;
2417 else if (pEl->value == EMPTYHT) {
2418 if (FirstDEL!=NULL) pEl=FirstDEL;
2419 pEl->value = value;
2420 pEl->key = key;
2421 return value;
2422 } else if ((long) pEl->key == (long) key) {
2423 pTable->count--;
2424 pEl->value = value;
2425 return value;
2426 }
2427 indice = (indice + 1) % pTable->length;
2428 } while (1);
2429 }
2430
2431 void resetht_v2(ht_v2 *h)
2432 {
2433 int i;
2434 for (i=0; i<h->size; i++) h->ITEM_HASHTABLE[i]=NULL;
2435 DeleteHeap(&h->ha);
2436 }
2437
2438 void resetht(ht *pTable)
2439 {
2440 int i;
2441 if( V_BOOL_TAB[__AVT_USEHT_V2].VALUE )
2442 resetht_v2((ht_v2*)pTable);
2443 for (i=0; i<pTable->length; i++)
2444 {
2445 pTable->pElem[i].key = NULL;
2446 pTable->pElem[i].value = EMPTYHT;
2447 }
2448 pTable->count = 0;
2449 }
2450
2451 ht* controlled_dupht( ht *orig, long (*func)( long value, void *user_data ), void *user_data )
2452 {
2453 ht *h ;
2454 int i ;
2455
2456 if( V_BOOL_TAB[__AVT_USEHT_V2].VALUE )
2457 return (ht*)controlled_dupht( orig, func, user_data );
2458
2459 h = dupht( orig ) ;
2460 for( i=0 ; i<h->length ; i++ )
2461 h->pElem[i].value = func( h->pElem[i].value, user_data );
2462
2463 return h ;
2464 }
2465
2466 ht_v2* controlled_dupht_v2( ht_v2 *orig, long (*func)( long value, void *user_data ), void *user_data )
2467 {
2468 ht_v2 *h ;
2469 htitem_v2 *item ;
2470 int i ;
2471
2472 h = dupht_v2( orig ) ;
2473 for( i=0 ; i<h->size ; i++ ) {
2474 for( item = h->ITEM_HASHTABLE[i] ; item ; item = item->next ) {
2475 item->value = func( item->value, user_data );
2476 }
2477 }
2478
2479 return h ;
2480 }
2481
2482 long controlled_addhtitem(ht *pTable, void *key, long (*func)(int newone, long old_value, void *user_data), void *user_data)
2483 {
2484 int indice = 0;
2485 htitem *pEl, *FirstDEL=NULL;
2486 int co = 0;
2487
2488 if( V_BOOL_TAB[__AVT_USEHT_V2].VALUE )
2489 return controlled_addhtitem_v2( (ht_v2*)pTable, key, func, user_data );
2490
2491 if (pTable->count++ > (pTable->length) * 8 / 10) {
2492 reallocht(pTable);
2493 return controlled_addhtitem(pTable, key, func, user_data);
2494 }
2495
2496 indice = hash(key) % pTable->length;
2497 do {
2498 if (co++ > HMAX_CALLS) {
2499 if (pTable->count > (pTable->length) * 2 / 10 || (co >= pTable->length)) {
2500 reallocht(pTable);
2501 return controlled_addhtitem(pTable, key, func, user_data);
2502 } else if(TRACE_MODE == 'Y') {
2503 fflush(stdout);
2504 (void)fprintf (stderr, "*** mbk warning ***\n");
2505 (void)fprintf (stderr, "reallocht undone : density is too low\n");
2506 }
2507 }
2508 pEl = (pTable->pElem) + indice;
2509 if (FirstDEL==NULL && pEl->value == DELETEHT) FirstDEL=pEl;
2510 else if (pEl->value == EMPTYHT) {
2511 if (FirstDEL!=NULL) pEl=FirstDEL;
2512 pEl->value = func(1, pEl->value, user_data);
2513
2514 if (pEl->value == EMPTYHT || pEl->value == DELETEHT) {
2515 fflush(stdout);
2516 (void)fprintf(stderr, "*** mbk error ***\n");
2517 (void)fprintf(stderr, "controlled_addhtitem impossible : value is EMPTYHT or DELETEHT\n");
2518 EXIT(1);
2519 }
2520 pEl->key = key;
2521 return pEl->value;
2522 } else if ((long) pEl->key == (long) key) {
2523 pTable->count--;
2524 pEl->value = func(0, pEl->value, user_data);
2525 if (pEl->value == EMPTYHT || pEl->value == DELETEHT) {
2526 fflush(stdout);
2527 (void)fprintf(stderr, "*** mbk error ***\n");
2528 (void)fprintf(stderr, "controlled_addhtitem impossible : value is EMPTYHT or DELETEHT\n");
2529 EXIT(1);
2530 }
2531 return pEl->value;
2532 }
2533 indice = (indice + 1) % pTable->length;
2534 } while (1);
2535 }
2536
2537 long sethtitem(pTable, key, value)
2538 ht *pTable;
2539 void *key;
2540 long value;
2541 {
2542 int indice = 0;
2543 htitem *pEl, *FirstDEL=NULL;
2544 int co = 0;
2545
2546 if( V_BOOL_TAB[__AVT_USEHT_V2].VALUE )
2547 return sethtitem_v2( (ht_v2*)pTable, key, value );
2548
2549 if (value == EMPTYHT || value == DELETEHT) {
2550 fflush(stdout);
2551 (void)fprintf(stderr, "*** mbk error ***\n");
2552 (void)fprintf(stderr, "sethtitem impossible : value is EMPTYHT or DELETEHT\n");
2553 EXIT(1);
2554 }
2555 if (pTable->count++ > (pTable->length) * 8 / 10) {
2556 reallocht(pTable);
2557 return sethtitem(pTable, key, value);
2558 }
2559
2560 indice = hash(key) % pTable->length;
2561 do {
2562 if (co++ > HMAX_CALLS) {
2563 if (pTable->count > (pTable->length) * 2 / 10 || (co >= pTable->length)) {
2564 reallocht(pTable);
2565 return sethtitem(pTable, key, value);
2566 } else if(TRACE_MODE == 'Y') {
2567 fflush(stdout);
2568 (void)fprintf (stderr, "*** mbk warning ***\n");
2569 (void)fprintf (stderr, "reallocht undone : density is too low\n");
2570 }
2571 }
2572 pEl = (pTable->pElem) + indice;
2573 if (FirstDEL==NULL && pEl->value == DELETEHT) FirstDEL=pEl;
2574 else if (pEl->value == EMPTYHT) {
2575 if (FirstDEL!=NULL) pEl=FirstDEL;
2576 pEl->value = value;
2577 pEl->key = key;
2578 return 0;
2579 } else if ((long) pEl->key == (long) key) {
2580 pTable->count--;
2581 pEl->value = value;
2582 return 1;
2583 }
2584 indice = (indice + 1) % pTable->length;
2585 } while (1);
2586 }
2587
2588 /*******************************************************************************
2589 * function delhtitem, delete an element in a hash table *
2590 *******************************************************************************/
2591 long delhtitem(pTable, key)
2592 ht *pTable;
2593 void *key;
2594 {
2595 int indice = 0;
2596 htitem *pEl;
2597 int co = 0;
2598
2599 if( V_BOOL_TAB[__AVT_USEHT_V2].VALUE )
2600 return delhtitem_v2( (ht_v2*)pTable, key );
2601
2602 indice = hash(key) % pTable->length;
2603 do {
2604 if (co++ > HMAX_CALLS) {
2605 if (pTable->count > (pTable->length) * 2 / 10 || (co >= pTable->length)) {
2606
2607 reallocht(pTable);
2608 return delhtitem(pTable, key);
2609 }
2610 }
2611 pEl = (pTable->pElem) + indice;
2612 if (pEl->value != EMPTYHT && pEl->value != DELETEHT) {
2613 if ((long) key == (long)pEl->key) {
2614 pTable->count--;
2615 pEl->value = DELETEHT;
2616 return pEl->value;
2617 }
2618 } else if (pEl->value == EMPTYHT)
2619 return EMPTYHT;
2620 indice = (indice + 1) % pTable->length;
2621 } while (1);
2622 }
2623
2624 /*******************************************************************************
2625 Scan all element of an hash table
2626 first must be set to 1 on the first call, then set to 0 for the following calls.
2627 nextkey must contains the previous value returned (not applicable for the
2628 first call).
2629 end is reached when nextitem contain EMPTYHT.
2630 *******************************************************************************/
2631
2632 void scanhtkey(pTable, first, nextkey, nextitem)
2633 ht *pTable;
2634 int first;
2635 void **nextkey;
2636 long *nextitem;
2637 {
2638 long indice = 0;
2639 htitem * pEl;
2640 int co;
2641
2642 if( V_BOOL_TAB[__AVT_USEHT_V2].VALUE ) {
2643 scanhtkey_v2( (ht_v2*)pTable, first, nextkey, nextitem );
2644 return ;
2645 }
2646
2647 if( first )
2648 indice = 0;
2649 else {
2650 indice = hash(*nextkey) % pTable->length ;
2651 co=pTable->length+1;
2652 do {
2653 pEl = (pTable->pElem) + indice;
2654 if( pEl->key == *nextkey )
2655 break;
2656
2657 indice++ ;
2658 if( indice == pTable->length )
2659 indice = 0;
2660 co--;
2661 }
2662 while( co );
2663
2664 if( !co ) {
2665 fflush( stdout );
2666 fprintf( stderr, "Internal error in scanhtitem().\n" );
2667 EXIT(1);
2668 }
2669 indice++;
2670 }
2671
2672 while( indice < pTable->length ) {
2673 pEl = (pTable->pElem) + indice;
2674 if( pEl->value != EMPTYHT && pEl->value != DELETEHT ) {
2675 *nextkey = pEl->key;
2676 *nextitem = pEl->value;
2677 return ;
2678 }
2679 indice++;
2680 }
2681
2682 *nextkey = NULL ;
2683 *nextitem = EMPTYHT;
2684 }
2685
2686 /*******************************************************************************
2687 * display contents of an hash table *
2688 *******************************************************************************/
2689 void viewht(pTable, pout)
2690 ht *pTable;
2691 char *(*pout)();
2692 {
2693 long i;
2694 htitem *pEl = pTable->pElem;
2695
2696 (void)printf("================== viewht ================\n");
2697 (void)printf("length = %ld\t count = %ld\n",
2698 pTable->length, pTable->count);
2699 (void)printf("==========================================\n");
2700 for (i = 0; i < pTable->length; i++) {
2701 if (pEl->value != EMPTYHT && pEl->value != DELETEHT) {
2702 printf("index %ld\t", i);
2703 printf("key %s\t", pout(pEl->key));
2704 printf("value %ld \n", pEl->value);
2705 }
2706 pEl++;
2707 }
2708 }
2709
2710 /*******************************************************************************
2711 * realloc space to adapt hash table size to number of entries *
2712 *******************************************************************************/
2713 static void reallocht(pTable)
2714 ht *pTable;
2715 {
2716 ht *tabBis;
2717 htitem *pEl;
2718 int i;
2719 double ratio;
2720
2721 pEl = pTable->pElem;
2722
2723 ratio = (double)pTable->count / (double)pTable->length;
2724 if (ratio > 0.8) ratio = 1;
2725 else if (ratio < 0.3) ratio = 0.3;
2726
2727 tabBis = addht((unsigned long)((double)(pTable->length) * 5.0 * ratio)) ;
2728 for (i = 0; i < pTable->length; i++) {
2729 if (pEl->value != EMPTYHT && pEl->value != DELETEHT)
2730 addhtitem(tabBis, pEl->key, pEl->value);
2731 pEl++;
2732 }
2733 mbkfree(pTable->pElem);
2734 pTable->length = tabBis->length;
2735 pTable->pElem = tabBis->pElem;
2736 pTable->count = tabBis->count;
2737 mbkfree(tabBis);
2738 }
2739
2740 /*******************************************************************************
2741 * function addvt, create a pointer table *
2742 *******************************************************************************/
2743 voidt *addvt(length)
2744 unsigned int length ;
2745 {
2746 voidt *ptvt ;
2747 int i ;
2748
2749 if(length <= 0)
2750 length = 10 ;
2751
2752 ptvt = (voidt *)mbkalloc(sizeof(voidt));
2753 ptvt->size = 0;
2754 ptvt->length = length;
2755 ptvt->data = mbkalloc(length * sizeof(void *));
2756 for(i = ptvt->size ; i < ptvt->length ; i++)
2757 (ptvt->data)[i] = (void *)EMPTYHT ;
2758
2759 return ptvt;
2760 }
2761
2762 /*******************************************************************************
2763 * function delvt, delete a pointer table *
2764 *******************************************************************************/
2765 void delvt(table)
2766 voidt *table ;
2767 {
2768 if (table->data != NULL) mbkfree(table->data);
2769 mbkfree(table);
2770 }
2771
2772 /*******************************************************************************
2773 * function addvtitem, add an element in a pointer table *
2774 *******************************************************************************/
2775 int addvtitem(table,data)
2776 voidt *table;
2777 void *data ;
2778 {
2779 int i ;
2780
2781 if(table->size == table->length)
2782 {
2783 table->length = table->length * 2 ;
2784 table->data = mbkrealloc(table->data,table->length * sizeof(void *));
2785 for(i = table->size ; i < table->length ; i++)
2786 (table->data)[i] = (void *)EMPTYHT ;
2787 }
2788 (table->data)[(table->size)++] = data;
2789 return(table->size - 1) ;
2790 }
2791
2792 /*******************************************************************************
2793 * function setvtitem, set an element in a pointer table *
2794 *******************************************************************************/
2795 void setvtitem(table,item,data)
2796 voidt *table;
2797 int item ;
2798 void *data ;
2799 {
2800 int i ;
2801
2802 if(item >= table->length)
2803 {
2804 table->size = table->length ;
2805 table->length = item * 2 ;
2806 table->data = mbkrealloc(table->data,table->length * sizeof(void *));
2807 for(i = table->size ; i < table->length ; i++)
2808 (table->data)[i] = (void *)EMPTYHT ;
2809 table->size = item + 1 ;
2810 }
2811 (table->data)[item] = data;
2812 }
2813
2814 /*******************************************************************************
2815 * function getvtitem, get an element in a pointer table *
2816 *******************************************************************************/
2817 void *getvtitem(table,item)
2818 voidt *table;
2819 int item ;
2820 {
2821 if(item >= table->length)
2822 return((void *)EMPTYHT) ;
2823 else
2824 return((table->data)[item]) ;
2825 }
2826
2827 /*******************************************************************************
2828 * function delvtitem, del an element in a interger table *
2829 *******************************************************************************/
2830 void delvtitem(table,item)
2831 voidt *table;
2832 int item ;
2833 {
2834 if(item >= table->length)
2835 return ;
2836 else
2837 (table->data)[item] = (void *)DELETEHT ;
2838 }
2839
2840 /*******************************************************************************
2841 * function addit, create a integer table *
2842 *******************************************************************************/
2843 it *addit(length)
2844 unsigned int length ;
2845 {
2846 it *ptit ;
2847 int i ;
2848
2849 if(length <= 0)
2850 length = 10 ;
2851
2852 ptit = (it *)mbkalloc(sizeof(it));
2853 ptit->size = 0;
2854 ptit->length = length;
2855 ptit->data = mbkalloc(length * sizeof(long));
2856 for(i = ptit->size ; i < ptit->length ; i++)
2857 (ptit->data)[i] = (long)EMPTYHT ;
2858
2859 return ptit;
2860 }
2861
2862 /*******************************************************************************
2863 * function delit, delete a integer table *
2864 *******************************************************************************/
2865 void delit(table)
2866 it *table ;
2867 {
2868 if (table->data != NULL) mbkfree(table->data);
2869 mbkfree(table);
2870 }
2871
2872 /*******************************************************************************
2873 * function addititem, add an element in a interger table *
2874 *******************************************************************************/
2875 int addititem(table,data)
2876 it *table;
2877 long data ;
2878 {
2879 int i ;
2880
2881 if(table->size == table->length)
2882 {
2883 table->length = table->length * 2 ;
2884 table->data = mbkrealloc(table->data,table->length * sizeof(long));
2885 for(i = table->size ; i < table->length ; i++)
2886 (table->data)[i] = (long)EMPTYHT ;
2887 }
2888 (table->data)[(table->size)++] = data;
2889 return(table->size - 1) ;
2890 }
2891
2892 /*******************************************************************************
2893 * function setititem, set an element in a interger table *
2894 *******************************************************************************/
2895 void setititem(table,item,data)
2896 it *table;
2897 int item ;
2898 long data ;
2899 {
2900 int i ;
2901
2902 if(item >= table->length)
2903 {
2904 table->size = table->length ;
2905 table->length = item * 2 ;
2906 table->data = mbkrealloc(table->data,table->length * sizeof(long));
2907 for(i = table->size ; i < table->length ; i++)
2908 (table->data)[i] = (long)EMPTYHT ;
2909 table->size = item + 1 ;
2910 }
2911 (table->data)[item] = data;
2912 }
2913
2914 /*******************************************************************************
2915 * function getititem, add an element in a interger table *
2916 *******************************************************************************/
2917 long getititem(table,item)
2918 it *table;
2919 int item ;
2920 {
2921 if(item >= table->length)
2922 return((long)EMPTYHT) ;
2923 else
2924 return((table->data)[item]) ;
2925 }
2926
2927 /*******************************************************************************
2928 * function delititem, del an element in a interger table *
2929 *******************************************************************************/
2930 void delititem(table,item)
2931 it *table;
2932 int item ;
2933 {
2934 if(item >= table->length)
2935 return ;
2936 else
2937 (table->data)[item] = (long)DELETEHT ;
2938 }
2939
2940 /*******************************************************************************
2941 * function adddt, create a integer table *
2942 *******************************************************************************/
2943 dt *adddt(length)
2944 unsigned int length ;
2945 {
2946 dt *ptdt ;
2947 int i ;
2948
2949 if(length <= 0)
2950 length = 10 ;
2951
2952 ptdt = (dt *)mbkalloc(sizeof(dt));
2953 ptdt->size = 0;
2954 ptdt->length = length;
2955 ptdt->data = (double *)mbkalloc(length * sizeof(double));
2956 for(i = ptdt->size ; i < ptdt->length ; i++)
2957 (ptdt->data)[i] = (double)EMPTYHT ;
2958
2959 return ptdt;
2960 }
2961
2962 /*******************************************************************************
2963 * function deldt, delete a integer table *
2964 *******************************************************************************/
2965 void deldt(table)
2966 dt *table ;
2967 {
2968 if (table->data != NULL) mbkfree(table->data);
2969 mbkfree(table);
2970 }
2971
2972 /*******************************************************************************
2973 * function adddtitem, add an element in a interger table *
2974 *******************************************************************************/
2975 int adddtitem(table,data)
2976 dt *table;
2977 double data ;
2978 {
2979 int i ;
2980
2981 if(table->size == table->length)
2982 {
2983 table->length = table->length * 2 ;
2984 table->data = mbkrealloc(table->data,table->length * sizeof(double));
2985 for(i = table->size ; i < table->length ; i++)
2986 (table->data)[i] = (double)EMPTYHT ;
2987 }
2988 (table->data)[(table->size)++] = data;
2989 return(table->size - 1) ;
2990 }
2991
2992 /*******************************************************************************
2993 * function setdtitem, set an element in a interger table *
2994 *******************************************************************************/
2995 void setdtitem(table,item,data)
2996 dt *table;
2997 int item ;
2998 double data ;
2999 {
3000 int i ;
3001
3002 if(item >= table->length)
3003 {
3004 table->size = table->length ;
3005 table->length = item * 2 ;
3006 table->data = mbkrealloc(table->data,table->length * sizeof(double));
3007 for(i = table->size ; i < table->length ; i++)
3008 (table->data)[i] = (double)EMPTYHT ;
3009 table->size = item + 1 ;
3010 }
3011 (table->data)[item] = data;
3012 }
3013
3014 /*******************************************************************************
3015 * function getdtitem, add an element in a interger table *
3016 *******************************************************************************/
3017 double getdtitem(table,item)
3018 dt *table;
3019 int item ;
3020 {
3021 if(item >= table->length)
3022 return((double)EMPTYHT) ;
3023 else
3024 return((table->data)[item]) ;
3025 }
3026
3027 /*******************************************************************************
3028 * function deldtitem, del an element in a interger table *
3029 *******************************************************************************/
3030 void deldtitem(table,item)
3031 dt *table;
3032 int item ;
3033 {
3034 if(item >= table->length)
3035 return ;
3036 else
3037 (table->data)[item] = (double)DELETEHT ;
3038 }
3039
3040 /*******************************************************************************
3041 * All that needed for a cute banner, by Frederic Petrot *
3042 * Used to be a standalone library *
3043 *******************************************************************************/
3044 #include <time.h>
3045 #define WINDOW_SIZE 81
3046 #define LINES 15
3047 #define ASCENT 13
3048 static char screen[LINES][WINDOW_SIZE];
3049
3050 static int indx(c)
3051 char c;
3052 {
3053 return c >= '0' && c <= '9' ? (int)c - '0'
3054 : isupper((int)c) ? (int)10 + c - 'A'
3055 : islower((int)c) ? (int)11 + 'Z' - 'A' + c - 'a'
3056 : -1;
3057 }
3058
3059 static void banner(s, police, nl)
3060 char *s;
3061 char *police[][62];
3062 int nl;
3063 {
3064 int i, j, k, l, m;
3065 char *line;
3066
3067 /* rince off :
3068 the buffer is filled with nul characteres. */
3069 for (j = 0; j < nl; j++)
3070 for (i = 0; i < WINDOW_SIZE; i++)
3071 screen[j][i] = '\0';
3072 /* first :
3073 filling the buffer with direct table output. */
3074 while (*s) {
3075 for (i = 0; i < nl; i++) {
3076 if ((j = indx(*s)) == -1) {
3077 fprintf(stderr,
3078 "alliancebanner: Error: Character out of [0-9A-Za-z] range\n");
3079 EXIT(1);
3080 }
3081 line = police[j][i];
3082 if (strlen(line) + strlen(screen[i]) >= WINDOW_SIZE) {
3083 fprintf(stderr,
3084 "alliancebanner: Error: Resulting size bigger than %d columns not allowed\n",
3085 WINDOW_SIZE - 1);
3086 EXIT(1);
3087 }
3088 strcat(screen[i], line);
3089 if (*(s + 1) != '\0')
3090 strcat(screen[i], " ");
3091 }
3092 s++;
3093 }
3094 for (m = l = -1, j = 0; j < nl; j++)
3095 for (i = 0; i < WINDOW_SIZE; i++)
3096 if (screen[j][i] == '@') {
3097 if (m == -1)
3098 m = j;
3099 l = j;
3100 break;
3101 }
3102 k = strlen(screen[0]);
3103 /* banner :
3104 output on stdout. */
3105 putc('\n', stdout);
3106 for (j = m; j <= l; j++) {
3107 for (i = 0; i < (WINDOW_SIZE - k) / 2; i++)
3108 putc(' ', stdout);
3109 for (i = 0; i < k; i++)
3110 putc(screen[j][i], stdout);
3111 putc('\n', stdout);
3112 }
3113 }
3114
3115 static void cartouche(tool, tv, comment, date, av, authors, contrib)
3116 char *tool, *tv, *comment, *date, *av, *authors, *contrib;
3117 {
3118 int i, j, k, l;
3119 static char *msg[6] = {
3120 "%s",
3121 "Alliance CAD System %s,\"%s %s",
3122 "Copyright (c) %s-%d,\"ASIM/LIP6/UPMC",
3123 "Author(s):\"%s",
3124 "Contributor(s):\"%s",
3125 "E-mail support:\"alliance-support@asim.lip6.fr"
3126 };
3127 int msgl[6];
3128 char *str;
3129 time_t timer;
3130 char day[4], month[4];
3131 int year, nday, hour, minute, second;
3132
3133 (void)time(&timer);
3134 (void)sscanf(ctime(&timer), "%s %s %d %d:%d:%d %d",
3135 day, month, &nday, &hour, &minute, &second, &year);
3136 /* rince off :
3137 the buffer is filled with nul characteres. */
3138 for (j = 0; j < 12; j++)
3139 for (i = 0; i < WINDOW_SIZE; i++)
3140 screen[j][i] = '\0';
3141 i = strlen(tool);
3142 str = mbkstrdup(tool);
3143 for (k = 0; k < i; k++)
3144 str[k] = isupper((int)tool[k]) ? tolower(tool[k]) : tool[k];
3145 sprintf(screen[0], msg[0], comment);
3146 sprintf(screen[1], msg[1], av, str, tv);
3147 mbkfree(str);
3148 sprintf(screen[2], msg[2], date, year);
3149 if (authors != (char *)0 )
3150 sprintf(screen[3], msg[3],authors);
3151 else
3152 screen[3][0] = '\0';
3153 if (contrib != (char *)0 )
3154 sprintf(screen[4], msg[4],contrib);
3155 else
3156 screen[4][0] = '\0';
3157
3158 strcat(screen[5], msg[5]);
3159
3160 for (i = 1; i < 6; i++) {
3161 msgl[i] = strlen(screen[i]);
3162 j = j < msgl[i] ? msgl[i] : j;
3163 }
3164 for (i = 1; i < 6; i++)
3165 for (l = 0, k = 0; k < WINDOW_SIZE; k++) {
3166 if (screen[i][k] == '\0') {
3167 screen[i + 6][k + l] = '\0';
3168 break;
3169 }
3170 if (screen[i][k] == '"') { /* only once per line */
3171 for (; l <= j - msgl[i]; l++)
3172 screen[i + 6][k + l] = ' ';
3173 continue;
3174 }
3175 screen[i + 6][k + l] = screen[i][k];
3176 }
3177 /* cartouche :
3178 output on stdout. */
3179 i = strlen(comment);
3180 putc('\n', stdout);
3181 for (k = 0; k < (WINDOW_SIZE - i) / 2; k++)
3182 putc(' ', stdout);
3183 puts(screen[0]);
3184 putc('\n', stdout);
3185 for (i = 1; i < 6; i++) {
3186 if (screen[i][0]=='\0') continue;
3187 for (k = 0; k < (WINDOW_SIZE - j) / 2; k++)
3188 putc(' ', stdout);
3189 for (k = 0; k <= j; k++)
3190 if (screen[i + 6][k] != 0) /* not so nice, but */
3191 putc(screen[i + 6][k], stdout);
3192 putc('\n', stdout);
3193 }
3194 putc('\n', stdout);
3195 }
3196
3197 void alliancebanner_with_contrib( tool, tv, comment, date, av, authors, contrib)
3198 char *tool, *tv, *comment, *date, *av, *authors, *contrib;
3199 {
3200 banner(tool, Unknown_Bold_Normal_14, 15);
3201 cartouche(tool, tv, comment, date, av, authors,contrib);
3202 }
3203
3204 void alliancebanner_with_authors( tool, tv, comment, date, av, authors)
3205 char *tool, *tv, *comment, *date, *av, *authors;
3206 {
3207 alliancebanner_with_contrib( tool, tv, comment, date, av, authors, NULL );
3208 }
3209
3210
3211 void alliancebanner(tool, tv, comment, date, av)
3212 char *tool, *tv, *comment, *date, *av;
3213 {
3214 alliancebanner_with_contrib( tool, tv, comment, date, av, NULL, NULL );
3215 }
3216
3217 /******************
3218 * Contributed to by Ludovic Jacomme
3219 **************************/
3220 ptype_list *HEAD_MBKDEBUG = NULL;
3221 char MBK_DEBUG_ON = 0;
3222
3223 static void trapdebug()
3224 {
3225 ptype_list *ScanDebug;
3226
3227 for ( ScanDebug = HEAD_MBKDEBUG;
3228 ScanDebug != (ptype_list *)NULL;
3229 ScanDebug = ScanDebug->NEXT )
3230 {
3231 fprintf( stdout, "mbkdebug: file %s line %ld\n",
3232 (char *)ScanDebug->DATA, ScanDebug->TYPE );
3233 }
3234
3235 fflush( stdout );
3236
3237 signal( SIGQUIT, trapdebug );
3238 signal( SIGSEGV, SIG_DFL );
3239 signal( SIGBUS , SIG_DFL );
3240 signal( SIGILL , SIG_DFL );
3241 }
3242
3243 void mbkdebug()
3244 {
3245 signal( SIGSEGV, trapdebug );
3246 signal( SIGBUS, trapdebug );
3247 signal( SIGILL, trapdebug );
3248 signal( SIGQUIT, trapdebug );
3249
3250 MBK_DEBUG_ON = 1;
3251 }
3252
3253 /*
3254 ** Added by Ludovic Jacomme (The slave)
3255 ** in order to "trap" exit with Graal/Dreal etc ...
3256 */
3257
3258 /*
3259 void mbkexit( ExitValue )
3260
3261 int ExitValue;
3262 {
3263 if(MBK_EXIT_KILL == 'Y') kill( getpid(), SIGTERM ) ;
3264 else if ( MBK_EXIT_FUNCTION != NULL )
3265 {
3266 (*MBK_EXIT_FUNCTION)( ExitValue );
3267 }
3268 else exit(ExitValue) ;
3269
3270 while(1);
3271 }*/
3272
3273
3274 /* To compile with gcc under SunOS */
3275
3276 #ifdef SunOS
3277
3278 void *dlopen(path, mode)
3279 char *path; int mode;
3280 {
3281 }
3282
3283 void *dlsym(handle, symbol)
3284 void *handle; char *symbol;
3285 {
3286 }
3287
3288 char *dlerror()
3289 {
3290 }
3291
3292 int dlclose(handle)
3293 void *handle;
3294 {
3295 }
3296
3297 #endif
3298
3299 void CreateHeap(int size, int granularity, HeapAlloc *myheap)
3300 {
3301 if (size<(signed)sizeof(void *)) size=sizeof(void *);
3302 myheap->size=size;
3303 myheap->blocks_to_free=NULL;
3304 if (granularity==0) granularity=BUFSIZE;
3305 myheap->granularity=granularity;
3306 myheap->HEAD=NULL;
3307 #ifdef ENABLE_STATS
3308 myheap->__SIZE__=0;
3309 #endif
3310 }
3311
3312 void DeleteHeap(HeapAlloc *myheap)
3313 {
3314 #ifndef NOHEAPALLOCFORHEAP
3315 chain_list *cl;
3316 for (cl=myheap->blocks_to_free; cl!=NULL; cl=cl->NEXT)
3317 mbkfree(cl->DATA);
3318 freechain(myheap->blocks_to_free);
3319 #endif
3320 }
3321
3322 void *AddHeapItem(HeapAlloc *myheap)
3323 {
3324 #ifdef NOHEAPALLOCFORHEAP
3325 return mbkalloc(myheap->size);
3326 #else
3327 char *pt;
3328 if (myheap->HEAD == NULL) {
3329 int i;
3330 pt = (char *)mbkalloc(myheap->granularity*myheap->size);
3331 myheap->blocks_to_free=addchain(myheap->blocks_to_free, pt);
3332 myheap->HEAD = pt;
3333 for (i = 1; i < myheap->granularity; i++)
3334 {
3335 *(void **)pt = pt+myheap->size;
3336 pt+=myheap->size;
3337 }
3338 // printf("<%d>",(pt-(char *)myheap->HEAD)/myheap->size);
3339 *(void **)pt = NULL;
3340 #ifdef ENABLE_STATS
3341 myheap->__SIZE__+=sizeof(chain_list *)+myheap->granularity*myheap->size;
3342 #endif
3343 }
3344
3345 pt = myheap->HEAD;
3346 myheap->HEAD = *(void **)myheap->HEAD;
3347 return pt;
3348 #endif
3349 }
3350
3351 void DelHeapItem(HeapAlloc *myheap, void *item)
3352 {
3353 #ifdef NOHEAPALLOCFORHEAP
3354 mbkfree(item);
3355 #else
3356 *(void **)item=myheap->HEAD;
3357 myheap->HEAD=item;
3358 #endif
3359 }
3360
3361 size_t getsizeofHeapAlloc( HeapAlloc *heap )
3362 {
3363 size_t size = 0 ;
3364 chain_list *chain ;
3365 if( !heap )
3366 return 0 ;
3367 for( chain = heap->blocks_to_free ; chain ; chain = chain->NEXT )
3368 size = size + heap->size * heap->granularity + sizeof( chain_list );
3369 return size ;
3370 }
3371
3372 typedef struct
3373 {
3374 char *key;
3375 void *data;
3376 } s2sort;
3377
3378 int s2sort_sortfunc(const void *a0, const void *b0)
3379 {
3380 s2sort *a=(s2sort *)a0, *b=(s2sort *)b0;
3381 return strcmp(b->key, a->key);
3382 }
3383
3384 chain_list *GetAllHTElems_sub(ht *pTable, int sort)
3385 {
3386 chain_list *cl=NULL, *ch=NULL;
3387 int i, cnt;
3388 htitem *pEl;
3389 s2sort *s2c;
3390
3391 if( V_BOOL_TAB[__AVT_USEHT_V2].VALUE )
3392 return GetAllHTElems_sub_v2( (ht_v2*)pTable, sort );
3393
3394 if (!pTable) return cl;
3395
3396 pEl = pTable->pElem;
3397 for (i = 0, cnt=0; i < pTable->length; i++) {
3398 if (pEl->value != EMPTYHT && pEl->value != DELETEHT) {
3399 cl=addchain(cl, (void *)pEl->value);
3400 if (sort) ch=addchain(ch, (void *)pEl->key);
3401 cnt++;
3402 }
3403 pEl++;
3404 }
3405
3406 if (!sort) return cl;
3407
3408 s2c=(s2sort *)mbkalloc(sizeof(s2sort)*cnt);
3409 for (i=0; i<cnt; i++, cl=delchain(cl, cl), ch=delchain(ch,ch))
3410 {
3411 s2c[i].key=(char *)ch->DATA;
3412 s2c[i].data=cl->DATA;
3413 }
3414
3415 qsort(s2c, cnt, sizeof(s2sort), s2sort_sortfunc);
3416
3417 for (i=0, cl=NULL; i<cnt; i++)
3418 cl=addchain(cl, s2c[i].data);
3419
3420 mbkfree(s2c);
3421
3422 return cl;
3423 }
3424
3425 chain_list *GetAllHTElems_sub_v2( ht_v2 *h, int sort)
3426 {
3427 chain_list *cl=NULL, *ch=NULL;
3428 int i, cnt;
3429 htitem_v2 *item;
3430 s2sort *s2c;
3431
3432
3433 if (!h) return cl;
3434
3435 cnt=0;
3436 for( i=0 ; i<h->size ; i++ ) {
3437 for( item = h->ITEM_HASHTABLE[i] ; item ; item = item->next ) {
3438 cl = addchain( cl, (void*)item->value );
3439 if( sort ) ch=addchain( ch, (void*)item->key );
3440 cnt++;
3441 }
3442 }
3443
3444 if (!sort) return cl;
3445
3446 s2c=(s2sort *)mbkalloc(sizeof(s2sort)*cnt);
3447 for (i=0; i<cnt; i++, cl=delchain(cl, cl), ch=delchain(ch,ch))
3448 {
3449 s2c[i].key=(char *)ch->DATA;
3450 s2c[i].data=cl->DATA;
3451 }
3452
3453 qsort(s2c, cnt, sizeof(s2sort), s2sort_sortfunc);
3454
3455 for (i=0, cl=NULL; i<cnt; i++)
3456 cl=addchain(cl, s2c[i].data);
3457
3458 mbkfree(s2c);
3459
3460 return cl;
3461 }
3462
3463 chain_list *GetAllHTElems(ht *pTable)
3464 {
3465 return GetAllHTElems_sub(pTable, 0);
3466 }
3467
3468 chain_list *GetAllHTKeys(ht *pTable)
3469 {
3470 chain_list *cl=NULL;
3471 int i;
3472 htitem *pEl;
3473
3474 if( V_BOOL_TAB[__AVT_USEHT_V2].VALUE )
3475 return GetAllHTKeys_v2( (ht_v2*)pTable );
3476
3477 if (!pTable) return cl;
3478
3479 pEl = pTable->pElem;
3480 for (i = 0; i < pTable->length; i++) {
3481 if (pEl->value != EMPTYHT && pEl->value != DELETEHT) {
3482 cl=addchain(cl, (void *)pEl->key);
3483 }
3484 pEl++;
3485 }
3486 return cl;
3487 }
3488
3489 chain_list* GetAllHTKeys_v2( ht_v2 *h )
3490 {
3491 int i;
3492 htitem_v2 *item ;
3493 chain_list *head ;
3494
3495 head = NULL ;
3496 for( i=0 ; i<h->size ; i++ )
3497 for( item = h->ITEM_HASHTABLE[i] ; item ; item = item->next )
3498 head = addchain( head, item->key );
3499 return head ;
3500 }
3501
3502 ht_v2 *addht_v2(long len)
3503 {
3504 int i;
3505 ht_v2 *h;
3506 h=(ht_v2 *)mbkalloc(sizeof(ht_v2));
3507 if (len!=0)
3508 {
3509 h->size=(len+127)/128;
3510 h->primes_index=-1;
3511 }
3512 else
3513 {
3514 h->primes_index=0;
3515 h->size=namealloc_primes[0];
3516 }
3517
3518 h->ITEM_HASHTABLE=(htitem_v2 **)mbkalloc(sizeof(htitem_v2 *)*h->size);
3519 for (i=0; i<h->size; i++) h->ITEM_HASHTABLE[i]=NULL;
3520 CreateHeap(sizeof(htitem_v2), 0, &h->ha);
3521 h->rehashlimit=128;
3522 return h;
3523 }
3524
3525 void delht_v2(ht_v2 *h)
3526 {
3527 DeleteHeap(&h->ha);
3528 mbkfree(h->ITEM_HASHTABLE);
3529 mbkfree(h);
3530 }
3531
3532 static void ht_v2_rehash(ht_v2 *h)
3533 {
3534 htitem_v2 **nn, *cl, *next;
3535 int i, index;
3536 unsigned int prm;
3537
3538 if (h->primes_index==-1)
3539 prm=0;
3540 else
3541 prm=h->primes_index+1;
3542 while (prm<sizeof(namealloc_primes)/sizeof(*namealloc_primes) && namealloc_primes[prm]<h->size) prm++;
3543 h->primes_index=prm;
3544 if (prm>=sizeof(namealloc_primes)/sizeof(*namealloc_primes))
3545 {
3546 return;
3547 }
3548
3549 // fprintf(stdout,".rehashing ht: %d -> %d...",h->size,namealloc_primes[prm]); fflush(stdout);
3550
3551 nn=(htitem_v2 **)mbkalloc(sizeof(htitem_v2 *)* namealloc_primes[prm]);
3552 for (i=0;i<namealloc_primes[prm];i++)
3553 nn[i]=NULL;
3554
3555 for (i=0;i<h->size;i++)
3556 {
3557 for (cl=h->ITEM_HASHTABLE[i]; cl!=NULL; cl=next)
3558 {
3559 next=cl->next;
3560 index=hash(cl->key) % namealloc_primes[prm];
3561 cl->next=nn[index];
3562 nn[index]=cl;
3563 }
3564 }
3565 mbkfree(h->ITEM_HASHTABLE);
3566 h->ITEM_HASHTABLE=nn;
3567 h->size=namealloc_primes[prm];
3568 // fprintf(stdout,"done\n");
3569 }
3570
3571
3572 long gethtitem_v2(ht_v2 *h, void *key)
3573 {
3574 int index;
3575 htitem_v2 *head;
3576
3577 index=hash(key) % h->size;
3578 head=h->ITEM_HASHTABLE[index];
3579 while (head!=NULL && head->key!=key) head=head->next;
3580
3581 if (head==NULL) return EMPTYHT;
3582 return head->value;
3583 }
3584
3585 ht_v2 *dupht_v2( ht_v2 *orig )
3586 {
3587 ht_v2 *dup;
3588 void *nextkey ;
3589 long nextitem ;
3590
3591 dup = addht_v2( orig->size );
3592
3593 scanhtkey_v2( orig, 1, &nextkey, &nextitem );
3594 while( nextitem != EMPTYHT ) {
3595 addhtitem_v2( dup, nextkey, nextitem );
3596 scanhtkey_v2( orig, 0, &nextkey, &nextitem );
3597 }
3598
3599 return dup ;
3600 }
3601
3602 void scanhtkey_v2( ht_v2 *h, int first, void **nextkey, long *nextitem )
3603 {
3604 int i ;
3605 htitem_v2 *item ;
3606
3607 i = 0;
3608 item = NULL ;
3609
3610 if( !first ) {
3611 i = hash( *nextkey ) % h->size ;
3612
3613 for( item = h->ITEM_HASHTABLE[i] ; item->key != *nextkey ; item = item->next ) ;
3614 item = item->next ;
3615
3616 if( item ) {
3617 *nextkey = item->key ;
3618 *nextitem = item->value ;
3619 }
3620 else
3621 i++ ;
3622 }
3623
3624 if( !item ) {
3625
3626 for( i=i ; i<h->size && !h->ITEM_HASHTABLE[i] ; i++ );
3627
3628 if( i==h->size ) {
3629 *nextkey = NULL ;
3630 *nextitem = EMPTYHT ;
3631 }
3632 else {
3633 *nextkey = h->ITEM_HASHTABLE[i]->key ;
3634 *nextitem = h->ITEM_HASHTABLE[i]->value ;
3635 }
3636 }
3637 }
3638
3639 void set_ht_v2_rehashlimit(ht_v2 *h, int value)
3640 {
3641 h->rehashlimit=value;
3642 }
3643
3644 long sethtitem_v2(ht_v2 *h, void *key, long value)
3645 {
3646 return addhtitem_v2( h, key, value );
3647 }
3648
3649 long controlled_addhtitem_v2(ht_v2 *h, void *key, long (*func)(int newone, long old_value, void *user_data), void *user_data )
3650 {
3651 int index, depth=0;
3652 htitem_v2 *hi ;
3653 long value ;
3654
3655 index=hash(key) % h->size;
3656 hi=h->ITEM_HASHTABLE[index];
3657 while(hi !=NULL && hi->key!=key) { hi=hi->next; depth++; }
3658
3659 if (hi==NULL)
3660 {
3661 hi=(htitem_v2 *)AddHeapItem(&h->ha);
3662 hi->next=h->ITEM_HASHTABLE[index];
3663 h->ITEM_HASHTABLE[index]=hi;
3664 hi->key=key;
3665 hi->value=func( 1, EMPTYHT, user_data );
3666 }
3667 else {
3668 hi->value=func( 0, hi->value, user_data );
3669 }
3670
3671 value = hi->value ;
3672
3673 if (depth>h->rehashlimit && (h->primes_index==-1 || (unsigned)h->primes_index<(sizeof(namealloc_primes)/sizeof(*namealloc_primes))-1))
3674 ht_v2_rehash(h);
3675
3676 return value ;
3677 }
3678
3679 long addhtitem_v2(ht_v2 *h, void *key, long value)
3680 {
3681 int index, depth=0;
3682 htitem_v2 *hi, *head;
3683 long replaced ;
3684
3685 index=hash(key) % h->size;
3686 head=h->ITEM_HASHTABLE[index];
3687 while (head!=NULL && head->key!=key) { head=head->next; depth++; }
3688
3689 if (head==NULL)
3690 {
3691 hi=(htitem_v2 *)AddHeapItem(&h->ha);
3692 hi->next=h->ITEM_HASHTABLE[index];
3693 h->ITEM_HASHTABLE[index]=hi;
3694 hi->key=key;
3695 hi->value=value;
3696 replaced=0;
3697 }
3698 else {
3699 head->value=value;
3700 replaced=1;
3701 }
3702
3703 if (depth>h->rehashlimit && (h->primes_index==-1 || (unsigned)h->primes_index<(sizeof(namealloc_primes)/sizeof(*namealloc_primes))-1))
3704 ht_v2_rehash(h);
3705
3706 return replaced ;
3707 }
3708
3709 long delhtitem_v2(ht_v2 *h, void *key)
3710 {
3711 int index;
3712 long value;
3713 htitem_v2 *head, *prev=NULL;
3714
3715 index=hash(key) % h->size;
3716 head=h->ITEM_HASHTABLE[index];
3717 while (head!=NULL && head->key!=key) prev=head, head=head->next;
3718
3719 if (head==NULL) return EMPTYHT;
3720
3721 if (prev==NULL)
3722 h->ITEM_HASHTABLE[index]=head->next;
3723 else
3724 prev->next=head->next;
3725
3726 value=head->value;
3727 DelHeapItem(&h->ha, head);
3728 return value;
3729 }
3730
3731 size_t getsizeofht_v2( ht_v2 *ht )
3732 {
3733 size_t size =0 ;
3734 if( !ht )
3735 return 0 ;
3736 size = sizeof( ht_v2 ) ;
3737 size = size + sizeof( htitem_v2* ) * ht->size ;
3738 size = size + getsizeofHeapAlloc( & ht->ha );
3739 return size ;
3740 }
3741
3742 chain_list *GetAllHTElems_v2(ht_v2 *h)
3743 {
3744 chain_list *cl=NULL;
3745 int i;
3746 htitem_v2 *he;
3747
3748 for (i=0;i<h->size;i++)
3749 for (he=h->ITEM_HASHTABLE[i];he!=NULL; he=he->next)
3750 cl=addchain(cl, (void *)he->value);
3751
3752 return cl;
3753 }
3754
3755 void ht_v2Stat(ht_v2 *h)
3756 {
3757 int i, nb, max=0,moy=0, nb0=0;
3758 htitem_v2 *cl;
3759
3760 if (h==NULL) return;
3761 printf("--- ht_v2 stats:\n");
3762 for (i=0, nb=0;i<h->size;i++) if (h->ITEM_HASHTABLE[i]==NULL) nb++;
3763 printf(" %d/%d entries unused\n",nb,h->size);
3764 for (i=0, max=0;i<h->size;i++)
3765 if (h->ITEM_HASHTABLE[i]!=NULL)
3766 {
3767 nb0++;
3768 for (nb=0, cl=h->ITEM_HASHTABLE[i];cl!=NULL; cl=cl->next, nb++) ;
3769 if (nb>max) max=nb;
3770 moy+=nb;
3771 }
3772 printf(" chain length: mean=%.1f max=%d\n",(float)moy/(float)nb0,max);
3773 }
3774
3775 #ifdef MALLOC_HISTOGRAM
3776
3777 #undef mbkalloc
3778 #undef mbkfree
3779 #undef mbkrealloc
3780 #undef malloc
3781 #undef free
3782 #undef realloc
3783
3784 void malloc_hook_error()
3785 {
3786
3787 }
3788
3789
3790 void *my_malloc_hook(char *file, int line, size_t size)
3791 {
3792 char *result;
3793 long val;
3794 if (!MALLOC_HISTO_mutex) return mbkalloc (size);
3795 MALLOC_HISTO_mutex=0;
3796 result = malloc (size+sizeof(long)*2);
3797
3798 if (result==NULL)
3799 {
3800 (void)fflush(stdout);
3801 (void)fprintf(stderr,"*** mbk error ***\n");
3802 (void)fprintf(stderr,"fatal mbkalloc error : not enough memory\n");
3803 fprintf(stderr,"when trying to allocate %ld bytes, top= %ldKb\n",size,mbkprocessmemoryusage()/1024);
3804 EXIT(1);
3805 }
3806 MALLOC_HOOK_CONSO+=sizeof(long)*2;
3807 MALLOC_HOOK_TOTAL_MEM+=size;
3808 MALLOC_HOOK_TOTAL_MEM_FROM_START+=size;
3809 MALLOC_HOOK_TOTAL_CALL++;
3810 if ((val=gethtitem_v2(MALLOC_HISTO, (void *)size))==EMPTYHT) val=0;
3811 val++;
3812 addhtitem_v2(MALLOC_HISTO, (void *)size, val);
3813
3814 // printf ("malloc (%ld) returns %p\n", (unsigned long)size, result);
3815 *(long *)result=size;
3816 *(long *)(result+sizeof(long))=0x12345678;
3817 MALLOC_HISTO_mutex=1;
3818 return result+sizeof(long)*2;
3819 }
3820
3821 void my_free_hook(void *block)
3822 {
3823 char *result=block;
3824 unsigned long size;
3825 long val;
3826 if (!MALLOC_HISTO_mutex) { mbkfree(block); return ;}
3827 if (block==NULL) return;
3828 result-=sizeof(long)*2;
3829 if (*(long *)(result+sizeof(long))!=0x12345678)
3830 {
3831 MALLOC_HOOK_ERRORS++;
3832 malloc_hook_error();
3833 free(block);
3834 printf("ERR-FR\n");
3835 return ;
3836 }
3837 else
3838 *(long *)(result+sizeof(long))=0;
3839
3840 size=*(long *)result;
3841 MALLOC_HOOK_CONSO-=sizeof(long)*2;
3842 MALLOC_HOOK_TOTAL_MEM-=size;
3843 MALLOC_HOOK_TOTAL_MEM_FROM_START-=size;
3844 FREE_HOOK_TOTAL_CALL++;
3845
3846 MALLOC_HISTO_mutex=0;
3847 if ((val=gethtitem_v2(MALLOC_HISTO, (void *)size))==EMPTYHT) MALLOC_HOOK_ERRORS++;
3848 else addhtitem_v2(MALLOC_HISTO, (void *)size, val-1);
3849 MALLOC_HISTO_mutex=1;
3850 free (result);
3851 // printf ("free (%ld)\n", (unsigned long)size, result);
3852 }
3853
3854 void *my_realloc_hook(char *file, int line, void *block, size_t size)
3855 {
3856 char *result=block;
3857 unsigned long size0;
3858 long val;
3859 if (!MALLOC_HISTO_mutex) return mbkrealloc(block, size);
3860 result-=sizeof(long)*2;
3861 if (*(long *)(result+sizeof(long))!=0x12345678)
3862 {
3863 MALLOC_HOOK_ERRORS++;
3864 printf("ERR-RE\n");
3865 malloc_hook_error();
3866 return realloc(block, size);
3867 }
3868 MALLOC_HISTO_mutex=0;
3869 size0=*(long *)result;
3870 MALLOC_HOOK_TOTAL_MEM-=size0;
3871 MALLOC_HOOK_TOTAL_MEM_FROM_START-=size0;
3872 REALLOC_HOOK_TOTAL_CALL++;
3873
3874 if ((val=gethtitem_v2(MALLOC_HISTO, (void *)size0))==EMPTYHT) MALLOC_HOOK_ERRORS++;
3875 else addhtitem_v2(MALLOC_HISTO, (void *)size0, val-1);
3876
3877 result=realloc(result, size+sizeof(long)*2);
3878 if (result==NULL)
3879 {
3880 (void)fflush(stdout);
3881 (void)fprintf(stderr,"*** mbk error ***\n");
3882 (void)fprintf(stderr,"fatal mbkalloc error : not enough memory\n");
3883 fprintf(stderr,"when trying to allocate %ld bytes, top= %ldKb\n",size,mbkprocessmemoryusage()/1024);
3884 EXIT(1);
3885 }
3886 MALLOC_HOOK_TOTAL_MEM+=size;
3887 MALLOC_HOOK_TOTAL_MEM_FROM_START+=size;
3888 if ((val=gethtitem_v2(MALLOC_HISTO, (void *)size))==EMPTYHT) val=0;
3889 val++;
3890 addhtitem_v2(MALLOC_HISTO, (void *)size, val);
3891
3892 *(long *)result=size;
3893 *(long *)(result+sizeof(long))=0x12345678;
3894 MALLOC_HISTO_mutex=1;
3895 return result+sizeof(long)*2;
3896 }
3897
3898
3899 void setup_malloc_hook()
3900 {
3901 if (MALLOC_HISTO_mutex) return;
3902 MALLOC_HISTO=addht_v2(19);
3903 MALLOC_HISTO_mutex=1;
3904 }
3905
3906 void reset_malloc_hook()
3907 {
3908 if (!MALLOC_HISTO_mutex) return;
3909 MALLOC_HISTO_mutex=0;
3910 MALLOC_HOOK_TOTAL_MEM=0, MALLOC_HOOK_TOTAL_CALL=0, MALLOC_HOOK_ERRORS=0, FREE_HOOK_TOTAL_CALL=0, REALLOC_HOOK_TOTAL_CALL=0;
3911 delht_v2(MALLOC_HISTO);
3912 MALLOC_HISTO=addht_v2(190);
3913 MALLOC_HISTO_mutex=1;
3914 }
3915
3916
3917 typedef struct
3918 {
3919 unsigned long size, nb, tot;
3920 } mhtos;
3921 static int mhtos_mode;
3922 int mhtos_sort(const void *a, const void *b)
3923 {
3924 mhtos *a0=(mhtos *)a, *b0=(mhtos *)b;
3925 if (mhtos_mode==0)
3926 {
3927 if (a0->size<b0->size) return -1;
3928 else if (a0->size>b0->size) return 1;
3929 return 0;
3930 }
3931 else
3932 {
3933 if (a0->tot<b0->tot) return -1;
3934 else if (a0->tot>b0->tot) return 1;
3935 return 0;
3936 }
3937 }
3938
3939 void malloc_hook_stats(char *filename, int mode)
3940 {
3941 int i, j, tot;
3942 htitem_v2 *cl;
3943 FILE *f;
3944 mhtos tab[1000];
3945 unsigned long all;
3946
3947 mhtos_mode=mode;
3948
3949 if (!MALLOC_HISTO_mutex) return;
3950
3951 if (strcmp(filename,"stdout")==0) f=stdout;
3952 else f=fopen(filename,"wt");
3953
3954 all=0;
3955 tot=0;
3956 fprintf(f,"--- malloc_hook_stats: REAL TOTAL=%ldk (+%ldk)\n", MALLOC_HOOK_TOTAL_MEM_FROM_START/1024, MALLOC_HOOK_CONSO/1024);
3957 fprintf(f," %10s %10s %10s\n","size","nb","total");
3958 fprintf(f,"--------------------------------------\n");
3959 for (i=0;i<MALLOC_HISTO->size;i++)
3960 for (cl=MALLOC_HISTO->ITEM_HASHTABLE[i];cl!=NULL; cl=cl->next)
3961 if (cl->value!=0)
3962 {
3963 tab[tot].size=(unsigned long)cl->key;
3964 tab[tot].nb=(unsigned long)cl->value;
3965 tab[tot].tot=tab[tot].size*tab[tot].nb;
3966 all+=tab[tot].tot;
3967 tot++;
3968 }
3969
3970 qsort(tab, tot, sizeof(mhtos), mhtos_sort);
3971
3972 for (i=0;i<tot; i++)
3973 fprintf(f," %10ld %10ld %10ldk %3.0f%%\n",tab[i].size,tab[i].nb,tab[i].tot/1024, tab[i].tot*100.0/all);
3974
3975 fprintf(f,"--------------------------------------\n");
3976 fprintf(f," %ld errors, total mem =%ldk, #malloc=%ld, #free=%ld, #realloc=%ld\n",MALLOC_HOOK_ERRORS, MALLOC_HOOK_TOTAL_MEM/1024,MALLOC_HOOK_TOTAL_CALL,FREE_HOOK_TOTAL_CALL,REALLOC_HOOK_TOTAL_CALL);
3977 if (f!=stdout) fclose(f);
3978 }
3979 #endif
3980 static void mbk_remove_1(char *buf)
3981 {
3982 int i, j;
3983 i=0; j=0;
3984 while (buf[i]!='\0')
3985 {
3986 if (buf[i]!=1) buf[j++]=buf[i];
3987 i++;
3988 }
3989 buf[j++]='\0';
3990 }
3991
3992 char *mbk_devect_sub(char *name, char *leftb, char *rightb, char *sepb, char *buf, int testchar(int))
3993 /* arguments :
3994 leftb = string of opening delimiter.
3995 rightb = string of closing delimiter corresponding to leftb.
3996 sepb = string of single character delimiter.
3997 testchar = an optional function to check contents of vecter.
3998
3999 eg : leftb = "([<"
4000 rightb = ")]>"
4001 sebp = "_."
4002 testchar = isdigit()
4003 traitement special des wildcards C commencant par %
4004 */
4005 {
4006 char c;
4007 int l, i, j;
4008 char emptystyring[]="\0";
4009
4010 if( !leftb ) leftb = emptystyring ;
4011 if( !rightb ) rightb = emptystyring ;
4012 if( !sepb ) sepb = emptystyring ;
4013
4014 strcpy(buf, name);
4015 if (!MBK_DEVECT || buf[0]=='\0') return buf;
4016 l=strlen(buf)-1;
4017 c=buf[l];
4018
4019 for (i=0; rightb[i]!='\0' && leftb[i]!='\0' && c!=rightb[i]; i++);
4020 if (buf[0]=='%' && c==']' && (l==0 || buf[l-1]!='\\')) return buf;
4021
4022 if (rightb[i]=='\0' || leftb[i]=='\0') {
4023 if (buf[0]=='%') {l--; buf[l]=1;}
4024 if (testchar) {
4025 for( i=l ; i && testchar((unsigned char)buf[i]) ; i-- );
4026 if( i && i!=l ) {
4027 for(j=0; sepb[j] && sepb[j]!=buf[i]; j++ );
4028 if(sepb[j] && !(buf[0]=='%' && i!=0 && buf[i-1]!='\\')) {
4029 buf[i]=' ';
4030 if (buf[0]=='%') { buf[i-1]=1; mbk_remove_1(buf); }
4031 return buf;
4032 }
4033 }
4034 }
4035 else {
4036 i=l ;
4037 while( i>0 ) {
4038 for( j=0; sepb[j] && sepb[j]!=buf[i] ; j++ );
4039 if( sepb[j] && !(buf[0]=='%' && i!=0 && buf[i-1]!='\\')) {
4040 if( i!=l ) {
4041 buf[i]=' ';
4042 if (buf[0]=='%') { buf[i-1]=1; mbk_remove_1(buf); }
4043 return buf;
4044 }
4045 else
4046 break ;
4047 }
4048 i--;
4049 }
4050 }
4051 }
4052 else {
4053 buf[l]='\0';
4054 if (buf[0]=='%') { l--; buf[l]=1; }
4055 if( testchar ) {
4056 for( j=l-1 ; j && testchar((unsigned char)buf[j] ); j-- );
4057 if( j && buf[j]==leftb[i] && !(buf[0]=='%' && j!=0 && buf[j-1]!='\\')) {
4058 buf[j]=' ';
4059 if (buf[0]=='%') { buf[i-1]=1; mbk_remove_1(buf); }
4060 return buf ;
4061 }
4062 }
4063 else {
4064 while (l>0 && buf[l]!=leftb[i]) l--;
4065 if (l && !(buf[0]=='%' && buf[l-1]!='\\')) {
4066 buf[l]=' ';
4067 if (buf[0]=='%') { buf[l-1]=1; mbk_remove_1(buf); }
4068 return buf ;
4069 }
4070 }
4071 }
4072 return name;
4073 }
4074
4075 char *mbk_decodevector(char *name)
4076 {
4077 char res[4096];
4078 return namealloc(mbk_devect_sub(name, MBK_VECTOR_OPEN, MBK_VECTOR_CLOSE, MBK_VECTOR_SINGLE, res, isdigit));
4079 }
4080
4081 char *mbk_decodeanyvector(char *name)
4082 {
4083 char res[4096];
4084 return namealloc(mbk_devect_sub(name, MBK_VECTOR_OPEN, MBK_VECTOR_CLOSE, MBK_VECTOR_SINGLE, res, NULL));
4085 }
4086
4087 char *mbk_devect(char *name, char *leftb, char *rightb)
4088 {
4089 char res[4096];
4090 return namealloc(mbk_devect_sub(name, leftb, rightb, NULL, res, NULL));
4091 }
4092
4093 char *mbk_vect_sub(char *name, char leftb, char rightb, char *buf)
4094 {
4095 char *c;
4096 int i, j, done=0;
4097
4098 i=j=0;
4099 while (name[i]!='\0')
4100 {
4101 if (name[i]==' ' && !done)
4102 {
4103 done=1;
4104 if (name[0]=='%' && leftb=='[') buf[j++]='\\';
4105 buf[j++]=leftb;
4106 }
4107 else
4108 buf[j++]=name[i];
4109 i++;
4110 }
4111 if (done)
4112 {
4113 if (name[0]=='%' && rightb==']') buf[j++]='\\';
4114 buf[j++]=rightb;
4115 }
4116 buf[j++]='\0';
4117 return buf;
4118 }
4119
4120 char *mbk_vect(char *name, char leftb, char rightb)
4121 {
4122 char res[4096];
4123 return namealloc(mbk_vect_sub(name, leftb, rightb, res));
4124 }
4125
4126
4127 int mbk_ReadFlags(int varnum, mbk_options_pack_struct *gen_opack, int nbopt, int warn, int initval)
4128 {
4129 char *str;
4130 int i;
4131 char *l;
4132 char buf[1024];
4133 int GEN_OPTIONS_PACK=initval;
4134
4135 str=V_STR_TAB[varnum].VALUE;
4136 if (str!=NULL)
4137 {
4138 strcpy(buf,str);
4139 l=strtok(buf, ",");
4140 while (l!=NULL)
4141 {
4142 for (i=0;i<nbopt; i++)
4143 if (strcasecmp(l, gen_opack[i].name)==0)
4144 {
4145 GEN_OPTIONS_PACK|=gen_opack[i].mask;
4146 break;
4147 }
4148 else if (l[0]=='!' && strcasecmp(&l[1], gen_opack[i].name)==0)
4149 {
4150 GEN_OPTIONS_PACK&=~gen_opack[i].mask;
4151 break;
4152 }
4153 if (i>=nbopt && warn)
4154 {
4155 fprintf(stderr,"warning: option '%s' is unknown\n", l);
4156 }
4157 l=strtok(NULL, ",");
4158 }
4159 }
4160 return GEN_OPTIONS_PACK;
4161 }
4162
4163 char* mbk_getvssname()
4164 {
4165 static char *ptvss=NULL ;
4166 char buffer[BUFSIZE] ;
4167 int i, l, p ;
4168
4169 if( !ptvss ) {
4170
4171 l = strlen( GLOBAL_VSS );
4172
4173 /* Passe tous les caractères ':' ou '*' */
4174 for( i = 0 ;
4175 i < l && ( GLOBAL_VSS[i] == ':' || GLOBAL_VSS[i] == '*' ) ;
4176 i++
4177 );
4178
4179 if( i < l ) {
4180 /* retiens tous les caractères différents de ':' ou '*' */
4181 for( p = 0 ;
4182 i < l && GLOBAL_VSS[i] != ':' && GLOBAL_VSS[i] != '*' ;
4183 i++, p++
4184 ) buffer[p] = GLOBAL_VSS[i] ;
4185 }
4186
4187 buffer[p] = '\0' ;
4188 ptvss = namealloc( buffer );
4189 }
4190
4191 return ptvss ;
4192 }
4193
4194 char* mbk_getvddname()
4195 {
4196 static char *ptvdd=NULL ;
4197 char buffer[BUFSIZE] ;
4198 int i, l, p ;
4199
4200 if( !ptvdd ) {
4201
4202 l = strlen( GLOBAL_VDD );
4203
4204 /* Passe tous les caractères ':' ou '*' */
4205 for( i = 0 ;
4206 i < l && ( GLOBAL_VDD[i] == ':' || GLOBAL_VDD[i] == '*' ) ;
4207 i++
4208 );
4209
4210 if( i < l ) {
4211 /* retiens tous les caractères différents de ':' ou '*' */
4212 for( p = 0 ;
4213 i < l && GLOBAL_VDD[i] != ':' && GLOBAL_VDD[i] != '*' ;
4214 i++, p++
4215 ) buffer[p] = GLOBAL_VDD[i] ;
4216 }
4217
4218 buffer[p] = '\0' ;
4219 ptvdd = namealloc( buffer );
4220 }
4221
4222 return ptvdd ;
4223 }
4224
4225 void mbk_dumpfile(FILE *infile, FILE *outfile, int level)
4226 {
4227 char buf[32000];
4228
4229 while (fgets(buf, 32000, infile)!=NULL)
4230 {
4231 avt_log(LOGCONFIG, level, "%s", buf);
4232 }
4233 avt_log(LOGCONFIG, level, "\n");
4234 }
4235
4236 unsigned int mbk_get_a_seed()
4237 {
4238 struct timeval tp;
4239 if (!gettimeofday(&tp, NULL))
4240 return tp.tv_sec+(tp.tv_usec<<21)+(getpid()<<15);
4241 else
4242 return time(NULL)+(getpid()<<15);
4243 }
4244
4245
4246 // algo Random Number generator 'Mersenne Twister'
4247 // simplifie a mort par zinaps
4248
4249 #define MERS_N 1
4250 #define MERS_M 1
4251 #define MERS_R 31
4252 #define MERS_U 11
4253 #define MERS_S 7
4254 #define MERS_T 15
4255 #define MERS_L 18
4256 #define MERS_A 0x9908B0DF
4257 #define MERS_B 0x9D2C5680
4258 #define MERS_C 0xEFC60000
4259
4260 #ifdef USE_DEFAULT_RANDR
4261 unsigned int mbk_rand_r(unsigned int *mt)
4262 {
4263 return rand_r(mt);
4264 }
4265 #else
4266 unsigned int mbk_rand_r(unsigned int *mt) {
4267 // Generate 32 random bits
4268 unsigned int y;
4269 // int mti;
4270
4271 // if (mti >= MERS_N) {
4272 // Generate MERS_N words at one time
4273 const unsigned int LOWER_MASK = (1LU << MERS_R) - 1; // Lower MERS_R bits
4274 const unsigned int UPPER_MASK = 0xFFFFFFFF << MERS_R; // Upper (32 - MERS_R) bits
4275 static const unsigned int mag01[2] = {0, MERS_A};
4276
4277 int kk;
4278 for (kk=0; kk < MERS_N-MERS_M; kk++) {
4279 y = (mt[kk] & UPPER_MASK) | (mt[kk+1] & LOWER_MASK);
4280 mt[kk] = mt[kk+MERS_M] ^ (y >> 1) ^ mag01[y & 1];}
4281
4282 for (; kk < MERS_N-1; kk++) {
4283 y = (mt[kk] & UPPER_MASK) | (mt[kk+1] & LOWER_MASK);
4284 mt[kk] = mt[kk+(MERS_M-MERS_N)] ^ (y >> 1) ^ mag01[y & 1];}
4285
4286 y = (mt[MERS_N-1] & UPPER_MASK) | (mt[0] & LOWER_MASK);
4287 mt[MERS_N-1] = mt[MERS_M-1] ^ (y >> 1) ^ mag01[y & 1];
4288 // mti = 0;
4289 // }
4290
4291 y = mt[0];
4292
4293 #if 1
4294 // Tempering (May be omitted):
4295 y ^= y >> MERS_U;
4296 y ^= (y << MERS_S) & MERS_B;
4297 y ^= (y << MERS_T) & MERS_C;
4298 y ^= y >> MERS_L;
4299 #endif
4300
4301 return y;
4302 }
4303 #endif
4304
4305 int mbk_sumchar(char *name)
4306 {
4307 int i, j;
4308 char c;
4309 if (name==NULL) return 0x12345;
4310 for (i=0, j=0; name[i]!='\0'; i++)
4311 {
4312 if (CASE_SENSITIVE!='Y') c=tolower(name[i]);
4313 else c=name[i];
4314 j+=c*(i+1);
4315 }
4316 return j;
4317 }
4318
4319 void mbk_substenvvariable(char *ref, char *res)
4320 {
4321 int i, j, k;
4322 char tc, *var;
4323 i=j=0;
4324 do
4325 {
4326 if (ref[i]=='$' && isalpha(ref[i+1]))
4327 {
4328 i++;
4329 k=i;
4330 while (ref[i]!='\0' && (isalnum(ref[i]) || ref[i]=='_')) i++;
4331 tc=ref[i];
4332 ref[i]='\0';
4333 var=getenv(&ref[k]);
4334 if (var==NULL)
4335 avt_errmsg (MBK_ERRMSG, "069", AVT_ERROR, &ref[k]);
4336 else
4337 for (k=0; var[k]!='\0'; k++) res[j++]=var[k];
4338 ref[i]=tc;
4339 }
4340 else
4341 {
4342 res[j++]=ref[i++];
4343 }
4344 } while (ref[i]!='\0');
4345 res[j]='\0';
4346 }