aboutsummaryrefslogtreecommitdiffstats
path: root/dfilter-grammar.y
diff options
context:
space:
mode:
authorGilbert Ramirez <gram@alumni.rice.edu>1999-10-19 05:31:14 +0000
committerGilbert Ramirez <gram@alumni.rice.edu>1999-10-19 05:31:14 +0000
commita5b7e70a3e915739704940e024a7f3c2afe102b1 (patch)
tree6621a71b8ed6d54fff521c43919bbe6b1b8bf6fe /dfilter-grammar.y
parent2202c089fe8773d0f73cc48a95732ffe83586dd9 (diff)
Enable display filtering on FT_DOUBLE fields.
svn path=/trunk/; revision=886
Diffstat (limited to 'dfilter-grammar.y')
-rw-r--r--dfilter-grammar.y172
1 files changed, 151 insertions, 21 deletions
diff --git a/dfilter-grammar.y b/dfilter-grammar.y
index fc2534bc61..7b3c7839fa 100644
--- a/dfilter-grammar.y
+++ b/dfilter-grammar.y
@@ -3,7 +3,7 @@
/* dfilter-grammar.y
* Parser for display filters
*
- * $Id: dfilter-grammar.y,v 1.35 1999/10/17 20:54:56 gram Exp $
+ * $Id: dfilter-grammar.y,v 1.36 1999/10/19 05:31:12 gram Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org>
@@ -51,6 +51,8 @@
#endif
#include <string.h>
+#include <errno.h>
+#include <math.h>
#ifndef _STDLIB_H
#include <stdlib.h>
@@ -78,6 +80,8 @@ static GNode* dfilter_mknode_join(GNode *n1, enum node_type ntype, int operand,
static GNode* dfilter_mknode_unary(int operand, GNode *n2);
static GNode* dfilter_mknode_numeric_variable(gint id);
static GNode* dfilter_mknode_numeric_value(guint32 val);
+static GNode* dfilter_mknode_floating_variable(gint id);
+static GNode* dfilter_mknode_floating_value(double val);
static GNode* dfilter_mknode_ether_value(gchar*);
static GNode* dfilter_mknode_ether_variable(gint id);
static GNode* dfilter_mknode_ipxnet_value(guint32);
@@ -90,7 +94,8 @@ static GNode* dfilter_mknode_existence(gint id);
static GNode* dfilter_mknode_bytes_value(GByteArray *barray);
static GNode* dfilter_mknode_bytes_variable(gint id, gint offset, guint length);
-static guint32 string_to_value(char *s);
+static guint32 string_to_guint32(char *s, gboolean *success);
+static double string_to_double(char *s, gboolean *success);
static int ether_str_to_guint8_array(const char *s, guint8 *mac);
static guint dfilter_get_bytes_variable_offset(GNode *gnode);
static guint dfilter_get_bytes_value_length(GNode* gnode);
@@ -123,6 +128,7 @@ dfilter *global_df = NULL;
%type <node> statement expression relation
%type <node> numeric_value numeric_variable
+%type <node> floating_value floating_variable
%type <node> ether_value ether_variable
%type <node> ipxnet_value ipxnet_variable
%type <node> ipv4_value ipv4_variable
@@ -150,6 +156,7 @@ dfilter *global_df = NULL;
%token <variable> T_FT_BOOLEAN
%token <variable> T_FT_STRING
%token <variable> T_FT_IPXNET
+%token <variable> T_FT_DOUBLE
%token <string> T_VAL_UNQUOTED_STRING
%token <string> T_VAL_BYTE_STRING
@@ -191,6 +198,15 @@ relation: numeric_variable numeric_relation numeric_value
$$ = dfilter_mknode_join($1, relation, $2, $3);
}
+ | floating_variable numeric_relation floating_value
+ {
+ $$ = dfilter_mknode_join($1, relation, $2, $3);
+ }
+ | floating_variable numeric_relation floating_variable
+ {
+ $$ = dfilter_mknode_join($1, relation, $2, $3);
+ }
+
| ether_variable equality_relation ether_value
{
$$ = dfilter_mknode_join($1, relation, $2, $3);
@@ -289,8 +305,12 @@ relation: numeric_variable numeric_relation numeric_value
numeric_value: T_VAL_UNQUOTED_STRING
{
- $$ = dfilter_mknode_numeric_value(string_to_value($1));
+ gboolean success;
+ $$ = dfilter_mknode_numeric_value(string_to_guint32($1, &success));
g_free($1);
+ if (!success) {
+ YYERROR;
+ }
}
;
@@ -306,8 +326,34 @@ ether_value: T_VAL_BYTE_STRING
ipxnet_value: T_VAL_UNQUOTED_STRING
{
- $$ = dfilter_mknode_ipxnet_value(string_to_value($1));
+ gboolean success;
+ $$ = dfilter_mknode_ipxnet_value(string_to_guint32($1, &success));
+ g_free($1);
+ if (!success) {
+ YYERROR;
+ }
+ }
+ ;
+
+floating_value: T_VAL_UNQUOTED_STRING
+ {
+ gboolean success;
+ $$ = dfilter_mknode_floating_value(string_to_double($1, &success));
+ g_free($1);
+ if (!success) {
+ YYERROR;
+ }
+ }
+
+ | T_VAL_BYTE_STRING
+ {
+ /* e.g., 0.0, 0.1, 0.01 ... */
+ gboolean success;
+ $$ = dfilter_mknode_floating_value(string_to_double($1, &success));
g_free($1);
+ if (!success) {
+ YYERROR;
+ }
}
;
@@ -361,13 +407,20 @@ bytes_value: T_VAL_BYTE_STRING
| T_VAL_UNQUOTED_STRING
{
- guint32 val32 = string_to_value($1);
+ gboolean success;
+ guint32 val32;
guint8 val8;
GByteArray *barray;
+ val32 = string_to_guint32($1, &success);
+ if (!success) {
+ g_free($1);
+ YYERROR;
+ }
if (val32 > 0xff) {
dfilter_fail("The value \"%s\" cannot be stored in a single-byte byte-string. "
"Use the multi-byte \"xx:yy\" representation.", $1);
+ g_free($1);
YYERROR;
}
val8 = (guint8) val32;
@@ -391,6 +444,9 @@ numeric_variable: T_FT_UINT8 { $$ = dfilter_mknode_numeric_variable($1.id); }
ether_variable: T_FT_ETHER { $$ = dfilter_mknode_ether_variable($1.id); }
;
+floating_variable: T_FT_DOUBLE { $$ = dfilter_mknode_floating_variable($1.id); }
+ ;
+
ipxnet_variable: T_FT_IPXNET { $$ = dfilter_mknode_ipxnet_variable($1.id); }
;
@@ -423,20 +479,21 @@ bytes_variable: any_variable_type T_VAL_BYTE_RANGE
}
;
-any_variable_type: T_FT_UINT8 { $$ = $1; }
- | T_FT_UINT16 { $$ = $1; }
- | T_FT_UINT32 { $$ = $1; }
- | T_FT_INT8 { $$ = $1; }
- | T_FT_INT16 { $$ = $1; }
- | T_FT_INT32 { $$ = $1; }
- | T_FT_ETHER { $$ = $1; }
- | T_FT_IPv4 { $$ = $1; }
- | T_FT_IPv6 { $$ = $1; }
- | T_FT_IPXNET { $$ = $1; }
- | T_FT_NONE { $$ = $1; }
- | T_FT_BYTES { $$ = $1; }
- | T_FT_BOOLEAN { $$ = $1; }
- | T_FT_STRING { $$ = $1; }
+any_variable_type: T_FT_UINT8 { $$ = $1; }
+ | T_FT_UINT16 { $$ = $1; }
+ | T_FT_UINT32 { $$ = $1; }
+ | T_FT_INT8 { $$ = $1; }
+ | T_FT_INT16 { $$ = $1; }
+ | T_FT_INT32 { $$ = $1; }
+ | T_FT_DOUBLE { $$ = $1; }
+ | T_FT_ETHER { $$ = $1; }
+ | T_FT_IPv4 { $$ = $1; }
+ | T_FT_IPv6 { $$ = $1; }
+ | T_FT_IPXNET { $$ = $1; }
+ | T_FT_NONE { $$ = $1; }
+ | T_FT_BYTES { $$ = $1; }
+ | T_FT_BOOLEAN { $$ = $1; }
+ | T_FT_STRING { $$ = $1; }
;
numeric_relation: TOK_EQ { $$ = TOK_EQ; }
@@ -542,6 +599,23 @@ dfilter_mknode_ether_variable(gint id)
}
static GNode*
+dfilter_mknode_floating_variable(gint id)
+{
+ dfilter_node *node;
+ GNode *gnode;
+
+ node = g_mem_chunk_alloc(global_df->node_memchunk);
+ node->ntype = variable;
+ node->elem_size = sizeof(double);
+ node->fill_array_func = fill_array_floating_variable;
+ node->check_relation_func = check_relation_floating;
+ node->value.variable = id;
+ gnode = g_node_new(node);
+
+ return gnode;
+}
+
+static GNode*
dfilter_mknode_ipxnet_variable(gint id)
{
dfilter_node *node;
@@ -684,6 +758,23 @@ dfilter_mknode_numeric_value(guint32 val)
return gnode;
}
+static GNode*
+dfilter_mknode_floating_value(double val)
+{
+ dfilter_node *node;
+ GNode *gnode;
+
+ node = g_mem_chunk_alloc(global_df->node_memchunk);
+ node->ntype = floating;
+ node->elem_size = sizeof(double);
+ node->fill_array_func = fill_array_floating_value;
+ node->check_relation_func = check_relation_floating;
+ node->value.floating = val;
+ gnode = g_node_new(node);
+
+ return gnode;
+}
+
/* Returns NULL on bad parse of ETHER value */
static GNode*
dfilter_mknode_ether_value(gchar *byte_string)
@@ -810,20 +901,59 @@ dfilter_get_bytes_value_length(GNode* gnode)
}
static guint32
-string_to_value(char *s)
+string_to_guint32(char *s, gboolean *success)
{
char *endptr;
guint32 val;
val = strtoul(s, &endptr, 0);
+ *success = TRUE;
if (endptr == s || *endptr != '\0') {
/* This isn't a valid number. */
dfilter_fail("\"%s\" is not a valid number.", s);
+ *success = FALSE;
+ }
+ if (errno == ERANGE) {
+ *success = FALSE;
+ if (val == ULONG_MAX) {
+ dfilter_fail("\"%s\" causes an integer overflow.", s);
+ }
+ else {
+ dfilter_fail("\"%s\" is not an integer.", s);
+ }
}
- /* I should probably check errno here */
return (guint32)val;
}
+
+static double
+string_to_double(char *s, gboolean *success)
+{
+ char *endptr = NULL;
+ double retval;
+
+ retval = strtod(s, &endptr);
+ *success = TRUE;
+
+ if (endptr == s) {
+ dfilter_fail("\"%s\" is not a valid floating-point number.", s);
+ *success = FALSE;
+ }
+
+ if (errno == ERANGE) {
+ *success = FALSE;
+ if (retval == 0) {
+ dfilter_fail("\"%s\" causes a floating-point underflow.", s);
+ }
+ else if (retval == HUGE_VAL) {
+ dfilter_fail("\"%s\" causes a floating-point overflow.", s);
+ }
+ else {
+ dfilter_fail("\"%s\" is not a valid floating-point.", s);
+ }
+ }
+ return retval;
+}
static GNode*
dfilter_mknode_existence(gint id)