]>
Commit | Line | Data |
---|---|---|
c84142e8 UD |
1 | /* Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc. |
2 | This file is part of the GNU C Library. | |
3 | Contributed by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1995. | |
19bc17a9 | 4 | |
c84142e8 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 | |
c84142e8 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 | |
c84142e8 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 | #ifdef HAVE_CONFIG_H | |
21 | # include <config.h> | |
22 | #endif | |
23 | ||
24 | #include <alloca.h> | |
25 | #include <langinfo.h> | |
26 | #include <string.h> | |
27 | #include <sys/uio.h> | |
28 | ||
29 | #ifdef HAVE_REGEX | |
30 | # include <regex.h> | |
31 | #else | |
32 | # include <rx.h> | |
33 | #endif | |
34 | ||
35 | /* Undefine following line in production version. */ | |
36 | /* #define NDEBUG 1 */ | |
37 | #include <assert.h> | |
38 | ||
39 | #include "locales.h" | |
40 | #include "stringtrans.h" | |
41 | #include "localeinfo.h" | |
42 | ||
43 | ||
44 | void *xmalloc (size_t __n); | |
45 | ||
46 | ||
47 | /* The real definition of the struct for the LC_MESSAGES locale. */ | |
48 | struct locale_messages_t | |
49 | { | |
50 | const char *yesexpr; | |
51 | const char *noexpr; | |
52 | const char *yesstr; | |
53 | const char *nostr; | |
54 | }; | |
55 | ||
56 | ||
57 | void | |
58 | messages_startup (struct linereader *lr, struct localedef_t *locale, | |
59 | struct charset_t *charset) | |
60 | { | |
61 | struct locale_messages_t *messages; | |
62 | ||
63 | /* It is important that we always use UCS1 encoding for strings now. */ | |
64 | encoding_method = ENC_UCS1; | |
65 | ||
66 | locale->categories[LC_MESSAGES].messages = messages = | |
67 | (struct locale_messages_t *) xmalloc (sizeof (struct locale_messages_t)); | |
68 | ||
69 | memset (messages, '\0', sizeof (struct locale_messages_t)); | |
70 | } | |
71 | ||
72 | ||
73 | void | |
74 | messages_finish (struct localedef_t *locale) | |
75 | { | |
76 | struct locale_messages_t *messages | |
77 | = locale->categories[LC_MESSAGES].messages; | |
78 | ||
79 | /* The fields YESSTR and NOSTR are optional. */ | |
c84142e8 | 80 | if (messages->yesexpr == NULL && !be_quiet) |
19bc17a9 RM |
81 | error (0, 0, _("field `%s' in category `%s' undefined"), |
82 | "yesexpr", "LC_MESSAGES"); | |
83 | else | |
84 | { | |
85 | int result; | |
86 | regex_t re; | |
87 | ||
88 | /* Test whether it are correct regular expressions. */ | |
89 | result = regcomp (&re, messages->yesexpr, REG_EXTENDED); | |
c84142e8 | 90 | if (result != 0 && !be_quiet) |
19bc17a9 RM |
91 | { |
92 | char errbuf[BUFSIZ]; | |
93 | ||
94 | (void) regerror (result, &re, errbuf, BUFSIZ); | |
95 | error (0, 0, _("\ | |
96 | no correct regular expression for field `%s' in category `%s': %s"), | |
97 | "yesexpr", "LC_MESSAGES", errbuf); | |
98 | } | |
99 | } | |
100 | ||
c84142e8 | 101 | if (messages->noexpr == NULL && !be_quiet) |
19bc17a9 RM |
102 | error (0, 0, _("field `%s' in category `%s' undefined"), |
103 | "noexpr", "LC_MESSAGES"); | |
104 | else | |
105 | { | |
106 | int result; | |
107 | regex_t re; | |
108 | ||
109 | /* Test whether it are correct regular expressions. */ | |
110 | result = regcomp (&re, messages->noexpr, REG_EXTENDED); | |
c84142e8 | 111 | if (result != 0 && !be_quiet) |
19bc17a9 RM |
112 | { |
113 | char errbuf[BUFSIZ]; | |
114 | ||
115 | (void) regerror (result, &re, errbuf, BUFSIZ); | |
116 | error (0, 0, _("\ | |
117 | no correct regular expression for field `%s' in category `%s': %s"), | |
118 | "noexpr", "LC_MESSAGES", errbuf); | |
119 | } | |
120 | } | |
121 | } | |
122 | ||
123 | ||
124 | void | |
125 | messages_output (struct localedef_t *locale, const char *output_path) | |
126 | { | |
127 | struct locale_messages_t *messages | |
128 | = locale->categories[LC_MESSAGES].messages; | |
129 | struct iovec iov[2 + _NL_ITEM_INDEX (_NL_NUM_LC_MESSAGES)]; | |
130 | struct locale_file data; | |
7a12c6bb | 131 | u_int32_t idx[_NL_ITEM_INDEX (_NL_NUM_LC_MESSAGES)]; |
19bc17a9 RM |
132 | size_t cnt = 0; |
133 | ||
134 | if ((locale->binary & (1 << LC_MESSAGES)) != 0) | |
135 | { | |
136 | iov[0].iov_base = messages; | |
137 | iov[0].iov_len = locale->len[LC_MESSAGES]; | |
138 | ||
139 | write_locale_data (output_path, "LC_MESSAGES", 1, iov); | |
140 | ||
141 | return; | |
142 | } | |
143 | ||
144 | data.magic = LIMAGIC (LC_MESSAGES); | |
145 | data.n = _NL_ITEM_INDEX (_NL_NUM_LC_MESSAGES); | |
146 | iov[cnt].iov_base = (void *) &data; | |
147 | iov[cnt].iov_len = sizeof (data); | |
148 | ++cnt; | |
149 | ||
150 | iov[cnt].iov_base = (void *) idx; | |
151 | iov[cnt].iov_len = sizeof (idx); | |
152 | ++cnt; | |
153 | ||
154 | idx[cnt - 2] = iov[0].iov_len + iov[1].iov_len; | |
155 | iov[cnt].iov_base = (void *) (messages->yesexpr ?: ""); | |
156 | iov[cnt].iov_len = strlen (iov[cnt].iov_base) + 1; | |
157 | ++cnt; | |
158 | ||
159 | idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len; | |
160 | iov[cnt].iov_base = (void *) (messages->noexpr ?: ""); | |
161 | iov[cnt].iov_len = strlen (iov[cnt].iov_base) + 1; | |
162 | ++cnt; | |
163 | ||
164 | idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len; | |
165 | iov[cnt].iov_base = (void *) (messages->yesstr ?: ""); | |
166 | iov[cnt].iov_len = strlen (iov[cnt].iov_base) + 1; | |
167 | ++cnt; | |
168 | ||
169 | idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len; | |
170 | iov[cnt].iov_base = (void *) (messages->nostr ?: ""); | |
171 | iov[cnt].iov_len = strlen (iov[cnt].iov_base) + 1; | |
172 | ||
173 | assert (cnt + 1 == 2 + _NL_ITEM_INDEX (_NL_NUM_LC_MESSAGES)); | |
174 | ||
175 | write_locale_data (output_path, "LC_MESSAGES", | |
176 | 2 + _NL_ITEM_INDEX (_NL_NUM_LC_MESSAGES), iov); | |
177 | } | |
178 | ||
179 | ||
180 | void | |
181 | messages_add (struct linereader *lr, struct localedef_t *locale, | |
182 | enum token_t tok, struct token *code, | |
183 | struct charset_t *charset) | |
184 | { | |
185 | struct locale_messages_t *messages | |
186 | = locale->categories[LC_MESSAGES].messages; | |
187 | ||
188 | switch (tok) | |
189 | { | |
190 | case tok_yesexpr: | |
191 | if (code->val.str.start == NULL) | |
192 | { | |
193 | lr_error (lr, _("unknown character in field `%s' of category `%s'"), | |
194 | "yesexpr", "LC_MESSAGES"); | |
195 | messages->yesexpr = ""; | |
196 | } | |
197 | else | |
198 | messages->yesexpr = code->val.str.start; | |
199 | break; | |
200 | ||
201 | case tok_noexpr: | |
202 | if (code->val.str.start == NULL) | |
203 | { | |
204 | lr_error (lr, _("unknown character in field `%s' of category `%s'"), | |
205 | "noexpr", "LC_MESSAGES"); | |
206 | messages->noexpr = ""; | |
207 | } | |
208 | else | |
209 | messages->noexpr = code->val.str.start; | |
210 | break; | |
211 | ||
212 | case tok_yesstr: | |
213 | if (code->val.str.start == NULL) | |
214 | { | |
215 | lr_error (lr, _("unknown character in field `%s' of category `%s'"), | |
216 | "yesstr", "LC_MESSAGES"); | |
217 | messages->yesstr = ""; | |
218 | } | |
219 | else | |
220 | messages->yesstr = code->val.str.start; | |
221 | break; | |
222 | ||
223 | case tok_nostr: | |
224 | if (code->val.str.start == NULL) | |
225 | { | |
226 | lr_error (lr, _("unknown character in field `%s' of category `%s'"), | |
227 | "nostr", "LC_MESSAGES"); | |
228 | messages->nostr = ""; | |
229 | } | |
230 | else | |
231 | messages->nostr = code->val.str.start; | |
232 | break; | |
233 | ||
234 | default: | |
235 | assert (! "unknown token in category `LC_MESSAGES': should not happen"); | |
236 | } | |
237 | } |