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 | |
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.
-rw-r--r-- | NEWS | 2 | ||||
-rw-r--r-- | configure.ac | 2 | ||||
-rw-r--r-- | etc/Makefile.am | 2 | ||||
-rw-r--r-- | etc/logfilter.awk | 40 | ||||
-rw-r--r-- | etc/tagr.tmpl | 12 | ||||
-rw-r--r-- | etc/upgrade.awk | 16 | ||||
-rw-r--r-- | etc/uptmpl.sed | 2 | ||||
-rw-r--r-- | gnulib.modules | 1 | ||||
-rw-r--r-- | src/graph.c | 9 | ||||
-rw-r--r-- | src/grid.c | 5 | ||||
-rw-r--r-- | src/html.gram.y | 161 | ||||
-rw-r--r-- | src/html.lex.l | 27 | ||||
-rw-r--r-- | src/output.c | 23 | ||||
-rw-r--r-- | src/tagr.h | 23 |
14 files changed, 241 insertions, 84 deletions
@@ -5,5 +5,5 @@ See the end for copying conditions. Please send tagr bug reports to <gray@gnu.org.ua> -Version 1.0.95 (Git) +Version 1.9.90 (Git) ^L diff --git a/configure.ac b/configure.ac index 1d4673b..a622998 100644 --- a/configure.ac +++ b/configure.ac @@ -17,5 +17,5 @@ AC_PREREQ(2.59) -AC_INIT([tagr], 1.0.95, [gray@gnu.org.ua]) +AC_INIT([tagr], 1.9.90, [gray@gnu.org.ua]) AC_CONFIG_SRCDIR([src/main.c]) AC_CONFIG_AUX_DIR([build-aux]) diff --git a/etc/Makefile.am b/etc/Makefile.am index e9e5fcc..ccd72c9 100644 --- a/etc/Makefile.am +++ b/etc/Makefile.am @@ -1 +1 @@ -EXTRA_DIST = tagr.css tagr.tmpl upgrade.awk +EXTRA_DIST = tagr.css tagr.tmpl upgrade.awk logfilter.awk uptmpl.sed diff --git a/etc/logfilter.awk b/etc/logfilter.awk new file mode 100644 index 0000000..88e1d98 --- /dev/null +++ b/etc/logfilter.awk @@ -0,0 +1,40 @@ +# Format ipacct log file for input to tagr --read +# Copyright (C) 2009 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 3, 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, see <http://www.gnu.org/licenses/>. + +BEGIN { + month["Jan"] = 1 + month["Feb"] = 2 + month["Mar"] = 3 + month["Apr"] = 4 + month["May"] = 5 + month["Jun"] = 6 + month["Jul"] = 7 + month["Aug"] = 8 + month["Sep"] = 9 + month["Oct"] = 10 + month["Nov"] = 11 + month["Dec"] = 12 +} + +# mktime input format is: +# YYYY MM DD HH MM SS +# Log entry format is: +# Sat Apr 25 00:25:00 2009 pirx 199004 4238901 +# $1 $2 $3 $4 $5 $6 $7 $8 +NF == 8 { + gsub(/:/, " ", $4) + print $6, mktime($5 " " month[$2] " " $3 " " $4), $8, $7 +} diff --git a/etc/tagr.tmpl b/etc/tagr.tmpl index 0663f57..e5a198e 100644 --- a/etc/tagr.tmpl +++ b/etc/tagr.tmpl @@ -5,5 +5,5 @@ <head> - <title>Traffic Analysis for $ROUTERNAME</title> + <title>Traffic Analysis for $(MONITOR)</title> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <link rev="made" href="mailto:gray@gnu.org.ua" /> @@ -14,5 +14,5 @@ <body> -<h1>Stats for $ROUTERNAME ($ROUTERIP)</h1> +<h1>Stats for $MONITOR ($ID)</h1> <p> <span class="emph">Speed on port is $(SPEED:0)</span> @@ -24,5 +24,5 @@ The statistics were last updated <b>$NOW</b> <div class="graph"> <h3>`Daily' Graph (5 Minute Average)</h3> -<img src="$(ROUTERNAME)-day.png" alt="[ daily graph ]" /> +<img src="$(MONITOR)-day.png" alt="[ daily graph ]" /> <table class="graph"> <tr> @@ -51,5 +51,5 @@ The statistics were last updated <b>$NOW</b> <div class="graph"> <h3>`Weekly' Graph (30 Minute Average)</h3> -<img src="$(ROUTERNAME)-week.png" alt="[ weekly graph ]" /> +<img src="$(MONITOR)-week.png" alt="[ weekly graph ]" /> <table class="graph"> <tr> @@ -78,5 +78,5 @@ The statistics were last updated <b>$NOW</b> <div class="graph"> <h3>`Monthly' Graph (2 Hour Average)</h3> -<img src="$(ROUTERNAME)-month.png" alt="[ monthly graph ]" /> +<img src="$(MONITOR)-month.png" alt="[ monthly graph ]" /> <table class="graph"> <tr> @@ -105,5 +105,5 @@ The statistics were last updated <b>$NOW</b> <div class="graph"> <h3>`Yearly' Graph (1 Day Average)</h3> -<img src="$(ROUTERNAME)-year.png" alt="[ yearly graph ]" /> +<img src="$(MONITOR)-year.png" alt="[ yearly graph ]" /> <table class="graph"> <tr> diff --git a/etc/upgrade.awk b/etc/upgrade.awk index 0479609..2278758 100644 --- a/etc/upgrade.awk +++ b/etc/upgrade.awk @@ -1,2 +1,18 @@ +# Upgrade 1.0-style Tagr configuration file. +# Copyright (C) 2009 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 3, 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, see <http://www.gnu.org/licenses/>. + NF == 0 || /[ \t]*#/ { print; next } $1 == "user" || $1 == "template" || $1 == "basedir" { diff --git a/etc/uptmpl.sed b/etc/uptmpl.sed new file mode 100644 index 0000000..1229984 --- /dev/null +++ b/etc/uptmpl.sed @@ -0,0 +1,2 @@ +s/\$ROUTERNAME/$MONITOR/g +s/\$ROUTERIP/$ID/g
\ No newline at end of file diff --git a/gnulib.modules b/gnulib.modules index f7631e3..7eecc00 100644 --- a/gnulib.modules +++ b/gnulib.modules @@ -3,4 +3,5 @@ argp +fprintftime getline gitlog-to-changelog diff --git a/src/graph.c b/src/graph.c index 16483bb..bfd00cb 100644 --- a/src/graph.c +++ b/src/graph.c @@ -55,9 +55,5 @@ int graph_h_margin[2] = { 100, 14 }; int graph_v_margin[2] = { 14, 35 }; -char *rate_unit = "Bits per Second"; - -static char *short_suffix[] = {"", "k", "M", "G", "T"}; -char **number_suffix = short_suffix; -size_t number_suffix_count = sizeof (short_suffix) / sizeof (short_suffix[0]); +char *rate_unit = "Bytes per Second"; #define make_color_index(g, ar) \ @@ -99,5 +95,6 @@ draw_graph (FILE *fp, #define ytr(y) \ - (unsigned long) ((ymax >= (y) ? (ymax - (y)) : ymax) * yscale + graph_h_margin[1]) + (unsigned long) ((ymax >= (y) ? (ymax - (y)) : ymax) * \ + yscale + graph_h_margin[1]) #define xtr(x) \ (unsigned long) (growright ? \ @@ -81,4 +81,9 @@ grid_free_data (void *ptr) +/* FIXME: Suffixes not yet used. */ +static char *short_suffix[] = {"", "k", "M", "G", "T"}; +char **number_suffix = short_suffix; +size_t number_suffix_count = sizeof (short_suffix) / sizeof (short_suffix[0]); + struct ygrid_data { 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 @@ -37,4 +37,6 @@ 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); %} @@ -84,5 +86,5 @@ eval : IDENT | obrace error cbrace { - $$.type = unspecified_value; + init_value (&$$, unspecified_value, NULL); } ; @@ -109,14 +111,14 @@ expr : value if ($1.type == unspecified_value || $3.type == unspecified_value) - $$.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) { @@ -141,19 +143,19 @@ expr : value if ($1.type == unspecified_value || $3.type == unspecified_value) - $$.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; } @@ -163,19 +165,19 @@ expr : value if ($1.type == unspecified_value || $3.type == unspecified_value) - $$.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; } @@ -185,24 +187,24 @@ expr : value if ($1.type == unspecified_value || $3.type == unspecified_value) - $$.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; } @@ -211,14 +213,13 @@ expr : value { 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; } @@ -227,9 +228,9 @@ expr : value { 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 @@ -243,7 +244,7 @@ value : IDENT | NUMBER { - $$.type = numeric_value; - $$.prec = -1; - $$.v.number = $1; + union value v; + v.number = $1; + init_value (&$$, numeric_value, &v); } ; @@ -310,26 +311,58 @@ 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; + res->fmt = b->fmt; + res->format = b->format; + } + else + { + res->fmt = a->fmt; + res->format = a->format; + } +} - case numeric_value: - if (val->prec >= 0) - fprintf (tmp_file, "%.*f", val->prec, val->v.number); + +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 (tmp_file, "%f", val->v.number); - break; + fprintf (fp, "%f", v.number); +} - case string_value: - if (val->prec > 0) - fprintf (tmp_file, "%.*s", val->prec, val->v.string); +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 (tmp_file, "%s", val->v.string); - break; + 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); } @@ -357,6 +390,25 @@ free_value (pp_value_t *val) } -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; @@ -375,27 +427,24 @@ add_value (pp_tab_t **ptab, const char *name, pp_value_t *val) *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; + union value v; - val.type = numeric_value; - val.prec = -1; - val.v.number = number; - add_value (ptab, name, &val); + 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); } diff --git a/src/html.lex.l b/src/html.lex.l index 9f323dd..931bfc1 100644 --- a/src/html.lex.l +++ b/src/html.lex.l @@ -45,5 +45,5 @@ N [0-9]+ { yyerror ("unknown identifier"); - yylval.value.type = unspecified_value; + init_value (&yylval.value, unspecified_value, NULL); } return IDENT; @@ -54,5 +54,5 @@ N [0-9]+ { yyerror ("unknown identifier"); - yylval.value.type = unspecified_value; + init_value (&yylval.value, unspecified_value, NULL); } return IDENT; @@ -64,5 +64,5 @@ N [0-9]+ { yyerror ("unknown identifier"); - yylval.value.type = unspecified_value; + init_value (&yylval.value, unspecified_value, NULL); } else @@ -72,4 +72,25 @@ N [0-9]+ return IDENT; } +\$\({NAME}:[^)]+\) { + pp_value_t val; + char *p = strchr (yytext, ':'); + *p++ = 0; + if (find_value (yytext+2, &val)) + { + yyerror ("unknown identifier"); + init_value (&yylval.value, unspecified_value, NULL); + } + else + { + size_t len = strlen (p) - 1; + init_value (&yylval.value, val.type, &val.v); + yylval.value.prec = val.prec; + yylval.value.format = val.format; + yylval.value.fmt = xmalloc (len + 1); + memcpy (yylval.value.fmt, p, len); + yylval.value.fmt[len] = 0; + } + return IDENT; +} \$\{ return OBRACE; \$\} return CBRACE; diff --git a/src/output.c b/src/output.c index 980f9e1..e376ad4 100644 --- a/src/output.c +++ b/src/output.c @@ -24,4 +24,5 @@ #include <errno.h> #include <sys/stat.h> +#include <fprintftime.h> #include <tagr.h> @@ -221,4 +222,16 @@ struct image_descr img_year = { }; +static void +format_timestamp (FILE *fp, union value v, const char *fmt, int prec) +{ + time_t t = v.number; + struct tm *tm = localtime (&t); + + if (!fmt) + fmt = "%c"; + + fprintftime(fp, fmt, tm, 0, 0); +} + int update_output (struct monitor *mon, struct traffic_record *tr, @@ -231,4 +244,5 @@ update_output (struct monitor *mon, struct traffic_record *tr, char *tabfile = mkfilename (dirname, mon->name, ".tab"); char *htmlname; + pp_value_t *p; if (!force_update) @@ -265,7 +279,10 @@ update_output (struct monitor *mon, struct traffic_record *tr, add_string_value (&tab, "PROGRAM", PACKAGE_NAME); add_string_value (&tab, "VERSION", PACKAGE_VERSION); - add_string_value (&tab, "ROUTERNAME", mon->name); - add_string_value (&tab, "ROUTERIP", mon->id); - add_string_value (&tab, "NOW", ctime (×tamp)); + add_string_value (&tab, "MONITOR", mon->name); + add_string_value (&tab, "ID", mon->id); + + p = add_numeric_value (&tab, "NOW", timestamp); + p->format = format_timestamp; + p->fmt = "%c"; add_numeric_value (&tab, "SPEED", mon->max_rate); @@ -98,13 +98,19 @@ int yyerror (char *s); typedef enum { unspecified_value, numeric_value, string_value } value_type; +union value +{ + double number; + char *string; +}; + +typedef void (*value_format_fn) (FILE *, union value, const char *, int); + typedef struct { value_type type; int prec; - union - { - double number; - char *string; - } v; + char *fmt; + value_format_fn format; + union value v; } pp_value_t; @@ -118,6 +124,9 @@ typedef struct pp_value_list int read_symtab (pp_tab_t **tab, const char *name); int write_symtab (pp_tab_t *tab, const char *name); -void add_numeric_value (pp_tab_t ** ptab, const char *name, double number); -void add_string_value (pp_tab_t ** ptab, const char *name, const char *string); +void init_value (pp_value_t *p, value_type type, union value *v); +pp_value_t *add_numeric_value (pp_tab_t ** ptab, + const char *name, double number); +pp_value_t *add_string_value (pp_tab_t ** ptab, + const char *name, const char *string); int find_value (char *name, pp_value_t * val); void free_tab (pp_tab_t ** ptab); |