1114402Sru// -*- C++ -*-
2151497Sru/* Copyright (C) 1989, 1990, 1991, 1992, 2000, 2001, 2002, 2003, 2004
3114402Sru   Free Software Foundation, Inc.
4114402Sru     Written by James Clark (jjc@jclark.com)
5114402Sru
6114402SruThis file is part of groff.
7114402Sru
8114402Srugroff is free software; you can redistribute it and/or modify it under
9114402Sruthe terms of the GNU General Public License as published by the Free
10114402SruSoftware Foundation; either version 2, or (at your option) any later
11114402Sruversion.
12114402Sru
13114402Srugroff is distributed in the hope that it will be useful, but WITHOUT ANY
14114402SruWARRANTY; without even the implied warranty of MERCHANTABILITY or
15114402SruFITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
16114402Srufor more details.
17114402Sru
18114402SruYou should have received a copy of the GNU General Public License along
19114402Sruwith groff; see the file COPYING.  If not, write to the Free Software
20151497SruFoundation, 51 Franklin St - Fifth Floor, Boston, MA 02110-1301, USA. */
21114402Sru
22114402Sru#include "lib.h"
23114402Sru
24114402Sru#include <ctype.h>
25114402Sru#include <assert.h>
26114402Sru#include <stdlib.h>
27114402Sru#include "errarg.h"
28114402Sru#include "error.h"
29114402Sru#include "font.h"
30114402Sru#include "ptable.h"
31114402Sru
32114402Srudeclare_ptable(int)
33114402Sruimplement_ptable(int)
34114402Sru
35114402Sruclass character_indexer {
36114402Srupublic:
37114402Sru  character_indexer();
38114402Sru  ~character_indexer();
39114402Sru  int ascii_char_index(unsigned char);
40114402Sru  int named_char_index(const char *);
41114402Sru  int numbered_char_index(int);
42114402Sruprivate:
43114402Sru  enum { NSMALL = 256 };
44114402Sru  int next_index;
45114402Sru  int ascii_index[256];
46114402Sru  int small_number_index[NSMALL];
47114402Sru  PTABLE(int) table;
48114402Sru};
49114402Sru
50114402Srucharacter_indexer::character_indexer()
51114402Sru: next_index(0)
52114402Sru{
53114402Sru  int i;
54114402Sru  for (i = 0; i < 256; i++)
55114402Sru    ascii_index[i] = -1;
56114402Sru  for (i = 0; i < NSMALL; i++)
57114402Sru    small_number_index[i] = -1;
58114402Sru}
59114402Sru
60114402Srucharacter_indexer::~character_indexer()
61114402Sru{
62114402Sru}
63114402Sru
64114402Sruint character_indexer::ascii_char_index(unsigned char c)
65114402Sru{
66114402Sru  if (ascii_index[c] < 0)
67114402Sru    ascii_index[c] = next_index++;
68114402Sru  return ascii_index[c];
69114402Sru}
70114402Sru
71114402Sruint character_indexer::numbered_char_index(int n)
72114402Sru{
73114402Sru  if (n >= 0 && n < NSMALL) {
74114402Sru    if (small_number_index[n] < 0)
75114402Sru      small_number_index[n] = next_index++;
76114402Sru    return small_number_index[n];
77114402Sru  }
78114402Sru  // Not the most efficient possible implementation.
79114402Sru  char buf[INT_DIGITS + 3];
80114402Sru  buf[0] = ' ';
81114402Sru  strcpy(buf + 1, i_to_a(n));
82114402Sru  return named_char_index(buf);
83114402Sru}
84114402Sru
85114402Sruint character_indexer::named_char_index(const char *s)
86114402Sru{
87114402Sru  int *np = table.lookup(s);
88114402Sru  if (!np) {
89114402Sru    np = new int[1];
90114402Sru    *np = next_index++;
91114402Sru    table.define(s, np);
92114402Sru  }
93114402Sru  return *np;
94114402Sru}
95114402Sru
96114402Srustatic character_indexer indexer;
97114402Sru
98114402Sruint font::number_to_index(int n)
99114402Sru{
100114402Sru  return indexer.numbered_char_index(n);
101114402Sru}
102114402Sru
103114402Sruint font::name_to_index(const char *s)
104114402Sru{
105114402Sru  assert(s != 0 && s[0] != '\0' && s[0] != ' ');
106114402Sru  if (s[1] == '\0')
107114402Sru    return indexer.ascii_char_index(s[0]);
108114402Sru  /* char128 and \200 are synonyms */
109114402Sru  if (s[0] == 'c' && s[1] == 'h' && s[2] == 'a' && s[3] == 'r') {
110151497Sru    char *val;
111151497Sru    long n = strtol(s + 4, &val, 10);
112151497Sru    if (val != s + 4 && *val == '\0' && n >= 0 && n < 256)
113114402Sru      return indexer.ascii_char_index((unsigned char)n);
114114402Sru  }
115114402Sru  return indexer.named_char_index(s);
116114402Sru}
117114402Sru
118