~ubuntu-branches/ubuntu/dapper/groff/dapper

« back to all changes in this revision

Viewing changes to src/roff/troff/symbol.cc

  • Committer: Bazaar Package Importer
  • Author(s): Colin Watson
  • Date: 2002-03-17 04:11:50 UTC
  • Revision ID: james.westby@ubuntu.com-20020317041150-wkgfawjc3gxlk0o5
Tags: upstream-1.17.2
ImportĀ upstreamĀ versionĀ 1.17.2

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// -*- C++ -*-
 
2
/* Copyright (C) 1989, 1990, 1991, 1992 Free Software Foundation, Inc.
 
3
     Written by James Clark (jjc@jclark.com)
 
4
 
 
5
This file is part of groff.
 
6
 
 
7
groff is free software; you can redistribute it and/or modify it under
 
8
the terms of the GNU General Public License as published by the Free
 
9
Software Foundation; either version 2, or (at your option) any later
 
10
version.
 
11
 
 
12
groff is distributed in the hope that it will be useful, but WITHOUT ANY
 
13
WARRANTY; without even the implied warranty of MERCHANTABILITY or
 
14
FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 
15
for more details.
 
16
 
 
17
You should have received a copy of the GNU General Public License along
 
18
with groff; see the file COPYING.  If not, write to the Free Software
 
19
Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
 
20
 
 
21
 
 
22
#include "troff.h"
 
23
#include "symbol.h"
 
24
 
 
25
const char **symbol::table = 0;
 
26
int symbol::table_used = 0;
 
27
int symbol::table_size = 0;
 
28
char *symbol::block = 0;
 
29
int symbol::block_size = 0;
 
30
 
 
31
const symbol NULL_SYMBOL;
 
32
 
 
33
#ifdef BLOCK_SIZE
 
34
#undef BLOCK_SIZE
 
35
#endif
 
36
 
 
37
const int BLOCK_SIZE = 1024;
 
38
// the table will increase in size as necessary
 
39
// the size will be chosen from the following array
 
40
// add some more if you want
 
41
// I think it unlikely that we'll need more than a million symbols
 
42
static const unsigned int table_sizes[] = { 
 
43
101, 503, 1009, 2003, 3001, 4001, 5003, 10007, 20011, 40009, 80021, 160001, 500009, 1000003, 0 
 
44
};
 
45
const double FULL_MAX = 0.3;    // don't let the table get more than this full
 
46
 
 
47
static unsigned int hash_string(const char *p)
 
48
{
 
49
  // compute a hash code; this assumes 32-bit unsigned ints
 
50
  // see p436 of  Compilers by Aho, Sethi & Ullman
 
51
  // give special treatment to two-character names
 
52
  unsigned int hc = 0, g;
 
53
  if (*p != 0) {
 
54
    hc = *p++;
 
55
    if (*p != 0) {
 
56
      hc <<= 7;
 
57
      hc += *p++;
 
58
      for (; *p != 0; p++) {
 
59
        hc <<= 4;
 
60
        hc += *p;
 
61
        if ((g = (hc & 0xf0000000)) == 0) {
 
62
          hc ^= g >> 24;
 
63
          hc ^= g;
 
64
        }
 
65
      }
 
66
    }
 
67
  }
 
68
  return hc;
 
69
}
 
70
 
 
71
// Tell compiler that a variable is intentionally unused.
 
72
inline void unused(void *) { }
 
73
 
 
74
symbol::symbol(const char *p, int how)
 
75
{
 
76
  if (p == 0 || *p == 0) {
 
77
    s = 0;
 
78
    return;
 
79
  }
 
80
  if (table == 0) {
 
81
    table_size = table_sizes[0];
 
82
    table = (const char **)new char*[table_size];
 
83
    for (int i = 0; i < table_size; i++)
 
84
      table[i] = 0;
 
85
    table_used = 0;
 
86
  }
 
87
  unsigned int hc = hash_string(p);
 
88
  const char **pp;
 
89
  for (pp = table + hc % table_size; 
 
90
       *pp != 0; 
 
91
       (pp == table ? pp = table + table_size - 1 : --pp))
 
92
    if (strcmp(p, *pp) == 0) {
 
93
      s = *pp;
 
94
      return;
 
95
    }
 
96
  if (how == MUST_ALREADY_EXIST) {
 
97
    s = 0;
 
98
    return;
 
99
  }
 
100
  if (table_used  >= table_size - 1 || table_used >= table_size*FULL_MAX) {
 
101
    const char **old_table = table;
 
102
    unsigned int old_table_size = table_size;
 
103
    int i;
 
104
    for (i = 1; table_sizes[i] <= old_table_size; i++)
 
105
      if (table_sizes[i] == 0)
 
106
        fatal("too many symbols");
 
107
    table_size = table_sizes[i];
 
108
    table_used = 0;
 
109
    table = (const char **)new char*[table_size];
 
110
    for (i = 0; i < table_size; i++)
 
111
      table[i] = 0;
 
112
    for (pp = old_table + old_table_size - 1; 
 
113
         pp >= old_table;
 
114
         --pp) {
 
115
           symbol temp(*pp, 1); /* insert it into the new table */
 
116
           unused(&temp);
 
117
         }
 
118
    a_delete old_table;
 
119
    for (pp = table + hc % table_size;
 
120
         *pp != 0; 
 
121
         (pp == table ? pp = table + table_size - 1 : --pp))
 
122
      ;
 
123
  }
 
124
  ++table_used;
 
125
  if (how == DONT_STORE) {
 
126
    s = *pp = p;
 
127
  }
 
128
  else {
 
129
    int len = strlen(p)+1;
 
130
    if (block == 0 || block_size < len) {
 
131
      block_size = len > BLOCK_SIZE ? len : BLOCK_SIZE;
 
132
      block = new char [block_size];
 
133
    }
 
134
    (void)strcpy(block, p);
 
135
    s = *pp = block;
 
136
    block += len;
 
137
    block_size -= len;
 
138
  }
 
139
}
 
140
 
 
141
symbol concat(symbol s1, symbol s2)
 
142
{
 
143
  char *buf = new char [strlen(s1.contents()) + strlen(s2.contents()) + 1];
 
144
  strcpy(buf, s1.contents());
 
145
  strcat(buf, s2.contents());
 
146
  symbol res(buf);
 
147
  a_delete buf;
 
148
  return res;
 
149
}
 
150