~ubuntu-branches/ubuntu/gutsy/evms/gutsy

« back to all changes in this revision

Viewing changes to intl/plural.y

  • Committer: Bazaar Package Importer
  • Author(s): Steinar H. Gunderson
  • Date: 2006-09-14 19:32:30 UTC
  • mfrom: (2.1.13 edgy)
  • Revision ID: james.westby@ubuntu.com-20060914193230-4b1pmy0coqk81sqa
Tags: 2.5.5-18
* Apply patches from upstream:
  * cli_query_segfault.patch, fixes a segfault in the CLI when doing a
    query.
  * cli_reload_options.patch, reloads the right option descriptors after
    a change.
  * ntfs_unmkfs.patch, fixes a bug in the wiping of NTFS file systems.
  * raid5_remove_spare_fix.patch + raid5_remove_spare_fix_2.patch, lets the
    user remove a spare if resync does not run.
  * raid5_algorithm.patch, makes EVMS heed the parity algorithm the user
    selects when creating a RAID-5 array.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
%{
 
2
/* Expression parsing for plural form selection.
 
3
   Copyright (C) 2000, 2001 Free Software Foundation, Inc.
 
4
   Written by Ulrich Drepper <drepper@cygnus.com>, 2000.
 
5
 
 
6
   This program is free software; you can redistribute it and/or modify it
 
7
   under the terms of the GNU Library General Public License as published
 
8
   by the Free Software Foundation; either version 2, or (at your option)
 
9
   any later version.
 
10
 
 
11
   This program is distributed in the hope that it will be useful,
 
12
   but WITHOUT ANY WARRANTY; without even the implied warranty of
 
13
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
14
   Library General Public License for more details.
 
15
 
 
16
   You should have received a copy of the GNU Library General Public
 
17
   License along with this program; if not, write to the Free Software
 
18
   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
 
19
   USA.  */
 
20
 
 
21
/* The bison generated parser uses alloca.  AIX 3 forces us to put this
 
22
   declaration at the beginning of the file.  The declaration in bison's
 
23
   skeleton file comes too late.  This must come before <config.h>
 
24
   because <config.h> may include arbitrary system headers.  */
 
25
#if defined _AIX && !defined __GNUC__
 
26
 #pragma alloca
 
27
#endif
 
28
 
 
29
#ifdef HAVE_CONFIG_H
 
30
# include <config.h>
 
31
#endif
 
32
 
 
33
#include <stddef.h>
 
34
#include <stdlib.h>
 
35
#include "plural-exp.h"
 
36
 
 
37
/* The main function generated by the parser is called __gettextparse,
 
38
   but we want it to be called PLURAL_PARSE.  */
 
39
#ifndef _LIBC
 
40
# define __gettextparse PLURAL_PARSE
 
41
#endif
 
42
 
 
43
#define YYLEX_PARAM     &((struct parse_args *) arg)->cp
 
44
#define YYPARSE_PARAM   arg
 
45
%}
 
46
%pure_parser
 
47
%expect 7
 
48
 
 
49
%union {
 
50
  unsigned long int num;
 
51
  enum operator op;
 
52
  struct expression *exp;
 
53
}
 
54
 
 
55
%{
 
56
/* Prototypes for local functions.  */
 
57
static struct expression *new_exp PARAMS ((int nargs, enum operator op,
 
58
                                           struct expression * const *args));
 
59
static inline struct expression *new_exp_0 PARAMS ((enum operator op));
 
60
static inline struct expression *new_exp_1 PARAMS ((enum operator op,
 
61
                                                   struct expression *right));
 
62
static struct expression *new_exp_2 PARAMS ((enum operator op,
 
63
                                             struct expression *left,
 
64
                                             struct expression *right));
 
65
static inline struct expression *new_exp_3 PARAMS ((enum operator op,
 
66
                                                   struct expression *bexp,
 
67
                                                   struct expression *tbranch,
 
68
                                                   struct expression *fbranch));
 
69
static int yylex PARAMS ((YYSTYPE *lval, const char **pexp));
 
70
static void yyerror PARAMS ((const char *str));
 
71
 
 
72
/* Allocation of expressions.  */
 
73
 
 
74
static struct expression *
 
75
new_exp (nargs, op, args)
 
76
     int nargs;
 
77
     enum operator op;
 
78
     struct expression * const *args;
 
79
{
 
80
  int i;
 
81
  struct expression *newp;
 
82
 
 
83
  /* If any of the argument could not be malloc'ed, just return NULL.  */
 
84
  for (i = nargs - 1; i >= 0; i--)
 
85
    if (args[i] == NULL)
 
86
      goto fail;
 
87
 
 
88
  /* Allocate a new expression.  */
 
89
  newp = (struct expression *) malloc (sizeof (*newp));
 
90
  if (newp != NULL)
 
91
    {
 
92
      newp->nargs = nargs;
 
93
      newp->operation = op;
 
94
      for (i = nargs - 1; i >= 0; i--)
 
95
        newp->val.args[i] = args[i];
 
96
      return newp;
 
97
    }
 
98
 
 
99
 fail:
 
100
  for (i = nargs - 1; i >= 0; i--)
 
101
    FREE_EXPRESSION (args[i]);
 
102
 
 
103
  return NULL;
 
104
}
 
105
 
 
106
static inline struct expression *
 
107
new_exp_0 (op)
 
108
     enum operator op;
 
109
{
 
110
  return new_exp (0, op, NULL);
 
111
}
 
112
 
 
113
static inline struct expression *
 
114
new_exp_1 (op, right)
 
115
     enum operator op;
 
116
     struct expression *right;
 
117
{
 
118
  struct expression *args[1];
 
119
 
 
120
  args[0] = right;
 
121
  return new_exp (1, op, args);
 
122
}
 
123
 
 
124
static struct expression *
 
125
new_exp_2 (op, left, right)
 
126
     enum operator op;
 
127
     struct expression *left;
 
128
     struct expression *right;
 
129
{
 
130
  struct expression *args[2];
 
131
 
 
132
  args[0] = left;
 
133
  args[1] = right;
 
134
  return new_exp (2, op, args);
 
135
}
 
136
 
 
137
static inline struct expression *
 
138
new_exp_3 (op, bexp, tbranch, fbranch)
 
139
     enum operator op;
 
140
     struct expression *bexp;
 
141
     struct expression *tbranch;
 
142
     struct expression *fbranch;
 
143
{
 
144
  struct expression *args[3];
 
145
 
 
146
  args[0] = bexp;
 
147
  args[1] = tbranch;
 
148
  args[2] = fbranch;
 
149
  return new_exp (3, op, args);
 
150
}
 
151
 
 
152
%}
 
153
 
 
154
/* This declares that all operators have the same associativity and the
 
155
   precedence order as in C.  See [Harbison, Steele: C, A Reference Manual].
 
156
   There is no unary minus and no bitwise operators.
 
157
   Operators with the same syntactic behaviour have been merged into a single
 
158
   token, to save space in the array generated by bison.  */
 
159
%right '?'              /*   ?          */
 
160
%left '|'               /*   ||         */
 
161
%left '&'               /*   &&         */
 
162
%left EQUOP2            /*   == !=      */
 
163
%left CMPOP2            /*   < > <= >=  */
 
164
%left ADDOP2            /*   + -        */
 
165
%left MULOP2            /*   * / %      */
 
166
%right '!'              /*   !          */
 
167
 
 
168
%token <op> EQUOP2 CMPOP2 ADDOP2 MULOP2
 
169
%token <num> NUMBER
 
170
%type <exp> exp
 
171
 
 
172
%%
 
173
 
 
174
start:    exp
 
175
          {
 
176
            if ($1 == NULL)
 
177
              YYABORT;
 
178
            ((struct parse_args *) arg)->res = $1;
 
179
          }
 
180
        ;
 
181
 
 
182
exp:      exp '?' exp ':' exp
 
183
          {
 
184
            $$ = new_exp_3 (qmop, $1, $3, $5);
 
185
          }
 
186
        | exp '|' exp
 
187
          {
 
188
            $$ = new_exp_2 (lor, $1, $3);
 
189
          }
 
190
        | exp '&' exp
 
191
          {
 
192
            $$ = new_exp_2 (land, $1, $3);
 
193
          }
 
194
        | exp EQUOP2 exp
 
195
          {
 
196
            $$ = new_exp_2 ($2, $1, $3);
 
197
          }
 
198
        | exp CMPOP2 exp
 
199
          {
 
200
            $$ = new_exp_2 ($2, $1, $3);
 
201
          }
 
202
        | exp ADDOP2 exp
 
203
          {
 
204
            $$ = new_exp_2 ($2, $1, $3);
 
205
          }
 
206
        | exp MULOP2 exp
 
207
          {
 
208
            $$ = new_exp_2 ($2, $1, $3);
 
209
          }
 
210
        | '!' exp
 
211
          {
 
212
            $$ = new_exp_1 (lnot, $2);
 
213
          }
 
214
        | 'n'
 
215
          {
 
216
            $$ = new_exp_0 (var);
 
217
          }
 
218
        | NUMBER
 
219
          {
 
220
            if (($$ = new_exp_0 (num)) != NULL)
 
221
              $$->val.num = $1;
 
222
          }
 
223
        | '(' exp ')'
 
224
          {
 
225
            $$ = $2;
 
226
          }
 
227
        ;
 
228
 
 
229
%%
 
230
 
 
231
void
 
232
internal_function
 
233
FREE_EXPRESSION (exp)
 
234
     struct expression *exp;
 
235
{
 
236
  if (exp == NULL)
 
237
    return;
 
238
 
 
239
  /* Handle the recursive case.  */
 
240
  switch (exp->nargs)
 
241
    {
 
242
    case 3:
 
243
      FREE_EXPRESSION (exp->val.args[2]);
 
244
      /* FALLTHROUGH */
 
245
    case 2:
 
246
      FREE_EXPRESSION (exp->val.args[1]);
 
247
      /* FALLTHROUGH */
 
248
    case 1:
 
249
      FREE_EXPRESSION (exp->val.args[0]);
 
250
      /* FALLTHROUGH */
 
251
    default:
 
252
      break;
 
253
    }
 
254
 
 
255
  free (exp);
 
256
}
 
257
 
 
258
 
 
259
static int
 
260
yylex (lval, pexp)
 
261
     YYSTYPE *lval;
 
262
     const char **pexp;
 
263
{
 
264
  const char *exp = *pexp;
 
265
  int result;
 
266
 
 
267
  while (1)
 
268
    {
 
269
      if (exp[0] == '\0')
 
270
        {
 
271
          *pexp = exp;
 
272
          return YYEOF;
 
273
        }
 
274
 
 
275
      if (exp[0] != ' ' && exp[0] != '\t')
 
276
        break;
 
277
 
 
278
      ++exp;
 
279
    }
 
280
 
 
281
  result = *exp++;
 
282
  switch (result)
 
283
    {
 
284
    case '0': case '1': case '2': case '3': case '4':
 
285
    case '5': case '6': case '7': case '8': case '9':
 
286
      {
 
287
        unsigned long int n = result - '0';
 
288
        while (exp[0] >= '0' && exp[0] <= '9')
 
289
          {
 
290
            n *= 10;
 
291
            n += exp[0] - '0';
 
292
            ++exp;
 
293
          }
 
294
        lval->num = n;
 
295
        result = NUMBER;
 
296
      }
 
297
      break;
 
298
 
 
299
    case '=':
 
300
      if (exp[0] == '=')
 
301
        {
 
302
          ++exp;
 
303
          lval->op = equal;
 
304
          result = EQUOP2;
 
305
        }
 
306
      else
 
307
        result = YYERRCODE;
 
308
      break;
 
309
 
 
310
    case '!':
 
311
      if (exp[0] == '=')
 
312
        {
 
313
          ++exp;
 
314
          lval->op = not_equal;
 
315
          result = EQUOP2;
 
316
        }
 
317
      break;
 
318
 
 
319
    case '&':
 
320
    case '|':
 
321
      if (exp[0] == result)
 
322
        ++exp;
 
323
      else
 
324
        result = YYERRCODE;
 
325
      break;
 
326
 
 
327
    case '<':
 
328
      if (exp[0] == '=')
 
329
        {
 
330
          ++exp;
 
331
          lval->op = less_or_equal;
 
332
        }
 
333
      else
 
334
        lval->op = less_than;
 
335
      result = CMPOP2;
 
336
      break;
 
337
 
 
338
    case '>':
 
339
      if (exp[0] == '=')
 
340
        {
 
341
          ++exp;
 
342
          lval->op = greater_or_equal;
 
343
        }
 
344
      else
 
345
        lval->op = greater_than;
 
346
      result = CMPOP2;
 
347
      break;
 
348
 
 
349
    case '*':
 
350
      lval->op = mult;
 
351
      result = MULOP2;
 
352
      break;
 
353
 
 
354
    case '/':
 
355
      lval->op = divide;
 
356
      result = MULOP2;
 
357
      break;
 
358
 
 
359
    case '%':
 
360
      lval->op = module;
 
361
      result = MULOP2;
 
362
      break;
 
363
 
 
364
    case '+':
 
365
      lval->op = plus;
 
366
      result = ADDOP2;
 
367
      break;
 
368
 
 
369
    case '-':
 
370
      lval->op = minus;
 
371
      result = ADDOP2;
 
372
      break;
 
373
 
 
374
    case 'n':
 
375
    case '?':
 
376
    case ':':
 
377
    case '(':
 
378
    case ')':
 
379
      /* Nothing, just return the character.  */
 
380
      break;
 
381
 
 
382
    case ';':
 
383
    case '\n':
 
384
    case '\0':
 
385
      /* Be safe and let the user call this function again.  */
 
386
      --exp;
 
387
      result = YYEOF;
 
388
      break;
 
389
 
 
390
    default:
 
391
      result = YYERRCODE;
 
392
#if YYDEBUG != 0
 
393
      --exp;
 
394
#endif
 
395
      break;
 
396
    }
 
397
 
 
398
  *pexp = exp;
 
399
 
 
400
  return result;
 
401
}
 
402
 
 
403
 
 
404
static void
 
405
yyerror (str)
 
406
     const char *str;
 
407
{
 
408
  /* Do nothing.  We don't print error messages here.  */
 
409
}