diff options
author | Sergey Poznyakoff <gray@gnu.org.ua> | 2008-07-11 22:45:37 +0000 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org.ua> | 2008-07-11 22:45:37 +0000 |
commit | eb79907f63b7985751849d7a13e13879b6b8da9e (patch) | |
tree | eefbe4fc827242cb32f18a1ef0a4ffb4772630cd /src/html.gram.y | |
parent | 156b2a34fbc4dd3215c5b8cc2cc326f56dfb7df8 (diff) | |
download | tagr-eb79907f63b7985751849d7a13e13879b6b8da9e.tar.gz tagr-eb79907f63b7985751849d7a13e13879b6b8da9e.tar.bz2 |
Reorganize project directory layout.
* README-hacking: New file.
* src: New directory
* src/Makefile.am: New file.
* graph.c, readconfig.c, tagr.h, log.c, report.h,
queue.c: Move to src
* main.c: Move to src, fix a minor bug in main.
* html.l: Move to src/html.lex.l.
* html.y: Move to src/html.gram.y.
* lib/argcv.c, lib/argcv.h: Move to src.
* config, INSTALL: Remove
* README_hacking: New file.
* configure.ac, Makefile.am: Update for new gnulib and new
directory structure.
* bootstrap: Update from gnulib.
* gnulib.modules: New file.
* bootstrap.conf: New file.
git-svn-id: file:///svnroot/tagr/trunk@89 7c378d0d-a4e4-4a64-9229-dfce8bfd23d4
Diffstat (limited to 'src/html.gram.y')
-rw-r--r-- | src/html.gram.y | 442 |
1 files changed, 442 insertions, 0 deletions
diff --git a/src/html.gram.y b/src/html.gram.y new file mode 100644 index 0000000..830791f --- /dev/null +++ b/src/html.gram.y @@ -0,0 +1,442 @@ +%{ +/* This file is part of tagr. + Copyright (C) 2000, 2005, Max Bouglacoff, Sergey Poznyakoff + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + 02111-1307, USA. */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <unistd.h> +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <errno.h> +#include <math.h> +#include <tagr.h> + +static pp_tab_t *ident_tab; +static char *tmp_file_name; +static FILE *tmp_file; + +#define maxprec(a,b) ((a)>(b)?(a):(b)) + +static void out_char (int c); +static void out_value (pp_value_t *val); + +%} + +%union { + int character; + double number; + pp_value_t value; +}; + +%token <character> CHAR +%token <number> NUMBER +%token <value> IDENT +%token OBRACE CBRACE + +%left '+' '-' +%left '*' '/' +%left UMINUS + +%type <value> eval value expr + +%% + +input: list + ; + + +list : item + | list item + ; + +item : CHAR + { + out_char ($1); + } + | eval + { + out_value (&$1); + } + ; + +eval : IDENT + | obrace expr cbrace + { + $$ = $2; + } + | obrace error cbrace + { + $$.type = unspecified_value; + } + ; + +obrace: OBRACE + { + begin_eval (); + } + ; + +cbrace: CBRACE + { + end_eval (); + } + ; + +expr : value + | '(' expr ')' + { + $$ = $2; + } + | expr '+' expr + { + if ($1.type == unspecified_value + || $3.type == unspecified_value) + $$.type = unspecified_value; + else if ($1.type != $3.type) + { + yyerror ("type mismatch in addition"); + $$.type = unspecified_value; + } + else + { + $$.type = $1.type; + $$.prec = maxprec ($1.prec, $3.prec); + switch ($1.type) + { + case numeric_value: + $$.v.number = $1.v.number + $3.v.number; + break; + + case string_value: + $$.v.string = xmalloc (strlen ($1.v.string) + + strlen ($3.v.string) + 1); + strcpy ($$.v.string, $1.v.string); + strcat ($$.v.string, $3.v.string); + break; + + default: + abort (); /* Should not happen */ + } + } + } + | expr '-' expr + { + if ($1.type == unspecified_value + || $3.type == unspecified_value) + $$.type = unspecified_value; + else if ($1.type != $3.type) + { + yyerror ("type mismatch in subtraction"); + $$.type = unspecified_value; + } + else if ($1.type == string_value) + { + yyerror ("subtraction not defined for strings"); + $$.type = unspecified_value; + } + else + { + $$.type = $1.type; + $$.prec = maxprec ($1.prec, $3.prec); + $$.v.number = $1.v.number - $3.v.number; + } + } + | expr '*' expr + { + if ($1.type == unspecified_value + || $3.type == unspecified_value) + $$.type = unspecified_value; + else if ($1.type != $3.type) + { + yyerror ("type mismatch in multiplication"); + $$.type = unspecified_value; + } + else if ($1.type == string_value) + { + yyerror ("multiplication not defined for strings"); + $$.type = unspecified_value; + } + else + { + $$.type = $1.type; + $$.prec = maxprec ($1.prec, $3.prec); + $$.v.number = $1.v.number * $3.v.number; + } + } + | expr '/' expr + { + if ($1.type == unspecified_value + || $3.type == unspecified_value) + $$.type = unspecified_value; + else if ($1.type != $3.type) + { + yyerror ("type mismatch in division"); + $$.type = unspecified_value; + } + else if ($1.type == string_value) + { + yyerror ("division not defined for strings"); + $$.type = unspecified_value; + } + else if (fabs ($3.v.number) < 1.0e-5) + { + yyerror ("division by zero"); + $$.type = unspecified_value; + } + else + { + $$.type = $1.type; + $$.prec = maxprec ($1.prec, $3.prec); + $$.v.number = $1.v.number / $3.v.number; + } + } + | '-' expr %prec UMINUS + { + if ($2.type == unspecified_value) + $$.type = unspecified_value; + else if ($2.type == string_value) + { + yyerror ("unary minus not defined for strings"); + $$.type = unspecified_value; + } + else + { + $$.type = $2.type; + $$.prec = $2.prec; + $$.v.number = - $2.v.number; + } + } + | '+' expr %prec UMINUS + { + if ($2.type == unspecified_value) + $$.type = unspecified_value; + else if ($2.type == string_value) + { + yyerror ("unary plus not defined for strings"); + $$.type = unspecified_value; + } + else + { + $$ = $2; + } + } + ; + +value : IDENT + | NUMBER + { + $$.type = numeric_value; + $$.prec = -1; + $$.v.number = $1; + } + ; + + +%% + + +int +yyerror (char *s) +{ + logmsg (L_ERR, "%s:%d: %s", html_input_file, html_input_line, s); + return 0; +} + +int +create_html (pp_tab_t *tab, char *file, char *dest) +{ + if (html_open (file)) + return 1; + + free (tmp_file_name); + tmp_file_name = xmalloc (strlen (dest) + 4 + 1); + strcpy (tmp_file_name, dest); + strcat (tmp_file_name, ".tmp"); + + tmp_file = fopen (tmp_file_name, "w"); + if (!tmp_file) + { + logmsg (L_ERR, "cannot open output file `%s': %s", + file, strerror (errno)); + html_close (); + return 1; + } + + ident_tab = tab; + if (yyparse () == 0) + { + if (unlink (dest) && errno != ENOENT) + { + logmsg (L_ERR, "cannot unlink file `%s': %s", + dest, strerror (errno)); + return 1; + } + + if (rename (tmp_file_name, dest)) + { + logmsg (L_ERR, "cannot rename `%s' to `%s': %s", + tmp_file_name, dest, + strerror (errno)); + } + } + return 0; +} + +static void +out_char (int c) +{ + fputc (c, tmp_file); +} + +static void +out_value (pp_value_t *val) +{ + switch (val->type) + { + 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; + } +} + + + +int +find_value (char *name, pp_value_t *val) +{ + pp_tab_t *p; + + for (p = ident_tab; p; p = p->next) + if (strcmp (p->name, name) == 0) + { + *val = p->value; + return 0; + } + return 1; +} + +static void +add_value (pp_tab_t **ptab, const char *name, pp_value_t *val) +{ + pp_tab_t *p = xmalloc (sizeof (*p)); + p->next = *ptab; + p->name = xstrdup (name); + p->value = *val; + *ptab = p; +} + +void +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); +} + +void +add_string_value (pp_tab_t **ptab, const char *name, const char *string) +{ + pp_value_t val; + + val.type = string_value; + val.prec = -1; + val.v.string = xstrdup (string); + add_value (ptab, name, &val); +} + +void +free_tab (pp_tab_t **ptab) +{ + pp_tab_t *p = *ptab; + while (p) + { + pp_tab_t *next = p->next; + free (p->name); + if (p->value.type == string_value) + free(p->value.v.string); + free (p); + p = next; + } + *ptab = NULL; +} + +int +check_template () +{ + int rc; + pp_tab_t *tab = NULL; + + add_string_value (&tab, "PROGRAM", PACKAGE_NAME); + add_string_value (&tab, "VERSION", PACKAGE_VERSION); + add_string_value (&tab, "ROUTERNAME", "routername"); + add_string_value (&tab, "ROUTERIP", "routerip"); + add_string_value (&tab, "NOW", "NOW"); + + add_numeric_value (&tab, "SPEED", 4096); + + add_numeric_value (&tab, "MAXIN", 0); + add_numeric_value (&tab, "AVGIN", 1); + add_numeric_value (&tab, "CURIN", 2); + add_numeric_value (&tab, "MAXOUT", 3); + add_numeric_value (&tab, "AVGOUT", 4); + add_numeric_value (&tab, "CUROUT", 5); + + add_numeric_value (&tab, "HMAXIN", 10); + add_numeric_value (&tab, "HAVGIN", 11); + add_numeric_value (&tab, "HCURIN", 12); + add_numeric_value (&tab, "HMAXOUT", 13); + add_numeric_value (&tab, "HAVGOUT", 14); + add_numeric_value (&tab, "HCUROUT", 15); + + add_numeric_value (&tab, "TMAXIN", 20); + add_numeric_value (&tab, "TAVGIN", 21); + add_numeric_value (&tab, "TCURIN", 22); + add_numeric_value (&tab, "TMAXOUT", 23); + add_numeric_value (&tab, "TAVGOUT", 24); + add_numeric_value (&tab, "TCUROUT", 25); + + add_numeric_value (&tab, "DMAXIN", 30); + add_numeric_value (&tab, "DAVGIN", 31); + add_numeric_value (&tab, "DCURIN", 32); + add_numeric_value (&tab, "DMAXOUT", 33); + add_numeric_value (&tab, "DAVGOUT", 34); + add_numeric_value (&tab, "DCUROUT", 35); + rc = create_html (tab, html_template, "test.html"); + free_tab (&tab); + return rc; +} |