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 | |
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')
-rw-r--r-- | src/graph.c | 9 | ||||
-rw-r--r-- | src/grid.c | 5 | ||||
-rw-r--r-- | src/html.gram.y | 181 | ||||
-rw-r--r-- | src/html.lex.l | 27 | ||||
-rw-r--r-- | src/output.c | 27 | ||||
-rw-r--r-- | src/tagr.h | 23 |
6 files changed, 185 insertions, 87 deletions
diff --git a/src/graph.c b/src/graph.c index 16483bb..bfd00cb 100644 --- a/src/graph.c +++ b/src/graph.c @@ -54,11 +54,7 @@ int graph_ysize = 100; 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) \ gdImageColorAllocate (g, (ar)[0], (ar)[1], (ar)[2]) @@ -98,7 +94,8 @@ draw_graph (FILE *fp, xscale = (double) graph_xsize / xmax; #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 ? \ ((full_xsize - (x)*xscale)) : \ @@ -80,6 +80,11 @@ 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 { unsigned long step; 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 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 @@ -44,7 +44,7 @@ N [0-9]+ if (find_value (yytext+1, &yylval.value)) { yyerror ("unknown identifier"); - yylval.value.type = unspecified_value; + init_value (&yylval.value, unspecified_value, NULL); } return IDENT; } @@ -53,7 +53,7 @@ N [0-9]+ if (find_value (yytext+2, &yylval.value)) { yyerror ("unknown identifier"); - yylval.value.type = unspecified_value; + init_value (&yylval.value, unspecified_value, NULL); } return IDENT; } @@ -63,7 +63,7 @@ N [0-9]+ if (find_value (yytext+2, &yylval.value)) { yyerror ("unknown identifier"); - yylval.value.type = unspecified_value; + init_value (&yylval.value, unspecified_value, NULL); } else { @@ -71,6 +71,27 @@ 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; <EVAL>[ \t]+ ; diff --git a/src/output.c b/src/output.c index 980f9e1..e376ad4 100644 --- a/src/output.c +++ b/src/output.c @@ -23,6 +23,7 @@ #include <string.h> #include <errno.h> #include <sys/stat.h> +#include <fprintftime.h> #include <tagr.h> void @@ -220,6 +221,18 @@ struct image_descr img_year = { "DMAXOUT", "DAVGOUT", "DCUROUT" } }; +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, time_t timestamp, int force_update) @@ -230,7 +243,8 @@ update_output (struct monitor *mon, struct traffic_record *tr, pp_tab_t *tab = NULL; char *tabfile = mkfilename (dirname, mon->name, ".tab"); char *htmlname; - + pp_value_t *p; + if (!force_update) { if (read_symtab (&tab, tabfile)) @@ -264,10 +278,13 @@ 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); htmlname = mkfilename (dirname, mon->name, ".html"); @@ -97,15 +97,21 @@ 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; typedef struct pp_value_list @@ -117,8 +123,11 @@ 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); int create_html (pp_tab_t * tab, char *file, char *dest); |