2 * Copyright (c) 2014 - 2015 Steffen (Daode) Nurpmeso <sdaoden@users.sf.net>.
4 * Copyright (C) 1989 - 1992, 2002, 2004
5 * Free Software Foundation, Inc.
6 * Written by James Clark (jjc@jclark.com)
8 * This is free software; you can redistribute it and/or modify it under
9 * the terms of the GNU General Public License as published by the Free
10 * Software Foundation; either version 2, or (at your option) any later
13 * This is distributed in the hope that it will be useful, but WITHOUT ANY
14 * WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
18 * You should have received a copy of the GNU General Public License along
19 * with groff; see the file COPYING. If not, write to the Free Software
20 * Foundation, 51 Franklin St - Fifth Floor, Boston, MA 02110-1301, USA.
30 const char **symbol::table
= 0;
31 int symbol::table_used
= 0;
32 int symbol::table_size
= 0;
33 char *symbol::block
= 0;
34 int symbol::block_size
= 0;
36 const symbol NULL_SYMBOL
;
37 const symbol
EMPTY_SYMBOL("");
42 const int BLOCK_SIZE
= 1024;
43 // the table will increase in size as necessary
44 // the size will be chosen from the following array
45 // add some more if you want
46 static const unsigned int table_sizes
[] = {
47 101, 503, 1009, 2003, 3001, 4001, 5003, 10007, 20011, 40009, 80021,
48 160001, 500009, 1000003, 1500007, 2000003, 0
50 const double FULL_MAX
= 0.3; // don't let the table get more than this full
52 symbol
default_symbol("default");
54 static unsigned int hash_string(const char *p
) /* FIXME Torek's hash */
56 // compute a hash code; this assumes 32-bit unsigned ints
57 // see p436 of Compilers by Aho, Sethi & Ullman
58 // give special treatment to two-character names
59 unsigned int hc
= 0, g
;
65 for (; *p
!= 0; p
++) {
68 if ((g
= (hc
& 0xf0000000)) == 0) {
78 // Tell compiler that a variable is intentionally unused.
79 inline void unused(void *) { }
81 symbol::symbol(const char *p
, int how
)
92 table_size
= table_sizes
[0];
93 table
= (const char **)new char*[table_size
];
94 for (int i
= 0; i
< table_size
; i
++)
98 unsigned int hc
= hash_string(p
);
100 for (pp
= table
+ hc
% table_size
;
102 (pp
== table
? pp
= table
+ table_size
- 1 : --pp
))
103 if (strcmp(p
, *pp
) == 0) {
107 if (how
== MUST_ALREADY_EXIST
) {
111 if (table_used
>= table_size
- 1 || table_used
>= table_size
*FULL_MAX
) {
112 const char **old_table
= table
;
113 unsigned int old_table_size
= table_size
;
115 for (i
= 1; table_sizes
[i
] <= old_table_size
; i
++)
116 if (table_sizes
[i
] == 0)
117 fatal("too many symbols");
118 table_size
= table_sizes
[i
];
120 table
= (const char **)new char*[table_size
];
121 for (i
= 0; i
< table_size
; i
++)
123 for (pp
= old_table
+ old_table_size
- 1;
126 symbol
temp(*pp
, 1); /* insert it into the new table */
130 for (pp
= table
+ hc
% table_size
;
132 (pp
== table
? pp
= table
+ table_size
- 1 : --pp
))
136 if (how
== DONT_STORE
) {
140 int len
= strlen(p
)+1;
141 if (block
== 0 || block_size
< len
) {
142 block_size
= len
> BLOCK_SIZE
? len
: BLOCK_SIZE
;
143 block
= new char [block_size
];
145 (void)strcpy(block
, p
);
152 symbol
concat(symbol s1
, symbol s2
)
154 char *buf
= new char [strlen(s1
.contents()) + strlen(s2
.contents()) + 1];
155 strcpy(buf
, s1
.contents());
156 strcat(buf
, s2
.contents());