]> git.ipfire.org Git - thirdparty/glibc.git/blame - locale/weight.h
Update to 2.1.x development version
[thirdparty/glibc.git] / locale / weight.h
CommitLineData
00de59a6 1/* Copyright (C) 1996, 1997 Free Software Foundation, Inc.
6d52618b
UD
2 This file is part of the GNU C Library.
3 Written by Ulrich Drepper, <drepper@gnu.ai.mit.edu>.
19bc17a9 4
6d52618b
UD
5 The GNU C Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Library General Public License as
7 published by the Free Software Foundation; either version 2 of the
8 License, or (at your option) any later version.
19bc17a9 9
6d52618b
UD
10 The GNU C Library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Library General Public License for more details.
19bc17a9 14
6d52618b
UD
15 You should have received a copy of the GNU Library General Public
16 License along with the GNU C Library; see the file COPYING.LIB. If not,
17 write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA. */
19bc17a9
RM
19
20#include <alloca.h>
0393dfd6
RM
21#include <langinfo.h>
22#include "localeinfo.h"
19bc17a9
RM
23
24#ifndef STRING_TYPE
25# error STRING_TYPE not defined
26#endif
27
28#ifndef USTRING_TYPE
29# error USTRING_TYPE not defined
30#endif
31
32typedef struct weight_t
33{
34 struct weight_t *prev;
35 struct weight_t *next;
0393dfd6
RM
36 struct data_pair
37 {
7a12c6bb 38 int number;
0393dfd6
RM
39 const u_int32_t *value;
40 } data[0];
19bc17a9
RM
41} weight_t;
42
43
6d52618b
UD
44/* The following five macros grant access to the values in the
45 collate locale file that do not depend on byte order. */
c84142e8
UD
46#ifndef USE_IN_EXTENDED_LOCALE_MODEL
47# define collate_nrules \
19bc17a9 48 (_NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_NRULES))
c84142e8 49# define collate_hash_size \
19bc17a9 50 (_NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_HASH_SIZE))
c84142e8 51# define collate_hash_layers \
19bc17a9 52 (_NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_HASH_LAYERS))
c84142e8 53# define collate_undefined \
19bc17a9 54 (_NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_UNDEFINED))
c84142e8 55# define collate_rules \
00de59a6 56 ((u_int32_t *) _NL_CURRENT (LC_COLLATE, _NL_COLLATE_RULES))
19bc17a9 57
19bc17a9
RM
58static __inline int get_weight (const STRING_TYPE **str, weight_t *result);
59static __inline int
60get_weight (const STRING_TYPE **str, weight_t *result)
c84142e8
UD
61#else
62# define collate_nrules \
63 current->values[_NL_ITEM_INDEX (_NL_COLLATE_NRULES)].word
64# define collate_hash_size \
65 current->values[_NL_ITEM_INDEX (_NL_COLLATE_HASH_SIZE)].word
66# define collate_hash_layers \
67 current->values[_NL_ITEM_INDEX (_NL_COLLATE_HASH_LAYERS)].word
68# define collate_undefined \
69 current->values[_NL_ITEM_INDEX (_NL_COLLATE_UNDEFINED)].word
70# define collate_rules \
71 ((u_int32_t *) current->values[_NL_ITEM_INDEX (_NL_COLLATE_RULES)].string)
72
73static __inline int get_weight (const STRING_TYPE **str, weight_t *result,
74 struct locale_data *current,
75 const u_int32_t *__collate_table,
76 const u_int32_t *__collate_extra);
77static __inline int
78get_weight (const STRING_TYPE **str, weight_t *result,
79 struct locale_data *current, const u_int32_t *__collate_table,
80 const u_int32_t *__collate_extra)
81#endif
19bc17a9
RM
82{
83 unsigned int ch = *((USTRING_TYPE *) (*str))++;
84 size_t slot;
85
86 if (sizeof (STRING_TYPE) == 1)
87 slot = ch * (collate_nrules + 1);
88 else
89 {
90 const size_t level_size = collate_hash_size * (collate_nrules + 1);
91 size_t level;
92
00de59a6 93 slot = (ch % collate_hash_size) * (collate_nrules + 1);
19bc17a9
RM
94
95 level = 0;
0393dfd6 96 while (__collate_table[slot] != (u_int32_t) ch)
19bc17a9
RM
97 {
98 if (__collate_table[slot + 1] == 0
99 || ++level >= collate_hash_layers)
100 {
101 size_t idx = collate_undefined;
102 size_t cnt;
103
104 for (cnt = 0; cnt < collate_nrules; ++cnt)
105 {
106 result->data[cnt].number = __collate_extra[idx++];
107 result->data[cnt].value = &__collate_extra[idx];
108 idx += result->data[cnt].number;
109 }
110 return 0;
111 }
112 slot += level_size;
113 }
114 }
115
503054c0 116 if (__collate_table[slot + 1] != (u_int32_t) FORWARD_CHAR)
19bc17a9
RM
117 {
118 /* We have a simple form. One one value for each weight. */
119 size_t cnt;
120
121 for (cnt = 0; cnt < collate_nrules; ++cnt)
122 {
123 result->data[cnt].number = 1;
124 result->data[cnt].value = &__collate_table[slot + 1 + cnt];
125 }
126 return ch == 0;
127 }
128
129 /* We now look for any collation element which starts with CH.
130 There might none, but the last list member is a catch-all case
131 because it is simple the character CH. The value of this entry
132 might be the same as UNDEFINED. */
133 slot = __collate_table[slot + 2];
134
135 while (1)
136 {
137 size_t idx;
138
7a12c6bb 139 /* This is a comparison between a u_int32_t array (aka wchar_t) and
19bc17a9
RM
140 an 8-bit string. */
141 for (idx = 0; __collate_extra[slot + 2 + idx] != 0; ++idx)
7e3be507 142 if (__collate_extra[slot + 2 + idx] != (u_int32_t) (*str)[idx])
19bc17a9
RM
143 break;
144
145 /* When the loop finished with all character of the collation
146 element used, we found the longest prefix. */
147 if (__collate_extra[slot + 2 + idx] == 0)
148 {
149 size_t cnt;
150
7e3be507 151 *str += idx;
19bc17a9
RM
152 idx += slot + 3;
153 for (cnt = 0; cnt < collate_nrules; ++cnt)
154 {
155 result->data[cnt].number = __collate_extra[idx++];
156 result->data[cnt].value = &__collate_extra[idx];
157 idx += result->data[cnt].number;
158 }
159 return 0;
160 }
161
162 /* To next entry in list. */
163 slot += __collate_extra[slot];
164 }
165 /* NOTREACHED */
166 return 0; /* To calm down gcc. */
167}
168
169
170/* To process a string efficiently we retrieve all information about
171 the string at once. The following macro constructs a double linked
172 list of this information. It is a macro because we use `alloca'
173 and we use a double linked list because of the backward collation
c84142e8
UD
174 order.
175
176 We have this strange extra macro since the functions which use the
177 given locale (not the global one) canot use the global tables. */
178#ifndef USE_IN_EXTENDED_LOCALE_MODEL
179# define call_get_weight(strp, newp) get_weight ((strp), (newp))
180#else
181# define call_get_weight(strp, newp) \
182 get_weight ((strp), (newp), current, collate_table, collate_extra)
183#endif
184
19bc17a9
RM
185#define get_string(str, forw, backw) \
186 do \
187 { \
188 weight_t *newp; \
189 do \
190 { \
191 newp = (weight_t *) alloca (sizeof (weight_t) \
192 + (collate_nrules \
193 * sizeof (struct data_pair))); \
194 \
195 newp->prev = backw; \
196 if (backw == NULL) \
197 forw = newp; \
198 else \
199 backw->next = newp; \
200 newp->next = NULL; \
201 backw = newp; \
202 } \
c84142e8 203 while (call_get_weight (&str, newp) == 0); \
19bc17a9
RM
204 } \
205 while (0)