summaryrefslogtreecommitdiffstats
path: root/dftest.c
diff options
context:
space:
mode:
Diffstat (limited to 'dftest.c')
-rw-r--r--dftest.c154
1 files changed, 112 insertions, 42 deletions
diff --git a/dftest.c b/dftest.c
index 9448f7f4..69034d34 100644
--- a/dftest.c
+++ b/dftest.c
@@ -25,6 +25,7 @@
#include <epan/timestamp.h>
#include <epan/prefs.h>
#include <epan/dfilter/dfilter.h>
+#include <epan/dfilter/dfilter-macro.h>
#ifdef HAVE_PLUGINS
#include <wsutil/plugins.h>
@@ -34,6 +35,7 @@
#include <wsutil/report_message.h>
#include <wsutil/wslog.h>
#include <wsutil/ws_getopt.h>
+#include <wsutil/utf8_entities.h>
#include <wiretap/wtap.h>
@@ -42,21 +44,20 @@
#include "ui/failure_message.h"
#include "wsutil/version_info.h"
-static int opt_verbose = 0;
-#define DFTEST_LOG_NONE 0
-#define DFTEST_LOG_DEBUG 1
-#define DFTEST_LOG_NOISY 2
-static int opt_log_level = DFTEST_LOG_NONE;
-static int opt_flex = 0;
-static int opt_lemon = 0;
-static int opt_syntax_tree = 0;
-static int opt_timer = 0;
+static int opt_verbose;
+static int opt_debug_level; /* currently up to 2 */
+static int opt_flex;
+static int opt_lemon;
+static int opt_syntax_tree;
+static int opt_return_vals;
+static int opt_timer;
static long opt_optimize = 1;
-static int opt_show_types = 0;
-static int opt_dump_refs = 0;
+static int opt_show_types;
+static int opt_dump_refs;
+static int opt_dump_macros;
-static gint64 elapsed_expand = 0;
-static gint64 elapsed_compile = 0;
+static int64_t elapsed_expand;
+static int64_t elapsed_compile;
/*
* Report an error in command-line arguments.
@@ -101,11 +102,14 @@ print_usage(int status)
fprintf(fp, "Usage: dftest [OPTIONS] -- EXPRESSION\n");
fprintf(fp, "Options:\n");
fprintf(fp, " -V, --verbose enable verbose mode\n");
- fprintf(fp, " -d, --debug enable compiler debug logs\n");
+ fprintf(fp, " -d, --debug[=N] increase or set debug level\n");
+ fprintf(fp, " -D set maximum debug level\n");
fprintf(fp, " -f, --flex enable Flex debug trace\n");
fprintf(fp, " -l, --lemon enable Lemon debug trace\n");
fprintf(fp, " -s, --syntax print syntax tree\n");
+ fprintf(fp, " -m --macros print saved macros\n");
fprintf(fp, " -t, --timer print elapsed compilation time\n");
+ fprintf(fp, " -r --return-vals return field values for the tree root\n");
fprintf(fp, " -0, --optimize=0 do not optimize (check syntax)\n");
fprintf(fp, " --types show field value types\n");
/* NOTE: References are loaded during runtime and dftest only does compilation.
@@ -127,9 +131,29 @@ print_syntax_tree(dfilter_t *df)
}
static void
+print_macros(void)
+{
+ if (dfilter_macro_table_count() == 0) {
+ printf("Macros: (empty)\n\n");
+ return;
+ }
+
+ struct dfilter_macro_table_iter iter;
+ const char *name, *text;
+
+ dfilter_macro_table_iter_init(&iter);
+ printf("Macros:\n");
+ while (dfilter_macro_table_iter_next(&iter, &name, &text)) {
+ printf(" "UTF8_BULLET" %s:\n", name);
+ printf(" %s\n", text);
+ }
+ printf("\n");
+}
+
+static void
print_warnings(dfilter_t *df)
{
- guint i;
+ unsigned i;
GPtrArray *deprecated;
int count = 0;
@@ -166,7 +190,7 @@ expand_filter(const char *text)
{
char *expanded = NULL;
df_error_t *err = NULL;
- gint64 start;
+ int64_t start;
start = g_get_monotonic_time();
expanded = dfilter_expand(text, &err);
@@ -178,13 +202,13 @@ expand_filter(const char *text)
return expanded;
}
-static gboolean
+static bool
compile_filter(const char *text, dfilter_t **dfp)
{
unsigned df_flags = 0;
- gboolean ok;
+ bool ok;
df_error_t *df_err = NULL;
- gint64 start;
+ int64_t start;
if (opt_optimize > 0)
df_flags |= DF_OPTIMIZE;
@@ -194,6 +218,8 @@ compile_filter(const char *text, dfilter_t **dfp)
df_flags |= DF_DEBUG_FLEX;
if (opt_lemon)
df_flags |= DF_DEBUG_LEMON;
+ if (opt_return_vals)
+ df_flags |= DF_RETURN_VALUES;
start = g_get_monotonic_time();
ok = dfilter_compile_full(text, dfp, &df_err, df_flags, "dftest");
@@ -209,6 +235,22 @@ compile_filter(const char *text, dfilter_t **dfp)
return ok;
}
+static int
+optarg_to_digit(const char *arg)
+{
+ if (strlen(arg) > 1 || !g_ascii_isdigit(*arg)) {
+ printf("Error: \"%s\" is not a valid number 0-9\n", arg);
+ print_usage(WS_EXIT_INVALID_OPTION);
+ }
+ errno = 0;
+ int digit = (int)strtol(ws_optarg, NULL, 10);
+ if (errno) {
+ printf("Error: %s\n", g_strerror(errno));
+ print_usage(WS_EXIT_INVALID_OPTION);
+ }
+ return digit;
+}
+
int
main(int argc, char **argv)
{
@@ -240,16 +282,18 @@ main(int argc, char **argv)
ws_init_version_info("DFTest", NULL, NULL);
- const char *optstring = "hvdflstV0";
+ const char *optstring = "hvdDflsmrtV0";
static struct ws_option long_options[] = {
{ "help", ws_no_argument, 0, 'h' },
{ "version", ws_no_argument, 0, 'v' },
- { "debug", ws_no_argument, 0, 'd' },
+ { "debug", ws_optional_argument, 0, 'd' },
{ "flex", ws_no_argument, 0, 'f' },
{ "lemon", ws_no_argument, 0, 'l' },
{ "syntax", ws_no_argument, 0, 's' },
+ { "macros", ws_no_argument, 0, 'm' },
{ "timer", ws_no_argument, 0, 't' },
{ "verbose", ws_no_argument, 0, 'V' },
+ { "return-vals", ws_no_argument, 0, 'r' },
{ "optimize", ws_required_argument, 0, 1000 },
{ "types", ws_no_argument, 0, 2000 },
{ "refs", ws_no_argument, 0, 3000 },
@@ -267,7 +311,19 @@ main(int argc, char **argv)
opt_verbose = 1;
break;
case 'd':
- opt_log_level = DFTEST_LOG_NOISY;
+ if (ws_optarg) {
+ opt_debug_level = optarg_to_digit(ws_optarg);
+ }
+ else {
+ opt_debug_level++;
+ }
+ opt_show_types = 1;
+ break;
+ case 'D':
+ opt_debug_level = 9;
+ opt_lemon = 1;
+ opt_flex = 1;
+ opt_show_types = 1;
break;
case 'f':
opt_flex = 1;
@@ -278,23 +334,20 @@ main(int argc, char **argv)
case 's':
opt_syntax_tree = 1;
break;
+ case 'm':
+ opt_dump_macros = 1;
+ break;
case 't':
opt_timer = 1;
break;
+ case 'r':
+ opt_return_vals = 1;
+ break;
case '0':
opt_optimize = 0;
break;
case 1000:
- if (strlen(ws_optarg) > 1 || !g_ascii_isdigit(*ws_optarg)) {
- printf("Error: \"%s\" is not a valid number 0-9\n", ws_optarg);
- print_usage(WS_EXIT_INVALID_OPTION);
- }
- errno = 0;
- opt_optimize = strtol(ws_optarg, NULL, 10);
- if (errno) {
- printf("Error: %s\n", g_strerror(errno));
- print_usage(WS_EXIT_INVALID_OPTION);
- }
+ opt_optimize = optarg_to_digit(ws_optarg);
break;
case 2000:
opt_show_types = 1;
@@ -317,19 +370,22 @@ main(int argc, char **argv)
}
}
- /* Check for filter on command line */
+ /* Check for filter on command line. */
if (argv[ws_optind] == NULL) {
- printf("Error: Missing argument.\n");
- print_usage(EXIT_FAILURE);
+ /* If not printing macros we need a filter expression to compile. */
+ if (!opt_dump_macros) {
+ printf("Error: Missing argument.\n");
+ print_usage(EXIT_FAILURE);
+ }
}
- if (opt_log_level == DFTEST_LOG_NOISY) {
+ /* Set dfilter domain logging. */
+ if (opt_debug_level > 1) {
ws_log_set_noisy_filter(LOG_DOMAIN_DFILTER);
}
- else if (opt_flex || opt_lemon) {
- /* Enable some dfilter logs with flex/lemon traces for context. */
+ else if (opt_debug_level > 0 || opt_flex || opt_lemon) {
+ /* Also enable some dfilter logs with flex/lemon traces for context. */
ws_log_set_debug_filter(LOG_DOMAIN_DFILTER);
- opt_log_level = DFTEST_LOG_DEBUG;
}
/*
@@ -372,13 +428,13 @@ main(int argc, char **argv)
* dissection-time handlers for file-type-dependent blocks can
* register using the file type/subtype value for the file type.
*/
- wtap_init(TRUE);
+ wtap_init(true);
/* Register all dissectors; we must do this before checking for the
"-g" flag, as the "-g" flag dumps a list of fields registered
by the dissectors, and we must do it before we read the preferences,
in case any dissectors register preferences. */
- if (!epan_init(NULL, NULL, FALSE))
+ if (!epan_init(NULL, NULL, true))
goto out;
/* Load libwireshark settings from the current profile. */
@@ -389,6 +445,20 @@ main(int argc, char **argv)
line that its preferences have changed. */
prefs_apply_all();
+ if (opt_dump_macros) {
+ print_macros();
+ if (argv[ws_optind] == NULL) {
+ /* No filter expression, we're done. */
+ exit(EXIT_SUCCESS);
+ }
+ }
+
+ /* Check again for filter on command line */
+ if (argv[ws_optind] == NULL) {
+ printf("Error: Missing argument.\n");
+ print_usage(EXIT_FAILURE);
+ }
+
/* This is useful to prevent confusion with option parsing.
* Skips printing options and argv[0]. */
if (opt_verbose) {
@@ -420,7 +490,7 @@ main(int argc, char **argv)
}
/* If logging is enabled add an empty line. */
- if (opt_log_level > DFTEST_LOG_NONE) {
+ if (opt_debug_level > 0) {
printf("\n");
}