diff options
author | Sergey Poznyakoff <gray@gnu.org.ua> | 2009-04-26 12:42:11 +0300 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org.ua> | 2009-04-26 12:42:11 +0300 |
commit | d50fc04ded36255465184a16c70eb4c50acdb199 (patch) | |
tree | 02a568794c2a211621d1fe39868eaad7963bdc43 /src/html.gram.y | |
parent | 099a946ad4465c42db4737b247f1e89bd03c83ae (diff) | |
download | tagr-d50fc04ded36255465184a16c70eb4c50acdb199.tar.gz tagr-d50fc04ded36255465184a16c70eb4c50acdb199.tar.bz2 |
Introduce formats in preprocessor variables.
* configure.ac: Version 1.9.90
* NEWS: Likewise.
* etc/Makefile.am (EXTRA_DIST): Add logfilter.awk uptmpl.sed
* etc/logfilter.awk: New file
* etc/uptmpl.sed: New file
* etc/tagr.tmpl: Update
* etc/upgrade.awk: Add copyleft header
* gnulib.modules: Add fprintftime.
* src/graph.c (rate_unit): Change to "Bytes per Second".
(number_suffix, number_suffix_count): Move to grid.c
* src/html.gram.y: Work with formats.
* src/html.lex.l: Likewise.
* src/output.c (update_output): Store NOW as a number and
provide a formatting function for it.
* src/tagr.h (union value, value_format_fn): New types.
(pp_value_t): New members: fmt, format
(add_numeric_value, add_string_value): Change return type.
(init_value): New proto.
Diffstat (limited to 'src/html.gram.y')
-rw-r--r-- | src/html.gram.y | 181 |
1 files changed, 115 insertions, 66 deletions
diff --git a/src/html.gram.y b/src/html.gram.y index bce5e93..fae64ff 100644 --- a/src/html.gram.y +++ b/src/html.gram.y @@ -36,6 +36,8 @@ static FILE *tmp_file; static void out_char (int c); static void out_value (pp_value_t *val); +static void deduce_format (pp_value_t *res, + const pp_value_t *a, const pp_value_t *b); %} @@ -83,7 +85,7 @@ eval : IDENT } | obrace error cbrace { - $$.type = unspecified_value; + init_value (&$$, unspecified_value, NULL); } ; @@ -107,17 +109,17 @@ expr : value | expr '+' expr { if ($1.type == unspecified_value - || $3.type == unspecified_value) - $$.type = unspecified_value; + || $3.type == unspecified_value) + init_value (&$$, unspecified_value, NULL); else if ($1.type != $3.type) { yyerror ("type mismatch in addition"); - $$.type = unspecified_value; + init_value (&$$, unspecified_value, NULL); } else { $$.type = $1.type; - $$.prec = maxprec ($1.prec, $3.prec); + deduce_format (&$$, &$1, &$3); switch ($1.type) { case numeric_value: @@ -126,7 +128,7 @@ expr : value case string_value: $$.v.string = xmalloc (strlen ($1.v.string) - + strlen ($3.v.string) + 1); + + strlen ($3.v.string) + 1); strcpy ($$.v.string, $1.v.string); strcat ($$.v.string, $3.v.string); break; @@ -139,98 +141,97 @@ expr : value | expr '-' expr { if ($1.type == unspecified_value - || $3.type == unspecified_value) - $$.type = unspecified_value; + || $3.type == unspecified_value) + init_value (&$$, unspecified_value, NULL); else if ($1.type != $3.type) { yyerror ("type mismatch in subtraction"); - $$.type = unspecified_value; + init_value (&$$, unspecified_value, NULL); } else if ($1.type == string_value) { yyerror ("subtraction not defined for strings"); - $$.type = unspecified_value; + init_value (&$$, unspecified_value, NULL); } else { $$.type = $1.type; - $$.prec = maxprec ($1.prec, $3.prec); + deduce_format (&$$, &$1, &$3); $$.v.number = $1.v.number - $3.v.number; } } | expr '*' expr { if ($1.type == unspecified_value - || $3.type == unspecified_value) - $$.type = unspecified_value; + || $3.type == unspecified_value) + init_value (&$$, unspecified_value, NULL); else if ($1.type != $3.type) { yyerror ("type mismatch in multiplication"); - $$.type = unspecified_value; + init_value (&$$, unspecified_value, NULL); } else if ($1.type == string_value) { yyerror ("multiplication not defined for strings"); - $$.type = unspecified_value; + init_value (&$$, unspecified_value, NULL); } else { $$.type = $1.type; - $$.prec = maxprec ($1.prec, $3.prec); + deduce_format (&$$, &$1, &$3); $$.v.number = $1.v.number * $3.v.number; } } | expr '/' expr { if ($1.type == unspecified_value - || $3.type == unspecified_value) - $$.type = unspecified_value; + || $3.type == unspecified_value) + init_value (&$$, unspecified_value, NULL); else if ($1.type != $3.type) { yyerror ("type mismatch in division"); - $$.type = unspecified_value; + init_value (&$$, unspecified_value, NULL); } else if ($1.type == string_value) { yyerror ("division not defined for strings"); - $$.type = unspecified_value; + init_value (&$$, unspecified_value, NULL); } else if (fabs ($3.v.number) < 1.0e-5) { yyerror ("division by zero"); - $$.type = unspecified_value; + init_value (&$$, unspecified_value, NULL); } else { $$.type = $1.type; - $$.prec = maxprec ($1.prec, $3.prec); + deduce_format (&$$, &$1, &$3); $$.v.number = $1.v.number / $3.v.number; } } | '-' expr %prec UMINUS { if ($2.type == unspecified_value) - $$.type = unspecified_value; + init_value (&$$, unspecified_value, NULL); else if ($2.type == string_value) { yyerror ("unary minus not defined for strings"); - $$.type = unspecified_value; + init_value (&$$, unspecified_value, NULL); } else { - $$.type = $2.type; - $$.prec = $2.prec; + $$ = $2; $$.v.number = - $2.v.number; } } | '+' expr %prec UMINUS { if ($2.type == unspecified_value) - $$.type = unspecified_value; + init_value (&$$, unspecified_value, NULL); else if ($2.type == string_value) { yyerror ("unary plus not defined for strings"); - $$.type = unspecified_value; + init_value (&$$, unspecified_value, NULL); } else { @@ -242,9 +243,9 @@ expr : value value : IDENT | NUMBER { - $$.type = numeric_value; - $$.prec = -1; - $$.v.number = $1; + union value v; + v.number = $1; + init_value (&$$, numeric_value, &v); } ; @@ -309,30 +310,62 @@ out_char (int c) } static void -out_value (pp_value_t *val) +deduce_format (pp_value_t *res, const pp_value_t *a, const pp_value_t *b) { - switch (val->type) + res->prec = maxprec (a->prec, b->prec); + if (!a->format && b->format) { - case unspecified_value: - fprintf (tmp_file, "#UNSPECIFIED"); - break; - - case numeric_value: - if (val->prec >= 0) - fprintf (tmp_file, "%.*f", val->prec, val->v.number); - else - fprintf (tmp_file, "%f", val->v.number); - break; - - case string_value: - if (val->prec > 0) - fprintf (tmp_file, "%.*s", val->prec, val->v.string); - else - fprintf (tmp_file, "%s", val->v.string); - break; + res->fmt = b->fmt; + res->format = b->format; + } + else + { + res->fmt = a->fmt; + res->format = a->format; } } + +void +format_unspecified (FILE *fp, union value v, const char *fmt, int prec) +{ + fprintf (fp, "#UNSPECIFIED"); +} + +void +format_numeric (FILE *fp, union value v, const char *fmt, int prec) +{ + if (prec >= 0) + fprintf (fp, "%.*f", prec, v.number); + else + fprintf (fp, "%f", v.number); +} + +void +format_string (FILE *fp, union value v, const char *fmt, int prec) +{ + if (fmt) + fprintf (fp, fmt, v.string); + else if (prec > 0) + fprintf (fp, "%.*s", prec, v.string); + else + fprintf (fp, "%s", v.string); +} + +static value_format_fn default_format[] = { + format_unspecified, + format_numeric, + format_string +}; + +static void +out_value (pp_value_t *val) +{ + value_format_fn format = + val->format ? val->format : default_format[val->type]; + format (tmp_file, val->v, val->fmt, val->prec); +} + int @@ -356,8 +389,27 @@ free_value (pp_value_t *val) free (val->v.string); } -static void -add_value (pp_tab_t **ptab, const char *name, pp_value_t *val) +void +init_value (pp_value_t *p, value_type type, union value *v) +{ + memset (p, 0, sizeof (*p)); + p->type = type; + p->prec = -1; + switch (p->type) + { + case unspecified_value: + break; + case numeric_value: + p->v.number = v->number; + break; + case string_value: + p->v.string = xstrdup (v->string); + } +} + +static pp_value_t * +add_value (pp_tab_t **ptab, const char *name, + value_type type, union value *v) { pp_tab_t *p; @@ -374,29 +426,26 @@ add_value (pp_tab_t **ptab, const char *name, pp_value_t *val) p->name = xstrdup (name); *ptab = p; } - p->value = *val; + init_value (&p->value, type, v); + return &p->value; } -void +pp_value_t * add_numeric_value (pp_tab_t **ptab, const char *name, double number) { - pp_value_t val; - - val.type = numeric_value; - val.prec = -1; - val.v.number = number; - add_value (ptab, name, &val); + union value v; + + v.number = number; + return add_value (ptab, name, numeric_value, &v); } -void +pp_value_t * add_string_value (pp_tab_t **ptab, const char *name, const char *string) { - pp_value_t val; + union value v; - val.type = string_value; - val.prec = -1; - val.v.string = xstrdup (string); - add_value (ptab, name, &val); + v.string = xstrdup (string); + return add_value (ptab, name, string_value, &v); } void |