aboutsummaryrefslogtreecommitdiff
path: root/intl/plural.y
diff options
context:
space:
mode:
Diffstat (limited to 'intl/plural.y')
-rw-r--r--intl/plural.y68
1 files changed, 39 insertions, 29 deletions
diff --git a/intl/plural.y b/intl/plural.y
index 00b6fccb4f..c13dbafab8 100644
--- a/intl/plural.y
+++ b/intl/plural.y
@@ -36,7 +36,7 @@
%{
/* Prototypes for local functions. */
-static struct expression *new_exp (enum operator op, ...);
+static struct expression *new_exp (enum operator op, int n, ...);
static int yylex (YYSTYPE *lval, const char **pexp);
static void yyerror (const char *str);
%}
@@ -60,62 +60,62 @@ start: exp
exp: exp '?' exp ':' exp
{
- if (($$ = new_exp (qmop, $1, $3, $5, NULL)) == NULL)
+ if (($$ = new_exp (qmop, 3, $1, $3, $5)) == NULL)
YYABORT
}
| exp '|' exp
{
- if (($$ = new_exp (lor, $1, $3, NULL)) == NULL)
+ if (($$ = new_exp (lor, 2, $1, $3)) == NULL)
YYABORT
}
| exp '&' exp
{
- if (($$ = new_exp (land, $1, $3, NULL)) == NULL)
+ if (($$ = new_exp (land, 2, $1, $3)) == NULL)
YYABORT
}
| exp '=' exp
{
- if (($$ = new_exp (equal, $1, $3, NULL)) == NULL)
+ if (($$ = new_exp (equal, 2, $1, $3)) == NULL)
YYABORT
}
| exp '!' exp
{
- if (($$ = new_exp (not_equal, $1, $3, NULL)) == NULL)
+ if (($$ = new_exp (not_equal, 2, $1, $3)) == NULL)
YYABORT
}
| exp '+' exp
{
- if (($$ = new_exp (plus, $1, $3, NULL)) == NULL)
+ if (($$ = new_exp (plus, 2, $1, $3)) == NULL)
YYABORT
}
| exp '-' exp
{
- if (($$ = new_exp (minus, $1, $3, NULL)) == NULL)
+ if (($$ = new_exp (minus, 2, $1, $3)) == NULL)
YYABORT
}
| exp '*' exp
{
- if (($$ = new_exp (mult, $1, $3, NULL)) == NULL)
+ if (($$ = new_exp (mult, 2, $1, $3)) == NULL)
YYABORT
}
| exp '/' exp
{
- if (($$ = new_exp (divide, $1, $3, NULL)) == NULL)
+ if (($$ = new_exp (divide, 2, $1, $3)) == NULL)
YYABORT
}
| exp '%' exp
{
- if (($$ = new_exp (module, $1, $3, NULL)) == NULL)
+ if (($$ = new_exp (module, 2, $1, $3)) == NULL)
YYABORT
}
| 'n'
{
- if (($$ = new_exp (var, NULL)) == NULL)
+ if (($$ = new_exp (var, 0)) == NULL)
YYABORT
}
| NUMBER
{
- if (($$ = new_exp (num, NULL)) == NULL)
+ if (($$ = new_exp (num, 0)) == NULL)
YYABORT;
$$->val.num = $1
}
@@ -128,31 +128,33 @@ exp: exp '?' exp ':' exp
%%
static struct expression *
-new_exp (enum operator op, ...)
+new_exp (enum operator op, int n, ...)
{
- struct expression *newp = (struct expression *) malloc (sizeof (*newp));
+ struct expression *newp = (struct expression *) calloc (1, sizeof (*newp));
va_list va;
- struct expression *next;
- va_start (va, op);
+ va_start (va, n);
if (newp == NULL)
- while ((next = va_arg (va, struct expression *)) != NULL)
- __gettext_free_exp (next);
+ while (n-- > 0)
+ __gettext_free_exp (va_arg (va, struct expression *));
else
{
newp->operation = op;
- next = va_arg (va, struct expression *);
- if (next != NULL)
+ if (n > 0)
{
- newp->val.args3.bexp = next;
- next = va_arg (va, struct expression *);
- if (next != NULL)
+ newp->val.args3.bexp = va_arg (va, struct expression *);
+ newp->val.args3.tbranch = va_arg (va, struct expression *);
+
+ if (n > 2)
+ newp->val.args3.fbranch = va_arg (va, struct expression *);
+
+ if (newp->val.args3.bexp == NULL
+ || newp->val.args3.tbranch == NULL
+ || (n > 2 && newp->val.args3.fbranch == NULL))
{
- newp->val.args3.tbranch = next;
- next = va_arg (va, struct expression *);
- if (next != NULL)
- newp->val.args3.fbranch = next;
+ __gettext_free_exp (newp);
+ newp = NULL;
}
}
}
@@ -210,7 +212,14 @@ yylex (YYSTYPE *lval, const char **pexp)
exp += 2;
continue;
}
- if (exp[0] != '\0' && exp[0] != ' ' && exp[0] != '\t')
+
+ if (exp[0] == '\0')
+ {
+ *pexp = exp;
+ return YYEOF;
+ }
+
+ if (exp[0] != ' ' && exp[0] != '\t')
break;
++exp;
@@ -262,6 +271,7 @@ yylex (YYSTYPE *lval, const char **pexp)
/* Nothing, just return the character. */
break;
+ case ';':
case '\n':
case '\0':
/* Be safe and let the user call this function again. */