1/* $NetBSD: nametoindex.cpp,v 1.1.1.1 2016/01/13 18:41:48 christos Exp $ */ 2 3// -*- C++ -*- 4/* Copyright (C) 1989, 1990, 1991, 1992, 2000, 2001, 2002, 2003, 2004 5 Free Software Foundation, Inc. 6 Written by James Clark (jjc@jclark.com) 7 8This file is part of groff. 9 10groff is free software; you can redistribute it and/or modify it under 11the terms of the GNU General Public License as published by the Free 12Software Foundation; either version 2, or (at your option) any later 13version. 14 15groff is distributed in the hope that it will be useful, but WITHOUT ANY 16WARRANTY; without even the implied warranty of MERCHANTABILITY or 17FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 18for more details. 19 20You should have received a copy of the GNU General Public License along 21with groff; see the file COPYING. If not, write to the Free Software 22Foundation, 51 Franklin St - Fifth Floor, Boston, MA 02110-1301, USA. */ 23 24#include "lib.h" 25 26#include <ctype.h> 27#include <assert.h> 28#include <stdlib.h> 29#include "errarg.h" 30#include "error.h" 31#include "font.h" 32#include "ptable.h" 33 34declare_ptable(int) 35implement_ptable(int) 36 37class character_indexer { 38public: 39 character_indexer(); 40 ~character_indexer(); 41 int ascii_char_index(unsigned char); 42 int named_char_index(const char *); 43 int numbered_char_index(int); 44private: 45 enum { NSMALL = 256 }; 46 int next_index; 47 int ascii_index[256]; 48 int small_number_index[NSMALL]; 49 PTABLE(int) table; 50}; 51 52character_indexer::character_indexer() 53: next_index(0) 54{ 55 int i; 56 for (i = 0; i < 256; i++) 57 ascii_index[i] = -1; 58 for (i = 0; i < NSMALL; i++) 59 small_number_index[i] = -1; 60} 61 62character_indexer::~character_indexer() 63{ 64} 65 66int character_indexer::ascii_char_index(unsigned char c) 67{ 68 if (ascii_index[c] < 0) 69 ascii_index[c] = next_index++; 70 return ascii_index[c]; 71} 72 73int character_indexer::numbered_char_index(int n) 74{ 75 if (n >= 0 && n < NSMALL) { 76 if (small_number_index[n] < 0) 77 small_number_index[n] = next_index++; 78 return small_number_index[n]; 79 } 80 // Not the most efficient possible implementation. 81 char buf[INT_DIGITS + 3]; 82 buf[0] = ' '; 83 strcpy(buf + 1, i_to_a(n)); 84 return named_char_index(buf); 85} 86 87int character_indexer::named_char_index(const char *s) 88{ 89 int *np = table.lookup(s); 90 if (!np) { 91 np = new int[1]; 92 *np = next_index++; 93 table.define(s, np); 94 } 95 return *np; 96} 97 98static character_indexer indexer; 99 100int font::number_to_index(int n) 101{ 102 return indexer.numbered_char_index(n); 103} 104 105int font::name_to_index(const char *s) 106{ 107 assert(s != 0 && s[0] != '\0' && s[0] != ' '); 108 if (s[1] == '\0') 109 return indexer.ascii_char_index(s[0]); 110 /* char128 and \200 are synonyms */ 111 if (s[0] == 'c' && s[1] == 'h' && s[2] == 'a' && s[3] == 'r') { 112 char *val; 113 long n = strtol(s + 4, &val, 10); 114 if (val != s + 4 && *val == '\0' && n >= 0 && n < 256) 115 return indexer.ascii_char_index((unsigned char)n); 116 } 117 return indexer.named_char_index(s); 118} 119 120