diff options
Diffstat (limited to 'dftest.c')
-rw-r--r-- | dftest.c | 154 |
1 files changed, 112 insertions, 42 deletions
@@ -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"); } |