2 * This file is part of the Alliance CAD System
3 * Copyright (C) Laboratoire LIP6 - Département ASIM
4 * Universite Pierre et Marie Curie
6 * Home page : http://www-asim.lip6.fr/alliance/
7 * E-mail support : mailto:alliance-support@asim.lip6.fr
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.
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.
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.
25 * Purpose : services functions and global variables
27 * Author : Frederic Petrot <Frederic.Petrot@lip6.fr>
28 * Modified by Czo <Olivier.Sirol@lip6.fr> 1997,98
31 #ident "$Id: mbk_util.c,v 1.198 2009/05/07 14:33:06 fabrice Exp $"
39 #include <sys/types.h>
44 #include "../avt/avt_init_funcs.h"
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();
53 /* Normally defined in values.h, but not available on all systems */
55 #define BITS(type) (8 * (int)sizeof(type))
58 /*******************************************************************************
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 */
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
;
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
;
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
;
119 static int namealloc_primes
[]={103, 5023, 10007, 50047, 100003, 507077, 1000099, 1500823, 2015177};
120 static int namealloc_primes_index
=4;
123 long i_nbchain
=0, i_nbptype
=0, i_nbnum
=0;
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;
138 ** Added by Ludovic Jacomme (The slave)
139 ** in order to "trap" exit with Graal/Dreal etc ...
141 void (*MBK_EXIT_FUNCTION
)(int) = 0;
142 char MBK_EXIT_KILL
= 'N' ;
144 char *MBK_BULK_NAME
,*MBK_GRID_NAME
,*MBK_DRAIN_NAME
,*MBK_SOURCE_NAME
;
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
;
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;
155 static NameAllocator SENSITIVE_NAMEALLOC_ALLOCATOR
;
157 mbk_parse_error MBK_PARSE_ERROR
= { NULL
, 0ul, 0ul, 0ul, 0ul, 0, 0};
158 chain_list
*MBK_ALL_PARSE_ERROR
=NULL
;
160 char MBK_VECTOR_OPEN
[256];
161 char MBK_VECTOR_CLOSE
[256];
162 char MBK_VECTOR_SINGLE
[256];
166 return NAME_HASHTABLE
!=NULL
;
168 void mbk_commit_errors(char *filename
)
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;
178 void mbk_reset_errors()
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
;
186 int isknowntrsparam(void *param
)
188 if ((char **)param
>= (char **)KNOWN_TRSPARAM
&& (char **)param
< (char **)KNOWN_TRSPARAM
+ NUM_KNOWN_TRSPARAM
) {
194 char **getknowntrsparam(char *name
)
198 for (i
= 0; i
< NUM_KNOWN_TRSPARAM
; i
+=2) {
199 if (!strcasecmp(name
, KNOWN_TRSPARAM
[i
])) return ((char **)KNOWN_TRSPARAM
+ i
);
204 static void dflhandler(int);
206 /*******************************************************************************
207 * fonction handler() *
208 *******************************************************************************/
209 static void dflhandler(int sig
)
212 sig
=0; /* avoir warning */
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
)
226 if( waitpid( pid
, status
, WNOHANG
) != 0 )
232 sleep(1); /* le sleep est interruptible : on ne perd rien */
238 int mbk_decodvectorconfig( char *env
)
242 static char separ
= ',';
245 char vector_open
[1024];
246 char vector_close
[1024];
247 char vector_single
[1024];
250 if( !env
|| strcasecmp(env
,"yes")==0) {
251 strcpy( MBK_VECTOR_OPEN
, "<[" );
252 strcpy( MBK_VECTOR_CLOSE
, ">]" );
253 strcpy( MBK_VECTOR_SINGLE
, "" );
256 else if (strcasecmp(env
,"no")==0)
263 *vector_open
= '\0' ;
264 *vector_close
= '\0' ;
265 *vector_single
= '\0' ;
271 *pt
&& *pt
!= separ
;
272 buf
[i
]=*pt
, i
++, pt
++
284 strcat( vector_single
, buf
);
290 onechar
[0] = buf
[0] ;
291 strcat( vector_open
, onechar
);
293 onechar
[0] = buf
[1] ;
294 strcat( vector_close
, onechar
);
302 strcpy( MBK_VECTOR_OPEN
, vector_open
) ;
303 strcpy( MBK_VECTOR_CLOSE
, vector_close
) ;
304 strcpy( MBK_VECTOR_SINGLE
, vector_single
) ;
309 /*******************************************************************************
310 * fonction mbkenv() *
311 *******************************************************************************/
317 struct sigaction sgct
;
321 static int protect_mbkenv
=0;
322 static char MBK_RAND_SEED
[] =
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
332 #ifdef MALLOC_HISTOGRAM
336 read_lib(); /* read the contents of MBK_WORK_LIB and MBK_CATA_LIB */
338 str
= getenv("MBK_DEBUG_MODE");
340 if (!strcmp(str
,"yes"))
343 str
= getenv("MBK_TRACE_MODE");
345 if (!strcmp(str
,"yes"))
348 FAST_MODE
= V_BOOL_TAB
[__MBK_FAST_MODE
].VALUE
?'Y':'N';
350 SCALE_X
= (long)V_INT_TAB
[__MBK_SCALE_X
].VALUE
;
352 srand((unsigned int) MBK_RAND_SEED
);
354 str
= V_STR_TAB
[__MBK_IN_LO
].VALUE
;
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");
385 (void)fflush(stdout
);
386 (void)fprintf(stderr
,"*** mbk error ***\n");
387 (void)fprintf(stderr
,"netlist input format '%s' not supported\n",str
);
392 str
= V_STR_TAB
[__MBK_OUT_LO
].VALUE
;
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");
425 (void)fflush(stdout
);
426 (void)fprintf(stderr
,"*** mbk error ***\n");
427 (void)fprintf(stderr
,"netlist output format '%s' not supported\n",str
);
432 /* par Fabrice le 7/2/2002 */
433 MBK_LOAD_PARA
=V_BOOL_TAB
[__MBK_LOAD_PARASITICS
].VALUE
;
435 str
= V_STR_TAB
[__MBK_IN_PARASITICS
].VALUE
;
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");
444 (void)fflush(stdout
);
445 (void)fprintf(stderr
,"*** mbk error ***\n");
446 (void)fprintf(stderr
,"parasitic netlist input format '%s' not supported\n",str
);
450 /* --------- le 8/2/2002 */
451 str
= getenv("MBK_DEVECT");
453 if (!strcmp(str
, "yes"))
455 else if (!strcmp(str
, "no"))
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");
467 str
= getenv("MBK_IN_PH");
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");
476 (void)fflush(stdout
);
477 (void)fprintf(stderr
,"*** mbk error ***\n");
478 (void)fprintf(stderr
,"layout input format '%s' not supported\n",str
);
483 str
= getenv("MBK_OUT_PH");
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");
492 (void)fflush(stdout
);
493 (void)fprintf(stderr
,"*** mbk error ***\n");
494 (void)fprintf(stderr
,"layout output format '%s' not supported\n",str
);
500 if ((str
= V_STR_TAB
[__MBK_CATAL_NAME
].VALUE
)) CATAL
= str
;
501 else CATAL
= "CATAL";
503 if ((str
= V_STR_TAB
[__MBK_SEPAR
].VALUE
)) SEPAR
= *str
;
505 if ((str
= V_STR_TAB
[__MBK_BLACKBOX_NAME
].VALUE
)) MBK_BBOX_NAME
= str
;
506 else MBK_BBOX_NAME
= "BLACKBOX";
508 if((str
= V_STR_TAB
[__MBK_IN_FILTER
].VALUE
)) IN_FILTER
= str
;
509 else IN_FILTER
= NULL
;
511 if((str
= V_STR_TAB
[__MBK_OUT_FILTER
].VALUE
)) OUT_FILTER
= str
;
512 else OUT_FILTER
= NULL
;
514 if((str
= V_STR_TAB
[__MBK_FILTER_SFX
].VALUE
)) FILTER_SFX
= str
;
515 else FILTER_SFX
= NULL
;
517 if((str
= V_STR_TAB
[__MBK_LIB_FILE
].VALUE
)) LIB_FILE
= str
;
518 else LIB_FILE
= NULL
;
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';
531 /* EXIT shall produce a real exit if not trapped */
532 signal(SIGTERM
, dflhandler
);
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
;
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
;
542 if ((str
= V_STR_TAB
[__MBK_VDD
].VALUE
)) VDD
= namealloc (str
);
543 else VDD
= namealloc ("");
545 if ((str
= V_STR_TAB
[__MBK_VSS
].VALUE
)) VSS
= namealloc (str
);
546 else VSS
= namealloc ("");
548 if ((str
= V_STR_TAB
[__MBK_GLOBAL_VDD
].VALUE
)) GLOBAL_VDD
= namealloc (str
);
549 else GLOBAL_VDD
= namealloc ("");
551 if ((str
= V_STR_TAB
[__MBK_GLOBAL_VSS
].VALUE
)) {
552 sprintf(buf
, "0:*%c0:%s", SEPAR
, str
);
553 GLOBAL_VSS
= namealloc (buf
);
556 sprintf(buf
, "0:*%c0", SEPAR
);
557 GLOBAL_VSS
= namealloc (buf
);
560 VDD_VSS_THRESHOLD
= SCALE_ALIM
*V_FLOAT_TAB
[__MBK_VDD_VSS_THRESHOLD
].VALUE
;
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");
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;
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
);
599 MBK_DUP_PNAME_FF
=V_BOOL_TAB
[__MBK_DUP_PNAME_FOR_FLAT
].VALUE
?'Y':'N';
601 if((env
= V_STR_TAB
[__MBK_SPI_VECTOR
].VALUE
)) {
602 if (strlen(env
) < 1024)
603 strcpy (SPI_VECTOR
, env
);
605 else strcpy (SPI_VECTOR
, "_");
607 FLATTEN_KEEP_ALL_NAMES
=V_BOOL_TAB
[__MBK_KEEP_ALL_SIGNAL_NAMES
].VALUE
;
609 if( V_INT_TAB
[__MBK_MAX_CACHE_FILE
].VALUE
<= 0 ) {
611 fprintf( stderr
, "*** mbk error ***\n" );
612 fprintf( stderr
, "bad value for MBK_MAX_CACHE_FILE.\n" );
615 MBK_MAX_CACHE
= V_INT_TAB
[__MBK_MAX_CACHE_FILE
].VALUE
;
617 if (!mbk_decodvectorconfig(V_STR_TAB
[__MBK_INPUT_VECTOR
].VALUE
))
619 fprintf( stderr
, "bad value for variable controlling input vectors\n" );
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.
638 signal( SIGCHLD
, mbkackchld
);
641 sgct
.sa_handler
= mbkackchld
;
643 sgct
.sa_flags
= SA_RESTART
;
644 sigaction( SIGCHLD
, &sgct
, NULL
);
647 CreateNameAllocator(1024, &SENSITIVE_NAMEALLOC_ALLOCATOR
, 'y');
652 AVT_FULLVERSION
= namealloc(AVT_FULLVERSION
);
657 /*******************************************************************************
658 * fonction readlibfile() *
659 *******************************************************************************/
660 void readlibfile(type
,fonc
,reload
)
662 void (*fonc
)(char *) ;
672 static chain_list
*typelist
= NULL
;
677 for(chain
= typelist
; chain
!= NULL
; chain
= chain
->NEXT
)
679 if(strcmp((char *)chain
->DATA
,type
) == 0)
690 pt
= namealloc(type
) ;
691 typelist
= addchain(typelist
,pt
) ;
694 file
= mbkfopen(LIB_FILE
,NULL
,"r") ;
698 if(TRACE_MODE
== 'Y')
701 (void)fprintf (stderr
, "*** mbk warning ***\n");
702 (void)fprintf (stderr
, "can not open lib file %s\n",LIB_FILE
);
712 nb_input
= fscanf(file
, "%s %s\n", buffile
, buftype
);
713 if(nb_input
== 0) continue;
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
);
722 if(strcmp(buftype
,type
) == 0)
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
)
738 (void)sprintf(str
,"%s%c%ld", name
, SEPAR
, index
);
739 return namealloc(str
);
742 /*******************************************************************************
743 * fonction addnum() *
744 * num list specialized allocator to avoid too many mallocs *
745 *******************************************************************************/
746 num_list
*addnum(ptnum
, data
)
754 HEAD_NUM
= (num_list
*)mbkalloc(sizeof(num_list
));
755 HEAD_NUM
->NEXT
= NULL
;
757 if (HEAD_NUM
== NULL
) {
758 HEAD_NUM
= (num_list
*)mbkalloc((1+BUFSIZE
)*sizeof(num_list
));
760 i_nbnum
+=(1+BUFSIZE
);
763 for (i
= 1; i
< BUFSIZE
; i
++) {
772 HEAD_NUM
= HEAD_NUM
->NEXT
;
781 /*******************************************************************************
782 * fonction getnum() *
783 * get pointer to num list element from data *
784 *******************************************************************************/
785 num_list
*getnum(ptnum
, data
)
791 for (pt
= ptnum
; pt
; pt
= pt
->NEXT
) {
792 if (pt
->DATA
== data
) return pt
;
797 /*******************************************************************************
798 * function freenum() *
799 * gives back freed block to the num memory allocator *
800 *******************************************************************************/
807 for (n
=pt
; n
!=NULL
; n
=n
->NEXT
)
813 num_list
*next
,*scan
;
814 for( scan
=pt
; scan
; scan
=next
) {
820 HEAD_NUM
= (num_list
*)append((chain_list
*)pt
, (chain_list
*)HEAD_NUM
);
824 num_list
* dupnumlst( num_list
*head
)
826 num_list
*reversed
= NULL
;
828 for( ; head
; head
= head
->NEXT
)
829 reversed
= addnum( reversed
, head
->DATA
);
830 reversed
= (num_list
*)reverse( (chain_list
*)reversed
);
834 /*******************************************************************************
835 * function addchain() *
836 * chain list specialized allocator to avoid too many mallocs *
837 *******************************************************************************/
838 chain_list
*addchain(pthead
, ptdata
)
846 HEAD_CHAIN
= (chain_list
*)mbkalloc( sizeof( chain_list
) );
847 HEAD_CHAIN
->NEXT
= NULL
;
849 if (HEAD_CHAIN
== NULL
) {
850 pt
= (chain_list
*)mbkalloc(BUFSIZE
*sizeof(chain_list
));
855 for (i
= 1; i
< BUFSIZE
; i
++) {
864 HEAD_CHAIN
= HEAD_CHAIN
->NEXT
;
873 chain_list
*getchain(chain_list
*ptchain
, void *data
)
875 while (ptchain
!=NULL
)
877 if (ptchain
->DATA
== data
) return ptchain
;
878 ptchain
=ptchain
->NEXT
;
883 /*******************************************************************************
884 * function freechain() *
885 * gives back freed block or blocks to the chain_list memory allocator *
886 *******************************************************************************/
892 for( scan
=pt
; scan
; scan
=scan
->NEXT
) i_nbchain
++;
897 for( scan
=pt
; scan
; scan
=next
) {
903 HEAD_CHAIN
= append(pt
, HEAD_CHAIN
);
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
)
916 chain_list
*ptsav
= NULL
; /* To make gcc -Wall silent */
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");
925 if (ptdel
== pthead
) {
931 for (pt
= pthead
; pt
; pt
= pt
->NEXT
) {
937 ptsav
->NEXT
= pt
->NEXT
;
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
)
955 chain_list
*retchain
=NULL
;
957 for( chain
= refchain
; chain
; chain
= chain
->NEXT
) {
958 if( !delchain
|| chain
->DATA
!= delchain
->DATA
) {
959 retchain
= addchain( retchain
, chain
->DATA
);
963 delchain
= delchain
->NEXT
;
967 return reverse( retchain
);
971 * renvoir le nombre d'element dans une chain_list
974 int countchain(chain_list
*doubl
)
977 for (count
=0;doubl
!=NULL
;doubl
=doubl
->NEXT
,count
++) ;
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
)
990 chain_list
*ptsav
= NULL
; /* To make gcc -Wall silent */
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");
999 if (ptdeldata
== pthead
->DATA
) {
1001 pthead
->NEXT
= NULL
;
1005 for (pt
= pthead
; pt
; pt
= pt
->NEXT
) {
1006 if (pt
->DATA
== ptdeldata
)
1011 ptsav
->NEXT
= pt
->NEXT
;
1020 /*##------------------------------------------------------------------##*/
1021 /* Function : dupptypelst() */
1022 /* contents : duplicate a ptype list and return a pointer on the new */
1024 /* called func. : reverse(), mbkalloc(), */
1025 /*##------------------------------------------------------------------##*/
1027 ptype_list
*dupptypelst(ptype_ptr
)
1028 ptype_list
*ptype_ptr
;
1030 ptype_list
*ptype_rpt
= NULL
; /* Returned chain pointer */
1032 while(ptype_ptr
!= NULL
)
1034 ptype_rpt
= addptype(ptype_rpt
, ptype_ptr
->TYPE
, ptype_ptr
->DATA
);
1035 ptype_ptr
= ptype_ptr
->NEXT
;
1037 ptype_rpt
= (ptype_list
*)reverse((chain_list
*)ptype_rpt
);
1041 /*##------------------------------------------------------------------##*/
1042 /* Function : dupchainlst() */
1043 /* contents : duplicate a chain list and return a pointer on the new */
1045 /* called func. : reverse(), mbkalloc(), */
1046 /*##------------------------------------------------------------------##*/
1048 chain_list
*dupchainlst(chain_ptr
)
1049 chain_list
*chain_ptr
;
1051 chain_list
*chain_rpt
= NULL
; /* Returned chain pointer */
1053 while(chain_ptr
!= NULL
)
1055 chain_rpt
= addchain(chain_rpt
, chain_ptr
->DATA
);
1056 chain_ptr
= chain_ptr
->NEXT
;
1058 chain_rpt
= reverse(chain_rpt
);
1062 /*******************************************************************************
1063 * function addptype() *
1064 *******************************************************************************/
1065 ptype_list
*addptype(pthead
,type
,ptdata
)
1073 if (HEAD_PTYPE
== NULL
) {
1075 pt
= (ptype_list
*)mbkalloc(sizeof(ptype_list
));
1078 pt
= (ptype_list
*)mbkalloc(BUFSIZE
* sizeof(ptype_list
));
1083 for (i
= 1; i
< BUFSIZE
; i
++) {
1092 HEAD_PTYPE
= HEAD_PTYPE
->NEXT
;
1102 /*******************************************************************************
1103 * function testanddelptype() *
1104 *******************************************************************************/
1105 ptype_list
*testanddelptype(pthead
, type
)
1110 ptype_list
*ptsav
= NULL
; /* To make gcc -Wall silent */
1112 if (pthead
== NULL
) return NULL
;
1114 if (pthead
->TYPE
== type
) {
1116 pthead
->NEXT
= NULL
;
1120 for (pt
= pthead
; pt
; pt
= pt
->NEXT
) {
1121 if (pt
->TYPE
== type
)
1126 ptsav
->NEXT
= pt
->NEXT
;
1134 /*******************************************************************************
1135 * function delptype() *
1136 *******************************************************************************/
1137 ptype_list
*delptype(pthead
, type
)
1142 ptype_list
*ptsav
= NULL
; /* To make gcc -Wall silent */
1144 if (pthead
== NULL
) {
1145 (void)fflush(stdout
);
1146 (void)fprintf(stderr
,"*** mbk error ***\n");
1147 (void)fprintf(stderr
,"delptype() impossible : pthead = NULL !\n");
1151 if (pthead
->TYPE
== type
) {
1153 pthead
->NEXT
= NULL
;
1157 for (pt
= pthead
; pt
; pt
= pt
->NEXT
) {
1158 if (pt
->TYPE
== type
)
1163 ptsav
->NEXT
= pt
->NEXT
;
1168 #if DELAY_DEBUG_STAT
1169 avt_fprintf(stderr
, "¤6delptype function called for non existing PTYPE¤.\n");
1176 /*******************************************************************************
1177 * function freeptype() *
1178 *******************************************************************************/
1184 for( scan
= pt
; scan
; scan
= scan
->NEXT
) i_nbptype
++;
1189 for( scan
= pt
; scan
; scan
= next
) {
1195 HEAD_PTYPE
= (ptype_list
*)append((chain_list
*)pt
,(chain_list
*)HEAD_PTYPE
);
1199 /*******************************************************************************
1200 * function getptype() *
1201 *******************************************************************************/
1202 ptype_list
*getptype(pthead
, type
)
1208 for (pt
= pthead
; pt
; pt
= pt
->NEXT
)
1209 if (pt
->TYPE
== type
)
1214 /*******************************************************************************
1215 * function append() *
1216 *******************************************************************************/
1217 chain_list
*append(pt1
, pt2
)
1218 chain_list
*pt1
,*pt2
;
1225 for (pt
= pt1
; pt
->NEXT
; pt
= pt
->NEXT
);
1226 pt
->NEXT
= pt2
; /* append the list 2 at the end of list 1 */
1231 /*******************************************************************************
1232 * Dictonnary related functions *
1233 *******************************************************************************/
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
1241 #define HASH_FUNC(inputname, name, code) \
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; \
1255 static inline int SUB_HASH_FUNC(char *inputname
, char *name
, int code
, char CASE_SENSITIVE
)
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
)
1269 static inline int HASH_FUNC(char *inputname
, char *name
, int code
, int HASHVAL0
)
1271 code
= SUB_HASH_FUNC(inputname
, name
, code
, CASE_SENSITIVE
) % HASHVAL0
;
1275 /*******************************************************************************
1276 * function namealloc() *
1277 *******************************************************************************/
1278 void CreateNameAllocator(int size
, NameAllocator
*na
, char _case
)
1281 if (size
==0) size
=5100; // next rehash @10007
1283 na
->NAME_HASHTABLE
=mbkalloc(sizeof(chain_list
*)*size
);
1284 for (i
=0; i
<size
; i
++) na
->NAME_HASHTABLE
[i
]=NULL
;
1286 if (tolower(_case
)=='y') na
->SENSITIVE
='Y';
1287 else if (tolower(_case
)=='p') na
->SENSITIVE
='P'; // case preserve
1288 else na
->SENSITIVE
='N';
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
++) ;
1294 na
->aba
=CreateAdvancedBlockAllocator(4000, 'n');
1296 na
->__SIZE__
=sizeof(chain_list
*)*size
;
1301 void DeleteNameAllocator(NameAllocator
*na
)
1305 for (i
=0; i
<na
->HASHVAL0
; i
++)
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
]);
1311 FreeAdvancedBlockAllocator(na
->aba
);
1312 mbkfree(na
->NAME_HASHTABLE
);
1315 static void NameAlloc_rehash(NameAllocator
*na
)
1317 chain_list
**nn
, *cl
;
1319 char *name
= buffer
;
1321 // fprintf(stdout,".rehashing name dico: %d -> %d...",na->HASHVAL0,namealloc_primes[na->namealloc_primes_index+1]); fflush(stdout);
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
++)
1327 for (i
=0;i
<na
->HASHVAL0
;i
++)
1329 for (cl
=na
->NAME_HASHTABLE
[i
]; cl
!=NULL
; cl
=cl
->NEXT
)
1331 code
= HASH_FUNC((char *)cl
->DATA
, name
, 0, namealloc_primes
[na
->namealloc_primes_index
+1]);
1332 nn
[code
]=addchain(nn
[code
], cl
->DATA
);
1334 freechain(na
->NAME_HASHTABLE
[i
]);
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");
1343 inline char *NameAlloc_sub(NameAllocator
*na
, char *inputname
, int find
)
1346 char buffer
[BUFSIZ
];
1347 char *name
= buffer
; /* ensure no modification of parameter string */
1348 int code
= 0, depth
;
1350 if (inputname
== NULL
)
1353 /* Beware, that's a define, ... */
1354 code
= SUB_HASH_FUNC(inputname
, name
, code
, na
->SENSITIVE
) % na
->HASHVAL0
;
1356 for (pt
= na
->NAME_HASHTABLE
[code
], depth
=0; pt
; pt
= pt
->NEXT
, depth
++)
1358 if (na
->SENSITIVE
!= 'P')
1360 if (!strcmp(buffer
, (char *)pt
->DATA
))
1361 return (char *)pt
->DATA
;
1365 if (!strcasecmp(buffer
, (char *)pt
->DATA
))
1366 return (char *)pt
->DATA
;
1370 if (find
) return NULL
;
1372 name
=(char *)AdvancedBlockAlloc(na
->aba
, (unsigned int)(strlen(buffer
) + 1));
1374 // name = (char *)mbkalloc((unsigned int)(strlen(buffer) + 1));
1375 strcpy(name
, buffer
);
1376 na
->NAME_HASHTABLE
[code
] = addchain(na
->NAME_HASHTABLE
[code
], name
);
1379 na
->__SIZE__
+=sizeof(chain_list
*)+strlen(buffer
)+1+4;
1381 if ((unsigned)na
->namealloc_primes_index
<(sizeof(namealloc_primes
)/sizeof(*namealloc_primes
))-1 && depth
>32)
1382 NameAlloc_rehash(na
);
1387 char *NameAlloc(NameAllocator
*na
, char *inputname
)
1389 return NameAlloc_sub(na
, inputname
, 0);
1392 char *NameAllocFind(NameAllocator
*na
, char *inputname
)
1394 return NameAlloc_sub(na
, inputname
, 1);
1397 void NameAllocStat(NameAllocator
*na
)
1399 int i
, nb
, max
=0,moy
=0, nb0
=0;
1400 int maxstr
=0, moystr
=0, lg
, cntstr
=0;
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
)
1410 for (nb
=0, cl
=na
->NAME_HASHTABLE
[i
];cl
!=NULL
; cl
=cl
->NEXT
, nb
++)
1412 lg
=strlen((char *)cl
->DATA
);
1413 if (lg
>maxstr
) maxstr
=lg
;
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
);
1424 char *sensitive_namealloc(char *name
)
1426 return NameAlloc(&SENSITIVE_NAMEALLOC_ALLOCATOR
, name
);
1429 char *min_namealloc(char *name
)
1431 char buf
[4096], *temp
;
1434 temp
=namealloc(buf
);
1438 char *min_namefind(char *name
)
1440 char buf
[4096], *temp
;
1447 static void namealloc_rehash()
1449 chain_list
**nn
, *cl
;
1451 char *name
= buffer
;
1453 // fprintf(stdout,".rehashing name dico: %d -> %d...",namealloc_primes[namealloc_primes_index],namealloc_primes[namealloc_primes_index+1]); fflush(stdout);
1455 nn
=mbkalloc(namealloc_primes
[namealloc_primes_index
+1]*sizeof(chain_list
*));
1456 for (i
=0;i
<namealloc_primes
[namealloc_primes_index
+1];i
++)
1459 for (i
=0;i
<namealloc_primes
[namealloc_primes_index
];i
++)
1461 for (cl
=NAME_HASHTABLE
[i
]; cl
!=NULL
; cl
=cl
->NEXT
)
1463 code
= HASH_FUNC((char *)cl
->DATA
, name
, 0, namealloc_primes
[namealloc_primes_index
+1]);
1464 nn
[code
]=addchain(nn
[code
], cl
->DATA
);
1466 freechain(NAME_HASHTABLE
[i
]);
1468 mbkfree(NAME_HASHTABLE
);
1470 namealloc_primes_index
++;
1472 // fprintf(stdout,"done\n");
1477 char *namealloc(inputname
)
1481 char *name
= buffer
; /* ensure no modification of parameter string */
1485 if (inputname
== NULL
)
1488 if (NAME_HASHTABLE
==NULL
)
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
;
1496 /* Beware, that's a define, ... */
1497 code
= HASH_FUNC(inputname
, name
, 0, namealloc_primes
[namealloc_primes_index
]);
1499 for (pt
= NAME_HASHTABLE
[code
], depth
=0; pt
; pt
= pt
->NEXT
, depth
++)
1501 if (CASE_SENSITIVE
!= 'P')
1503 if (!strcmp(buffer
, (char *)pt
->DATA
))
1504 return (char *)pt
->DATA
;
1508 if (!strcasecmp(buffer
, (char *)pt
->DATA
))
1509 return (char *)pt
->DATA
;
1513 name
= (char *)mbkalloc((unsigned int)(strlen(buffer
) + 1));
1515 ynmsize
+=strlen(buffer
) + 1+4+8;
1517 (void)strcpy(name
, buffer
);
1518 NAME_HASHTABLE
[code
] = addchain(NAME_HASHTABLE
[code
], (void *)name
);
1520 if ((unsigned)namealloc_primes_index
<(sizeof(namealloc_primes
)/sizeof(*namealloc_primes
))-1 && depth
>32)
1526 /*******************************************************************************
1527 * function namefind() *
1528 *******************************************************************************/
1529 char *namefind(inputname
)
1533 char *name
= buffer
; /* ensure no modification of parameter string */
1534 register int code
= 0;
1536 if (inputname
== NULL
)
1539 if (NAME_HASHTABLE
==NULL
) return NULL
;
1541 code
=HASH_FUNC(inputname
, name
, 0, namealloc_primes
[namealloc_primes_index
]);
1543 for (pt
= NAME_HASHTABLE
[code
]; pt
; pt
= pt
->NEXT
)
1545 if (CASE_SENSITIVE
!= 'P')
1547 if (!strcmp(buffer
, (char *)pt
->DATA
))
1548 return (char *)pt
->DATA
;
1552 if (!strcasecmp(buffer
, (char *)pt
->DATA
))
1553 return (char *)pt
->DATA
;
1560 /*******************************************************************************
1561 * function downstr() *
1562 *******************************************************************************/
1566 for (; *s
; s
++, t
++)
1567 *t
= tolowertable
[(int)*s
];
1571 /*******************************************************************************
1572 * function upstr() *
1573 *******************************************************************************/
1577 for (; *s
; s
++, t
++)
1578 *t
= touppertable
[(int)*s
];
1582 /*******************************************************************************
1583 * function endstr() : match occurence of find at the end of string *
1584 *******************************************************************************/
1586 char *endstr(s
, find
)
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]))
1609 /*******************************************************************************
1610 * function beginstr() : match occurence of find at the beginnig of string *
1611 *******************************************************************************/
1613 char *beginstr (s
, find
, separ
)
1614 char *s
, *find
, separ
;
1623 if ((s
= strrchr(s
, separ
)) == NULL
)
1626 s
++; /* skip the separator itself */
1628 if ((find
[0]) != 0) {
1629 lf
= strlen (find
) ;
1633 for (i
= 0 ; i
< lf
; i
++)
1634 if ((s
[i
] != find
[i
]) && (s
[i
] + 32 != find
[i
]) && (s
[i
] != find
[i
] + 32))
1640 /*******************************************************************************
1641 * function wildstrstr() : match multiple strings separated by ':' *
1642 * enabling wildcard '*' *
1643 *******************************************************************************/
1645 int wildstrstr (char *s
, char *find
)
1647 char buff
[1024], *buf
= buff
;
1651 while (find
[i
] != '\0') {
1654 while (find
[i
] != '\0' && find
[i
] != ':') buf
[j
++] = find
[i
++];
1657 if (mbk_TestREGEX(s
, buf
)) return 1;
1658 if (find
[i
] == ':') i
++;
1665 /*******************************************************************************
1666 * function vectorize : builds a legal mbk vector from a name and an index *
1667 *******************************************************************************/
1668 char *vectorize(radical
, index
)
1672 (void)sprintf(str
,"%s %ld", radical
, index
);
1673 return namealloc(str
);
1676 /*******************************************************************************
1677 * function vectorradical : returns the radical of an mbk vector *
1678 *******************************************************************************/
1679 char *vectorradical(name
)
1684 if ((t
=name
[strlen(name
)-1])<'0' || t
>'9') return name
;
1686 s
= strchr(name
, ' ');
1695 return namealloc(str
);
1698 char *mbk_VectorRadical(char *name
, char *openb
, char *closeb
)
1705 if (openb
==NULL
|| closeb
==NULL
) openb
="[(<", closeb
="])>";
1709 if (l
<=0) return name
;
1711 if (isdigit((int)(unsigned char)name
[l
]))
1716 if ((closebplace
=strchr(closeb
, name
[l
]))!=NULL
)
1718 findchar
=*(openb
-(closebplace
-closeb
));
1725 while (l
>0 && isdigit((int)(unsigned char)name
[l
])) l
--;
1727 if (l
==0 || name
[l
]!=findchar
) return name
;
1729 strncpy(str
, name
, l
);
1732 return namealloc(str
);
1735 int mbk_VectorIndex(char *name
, char *openb
, char *closeb
)
1741 if (openb
==NULL
|| closeb
==NULL
) openb
="[(<", closeb
="])>";
1745 if (l
<=0) return -1;
1747 if (isdigit((int)(unsigned char)name
[l
]))
1752 if ((closebplace
=strchr(closeb
, name
[l
]))!=NULL
)
1754 findchar
=*(openb
-(closebplace
-closeb
));
1760 while (l
>0 && isdigit((int)(unsigned char)name
[l
])) l
--;
1762 if (l
==0 || name
[l
]!=findchar
) return -1;
1764 return strtol(&name
[l
+1], NULL
, 10);
1768 /*******************************************************************************
1769 * function vectorindex : returns the index of an mbk vector *
1770 *******************************************************************************/
1771 int vectorindex(name
)
1774 char *s
= strchr(name
, ' ');
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
)
1790 char *spt
, *tpt
, *st
= s
, *tt
= t
;
1793 spt
= buffer
, tpt
= str
;
1795 while ((!isspace((int)*st
)) && *st
)
1799 while ((!isspace((int)*tt
)) && *tt
)
1803 if ((u
= strcmp(buffer
, str
)) != 0)
1806 if ((ls
= strlen(s
)) == (lt
= strlen(t
)))
1807 return strcmp(s
, t
);
1812 /*******************************************************************************
1813 * function concatname() *
1814 *******************************************************************************/
1815 char *concatname(name1
, name2
)
1816 char *name1
, *name2
;
1818 (void)sprintf(str
,"%s%c%s", name1
, SEPAR
, name2
);
1819 return namealloc(str
);
1822 /*******************************************************************************
1823 * function leftunconcatname() *
1824 * name="AAA.BBB.CCC.DDD" *
1826 * left="AAA" or NULL *
1827 * right="BBB.CCC.DDD" *
1828 *******************************************************************************/
1829 void leftunconcatname(name
, left
, right
)
1830 char *name
, **left
, **right
;
1834 // On recherche le premier séparateur.
1837 name
[i
] != SEPAR
&& name
[i
]!= 0 ;
1842 if( name
[i
] != SEPAR
) {
1843 // Il n'y a plus de séparateur : il ne reste donc que le right.
1847 *left
= namealloc( str
);
1848 *right
= namealloc( name
+i
+1 );
1852 /*******************************************************************************
1853 * function rightunconcatname() *
1854 * name="AAA.BBB.CCC.DDD" *
1856 * left="AAA.BBB.CCC" *
1857 * right="DDD" or NULL *
1858 *******************************************************************************/
1859 void rightunconcatname(name
, left
, right
)
1860 char *name
, **left
, **right
;
1864 // Positionne sur le dernier caractère;
1865 for( i
=0, m
=-1 ; name
[i
] ; i
++)
1866 if( name
[i
] == SEPAR
)
1870 // Il n'y a plus de séparateur : il ne reste donc que le left
1874 // strlcpy( str, name, m ); pas disponible sous Solaris 5.6
1875 for( i
=0 ; i
< m
; i
++ )
1879 *right
= namealloc( name
+m
+1 );
1880 *left
= namealloc( str
);
1884 /*******************************************************************************
1885 * mbkstrdup : since brain damaged system we aim at do not have it *
1886 *******************************************************************************/
1895 t
= (char *)mbkalloc((unsigned int)(strlen(s
) + 1));
1896 return strcpy(t
, s
);
1899 int mbk_casestrcmp(char *orig
, char *dest
)
1901 if (CASE_SENSITIVE
=='Y') return strcmp(orig
, dest
);
1902 return strcasecmp(orig
, dest
);
1905 int mbk_charcmp(char orig
, char dest
)
1907 if (CASE_SENSITIVE
=='Y') return orig
==dest
;
1908 return tolower(orig
)==tolower(dest
);
1911 /*******************************************************************************
1912 * function reverse *
1913 *******************************************************************************/
1914 chain_list
*reverse(head
)
1918 chain_list
*q
= (chain_list
*)NULL
;
1922 while ((p
= head
->NEXT
)) {
1931 /*******************************************************************************
1932 * function pstrcmp *
1933 * used for qsort and bsearch use for catalog sorting and acessing *
1934 *******************************************************************************/
1935 static int pstrcmp(s
, t
)
1938 return strcmp(*s
, *t
);
1941 /*******************************************************************************
1942 * function incatalogfeed *
1943 * tests if a model is present in the catalog with the F attribut *
1944 *******************************************************************************/
1945 int incatalogfeed(figname
)
1949 static char **table
;
1952 loadcatalog(&table
, &size
, 'F');
1954 (int)((long)bsearch(&figname
, table
, size
, sizeof(char *), pstrcmp
)) : 0;
1957 /*******************************************************************************
1958 * function incataloggds *
1959 * tests if a model is present in the catalog with the G attribut *
1960 *******************************************************************************/
1961 int incataloggds(figname
)
1965 static char **table
;
1968 loadcatalog(&table
, &size
, 'G');
1970 (int)((long)bsearch(&figname
, table
, size
, sizeof(char *), pstrcmp
)) : 0;
1973 /*******************************************************************************
1974 * function inlibcatalog *
1975 * tests if a model is present in the lib catalog with the C attribut *
1976 *******************************************************************************/
1977 int inlibcatalog(figname
)
1980 if(LIB_CATAL
!= NULL
) {
1981 if(gethtitem(LIB_CATAL
,figname
) != EMPTYHT
)
1988 /*******************************************************************************
1989 * function incatalog *
1990 * tests if a model is present in the catalog with the C attribut *
1991 *******************************************************************************/
1992 int incatalog(figname
)
1996 static char **table
;
1998 if(LIB_CATAL
!= NULL
) {
1999 if(gethtitem(LIB_CATAL
,figname
) != EMPTYHT
)
2004 loadcatalog(&table
, &size
, 'C');
2006 (int)((long)bsearch(&figname
, table
, size
, sizeof(char *), pstrcmp
)) : 0;
2009 /*******************************************************************************
2010 * function incatalogdelete *
2011 * tests if a model is present in the catalog with the D attribut *
2012 *******************************************************************************/
2013 int incatalogdelete(figname
)
2017 static char **table
;
2020 loadcatalog(&table
, &size
, 'D');
2022 (int)((long)bsearch(&figname
, table
, size
, sizeof(char *), pstrcmp
)) : 0;
2025 /*******************************************************************************
2026 * function addcatalog *
2027 * add a cell in the catalog *
2028 *******************************************************************************/
2029 void addcatalog(figname
)
2032 if(LIB_CATAL
== NULL
)
2034 LIB_CATAL
= addht(100) ;
2036 sethtitem(LIB_CATAL
,figname
,(long)1) ;
2039 chain_list
*getcataloglist()
2041 if(LIB_CATAL
== NULL
)
2043 LIB_CATAL
= addht(100) ;
2045 return GetAllHTKeys(LIB_CATAL
);
2048 void setcataloglist(chain_list
*cl
)
2050 if(LIB_CATAL
!= NULL
)
2057 addcatalog(namealloc((char *)cl
->DATA
));
2062 /*******************************************************************************
2063 * function loadcatalog *
2064 * read the catalog from disk checking the given type *
2065 *******************************************************************************/
2067 static void loadcatalog(table
, size
, type
)
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];
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
));
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
)
2103 while (!feof((FILE *)((chain_list
*)pt
)->DATA
)) {
2104 nb
++; /* count lines */
2105 nb_input
= fscanf((FILE *)((chain_list
*)pt
)->DATA
, "%s %c\n",
2107 if (nb_input
== 0) /* skip white lines */
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
);
2114 (void)fprintf(stderr
, "in file %s/%s\n", WORK_LIB
, CATAL
);
2116 (void)fprintf(stderr
, "in file %s/CATAL\n", CATA_LIB
[i
- 1]);
2119 attrib
= islower((int)attrib
) ? (char)toupper(attrib
) : attrib
;
2122 cells
[0] = addchain(cells
[0], namealloc(buffer
));
2126 cells
[1] = addchain(cells
[1], namealloc(buffer
));
2130 cells
[2] = addchain(cells
[2], namealloc(buffer
));
2134 cells
[3] = addchain(cells
[3], namealloc(buffer
));
2138 (void)fflush(stdout
);
2139 (void)fprintf(stderr
, "*** mbk error ***\n");
2140 (void)fprintf(stderr
, "loadcatalog syntax error line %d ",
2143 (void)fprintf(stderr
, "in file %s/%s\n", WORK_LIB
, CATAL
);
2145 (void)fprintf(stderr
, "in file %s/CATAL\n",
2147 (void)fprintf(stderr
,"unknown attribut %c\n", attrib
);
2151 (void)fclose((FILE *)((chain_list
*)pt
)->DATA
);
2154 for (nb
= 0; nb
< 4; 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
]);
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()
2192 char *str
, *s
, *stc
, *c
;
2195 if (WORK_LIB
!=NULL
) mbkfree(WORK_LIB
);
2196 str
= V_STR_TAB
[__MBK_WORK_LIB
].VALUE
;
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
, ".");
2209 while (CATA_LIB
[i
]) { mbkfree(CATA_LIB
[i
]); i
++; }
2213 str
= V_STR_TAB
[__MBK_CATA_LIB
].VALUE
;
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 */
2221 if ((c
= strchr(stc
, ':')) == NULL
)
2228 CATA_LIB
= (char **)mbkalloc((unsigned int)(argc
+ 2) * sizeof(char *));
2231 if ((s
= strchr(str
, ':')) == NULL
)
2234 CATA_LIB
[argc
++] = mbkstrdup(str
); /* no allocation necessary */
2238 CATA_LIB
[argc
++] = (str
== NULL
|| *str
== '\0') ? NULL
: mbkstrdup(str
);
2239 CATA_LIB
[argc
] = NULL
;
2241 } else { /* no specific path is given */
2242 CATA_LIB
= (char **)mbkalloc((unsigned int)2 * sizeof(char *));
2243 CATA_LIB
[0] = mbkstrdup(".");
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 *******************************************************************************/
2254 unsigned long hash(p
)
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
;
2267 key3
= bit2
^ bit0
;
2268 key2
= bit1
^ bit3
;
2269 key1
= bit3
^ bit2
;
2270 key0
= bit1
^ bit2
;
2272 key
= (key3
<< 24) | (key2
<< 16) | (key1
<< 8) | key0
;
2277 /*******************************************************************************
2278 * function addht, create a hash table *
2279 *******************************************************************************/
2287 if( V_BOOL_TAB
[__AVT_USEHT_V2
].VALUE
)
2288 return (ht
*)addht_v2(len
);
2292 (void)fprintf(stderr
, "*** mbk error ***\n");
2293 (void)fprintf(stderr
, "addht impossible : hash table size is '0'\n");
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
++) {
2302 pEl
[i
].value
= EMPTYHT
;
2314 if( V_BOOL_TAB
[__AVT_USEHT_V2
].VALUE
)
2315 return (ht
*)dupht_v2((ht_v2
*)orig
);
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);
2325 /*******************************************************************************
2326 * function delht, delete a hash table *
2327 *******************************************************************************/
2333 if( V_BOOL_TAB
[__AVT_USEHT_V2
].VALUE
) {
2334 delht_v2((ht_v2
*)pTable
);
2338 if (pTable
== NULL
) return;
2339 pEl
= pTable
->pElem
;
2344 /*******************************************************************************
2345 * function gethtitem, get an element in a hash table *
2346 *******************************************************************************/
2347 long gethtitem(pTable
, key
)
2355 if( V_BOOL_TAB
[__AVT_USEHT_V2
].VALUE
)
2356 return gethtitem_v2( (ht_v2
*)pTable
, key
);
2358 indice
= hash(key
) % pTable
->length
;
2360 if (co
++ > HMAX_CALLS
) {
2361 if ((pTable
->count
> (pTable
->length
) * 2 / 10) || (co
>= pTable
->length
)) {
2363 return gethtitem(pTable
, key
);
2367 pEl
= (pTable
->pElem
) + indice
;
2368 if (pEl
->value
!= EMPTYHT
&& pEl
->value
!= DELETEHT
) {
2369 if ((long) key
== (long) pEl
->key
)
2371 } else if (pEl
->value
== EMPTYHT
)
2373 indice
= (indice
+ 1) % pTable
->length
;
2377 /*******************************************************************************
2378 * function addhtitem, get an element in a hash table *
2379 *******************************************************************************/
2380 long addhtitem(pTable
, key
, value
)
2386 htitem
*pEl
, *FirstDEL
=NULL
;
2389 if( V_BOOL_TAB
[__AVT_USEHT_V2
].VALUE
)
2390 return addhtitem_v2( (ht_v2
*)pTable
, key
, value
);
2392 if (value
== EMPTYHT
|| value
== DELETEHT
) {
2394 (void)fprintf(stderr
, "*** mbk error ***\n");
2395 (void)fprintf(stderr
, "addhtitem impossible : value is EMPTYHT or DELETEHT\n");
2398 if (pTable
->count
++ > (pTable
->length
) * 8 / 10) {
2400 return addhtitem(pTable
, key
, value
);
2403 indice
= hash(key
) % pTable
->length
;
2405 if (co
++ > HMAX_CALLS
) {
2406 if (pTable
->count
> (pTable
->length
) * 2 / 10 || (co
>= pTable
->length
)) {
2408 return addhtitem(pTable
, key
, value
);
2409 } else if(TRACE_MODE
== 'Y') {
2411 (void)fprintf (stderr
, "*** mbk warning ***\n");
2412 (void)fprintf (stderr
, "reallocht undone : density is too low\n");
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
;
2422 } else if ((long) pEl
->key
== (long) key
) {
2427 indice
= (indice
+ 1) % pTable
->length
;
2431 void resetht_v2(ht_v2
*h
)
2434 for (i
=0; i
<h
->size
; i
++) h
->ITEM_HASHTABLE
[i
]=NULL
;
2438 void resetht(ht
*pTable
)
2441 if( V_BOOL_TAB
[__AVT_USEHT_V2
].VALUE
)
2442 resetht_v2((ht_v2
*)pTable
);
2443 for (i
=0; i
<pTable
->length
; i
++)
2445 pTable
->pElem
[i
].key
= NULL
;
2446 pTable
->pElem
[i
].value
= EMPTYHT
;
2451 ht
* controlled_dupht( ht
*orig
, long (*func
)( long value
, void *user_data
), void *user_data
)
2456 if( V_BOOL_TAB
[__AVT_USEHT_V2
].VALUE
)
2457 return (ht
*)controlled_dupht( orig
, func
, user_data
);
2460 for( i
=0 ; i
<h
->length
; i
++ )
2461 h
->pElem
[i
].value
= func( h
->pElem
[i
].value
, user_data
);
2466 ht_v2
* controlled_dupht_v2( ht_v2
*orig
, long (*func
)( long value
, void *user_data
), void *user_data
)
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
);
2482 long controlled_addhtitem(ht
*pTable
, void *key
, long (*func
)(int newone
, long old_value
, void *user_data
), void *user_data
)
2485 htitem
*pEl
, *FirstDEL
=NULL
;
2488 if( V_BOOL_TAB
[__AVT_USEHT_V2
].VALUE
)
2489 return controlled_addhtitem_v2( (ht_v2
*)pTable
, key
, func
, user_data
);
2491 if (pTable
->count
++ > (pTable
->length
) * 8 / 10) {
2493 return controlled_addhtitem(pTable
, key
, func
, user_data
);
2496 indice
= hash(key
) % pTable
->length
;
2498 if (co
++ > HMAX_CALLS
) {
2499 if (pTable
->count
> (pTable
->length
) * 2 / 10 || (co
>= pTable
->length
)) {
2501 return controlled_addhtitem(pTable
, key
, func
, user_data
);
2502 } else if(TRACE_MODE
== 'Y') {
2504 (void)fprintf (stderr
, "*** mbk warning ***\n");
2505 (void)fprintf (stderr
, "reallocht undone : density is too low\n");
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
);
2514 if (pEl
->value
== EMPTYHT
|| pEl
->value
== DELETEHT
) {
2516 (void)fprintf(stderr
, "*** mbk error ***\n");
2517 (void)fprintf(stderr
, "controlled_addhtitem impossible : value is EMPTYHT or DELETEHT\n");
2522 } else if ((long) pEl
->key
== (long) key
) {
2524 pEl
->value
= func(0, pEl
->value
, user_data
);
2525 if (pEl
->value
== EMPTYHT
|| pEl
->value
== DELETEHT
) {
2527 (void)fprintf(stderr
, "*** mbk error ***\n");
2528 (void)fprintf(stderr
, "controlled_addhtitem impossible : value is EMPTYHT or DELETEHT\n");
2533 indice
= (indice
+ 1) % pTable
->length
;
2537 long sethtitem(pTable
, key
, value
)
2543 htitem
*pEl
, *FirstDEL
=NULL
;
2546 if( V_BOOL_TAB
[__AVT_USEHT_V2
].VALUE
)
2547 return sethtitem_v2( (ht_v2
*)pTable
, key
, value
);
2549 if (value
== EMPTYHT
|| value
== DELETEHT
) {
2551 (void)fprintf(stderr
, "*** mbk error ***\n");
2552 (void)fprintf(stderr
, "sethtitem impossible : value is EMPTYHT or DELETEHT\n");
2555 if (pTable
->count
++ > (pTable
->length
) * 8 / 10) {
2557 return sethtitem(pTable
, key
, value
);
2560 indice
= hash(key
) % pTable
->length
;
2562 if (co
++ > HMAX_CALLS
) {
2563 if (pTable
->count
> (pTable
->length
) * 2 / 10 || (co
>= pTable
->length
)) {
2565 return sethtitem(pTable
, key
, value
);
2566 } else if(TRACE_MODE
== 'Y') {
2568 (void)fprintf (stderr
, "*** mbk warning ***\n");
2569 (void)fprintf (stderr
, "reallocht undone : density is too low\n");
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
;
2579 } else if ((long) pEl
->key
== (long) key
) {
2584 indice
= (indice
+ 1) % pTable
->length
;
2588 /*******************************************************************************
2589 * function delhtitem, delete an element in a hash table *
2590 *******************************************************************************/
2591 long delhtitem(pTable
, key
)
2599 if( V_BOOL_TAB
[__AVT_USEHT_V2
].VALUE
)
2600 return delhtitem_v2( (ht_v2
*)pTable
, key
);
2602 indice
= hash(key
) % pTable
->length
;
2604 if (co
++ > HMAX_CALLS
) {
2605 if (pTable
->count
> (pTable
->length
) * 2 / 10 || (co
>= pTable
->length
)) {
2608 return delhtitem(pTable
, key
);
2611 pEl
= (pTable
->pElem
) + indice
;
2612 if (pEl
->value
!= EMPTYHT
&& pEl
->value
!= DELETEHT
) {
2613 if ((long) key
== (long)pEl
->key
) {
2615 pEl
->value
= DELETEHT
;
2618 } else if (pEl
->value
== EMPTYHT
)
2620 indice
= (indice
+ 1) % pTable
->length
;
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
2629 end is reached when nextitem contain EMPTYHT.
2630 *******************************************************************************/
2632 void scanhtkey(pTable
, first
, nextkey
, nextitem
)
2642 if( V_BOOL_TAB
[__AVT_USEHT_V2
].VALUE
) {
2643 scanhtkey_v2( (ht_v2
*)pTable
, first
, nextkey
, nextitem
);
2650 indice
= hash(*nextkey
) % pTable
->length
;
2651 co
=pTable
->length
+1;
2653 pEl
= (pTable
->pElem
) + indice
;
2654 if( pEl
->key
== *nextkey
)
2658 if( indice
== pTable
->length
)
2666 fprintf( stderr
, "Internal error in scanhtitem().\n" );
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
;
2683 *nextitem
= EMPTYHT
;
2686 /*******************************************************************************
2687 * display contents of an hash table *
2688 *******************************************************************************/
2689 void viewht(pTable
, pout
)
2694 htitem
*pEl
= pTable
->pElem
;
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
);
2710 /*******************************************************************************
2711 * realloc space to adapt hash table size to number of entries *
2712 *******************************************************************************/
2713 static void reallocht(pTable
)
2721 pEl
= pTable
->pElem
;
2723 ratio
= (double)pTable
->count
/ (double)pTable
->length
;
2724 if (ratio
> 0.8) ratio
= 1;
2725 else if (ratio
< 0.3) ratio
= 0.3;
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
);
2733 mbkfree(pTable
->pElem
);
2734 pTable
->length
= tabBis
->length
;
2735 pTable
->pElem
= tabBis
->pElem
;
2736 pTable
->count
= tabBis
->count
;
2740 /*******************************************************************************
2741 * function addvt, create a pointer table *
2742 *******************************************************************************/
2743 voidt
*addvt(length
)
2744 unsigned int length
;
2752 ptvt
= (voidt
*)mbkalloc(sizeof(voidt
));
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
;
2762 /*******************************************************************************
2763 * function delvt, delete a pointer table *
2764 *******************************************************************************/
2768 if (table
->data
!= NULL
) mbkfree(table
->data
);
2772 /*******************************************************************************
2773 * function addvtitem, add an element in a pointer table *
2774 *******************************************************************************/
2775 int addvtitem(table
,data
)
2781 if(table
->size
== table
->length
)
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
;
2788 (table
->data
)[(table
->size
)++] = data
;
2789 return(table
->size
- 1) ;
2792 /*******************************************************************************
2793 * function setvtitem, set an element in a pointer table *
2794 *******************************************************************************/
2795 void setvtitem(table
,item
,data
)
2802 if(item
>= table
->length
)
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 ;
2811 (table
->data
)[item
] = data
;
2814 /*******************************************************************************
2815 * function getvtitem, get an element in a pointer table *
2816 *******************************************************************************/
2817 void *getvtitem(table
,item
)
2821 if(item
>= table
->length
)
2822 return((void *)EMPTYHT
) ;
2824 return((table
->data
)[item
]) ;
2827 /*******************************************************************************
2828 * function delvtitem, del an element in a interger table *
2829 *******************************************************************************/
2830 void delvtitem(table
,item
)
2834 if(item
>= table
->length
)
2837 (table
->data
)[item
] = (void *)DELETEHT
;
2840 /*******************************************************************************
2841 * function addit, create a integer table *
2842 *******************************************************************************/
2844 unsigned int length
;
2852 ptit
= (it
*)mbkalloc(sizeof(it
));
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
;
2862 /*******************************************************************************
2863 * function delit, delete a integer table *
2864 *******************************************************************************/
2868 if (table
->data
!= NULL
) mbkfree(table
->data
);
2872 /*******************************************************************************
2873 * function addititem, add an element in a interger table *
2874 *******************************************************************************/
2875 int addititem(table
,data
)
2881 if(table
->size
== table
->length
)
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
;
2888 (table
->data
)[(table
->size
)++] = data
;
2889 return(table
->size
- 1) ;
2892 /*******************************************************************************
2893 * function setititem, set an element in a interger table *
2894 *******************************************************************************/
2895 void setititem(table
,item
,data
)
2902 if(item
>= table
->length
)
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 ;
2911 (table
->data
)[item
] = data
;
2914 /*******************************************************************************
2915 * function getititem, add an element in a interger table *
2916 *******************************************************************************/
2917 long getititem(table
,item
)
2921 if(item
>= table
->length
)
2922 return((long)EMPTYHT
) ;
2924 return((table
->data
)[item
]) ;
2927 /*******************************************************************************
2928 * function delititem, del an element in a interger table *
2929 *******************************************************************************/
2930 void delititem(table
,item
)
2934 if(item
>= table
->length
)
2937 (table
->data
)[item
] = (long)DELETEHT
;
2940 /*******************************************************************************
2941 * function adddt, create a integer table *
2942 *******************************************************************************/
2944 unsigned int length
;
2952 ptdt
= (dt
*)mbkalloc(sizeof(dt
));
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
;
2962 /*******************************************************************************
2963 * function deldt, delete a integer table *
2964 *******************************************************************************/
2968 if (table
->data
!= NULL
) mbkfree(table
->data
);
2972 /*******************************************************************************
2973 * function adddtitem, add an element in a interger table *
2974 *******************************************************************************/
2975 int adddtitem(table
,data
)
2981 if(table
->size
== table
->length
)
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
;
2988 (table
->data
)[(table
->size
)++] = data
;
2989 return(table
->size
- 1) ;
2992 /*******************************************************************************
2993 * function setdtitem, set an element in a interger table *
2994 *******************************************************************************/
2995 void setdtitem(table
,item
,data
)
3002 if(item
>= table
->length
)
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 ;
3011 (table
->data
)[item
] = data
;
3014 /*******************************************************************************
3015 * function getdtitem, add an element in a interger table *
3016 *******************************************************************************/
3017 double getdtitem(table
,item
)
3021 if(item
>= table
->length
)
3022 return((double)EMPTYHT
) ;
3024 return((table
->data
)[item
]) ;
3027 /*******************************************************************************
3028 * function deldtitem, del an element in a interger table *
3029 *******************************************************************************/
3030 void deldtitem(table
,item
)
3034 if(item
>= table
->length
)
3037 (table
->data
)[item
] = (double)DELETEHT
;
3040 /*******************************************************************************
3041 * All that needed for a cute banner, by Frederic Petrot *
3042 * Used to be a standalone library *
3043 *******************************************************************************/
3045 #define WINDOW_SIZE 81
3048 static char screen
[LINES
][WINDOW_SIZE
];
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'
3059 static void banner(s
, police
, nl
)
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';
3073 filling the buffer with direct table output. */
3075 for (i
= 0; i
< nl
; i
++) {
3076 if ((j
= indx(*s
)) == -1) {
3078 "alliancebanner: Error: Character out of [0-9A-Za-z] range\n");
3081 line
= police
[j
][i
];
3082 if (strlen(line
) + strlen(screen
[i
]) >= WINDOW_SIZE
) {
3084 "alliancebanner: Error: Resulting size bigger than %d columns not allowed\n",
3088 strcat(screen
[i
], line
);
3089 if (*(s
+ 1) != '\0')
3090 strcat(screen
[i
], " ");
3094 for (m
= l
= -1, j
= 0; j
< nl
; j
++)
3095 for (i
= 0; i
< WINDOW_SIZE
; i
++)
3096 if (screen
[j
][i
] == '@') {
3102 k
= strlen(screen
[0]);
3104 output on stdout. */
3106 for (j
= m
; j
<= l
; j
++) {
3107 for (i
= 0; i
< (WINDOW_SIZE
- k
) / 2; i
++)
3109 for (i
= 0; i
< k
; i
++)
3110 putc(screen
[j
][i
], stdout
);
3115 static void cartouche(tool
, tv
, comment
, date
, av
, authors
, contrib
)
3116 char *tool
, *tv
, *comment
, *date
, *av
, *authors
, *contrib
;
3119 static char *msg
[6] = {
3121 "Alliance CAD System %s,\"%s %s",
3122 "Copyright (c) %s-%d,\"ASIM/LIP6/UPMC",
3124 "Contributor(s):\"%s",
3125 "E-mail support:\"alliance-support@asim.lip6.fr"
3130 char day
[4], month
[4];
3131 int year
, nday
, hour
, minute
, second
;
3134 (void)sscanf(ctime(&timer
), "%s %s %d %d:%d:%d %d",
3135 day
, month
, &nday
, &hour
, &minute
, &second
, &year
);
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';
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
);
3148 sprintf(screen
[2], msg
[2], date
, year
);
3149 if (authors
!= (char *)0 )
3150 sprintf(screen
[3], msg
[3],authors
);
3152 screen
[3][0] = '\0';
3153 if (contrib
!= (char *)0 )
3154 sprintf(screen
[4], msg
[4],contrib
);
3156 screen
[4][0] = '\0';
3158 strcat(screen
[5], msg
[5]);
3160 for (i
= 1; i
< 6; i
++) {
3161 msgl
[i
] = strlen(screen
[i
]);
3162 j
= j
< msgl
[i
] ? msgl
[i
] : j
;
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';
3170 if (screen
[i
][k
] == '"') { /* only once per line */
3171 for (; l
<= j
- msgl
[i
]; l
++)
3172 screen
[i
+ 6][k
+ l
] = ' ';
3175 screen
[i
+ 6][k
+ l
] = screen
[i
][k
];
3178 output on stdout. */
3179 i
= strlen(comment
);
3181 for (k
= 0; k
< (WINDOW_SIZE
- i
) / 2; k
++)
3185 for (i
= 1; i
< 6; i
++) {
3186 if (screen
[i
][0]=='\0') continue;
3187 for (k
= 0; k
< (WINDOW_SIZE
- j
) / 2; k
++)
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
);
3197 void alliancebanner_with_contrib( tool
, tv
, comment
, date
, av
, authors
, contrib
)
3198 char *tool
, *tv
, *comment
, *date
, *av
, *authors
, *contrib
;
3200 banner(tool
, Unknown_Bold_Normal_14
, 15);
3201 cartouche(tool
, tv
, comment
, date
, av
, authors
,contrib
);
3204 void alliancebanner_with_authors( tool
, tv
, comment
, date
, av
, authors
)
3205 char *tool
, *tv
, *comment
, *date
, *av
, *authors
;
3207 alliancebanner_with_contrib( tool
, tv
, comment
, date
, av
, authors
, NULL
);
3211 void alliancebanner(tool
, tv
, comment
, date
, av
)
3212 char *tool
, *tv
, *comment
, *date
, *av
;
3214 alliancebanner_with_contrib( tool
, tv
, comment
, date
, av
, NULL
, NULL
);
3218 * Contributed to by Ludovic Jacomme
3219 **************************/
3220 ptype_list
*HEAD_MBKDEBUG
= NULL
;
3221 char MBK_DEBUG_ON
= 0;
3223 static void trapdebug()
3225 ptype_list
*ScanDebug
;
3227 for ( ScanDebug
= HEAD_MBKDEBUG
;
3228 ScanDebug
!= (ptype_list
*)NULL
;
3229 ScanDebug
= ScanDebug
->NEXT
)
3231 fprintf( stdout
, "mbkdebug: file %s line %ld\n",
3232 (char *)ScanDebug
->DATA
, ScanDebug
->TYPE
);
3237 signal( SIGQUIT
, trapdebug
);
3238 signal( SIGSEGV
, SIG_DFL
);
3239 signal( SIGBUS
, SIG_DFL
);
3240 signal( SIGILL
, SIG_DFL
);
3245 signal( SIGSEGV
, trapdebug
);
3246 signal( SIGBUS
, trapdebug
);
3247 signal( SIGILL
, trapdebug
);
3248 signal( SIGQUIT
, trapdebug
);
3254 ** Added by Ludovic Jacomme (The slave)
3255 ** in order to "trap" exit with Graal/Dreal etc ...
3259 void mbkexit( ExitValue )
3263 if(MBK_EXIT_KILL == 'Y') kill( getpid(), SIGTERM ) ;
3264 else if ( MBK_EXIT_FUNCTION != NULL )
3266 (*MBK_EXIT_FUNCTION)( ExitValue );
3268 else exit(ExitValue) ;
3274 /* To compile with gcc under SunOS */
3278 void *dlopen(path
, mode
)
3279 char *path
; int mode
;
3283 void *dlsym(handle
, symbol
)
3284 void *handle
; char *symbol
;
3299 void CreateHeap(int size
, int granularity
, HeapAlloc
*myheap
)
3301 if (size
<(signed)sizeof(void *)) size
=sizeof(void *);
3303 myheap
->blocks_to_free
=NULL
;
3304 if (granularity
==0) granularity
=BUFSIZE
;
3305 myheap
->granularity
=granularity
;
3312 void DeleteHeap(HeapAlloc
*myheap
)
3314 #ifndef NOHEAPALLOCFORHEAP
3316 for (cl
=myheap
->blocks_to_free
; cl
!=NULL
; cl
=cl
->NEXT
)
3318 freechain(myheap
->blocks_to_free
);
3322 void *AddHeapItem(HeapAlloc
*myheap
)
3324 #ifdef NOHEAPALLOCFORHEAP
3325 return mbkalloc(myheap
->size
);
3328 if (myheap
->HEAD
== NULL
) {
3330 pt
= (char *)mbkalloc(myheap
->granularity
*myheap
->size
);
3331 myheap
->blocks_to_free
=addchain(myheap
->blocks_to_free
, pt
);
3333 for (i
= 1; i
< myheap
->granularity
; i
++)
3335 *(void **)pt
= pt
+myheap
->size
;
3338 // printf("<%d>",(pt-(char *)myheap->HEAD)/myheap->size);
3339 *(void **)pt
= NULL
;
3341 myheap
->__SIZE__
+=sizeof(chain_list
*)+myheap
->granularity
*myheap
->size
;
3346 myheap
->HEAD
= *(void **)myheap
->HEAD
;
3351 void DelHeapItem(HeapAlloc
*myheap
, void *item
)
3353 #ifdef NOHEAPALLOCFORHEAP
3356 *(void **)item
=myheap
->HEAD
;
3361 size_t getsizeofHeapAlloc( HeapAlloc
*heap
)
3367 for( chain
= heap
->blocks_to_free
; chain
; chain
= chain
->NEXT
)
3368 size
= size
+ heap
->size
* heap
->granularity
+ sizeof( chain_list
);
3378 int s2sort_sortfunc(const void *a0
, const void *b0
)
3380 s2sort
*a
=(s2sort
*)a0
, *b
=(s2sort
*)b0
;
3381 return strcmp(b
->key
, a
->key
);
3384 chain_list
*GetAllHTElems_sub(ht
*pTable
, int sort
)
3386 chain_list
*cl
=NULL
, *ch
=NULL
;
3391 if( V_BOOL_TAB
[__AVT_USEHT_V2
].VALUE
)
3392 return GetAllHTElems_sub_v2( (ht_v2
*)pTable
, sort
);
3394 if (!pTable
) return cl
;
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
);
3406 if (!sort
) return cl
;
3408 s2c
=(s2sort
*)mbkalloc(sizeof(s2sort
)*cnt
);
3409 for (i
=0; i
<cnt
; i
++, cl
=delchain(cl
, cl
), ch
=delchain(ch
,ch
))
3411 s2c
[i
].key
=(char *)ch
->DATA
;
3412 s2c
[i
].data
=cl
->DATA
;
3415 qsort(s2c
, cnt
, sizeof(s2sort
), s2sort_sortfunc
);
3417 for (i
=0, cl
=NULL
; i
<cnt
; i
++)
3418 cl
=addchain(cl
, s2c
[i
].data
);
3425 chain_list
*GetAllHTElems_sub_v2( ht_v2
*h
, int sort
)
3427 chain_list
*cl
=NULL
, *ch
=NULL
;
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
);
3444 if (!sort
) return cl
;
3446 s2c
=(s2sort
*)mbkalloc(sizeof(s2sort
)*cnt
);
3447 for (i
=0; i
<cnt
; i
++, cl
=delchain(cl
, cl
), ch
=delchain(ch
,ch
))
3449 s2c
[i
].key
=(char *)ch
->DATA
;
3450 s2c
[i
].data
=cl
->DATA
;
3453 qsort(s2c
, cnt
, sizeof(s2sort
), s2sort_sortfunc
);
3455 for (i
=0, cl
=NULL
; i
<cnt
; i
++)
3456 cl
=addchain(cl
, s2c
[i
].data
);
3463 chain_list
*GetAllHTElems(ht
*pTable
)
3465 return GetAllHTElems_sub(pTable
, 0);
3468 chain_list
*GetAllHTKeys(ht
*pTable
)
3470 chain_list
*cl
=NULL
;
3474 if( V_BOOL_TAB
[__AVT_USEHT_V2
].VALUE
)
3475 return GetAllHTKeys_v2( (ht_v2
*)pTable
);
3477 if (!pTable
) return cl
;
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
);
3489 chain_list
* GetAllHTKeys_v2( ht_v2
*h
)
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
);
3502 ht_v2
*addht_v2(long len
)
3506 h
=(ht_v2
*)mbkalloc(sizeof(ht_v2
));
3509 h
->size
=(len
+127)/128;
3515 h
->size
=namealloc_primes
[0];
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
);
3525 void delht_v2(ht_v2
*h
)
3528 mbkfree(h
->ITEM_HASHTABLE
);
3532 static void ht_v2_rehash(ht_v2
*h
)
3534 htitem_v2
**nn
, *cl
, *next
;
3538 if (h
->primes_index
==-1)
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
))
3549 // fprintf(stdout,".rehashing ht: %d -> %d...",h->size,namealloc_primes[prm]); fflush(stdout);
3551 nn
=(htitem_v2
**)mbkalloc(sizeof(htitem_v2
*)* namealloc_primes
[prm
]);
3552 for (i
=0;i
<namealloc_primes
[prm
];i
++)
3555 for (i
=0;i
<h
->size
;i
++)
3557 for (cl
=h
->ITEM_HASHTABLE
[i
]; cl
!=NULL
; cl
=next
)
3560 index
=hash(cl
->key
) % namealloc_primes
[prm
];
3565 mbkfree(h
->ITEM_HASHTABLE
);
3566 h
->ITEM_HASHTABLE
=nn
;
3567 h
->size
=namealloc_primes
[prm
];
3568 // fprintf(stdout,"done\n");
3572 long gethtitem_v2(ht_v2
*h
, void *key
)
3577 index
=hash(key
) % h
->size
;
3578 head
=h
->ITEM_HASHTABLE
[index
];
3579 while (head
!=NULL
&& head
->key
!=key
) head
=head
->next
;
3581 if (head
==NULL
) return EMPTYHT
;
3585 ht_v2
*dupht_v2( ht_v2
*orig
)
3591 dup
= addht_v2( orig
->size
);
3593 scanhtkey_v2( orig
, 1, &nextkey
, &nextitem
);
3594 while( nextitem
!= EMPTYHT
) {
3595 addhtitem_v2( dup
, nextkey
, nextitem
);
3596 scanhtkey_v2( orig
, 0, &nextkey
, &nextitem
);
3602 void scanhtkey_v2( ht_v2
*h
, int first
, void **nextkey
, long *nextitem
)
3611 i
= hash( *nextkey
) % h
->size
;
3613 for( item
= h
->ITEM_HASHTABLE
[i
] ; item
->key
!= *nextkey
; item
= item
->next
) ;
3617 *nextkey
= item
->key
;
3618 *nextitem
= item
->value
;
3626 for( i
=i
; i
<h
->size
&& !h
->ITEM_HASHTABLE
[i
] ; i
++ );
3630 *nextitem
= EMPTYHT
;
3633 *nextkey
= h
->ITEM_HASHTABLE
[i
]->key
;
3634 *nextitem
= h
->ITEM_HASHTABLE
[i
]->value
;
3639 void set_ht_v2_rehashlimit(ht_v2
*h
, int value
)
3641 h
->rehashlimit
=value
;
3644 long sethtitem_v2(ht_v2
*h
, void *key
, long value
)
3646 return addhtitem_v2( h
, key
, value
);
3649 long controlled_addhtitem_v2(ht_v2
*h
, void *key
, long (*func
)(int newone
, long old_value
, void *user_data
), void *user_data
)
3655 index
=hash(key
) % h
->size
;
3656 hi
=h
->ITEM_HASHTABLE
[index
];
3657 while(hi
!=NULL
&& hi
->key
!=key
) { hi
=hi
->next
; depth
++; }
3661 hi
=(htitem_v2
*)AddHeapItem(&h
->ha
);
3662 hi
->next
=h
->ITEM_HASHTABLE
[index
];
3663 h
->ITEM_HASHTABLE
[index
]=hi
;
3665 hi
->value
=func( 1, EMPTYHT
, user_data
);
3668 hi
->value
=func( 0, hi
->value
, user_data
);
3673 if (depth
>h
->rehashlimit
&& (h
->primes_index
==-1 || (unsigned)h
->primes_index
<(sizeof(namealloc_primes
)/sizeof(*namealloc_primes
))-1))
3679 long addhtitem_v2(ht_v2
*h
, void *key
, long value
)
3682 htitem_v2
*hi
, *head
;
3685 index
=hash(key
) % h
->size
;
3686 head
=h
->ITEM_HASHTABLE
[index
];
3687 while (head
!=NULL
&& head
->key
!=key
) { head
=head
->next
; depth
++; }
3691 hi
=(htitem_v2
*)AddHeapItem(&h
->ha
);
3692 hi
->next
=h
->ITEM_HASHTABLE
[index
];
3693 h
->ITEM_HASHTABLE
[index
]=hi
;
3703 if (depth
>h
->rehashlimit
&& (h
->primes_index
==-1 || (unsigned)h
->primes_index
<(sizeof(namealloc_primes
)/sizeof(*namealloc_primes
))-1))
3709 long delhtitem_v2(ht_v2
*h
, void *key
)
3713 htitem_v2
*head
, *prev
=NULL
;
3715 index
=hash(key
) % h
->size
;
3716 head
=h
->ITEM_HASHTABLE
[index
];
3717 while (head
!=NULL
&& head
->key
!=key
) prev
=head
, head
=head
->next
;
3719 if (head
==NULL
) return EMPTYHT
;
3722 h
->ITEM_HASHTABLE
[index
]=head
->next
;
3724 prev
->next
=head
->next
;
3727 DelHeapItem(&h
->ha
, head
);
3731 size_t getsizeofht_v2( ht_v2
*ht
)
3736 size
= sizeof( ht_v2
) ;
3737 size
= size
+ sizeof( htitem_v2
* ) * ht
->size
;
3738 size
= size
+ getsizeofHeapAlloc( & ht
->ha
);
3742 chain_list
*GetAllHTElems_v2(ht_v2
*h
)
3744 chain_list
*cl
=NULL
;
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
);
3755 void ht_v2Stat(ht_v2
*h
)
3757 int i
, nb
, max
=0,moy
=0, nb0
=0;
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
)
3768 for (nb
=0, cl
=h
->ITEM_HASHTABLE
[i
];cl
!=NULL
; cl
=cl
->next
, nb
++) ;
3772 printf(" chain length: mean=%.1f max=%d\n",(float)moy
/(float)nb0
,max
);
3775 #ifdef MALLOC_HISTOGRAM
3784 void malloc_hook_error()
3790 void *my_malloc_hook(char *file
, int line
, size_t size
)
3794 if (!MALLOC_HISTO_mutex
) return mbkalloc (size
);
3795 MALLOC_HISTO_mutex
=0;
3796 result
= malloc (size
+sizeof(long)*2);
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);
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;
3812 addhtitem_v2(MALLOC_HISTO
, (void *)size
, val
);
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;
3821 void my_free_hook(void *block
)
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)
3831 MALLOC_HOOK_ERRORS
++;
3832 malloc_hook_error();
3838 *(long *)(result
+sizeof(long))=0;
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
++;
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;
3851 // printf ("free (%ld)\n", (unsigned long)size, result);
3854 void *my_realloc_hook(char *file
, int line
, void *block
, size_t size
)
3857 unsigned long size0
;
3859 if (!MALLOC_HISTO_mutex
) return mbkrealloc(block
, size
);
3860 result
-=sizeof(long)*2;
3861 if (*(long *)(result
+sizeof(long))!=0x12345678)
3863 MALLOC_HOOK_ERRORS
++;
3865 malloc_hook_error();
3866 return realloc(block
, size
);
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
++;
3874 if ((val
=gethtitem_v2(MALLOC_HISTO
, (void *)size0
))==EMPTYHT
) MALLOC_HOOK_ERRORS
++;
3875 else addhtitem_v2(MALLOC_HISTO
, (void *)size0
, val
-1);
3877 result
=realloc(result
, size
+sizeof(long)*2);
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);
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;
3890 addhtitem_v2(MALLOC_HISTO
, (void *)size
, val
);
3892 *(long *)result
=size
;
3893 *(long *)(result
+sizeof(long))=0x12345678;
3894 MALLOC_HISTO_mutex
=1;
3895 return result
+sizeof(long)*2;
3899 void setup_malloc_hook()
3901 if (MALLOC_HISTO_mutex
) return;
3902 MALLOC_HISTO
=addht_v2(19);
3903 MALLOC_HISTO_mutex
=1;
3906 void reset_malloc_hook()
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;
3919 unsigned long size
, nb
, tot
;
3921 static int mhtos_mode
;
3922 int mhtos_sort(const void *a
, const void *b
)
3924 mhtos
*a0
=(mhtos
*)a
, *b0
=(mhtos
*)b
;
3927 if (a0
->size
<b0
->size
) return -1;
3928 else if (a0
->size
>b0
->size
) return 1;
3933 if (a0
->tot
<b0
->tot
) return -1;
3934 else if (a0
->tot
>b0
->tot
) return 1;
3939 void malloc_hook_stats(char *filename
, int mode
)
3949 if (!MALLOC_HISTO_mutex
) return;
3951 if (strcmp(filename
,"stdout")==0) f
=stdout
;
3952 else f
=fopen(filename
,"wt");
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
)
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
;
3970 qsort(tab
, tot
, sizeof(mhtos
), mhtos_sort
);
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
);
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
);
3980 static void mbk_remove_1(char *buf
)
3984 while (buf
[i
]!='\0')
3986 if (buf
[i
]!=1) buf
[j
++]=buf
[i
];
3992 char *mbk_devect_sub(char *name
, char *leftb
, char *rightb
, char *sepb
, char *buf
, int testchar(int))
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.
4002 testchar = isdigit()
4003 traitement special des wildcards C commencant par %
4008 char emptystyring
[]="\0";
4010 if( !leftb
) leftb
= emptystyring
;
4011 if( !rightb
) rightb
= emptystyring
;
4012 if( !sepb
) sepb
= emptystyring
;
4015 if (!MBK_DEVECT
|| buf
[0]=='\0') return buf
;
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
;
4022 if (rightb
[i
]=='\0' || leftb
[i
]=='\0') {
4023 if (buf
[0]=='%') {l
--; buf
[l
]=1;}
4025 for( i
=l
; i
&& testchar((unsigned char)buf
[i
]) ; i
-- );
4027 for(j
=0; sepb
[j
] && sepb
[j
]!=buf
[i
]; j
++ );
4028 if(sepb
[j
] && !(buf
[0]=='%' && i
!=0 && buf
[i
-1]!='\\')) {
4030 if (buf
[0]=='%') { buf
[i
-1]=1; mbk_remove_1(buf
); }
4038 for( j
=0; sepb
[j
] && sepb
[j
]!=buf
[i
] ; j
++ );
4039 if( sepb
[j
] && !(buf
[0]=='%' && i
!=0 && buf
[i
-1]!='\\')) {
4042 if (buf
[0]=='%') { buf
[i
-1]=1; mbk_remove_1(buf
); }
4054 if (buf
[0]=='%') { l
--; buf
[l
]=1; }
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]!='\\')) {
4059 if (buf
[0]=='%') { buf
[i
-1]=1; mbk_remove_1(buf
); }
4064 while (l
>0 && buf
[l
]!=leftb
[i
]) l
--;
4065 if (l
&& !(buf
[0]=='%' && buf
[l
-1]!='\\')) {
4067 if (buf
[0]=='%') { buf
[l
-1]=1; mbk_remove_1(buf
); }
4075 char *mbk_decodevector(char *name
)
4078 return namealloc(mbk_devect_sub(name
, MBK_VECTOR_OPEN
, MBK_VECTOR_CLOSE
, MBK_VECTOR_SINGLE
, res
, isdigit
));
4081 char *mbk_decodeanyvector(char *name
)
4084 return namealloc(mbk_devect_sub(name
, MBK_VECTOR_OPEN
, MBK_VECTOR_CLOSE
, MBK_VECTOR_SINGLE
, res
, NULL
));
4087 char *mbk_devect(char *name
, char *leftb
, char *rightb
)
4090 return namealloc(mbk_devect_sub(name
, leftb
, rightb
, NULL
, res
, NULL
));
4093 char *mbk_vect_sub(char *name
, char leftb
, char rightb
, char *buf
)
4099 while (name
[i
]!='\0')
4101 if (name
[i
]==' ' && !done
)
4104 if (name
[0]=='%' && leftb
=='[') buf
[j
++]='\\';
4113 if (name
[0]=='%' && rightb
==']') buf
[j
++]='\\';
4120 char *mbk_vect(char *name
, char leftb
, char rightb
)
4123 return namealloc(mbk_vect_sub(name
, leftb
, rightb
, res
));
4127 int mbk_ReadFlags(int varnum
, mbk_options_pack_struct
*gen_opack
, int nbopt
, int warn
, int initval
)
4133 int GEN_OPTIONS_PACK
=initval
;
4135 str
=V_STR_TAB
[varnum
].VALUE
;
4142 for (i
=0;i
<nbopt
; i
++)
4143 if (strcasecmp(l
, gen_opack
[i
].name
)==0)
4145 GEN_OPTIONS_PACK
|=gen_opack
[i
].mask
;
4148 else if (l
[0]=='!' && strcasecmp(&l
[1], gen_opack
[i
].name
)==0)
4150 GEN_OPTIONS_PACK
&=~gen_opack
[i
].mask
;
4153 if (i
>=nbopt
&& warn
)
4155 fprintf(stderr
,"warning: option '%s' is unknown\n", l
);
4157 l
=strtok(NULL
, ",");
4160 return GEN_OPTIONS_PACK
;
4163 char* mbk_getvssname()
4165 static char *ptvss
=NULL
;
4166 char buffer
[BUFSIZE
] ;
4171 l
= strlen( GLOBAL_VSS
);
4173 /* Passe tous les caractères ':' ou '*' */
4175 i
< l
&& ( GLOBAL_VSS
[i
] == ':' || GLOBAL_VSS
[i
] == '*' ) ;
4180 /* retiens tous les caractères différents de ':' ou '*' */
4182 i
< l
&& GLOBAL_VSS
[i
] != ':' && GLOBAL_VSS
[i
] != '*' ;
4184 ) buffer
[p
] = GLOBAL_VSS
[i
] ;
4188 ptvss
= namealloc( buffer
);
4194 char* mbk_getvddname()
4196 static char *ptvdd
=NULL
;
4197 char buffer
[BUFSIZE
] ;
4202 l
= strlen( GLOBAL_VDD
);
4204 /* Passe tous les caractères ':' ou '*' */
4206 i
< l
&& ( GLOBAL_VDD
[i
] == ':' || GLOBAL_VDD
[i
] == '*' ) ;
4211 /* retiens tous les caractères différents de ':' ou '*' */
4213 i
< l
&& GLOBAL_VDD
[i
] != ':' && GLOBAL_VDD
[i
] != '*' ;
4215 ) buffer
[p
] = GLOBAL_VDD
[i
] ;
4219 ptvdd
= namealloc( buffer
);
4225 void mbk_dumpfile(FILE *infile
, FILE *outfile
, int level
)
4229 while (fgets(buf
, 32000, infile
)!=NULL
)
4231 avt_log(LOGCONFIG
, level
, "%s", buf
);
4233 avt_log(LOGCONFIG
, level
, "\n");
4236 unsigned int mbk_get_a_seed()
4239 if (!gettimeofday(&tp
, NULL
))
4240 return tp
.tv_sec
+(tp
.tv_usec
<<21)+(getpid()<<15);
4242 return time(NULL
)+(getpid()<<15);
4246 // algo Random Number generator 'Mersenne Twister'
4247 // simplifie a mort par zinaps
4256 #define MERS_A 0x9908B0DF
4257 #define MERS_B 0x9D2C5680
4258 #define MERS_C 0xEFC60000
4260 #ifdef USE_DEFAULT_RANDR
4261 unsigned int mbk_rand_r(unsigned int *mt
)
4266 unsigned int mbk_rand_r(unsigned int *mt
) {
4267 // Generate 32 random bits
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
};
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];}
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];}
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];
4294 // Tempering (May be omitted):
4296 y
^= (y
<< MERS_S
) & MERS_B
;
4297 y
^= (y
<< MERS_T
) & MERS_C
;
4305 int mbk_sumchar(char *name
)
4309 if (name
==NULL
) return 0x12345;
4310 for (i
=0, j
=0; name
[i
]!='\0'; i
++)
4312 if (CASE_SENSITIVE
!='Y') c
=tolower(name
[i
]);
4319 void mbk_substenvvariable(char *ref
, char *res
)
4326 if (ref
[i
]=='$' && isalpha(ref
[i
+1]))
4330 while (ref
[i
]!='\0' && (isalnum(ref
[i
]) || ref
[i
]=='_')) i
++;
4333 var
=getenv(&ref
[k
]);
4335 avt_errmsg (MBK_ERRMSG
, "069", AVT_ERROR
, &ref
[k
]);
4337 for (k
=0; var
[k
]!='\0'; k
++) res
[j
++]=var
[k
];
4344 } while (ref
[i
]!='\0');