2 * This file has been modified for the cdrkit suite.
4 * The behaviour and appearence of the program code below can differ to a major
5 * extent from the version distributed by the original author(s).
7 * For details, see Changelog file distributed with the cdrkit package. If you
8 * received this file from another source then ask the distributing person for
9 * a log of modifications.
13 /* @(#)nls_file.c 1.3 05/05/01 2000 J. Schilling */
15 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License version 2
17 * as published by the Free Software Foundation.
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
24 * You should have received a copy of the GNU General Public License along with
25 * this program; see the file COPYING. If not, write to the Free Software
26 * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
29 * Modifications to make the code portable Copyright (c) 2000 J. Schilling
31 * nls_file: create a charset table from a input table file
32 * from the Unicode Organization (www.unicode.org).
33 * The Unicode to charset table has only exact mappings.
35 * Only reads single byte to word matches.
37 * James Pearson (j.pearson@ge.ucl.ac.uk) 16-Aug-2000
49 static void free_mem(struct unls_unicode *, unsigned char **);
52 free_mem(struct unls_unicode *charset2uni, unsigned char **page_uni2charset)
59 if (page_uni2charset) {
60 for (i = 0; i < NUM; i++) {
61 if (page_uni2charset[i]) {
62 free(page_uni2charset[i]);
65 free(page_uni2charset);
70 init_unls_file(char *filename)
73 struct unls_unicode *charset2uni = NULL;
74 unsigned char **page_uni2charset = NULL;
78 struct unls_table *table;
81 /* give up if no filename is given */
86 * see if we already have a table with this name - built in tables
87 * have precedence of file tables - i.e. can't have the name of an
88 * existing table. Also, we may have already registered this file table
90 if (find_unls(filename) != NULL)
93 if ((fp = fopen(filename, "r")) == NULL)
96 /* allocate memory for the forward conversion table */
97 if ((charset2uni = (struct unls_unicode *)
98 malloc(sizeof (struct unls_unicode) * NUM)) == NULL) {
99 free_mem(charset2uni, page_uni2charset);
103 /* any unknown character should be mapped to NULL */
104 memset(charset2uni, 0, sizeof (struct unls_unicode) * NUM);
107 * some source files don't set the control characters 0x00 - 0x1f
108 * so set these by default
110 for (i = 0; i < 32; i++) {
111 charset2uni[i].unls_low = i;
114 /* also set DELETE (0x7f) by default */
115 charset2uni[0x7f].unls_low = 0x7f;
117 /* read each line of the file */
118 while (fgets(buf, sizeof (buf), fp) != NULL) {
119 /* cut off any comments */
120 if ((p = strchr(buf, '#')) != NULL)
123 /* look for two hex values */
124 if (sscanf(buf, "%x%x", &cp, &uc) == 2) {
125 /* if they are not in range - fail */
126 if (cp > 0xff || uc > 0xffff) {
130 /* set the Unicode value for the given code point */
131 charset2uni[cp].unls_low = uc & 0xff;
132 charset2uni[cp].unls_high = (uc >> 8) & 0xff;
134 /* make sure we find at least one pair ... */
142 /* we haven't found anything ... */
143 free_mem(charset2uni, page_uni2charset);
147 /* allocate memory for the reverse table */
148 if ((page_uni2charset = (unsigned char **)
149 malloc(sizeof (unsigned char *) * NUM)) == NULL) {
150 free_mem(charset2uni, page_uni2charset);
154 memset(page_uni2charset, 0, sizeof (unsigned char *) * NUM);
156 /* loop through the forward table, setting the reverse value */
157 for (i = 0; i < NUM; i++) {
158 uc = charset2uni[i].unls_high;
159 cp = charset2uni[i].unls_low;
160 /* if the page doesn't exist, create a page */
161 if (page_uni2charset[uc] == NULL) {
162 if ((page_uni2charset[uc] =
163 (unsigned char *) malloc(NUM)) == NULL) {
164 free_mem(charset2uni, page_uni2charset);
167 memset(page_uni2charset[uc], 0, NUM);
170 /* set the reverse point in the page */
171 page_uni2charset[uc][cp] = i;
174 /* set up the table */
175 if ((table = (struct unls_table *)malloc(sizeof (struct unls_table)))
177 free_mem(charset2uni, page_uni2charset);
181 /* give the table the file name, so we can find it again if needed */
182 table->unls_name = strdup(filename);
183 table->unls_uni2cs = page_uni2charset;
184 table->unls_cs2uni = charset2uni;
185 table->unls_next = NULL;
187 /* register the table */
188 return (register_unls(table));