| 1 |
root |
1.2 |
#ifndef SHSTR_H__ |
| 2 |
|
|
#define SHSTR_H__ |
| 3 |
|
|
|
| 4 |
root |
1.4 |
//// OLD STUFF |
| 5 |
|
|
|
| 6 |
root |
1.1 |
/* The size of the shared strings hashtable. This must be smaller than |
| 7 |
|
|
* 32767, but 947 ought to be plenty enough. |
| 8 |
|
|
*/ |
| 9 |
|
|
#define TABLESIZE 4133 |
| 10 |
|
|
|
| 11 |
|
|
/* This specifies how many characters the hashing routine should look at. |
| 12 |
|
|
* You may actually save CPU by increasing this number if the typical string |
| 13 |
|
|
* is large. |
| 14 |
|
|
*/ |
| 15 |
|
|
#ifndef MAXSTRING |
| 16 |
|
|
#define MAXSTRING 20 |
| 17 |
|
|
#endif |
| 18 |
|
|
|
| 19 |
|
|
/* In the unlikely occurence that 16383 references to a string are too |
| 20 |
|
|
* few, you can modify the below type to something bigger. |
| 21 |
|
|
* (The top bit of "refcount" is used to signify that "u.array" points |
| 22 |
|
|
* at the array entry.) |
| 23 |
|
|
*/ |
| 24 |
|
|
#define REFCOUNT_TYPE int |
| 25 |
|
|
|
| 26 |
|
|
/* The offsetof macro is part of ANSI C, but many compilers lack it, for |
| 27 |
|
|
* example "gcc -ansi" |
| 28 |
|
|
*/ |
| 29 |
|
|
#if !defined (offsetof) |
| 30 |
|
|
#define offsetof(type, member) (int)&(((type *)0)->member) |
| 31 |
|
|
#endif |
| 32 |
|
|
|
| 33 |
|
|
/* SS(string) will return the address of the shared_string struct which |
| 34 |
|
|
* contains "string". |
| 35 |
|
|
*/ |
| 36 |
|
|
#define SS(x) ((shared_string *) ((x) - offsetof(shared_string, string))) |
| 37 |
|
|
|
| 38 |
|
|
#define SS_STATISTICS |
| 39 |
|
|
|
| 40 |
|
|
#define SS_DUMP_TABLE 1 |
| 41 |
|
|
#define SS_DUMP_TOTALS 2 |
| 42 |
|
|
|
| 43 |
|
|
#ifdef SS_STATISTICS |
| 44 |
|
|
static struct statistics { |
| 45 |
|
|
int calls; |
| 46 |
|
|
int hashed; |
| 47 |
|
|
int strcmps; |
| 48 |
|
|
int search; |
| 49 |
|
|
int linked; |
| 50 |
|
|
} add_stats, add_ref_stats, free_stats, find_stats, hash_stats; |
| 51 |
|
|
#define GATHER(n) (++n) |
| 52 |
|
|
#else /* !SS_STATISTICS */ |
| 53 |
|
|
#define GATHER(n) |
| 54 |
|
|
#endif /* SS_STATISTICS */ |
| 55 |
|
|
|
| 56 |
|
|
#define TOPBIT ((unsigned REFCOUNT_TYPE) 1 << (sizeof(REFCOUNT_TYPE) * CHAR_BIT - 1)) |
| 57 |
|
|
|
| 58 |
|
|
#define PADDING ((2 * sizeof(long) - sizeof(REFCOUNT_TYPE)) % sizeof(long)) + 1 |
| 59 |
|
|
|
| 60 |
|
|
typedef struct _shared_string { |
| 61 |
|
|
union { |
| 62 |
root |
1.3 |
struct _shared_string **array; |
| 63 |
|
|
struct _shared_string *previous; |
| 64 |
root |
1.1 |
} u; |
| 65 |
|
|
struct _shared_string *next; |
| 66 |
|
|
/* The top bit of "refcount" is used to signify that "u.array" points |
| 67 |
|
|
* at the array entry. |
| 68 |
|
|
*/ |
| 69 |
|
|
unsigned REFCOUNT_TYPE refcount; |
| 70 |
|
|
/* Padding will be unused memory, since we can't know how large |
| 71 |
|
|
* the padding when allocating memory. We assume here that |
| 72 |
|
|
* sizeof(long) is a good boundary. |
| 73 |
|
|
*/ |
| 74 |
|
|
char string[PADDING]; |
| 75 |
|
|
} shared_string; |
| 76 |
root |
1.2 |
|
| 77 |
|
|
extern void init_hash_table(void); |
| 78 |
|
|
extern const char *add_string(const char *str); |
| 79 |
|
|
extern const char *add_refcount(const char *str); |
| 80 |
|
|
extern int query_refcount(const char *str); |
| 81 |
|
|
extern const char *find_string(const char *str); |
| 82 |
|
|
extern void free_string(const char *str); |
| 83 |
|
|
extern void ss_dump_statistics(void); |
| 84 |
|
|
extern const char *ss_dump_table(int what); |
| 85 |
|
|
extern int buf_overflow(const char *buf1, const char *buf2, int bufsize); |
| 86 |
|
|
|
| 87 |
root |
1.4 |
//// NEW STUFF |
| 88 |
|
|
|
| 89 |
|
|
#if 0 |
| 90 |
|
|
struct shstr |
| 91 |
|
|
{ |
| 92 |
|
|
const char *s; |
| 93 |
|
|
operator const char *() const { return s; }; |
| 94 |
|
|
shstr &operator =(const char *str) { s = str; }; |
| 95 |
|
|
}; |
| 96 |
|
|
#else |
| 97 |
|
|
typedef const char *shstr; |
| 98 |
|
|
#endif |
| 99 |
|
|
|
| 100 |
root |
1.2 |
#endif |
| 101 |
|
|
|