summaryrefslogtreecommitdiffabout
authorSergey Poznyakoff <gray@gnu.org.ua>2009-04-26 09:42:11 (GMT)
committer Sergey Poznyakoff <gray@gnu.org.ua>2009-04-26 09:42:11 (GMT)
commitd50fc04ded36255465184a16c70eb4c50acdb199 (patch) (side-by-side diff)
tree02a568794c2a211621d1fe39868eaad7963bdc43
parent099a946ad4465c42db4737b247f1e89bd03c83ae (diff)
downloadtagr-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 (more/less context) (ignore whitespace changes)
-rw-r--r--NEWS2
-rw-r--r--configure.ac2
-rw-r--r--etc/Makefile.am2
-rw-r--r--etc/logfilter.awk40
-rw-r--r--etc/tagr.tmpl12
-rw-r--r--etc/upgrade.awk16
-rw-r--r--etc/uptmpl.sed2
-rw-r--r--gnulib.modules1
-rw-r--r--src/graph.c9
-rw-r--r--src/grid.c5
-rw-r--r--src/html.gram.y181
-rw-r--r--src/html.lex.l27
-rw-r--r--src/output.c27
-rw-r--r--src/tagr.h23
14 files changed, 253 insertions, 96 deletions
diff --git a/NEWS b/NEWS
index 2f75f6b..07ed6b8 100644
--- a/NEWS
+++ b/NEWS
@@ -4,7 +4,7 @@ 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
Version 1.0
diff --git a/configure.ac b/configure.ac
index 1d4673b..a622998 100644
--- a/configure.ac
+++ b/configure.ac
@@ -16,7 +16,7 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
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])
AC_CONFIG_HEADER([config.h])
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
--- a/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
@@ -4,7 +4,7 @@
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<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" />
<link rel="stylesheet" type="text/css" href="/~ipacct/ipacct.css" />
@@ -13,7 +13,7 @@
</head>
<body>
-<h1>Stats for $ROUTERNAME ($ROUTERIP)</h1>
+<h1>Stats for $MONITOR ($ID)</h1>
<p>
<span class="emph">Speed on port is $(SPEED:0)</span>
</p>
@@ -23,7 +23,7 @@ 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>
<td>Max <span class="input">&nbsp;In:</span></td>
@@ -50,7 +50,7 @@ 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>
<td>Max <span class="input">&nbsp;In:</span></td>
@@ -77,7 +77,7 @@ 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>
<td>Max <span class="input">&nbsp;In:</span></td>
@@ -104,7 +104,7 @@ 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>
<td>Max <span class="input">&nbsp;In:</span></td>
diff --git a/etc/upgrade.awk b/etc/upgrade.awk
index 0479609..2278758 100644
--- a/etc/upgrade.awk
+++ b/etc/upgrade.awk
@@ -1,3 +1,19 @@
+# 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" {
printf("%s;\n", $0)
diff --git a/etc/uptmpl.sed b/etc/uptmpl.sed
new file mode 100644
index 0000000..1229984
--- a/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
@@ -2,6 +2,7 @@
# A module name per line. Empty lines and comments are ignored.
argp
+fprintftime
getline
gitlog-to-changelog
glob
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)) : \
diff --git a/src/grid.c b/src/grid.c
index f4a75e1..1671753 100644
--- a/src/grid.c
+++ b/src/grid.c
@@ -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 (&timestamp));
-
+ 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");
diff --git a/src/tagr.h b/src/tagr.h
index b65b8d4..96035f2 100644
--- a/src/tagr.h
+++ b/src/tagr.h
@@ -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);

Return to:

Send suggestions and report system problems to the System administrator.