Make "dfilter_error()" available to the lexical analyzer.
authorguy <guy@f5534014-38df-0310-8fa8-9805f1628bb7>
Thu, 7 Oct 1999 21:47:20 +0000 (21:47 +0000)
committerguy <guy@f5534014-38df-0310-8fa8-9805f1628bb7>
Thu, 7 Oct 1999 21:47:20 +0000 (21:47 +0000)
Get rid of the declaration of the non-existent "dfilter_yyerror()", and
put in some #defines to work around the fact that the #defines to
replace "yy" with "dfilter_" in the names of Flex-generated and
Yacc-generated routines aren't put into a header file, they're put into
".c" files.

Have it remember the error message it was handed (unless it's Yacc's
boring "parse error" message).

When generating the message to be shown to the user on a parse error,
make it be the "Unable to parse filter string" message, and, if a
non-boring error message was supplied to "dfilter_error()", take that
error message onto the end.

Don't panic if a field type we don't yet support in the parser is seen;
generate an error, telling the user we don't support filter on that type
yet.

Don't assume that "global_df" has been set if we see an empty statement
(if the first token was the end-marker, because, say, the first token
the lexical analyzer found was a field of a type not yet supported in
filter expressions, "global_df" won't have been set).

git-svn-id: http://anonsvn.wireshark.org/wireshark/trunk@783 f5534014-38df-0310-8fa8-9805f1628bb7

dfilter-grammar.y
dfilter-int.h
dfilter-scanner.l
dfilter.c

index f0f46419373419493a65339b6b2e2a9bac0899a4..3594f66cf3671e5bfe11ccadd76dc611a50b4cc5 100644 (file)
@@ -3,7 +3,7 @@
 /* dfilter-grammar.y
  * Parser for display filters
  *
- * $Id: dfilter-grammar.y,v 1.19 1999/09/29 22:11:50 gram Exp $
+ * $Id: dfilter-grammar.y,v 1.20 1999/10/07 21:47:20 guy Exp $
  *
  * Ethereal - Network traffic analyzer
  * By Gerald Combs <gerald@zing.org>
@@ -164,7 +164,7 @@ statement: expression
                {
                        global_df->dftree = $1;
                }
-       |       /* NULL */ { global_df->dftree = NULL; }
+       |       /* NULL */ { if (global_df != NULL) global_df->dftree = NULL; }
        ;
 
 expression:    '(' expression ')' { $$ = $2; }
index 9de93a5303c649a14f2a8601cebd6d50ceb28051..8d1910a25e6d2eb2d92bb703bdc40c6af046d9e4 100644 (file)
@@ -2,7 +2,7 @@
  * Definitions for routines common to multiple modules in the display
  * filter code, but not used outside that code.
  *
- * $Id: dfilter-int.h,v 1.4 1999/08/30 16:01:42 gram Exp $
+ * $Id: dfilter-int.h,v 1.5 1999/10/07 21:47:19 guy Exp $
  *
  * Ethereal - Network traffic analyzer
  * By Gerald Combs <gerald@zing.org>
@@ -36,10 +36,24 @@ void dfilter_scanner_cleanup(void);
 extern dfilter *global_df;
 extern GSList *gnode_slist;
 
+/* Sigh.  The #defines to replace "yy" with "dfilter_" in the names of
+ * various parser routines appear in the ".c" files generated by Yacc
+ * and Flex, *not* in any header files; duplicate them here, but
+ * protect them with #ifdef so they're not used in files that define
+ * them. */
+#ifndef yylex
+#define yylex dfilter_lex
+#endif
+#ifndef yyerror
+#define yyerror dfilter_error
+#endif
+
 /* Here we provide interfaces to make our scanner act and look like lex */
 int yylex(void);
 void yyerror(char *s);
-void dfilter_yyerror(char *fmt, ...);
+
+/* Report an error during compilation of a filter */
+void dfilter_error(char *s);
 
 /* functions that dfilter-grammar.y needs during parsing*/
 gboolean check_relation_numeric(gint operand, GArray *a, GArray *b);
index 7fef7681f6ac6f068f53d8f4760338f59d3ec3dd..1daaf7fe31e9d9b8b7bb0b8f46eb39196525ba79 100644 (file)
@@ -3,7 +3,7 @@
 /* dfilter-scanner.l
  * Scanner for display filters
  *
- * $Id: dfilter-scanner.l,v 1.14 1999/10/06 18:42:40 gram Exp $
+ * $Id: dfilter-scanner.l,v 1.15 1999/10/07 21:47:19 guy Exp $
  *
  * Ethereal - Network traffic analyzer
  * By Gerald Combs <gerald@zing.org>
@@ -151,6 +151,12 @@ le|\<\=            { dfilter_lval.operand = TOK_LE; return TOK_LE; }
        
        ftype = proto_registrar_get_ftype(dfilter_lval.variable.id);
        switch (ftype) {
+               case FT_NONE:
+                       retval = T_FT_NONE;
+                       break;
+               case FT_BOOLEAN:
+                       retval = T_FT_BOOLEAN;
+                       break;
                case FT_UINT8:
                case FT_VALS_UINT8:
                        retval = T_FT_UINT8;
@@ -164,20 +170,34 @@ le|\<\=           { dfilter_lval.operand = TOK_LE; return TOK_LE; }
                case FT_VALS_UINT24:
                        retval = T_FT_UINT32;
                        break;
-               case FT_ETHER:
-                       retval = T_FT_ETHER;
+               case FT_DOUBLE:
+                       dfilter_error("sorry, we don't yet support filtering on floating-point values");
+                       retval = 0;
                        break;
-               case FT_IPv4:
-                       retval = T_FT_IPv4;
+               case FT_ABSOLUTE_TIME:
+                       dfilter_error("sorry, we don't yet support filtering on time-of-day values");
+                       retval = 0;
                        break;
-               case FT_NONE:
-                       retval = T_FT_NONE;
+               case FT_RELATIVE_TIME:
+                       dfilter_error("sorry, we don't yet support filtering on time-delta values");
+                       retval = 0;
+                       break;
+               case FT_STRING:
+                       dfilter_error("sorry, we don't yet support filtering on time-delta values");
+                       retval = 0;
+                       break;
+               case FT_ETHER:
+                       retval = T_FT_ETHER;
                        break;
                case FT_BYTES:
                        retval = T_FT_BYTES;
                        break;
-               case FT_BOOLEAN:
-                       retval = T_FT_BOOLEAN;
+               case FT_IPv4:
+                       retval = T_FT_IPv4;
+                       break;
+               case FT_IPv6:
+                       dfilter_error("sorry, we don't yet support filtering on IPv6 addresses");
+                       retval = 0;
                        break;
                case FT_IPXNET:
                        retval = T_FT_IPXNET;
index 5c6c933a7720108f4461c471417e6196bf8156cb..6fa05ccbe8fe0b4c374f070a6fd00e1369c6ffe9 100644 (file)
--- a/dfilter.c
+++ b/dfilter.c
@@ -1,7 +1,7 @@
 /* dfilter.c
  * Routines for display filters
  *
- * $Id: dfilter.c,v 1.23 1999/10/04 18:53:26 gram Exp $
+ * $Id: dfilter.c,v 1.24 1999/10/07 21:47:18 guy Exp $
  *
  * Ethereal - Network traffic analyzer
  * By Gerald Combs <gerald@zing.org>
@@ -167,15 +167,26 @@ dfilter_compile(dfilter *df, gchar *dfilter_text)
        /* clean up lex */
        dfilter_scanner_cleanup();
 
-       /* If a parse error occurred, fill in a generic error message
-        * if one was not created during parsing. */
+       /* Errors not found by the parser may not cause the parse to
+        * fail; if "dfilter_error_msg" is set, it means somebody
+        * else called "dfilter_error()", e.g. the lexical analyzer,
+        * so treat that as a parse error. */
+       if (dfilter_error_msg != NULL)
+               retval = 1;
+
        if (retval != 0) {
                if (dfilter_error_msg == NULL) {
-                       dfilter_error_msg = &dfilter_error_msg_buf[0];
-                       snprintf(dfilter_error_msg, sizeof(dfilter_error_msg_buf),
+                       snprintf(dfilter_error_msg_buf, sizeof(dfilter_error_msg_buf),
                                "Unable to parse filter string \"%s\".",
                                dfilter_text);
+               } else {
+                       /* An error message was supplied; use it in the
+                        * error we display. */
+                       snprintf(dfilter_error_msg_buf, sizeof(dfilter_error_msg_buf),
+                               "Unable to parse filter string \"%s\": %s.",
+                               dfilter_text, dfilter_error_msg);
                }
+               dfilter_error_msg = &dfilter_error_msg_buf[0];
        }
 
        /* Clear the list of allocated nodes */
@@ -262,6 +273,12 @@ clear_byte_array(gpointer data, gpointer user_data)
 void
 dfilter_error(char *s)
 {
+       /* Remember the error message we were handed, unless it's
+        * the boring "parse error" message used by YACC.
+        */
+       if (strcmp(s, "parse error") != 0)
+               dfilter_error_msg = s;
+
        /* The only data we have to worry about freeing is the
         * data used by any GNodes that were allocated during
         * parsing. The data in those Gnodes will be cleared
@@ -745,4 +762,3 @@ gboolean check_relation_bytes(gint operand, GArray *a, GArray *b)
        g_assert_not_reached();
        return FALSE;
 }
-