chiark / gitweb /
eglibc (2.11.3-4+deb6u3) squeeze-lts; urgency=medium
[eglibc.git] / debian / patches / locale / preprocessor-collate.diff
1 Allow preprocessor-like directives.  These keywords were already
2 defined in locale/programs/locfile-kw.h, an implementation for
3 'define', 'undef', 'ifdef', 'else' and 'endif' is now provided in
4 locale/programs/ld-collate.c.  For the moment, 'ifndef' and 'elif'
5 are not implemented because they do not appear in locfile-kw.h.
6 This patch is harmless, it only adds new keywords.
7
8 # DP: Dpatch author: Denis Barbier
9 # DP: Patch author: Denis Barbier
10 # DP: Upstream status: BZ686
11 # DP: Date: 2006-01-08
12
13 ---
14  locale/programs/ld-collate.c |  275 +++++++++++++++++++++++++++++++++++++++++++
15  1 file changed, 275 insertions(+)
16
17 --- a/locale/programs/ld-collate.c
18 +++ b/locale/programs/ld-collate.c
19 @@ -164,6 +164,24 @@
20    size_t line;
21  };
22  
23 +/* Data type for toggles.  */
24 +struct toggle_list_t;
25 +
26 +struct toggle_list_t
27 +{
28 +  const char *name;
29 +
30 +  /* Predecessor in the list.  */
31 +  struct toggle_list_t *last;
32 +
33 +  /* This flag is set when a keyword is undefined.  */
34 +  int is_undefined;
35 +
36 +  /* Where does the branch come from.  */
37 +  const char *file;
38 +  size_t line;
39 +};
40 +
41  /* Sparse table of struct element_t *.  */
42  #define TABLE wchead_table
43  #define ELEMENT struct element_t *
44 @@ -219,6 +237,9 @@
45    /* This value is used when handling ellipsis.  */
46    struct element_t ellipsis_weight;
47  
48 +  /* This is a stack of .  */
49 +  struct toggle_list_t *flow_control;
50 +
51    /* Known collating elements.  */
52    hash_table elem_table;
53  
54 @@ -1467,6 +1488,56 @@
55  }
56  
57  
58 +static struct token *
59 +flow_skip (struct linereader *ldfile, const struct charmap_t *charmap,
60 +          struct locale_collate_t *collate)
61 +{
62 +  int level = 0;
63 +  struct token *now;
64 +  enum token_t nowtok;
65 +  while (1)
66 +    {
67 +      lr_ignore_rest (ldfile, 0);
68 +      now = lr_token (ldfile, charmap, NULL, NULL, 0);
69 +      nowtok = now->tok;
70 +      if (nowtok == tok_eof)
71 +       break;
72 +      else if (nowtok == tok_ifdef || nowtok == tok_ifndef)
73 +       ++level ;
74 +      else if (nowtok == tok_else)
75 +       {
76 +         if (strcmp (collate->flow_control->name, "else") == 0)
77 +           lr_error (ldfile,
78 +                     _("%s: `else' statement at `%s:%Zu' cannot be followed by another `else' statement"),
79 +                     "LC_COLLATE", collate->flow_control->name, collate->flow_control->line);
80 +         if (level == 0)
81 +           {
82 +             collate->flow_control->name = "else";
83 +             collate->flow_control->file = ldfile->fname;
84 +             collate->flow_control->line = ldfile->lineno;
85 +             break;
86 +           }
87 +       }
88 +      else if (nowtok == tok_endif)
89 +       {
90 +         if (level == 0)
91 +           {
92 +             collate->flow_control = collate->flow_control->last;
93 +             break;
94 +           }
95 +         --level ;
96 +       }
97 +    }
98 +  if (nowtok == tok_eof)
99 +    WITH_CUR_LOCALE (error (0, 0, _("\
100 +%s: unterminated `%s' flow control beginning at %s:%Zu"),
101 +                                "LC_COLLATE", collate->flow_control->name,
102 +                                collate->flow_control->file,
103 +                                collate->flow_control->line));
104 +  return now;
105 +}
106 +
107 +
108  static void
109  collate_startup (struct linereader *ldfile, struct localedef_t *locale,
110                  struct localedef_t *copy_locale, int ignore_content)
111 @@ -2514,6 +2585,8 @@
112    */
113    int state = 0;
114  
115 +  static struct toggle_list_t *defined_keywords = NULL;
116 +
117    /* Get the repertoire we have to use.  */
118    if (repertoire_name != NULL)
119      repertoire = repertoire_read (repertoire_name);
120 @@ -2528,6 +2601,82 @@
121         }
122        while (nowtok == tok_eol);
123  
124 +  while (nowtok == tok_define || nowtok == tok_undef)
125 +    {
126 +      /* Ignore the rest of the line if we don't need the input of
127 +         this line.  */
128 +      if (ignore_content)
129 +        {
130 +          lr_ignore_rest (ldfile, 0);
131 +          now = lr_token (ldfile, charmap, result, NULL, verbose);
132 +          nowtok = now->tok;
133 +          continue;
134 +        }
135 +
136 +      arg = lr_token (ldfile, charmap, result, NULL, verbose);
137 +      if (arg->tok != tok_ident)
138 +        goto err_label;
139 +
140 +      if (nowtok == tok_define)
141 +        {
142 +         struct toggle_list_t *runp = defined_keywords;
143 +         char *name;
144 +
145 +         while (runp != NULL)
146 +           if (strncmp (runp->name, arg->val.str.startmb,
147 +                    arg->val.str.lenmb) == 0
148 +               && runp->name[arg->val.str.lenmb] == '\0')
149 +              SYNTAX_ERROR (_("%s: syntax error"), "LC_COLLATE");
150 +           else
151 +             runp = runp->last;
152 +
153 +         if (runp != NULL && runp->is_undefined == 0)
154 +           {
155 +             lr_ignore_rest (ldfile, 0);
156 +              SYNTAX_ERROR (_("%s: syntax error"), "LC_COLLATE");
157 +           }
158 +
159 +         if (runp == NULL)
160 +           {
161 +             runp = (struct toggle_list_t *) xcalloc (1, sizeof (*runp));
162 +             runp->last = defined_keywords;
163 +             defined_keywords = runp;
164 +           }
165 +         else
166 +           {
167 +             free ((char *) runp->name);
168 +             runp->is_undefined = 0;
169 +           }
170 +
171 +         name = (char *) xmalloc (arg->val.str.lenmb + 1);
172 +         memcpy (name, arg->val.str.startmb, arg->val.str.lenmb);
173 +         name[arg->val.str.lenmb] = '\0';
174 +         runp->name = name;
175 +        }
176 +      else
177 +        {
178 +         struct toggle_list_t *runp = defined_keywords;
179 +         while (runp != NULL)
180 +           if (strncmp (runp->name, arg->val.str.startmb,
181 +                    arg->val.str.lenmb) == 0
182 +               && runp->name[arg->val.str.lenmb] == '\0')
183 +           {
184 +             runp->is_undefined = 1;
185 +              SYNTAX_ERROR (_("%s: syntax error"), "LC_COLLATE");
186 +           }
187 +           else
188 +             runp = runp->last;
189 +        }
190 +
191 +      lr_ignore_rest (ldfile, 1);
192 +      do
193 +        {
194 +          now = lr_token (ldfile, charmap, result, NULL, verbose);
195 +          nowtok = now->tok;
196 +        }
197 +      while (nowtok == tok_eol);
198 +    }
199 +
200    if (nowtok == tok_copy)
201      {
202        now = lr_token (ldfile, charmap, result, NULL, verbose);
203 @@ -3682,6 +3831,125 @@
204                           repertoire, result, nowtok);
205           break;
206  
207 +       case tok_ifdef:
208 +         /* Ignore the rest of the line if we don't need the input of
209 +            this line.  */
210 +         if (ignore_content)
211 +           {
212 +             lr_ignore_rest (ldfile, 0);
213 +             break;
214 +           }
215 +
216 +         arg = lr_token (ldfile, charmap, result, NULL, verbose);
217 +         if (arg->tok != tok_ident)
218 +           goto err_label;
219 +         else
220 +           {
221 +             struct toggle_list_t *runp = defined_keywords;
222 +             struct toggle_list_t *flow = (struct toggle_list_t *) xcalloc (1, sizeof (*runp));
223 +             flow->name = "ifdef";
224 +             flow->file = ldfile->fname;
225 +             flow->line = ldfile->lineno;
226 +             flow->last = collate->flow_control;
227 +             collate->flow_control = flow;
228 +
229 +             while (runp != NULL)
230 +               if (strncmp (runp->name, arg->val.str.startmb,
231 +                            arg->val.str.lenmb) == 0
232 +                   && runp->name[arg->val.str.lenmb] == '\0')
233 +                 break;
234 +               else
235 +                 runp = runp->last;
236 +
237 +             if (runp == NULL)
238 +               {
239 +                 now = flow_skip(ldfile, charmap, collate);
240 +                 if (now->tok == tok_eof)
241 +                   WITH_CUR_LOCALE (error (0, 0, _("\
242 +%s: unterminated `%s' flow control"), "LC_COLLATE", collate->flow_control->name));
243 +               }
244 +           }
245 +         lr_ignore_rest (ldfile, 1);
246 +         break;
247 +
248 +       case tok_ifndef:
249 +         /* Ignore the rest of the line if we don't need the input of
250 +            this line.  */
251 +         if (ignore_content)
252 +           {
253 +             lr_ignore_rest (ldfile, 0);
254 +             break;
255 +           }
256 +
257 +         arg = lr_token (ldfile, charmap, result, NULL, verbose);
258 +         if (arg->tok != tok_ident)
259 +           goto err_label;
260 +         else
261 +           {
262 +             struct toggle_list_t *runp = defined_keywords;
263 +             struct toggle_list_t *flow = (struct toggle_list_t *) xcalloc (1, sizeof (*runp));
264 +             flow->name = "ifndef";
265 +             flow->file = ldfile->fname;
266 +             flow->line = ldfile->lineno;
267 +             flow->last = collate->flow_control;
268 +             collate->flow_control = flow;
269 +
270 +             while (runp != NULL)
271 +               if (strncmp (runp->name, arg->val.str.startmb,
272 +                            arg->val.str.lenmb) == 0
273 +                   && runp->name[arg->val.str.lenmb] == '\0')
274 +                 break;
275 +               else
276 +                 runp = runp->last;
277 +
278 +             if (runp != NULL)
279 +               {
280 +                 now = flow_skip(ldfile, charmap, collate);
281 +                 if (now->tok == tok_eof)
282 +                   WITH_CUR_LOCALE (error (0, 0, _("\
283 +%s: unterminated `%s' flow control"), "LC_COLLATE", collate->flow_control->name));
284 +               }
285 +           }
286 +         lr_ignore_rest (ldfile, 1);
287 +         break;
288 +
289 +       case tok_else:
290 +         /* Ignore the rest of the line if we don't need the input of
291 +            this line.  */
292 +         if (ignore_content)
293 +           {
294 +             lr_ignore_rest (ldfile, 0);
295 +             break;
296 +           }
297 +
298 +         if (strcmp (collate->flow_control->name, "else") == 0)
299 +           lr_error (ldfile,
300 +                     _("%s: `else' statement at `%s:%Zu' cannot be followed by another `else' statement"),
301 +                     "LC_COLLATE", collate->flow_control->name, collate->flow_control->line);
302 +         collate->flow_control->name = "else";
303 +         collate->flow_control->file = ldfile->fname;
304 +         collate->flow_control->line = ldfile->lineno;
305 +         now = flow_skip(ldfile, charmap, collate);
306 +         if (now->tok == tok_eof)
307 +           WITH_CUR_LOCALE (error (0, 0, _("\
308 +%s: unterminated `%s' flow control"), "LC_COLLATE", collate->flow_control->name));
309 +         break;
310 +
311 +       case tok_endif:
312 +         /* Ignore the rest of the line if we don't need the input of
313 +            this line.  */
314 +         if (ignore_content)
315 +           {
316 +             lr_ignore_rest (ldfile, 0);
317 +             break;
318 +           }
319 +
320 +         if (collate->flow_control == NULL)
321 +           goto err_label;
322 +         else
323 +           collate->flow_control = collate->flow_control->last;
324 +         break;
325 +
326         case tok_end:
327           /* Next we assume `LC_COLLATE'.  */
328           if (!ignore_content)
329 @@ -3711,6 +3979,13 @@
330               else if (state == 5)
331                 WITH_CUR_LOCALE (error (0, 0, _("\
332  %s: missing `reorder-sections-end' keyword"), "LC_COLLATE"));
333 +             if (collate->flow_control != NULL
334 +                 && strcmp(collate->flow_control->file, ldfile->fname) == 0)
335 +               WITH_CUR_LOCALE (error (0, 0, _("\
336 +%s: unterminated `%s' flow control beginning at %s:%Zu"),
337 +                                "LC_COLLATE", collate->flow_control->name,
338 +                                collate->flow_control->file,
339 +                                collate->flow_control->line));
340             }
341           arg = lr_token (ldfile, charmap, result, NULL, verbose);
342           if (arg->tok == tok_eof)