dfilter: Clean up error format and exception code
Misc code cleanups. Add some extra stnode functions for increased type safety. Fix a constness issue with df_lval_value().
This commit is contained in:
parent
63adcf7fb5
commit
e7ecc9b9e5
|
@ -64,9 +64,11 @@ df_lval_new(void)
|
|||
return g_new0(df_lval_t, 1);
|
||||
}
|
||||
|
||||
static inline char *
|
||||
static inline const char *
|
||||
df_lval_value(df_lval_t *lval)
|
||||
{
|
||||
if (!lval || !lval->value)
|
||||
return "(fixme: null)";
|
||||
return lval->value;
|
||||
}
|
||||
|
||||
|
@ -89,12 +91,17 @@ void Dfilter(void*, int, df_lval_t*, dfwork_t*);
|
|||
/* Return value for error in scanner. */
|
||||
#define SCAN_FAILED -1 /* not 0, as that means end-of-input */
|
||||
|
||||
/* Set dfw->error_message */
|
||||
void
|
||||
dfilter_vfail(dfwork_t *dfw, const char *format, va_list args);
|
||||
|
||||
void
|
||||
dfilter_fail(dfwork_t *dfw, const char *format, ...) G_GNUC_PRINTF(2, 3);
|
||||
|
||||
void
|
||||
dfilter_parse_fail(dfwork_t *dfw, const char *format, ...) G_GNUC_PRINTF(2, 3);
|
||||
dfilter_fail_throw(dfwork_t *dfw, long code, const char *format, ...) G_GNUC_PRINTF(3, 4);
|
||||
|
||||
void
|
||||
dfilter_fail_parse(dfwork_t *dfw, const char *format, ...) G_GNUC_PRINTF(2, 3);
|
||||
|
||||
void
|
||||
add_deprecated_token(dfwork_t *dfw, const char *token);
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
#include "semcheck.h"
|
||||
#include "dfvm.h"
|
||||
#include <epan/epan_dissect.h>
|
||||
#include <epan/exceptions.h>
|
||||
#include "dfilter.h"
|
||||
#include "dfilter-macro.h"
|
||||
#include "scanner_lex.h"
|
||||
|
@ -40,7 +41,7 @@ static void* ParserObj = NULL;
|
|||
*/
|
||||
dfwork_t *global_dfw;
|
||||
|
||||
static void
|
||||
void
|
||||
dfilter_vfail(dfwork_t *dfw, const char *format, va_list args)
|
||||
{
|
||||
/* If we've already reported one error, don't overwite it */
|
||||
|
@ -61,7 +62,18 @@ dfilter_fail(dfwork_t *dfw, const char *format, ...)
|
|||
}
|
||||
|
||||
void
|
||||
dfilter_parse_fail(dfwork_t *dfw, const char *format, ...)
|
||||
dfilter_fail_throw(dfwork_t *dfw, long code, const char *format, ...)
|
||||
{
|
||||
va_list args;
|
||||
|
||||
va_start(args, format);
|
||||
dfilter_vfail(dfw, format, args);
|
||||
va_end(args);
|
||||
THROW(code);
|
||||
}
|
||||
|
||||
void
|
||||
dfilter_fail_parse(dfwork_t *dfw, const char *format, ...)
|
||||
{
|
||||
va_list args;
|
||||
|
||||
|
|
|
@ -20,6 +20,9 @@
|
|||
#include <epan/exceptions.h>
|
||||
#include <wsutil/ws_assert.h>
|
||||
|
||||
#define FAIL(dfw, ...) \
|
||||
dfilter_fail_throw(dfw, TypeError, __VA_ARGS__)
|
||||
|
||||
/* Convert an FT_STRING using a callback function */
|
||||
static gboolean
|
||||
string_walk(GList* arg1list, GList **retval, gchar(*conv_func)(gchar))
|
||||
|
@ -181,8 +184,7 @@ ul_semcheck_is_field_string(dfwork_t *dfw, const char *func_name,
|
|||
return;
|
||||
}
|
||||
}
|
||||
dfilter_fail(dfw, "Only string type fields can be used as parameter for %s()", func_name);
|
||||
THROW(TypeError);
|
||||
FAIL(dfw, "Only string type fields can be used as parameter for %s()", func_name);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -194,8 +196,7 @@ ul_semcheck_is_field(dfwork_t *dfw, const char *func_name,
|
|||
if (stnode_type_id(st_node) == STTYPE_FIELD)
|
||||
return;
|
||||
|
||||
dfilter_fail(dfw, "Only fields can be used as parameter for %s()", func_name);
|
||||
THROW(TypeError);
|
||||
FAIL(dfw, "Only fields can be used as parameter for %s()", func_name);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -245,11 +246,9 @@ ul_semcheck_string_param(dfwork_t *dfw, const char *func_name,
|
|||
default:
|
||||
break;
|
||||
}
|
||||
dfilter_fail(dfw, "String conversion for field \"%s\" is not supported", hfinfo->abbrev);
|
||||
THROW(TypeError);
|
||||
FAIL(dfw, "String conversion for field \"%s\" is not supported", hfinfo->abbrev);
|
||||
}
|
||||
dfilter_fail(dfw, "Only fields can be used as parameter for %s()", func_name);
|
||||
THROW(TypeError);
|
||||
FAIL(dfw, "Only fields can be used as parameter for %s()", func_name);
|
||||
}
|
||||
|
||||
/* The table of all display-filter functions */
|
||||
|
|
|
@ -85,16 +85,8 @@ new_function(dfwork_t *dfw, df_lval_t *lval);
|
|||
/* This is called as soon as a syntax error happens. After that,
|
||||
any "error" symbols are shifted, if possible. */
|
||||
%syntax_error {
|
||||
|
||||
if (!TOKEN) {
|
||||
dfilter_fail(dfw, "Unexpected end of filter string.");
|
||||
dfw->syntax_error = TRUE;
|
||||
return;
|
||||
}
|
||||
|
||||
dfilter_fail(dfw, "\"%s\" was unexpected in this context.",
|
||||
df_lval_value(TOKEN));
|
||||
dfw->syntax_error = TRUE;
|
||||
dfilter_fail_parse(dfw, "\"%s\" was unexpected in this context.",
|
||||
df_lval_value(TOKEN));
|
||||
}
|
||||
|
||||
/* When a parse fails, mark an error. This occurs after
|
||||
|
@ -147,18 +139,18 @@ logical_test(T) ::= entity(E).
|
|||
/* Entities, or things that can be compared/tested/checked */
|
||||
entity(E) ::= STRING(S).
|
||||
{
|
||||
E = stnode_new(STTYPE_STRING, df_lval_value(S));
|
||||
E = stnode_new_string(df_lval_value(S));
|
||||
df_lval_free(S);
|
||||
}
|
||||
entity(E) ::= CHARCONST(C).
|
||||
{
|
||||
/* A charconst uses "unparsed" semantic rules. */
|
||||
E = stnode_new(STTYPE_UNPARSED, df_lval_value(C));
|
||||
E = stnode_new_unparsed(df_lval_value(C));
|
||||
df_lval_free(C);
|
||||
}
|
||||
entity(E) ::= UNPARSED(U).
|
||||
{
|
||||
E = stnode_new(STTYPE_UNPARSED, df_lval_value(U));
|
||||
E = stnode_new_unparsed(df_lval_value(U));
|
||||
dfilter_resolve_unparsed(dfw, E);
|
||||
df_lval_free(U);
|
||||
}
|
||||
|
@ -193,7 +185,7 @@ range_node(D) ::= RANGE(R).
|
|||
|
||||
D = drange_node_from_str(df_lval_value(R), &err);
|
||||
if (err != NULL) {
|
||||
dfilter_parse_fail(dfw, "%s", err);
|
||||
dfilter_fail_parse(dfw, "%s", err);
|
||||
g_free(err);
|
||||
}
|
||||
|
||||
|
@ -294,7 +286,7 @@ set_element(N) ::= entity(X) DOTDOT entity(Y).
|
|||
const char *name = df_lval_value(lval);
|
||||
df_func_def_t *def = df_func_lookup(name);
|
||||
if (!def) {
|
||||
dfilter_parse_fail(dfw, "Function '%s' does not exist", name);
|
||||
dfilter_fail_parse(dfw, "Function '%s' does not exist", name);
|
||||
}
|
||||
return stnode_new(STTYPE_FUNCTION, def);
|
||||
}
|
||||
|
|
|
@ -29,6 +29,9 @@
|
|||
#include <ftypes/ftypes-int.h>
|
||||
|
||||
|
||||
#define FAIL(dfw, ...) \
|
||||
dfilter_fail_throw(dfw, TypeError, __VA_ARGS__)
|
||||
|
||||
static void
|
||||
semcheck(dfwork_t *dfw, stnode_t *st_node);
|
||||
|
||||
|
@ -436,9 +439,8 @@ check_exists(dfwork_t *dfw, stnode_t *st_arg1)
|
|||
break;
|
||||
case STTYPE_STRING:
|
||||
case STTYPE_UNPARSED:
|
||||
dfilter_fail(dfw, "\"%s\" is neither a field nor a protocol name.",
|
||||
(char *)stnode_data(st_arg1));
|
||||
THROW(TypeError);
|
||||
FAIL(dfw, "%s is neither a field nor a protocol name.",
|
||||
stnode_todisplay(st_arg1));
|
||||
break;
|
||||
|
||||
case STTYPE_RANGE:
|
||||
|
@ -448,15 +450,13 @@ check_exists(dfwork_t *dfw, stnode_t *st_arg1)
|
|||
* has at least 2 bytes starting at an offset of
|
||||
* 3"?
|
||||
*/
|
||||
dfilter_fail(dfw, "You cannot test whether a range is present.");
|
||||
THROW(TypeError);
|
||||
FAIL(dfw, "You cannot test whether a range is present.");
|
||||
break;
|
||||
|
||||
case STTYPE_FUNCTION:
|
||||
/* XXX - Maybe we should change functions so they can return fields,
|
||||
* in which case the 'exist' should be fine. */
|
||||
dfilter_fail(dfw, "You cannot test whether a function is present.");
|
||||
THROW(TypeError);
|
||||
FAIL(dfw, "You cannot test whether a function is present.");
|
||||
break;
|
||||
|
||||
case STTYPE_UNINITIALIZED:
|
||||
|
@ -484,18 +484,16 @@ check_drange_sanity(dfwork_t *dfw, stnode_t *st)
|
|||
ftype1 = hfinfo1->type;
|
||||
|
||||
if (!ftype_can_slice(ftype1)) {
|
||||
dfilter_fail(dfw, "\"%s\" is a %s and cannot be sliced into a sequence of bytes.",
|
||||
FAIL(dfw, "\"%s\" is a %s and cannot be sliced into a sequence of bytes.",
|
||||
hfinfo1->abbrev, ftype_pretty_name(ftype1));
|
||||
THROW(TypeError);
|
||||
}
|
||||
} else if (stnode_type_id(entity1) == STTYPE_FUNCTION) {
|
||||
df_func_def_t *funcdef = sttype_function_funcdef(entity1);
|
||||
ftype1 = funcdef->retval_ftype;
|
||||
|
||||
if (!ftype_can_slice(ftype1)) {
|
||||
dfilter_fail(dfw, "Return value of function \"%s\" is a %s and cannot be converted into a sequence of bytes.",
|
||||
FAIL(dfw, "Return value of function \"%s\" is a %s and cannot be converted into a sequence of bytes.",
|
||||
funcdef->name, ftype_pretty_name(ftype1));
|
||||
THROW(TypeError);
|
||||
}
|
||||
|
||||
check_function(dfw, entity1);
|
||||
|
@ -503,9 +501,8 @@ check_drange_sanity(dfwork_t *dfw, stnode_t *st)
|
|||
/* Should this be rejected instead? */
|
||||
check_drange_sanity(dfw, entity1);
|
||||
} else {
|
||||
dfilter_fail(dfw, "Range is not supported for entity %s of type %s",
|
||||
FAIL(dfw, "Range is not supported for entity %s of type %s",
|
||||
stnode_todisplay(entity1), stnode_type_name(entity1));
|
||||
THROW(TypeError);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -537,13 +534,11 @@ check_function(dfwork_t *dfw, stnode_t *st_node)
|
|||
nparams = g_slist_length(params);
|
||||
|
||||
if (nparams < funcdef->min_nargs) {
|
||||
dfilter_fail(dfw, "Function %s needs at least %u arguments.",
|
||||
FAIL(dfw, "Function %s needs at least %u arguments.",
|
||||
funcdef->name, funcdef->min_nargs);
|
||||
THROW(TypeError);
|
||||
} else if (nparams > funcdef->max_nargs) {
|
||||
dfilter_fail(dfw, "Function %s can only accept %u arguments.",
|
||||
FAIL(dfw, "Function %s can only accept %u arguments.",
|
||||
funcdef->name, funcdef->max_nargs);
|
||||
THROW(TypeError);
|
||||
}
|
||||
|
||||
iparam = 0;
|
||||
|
@ -569,7 +564,7 @@ check_relation_LHS_FIELD(dfwork_t *dfw, test_op_t st_op,
|
|||
|
||||
type2 = stnode_type_id(st_arg2);
|
||||
|
||||
hfinfo1 = (header_field_info*)stnode_data(st_arg1);
|
||||
hfinfo1 = stnode_data(st_arg1);
|
||||
ftype1 = hfinfo1->type;
|
||||
|
||||
if (stnode_type_id(st_node) == STTYPE_TEST) {
|
||||
|
@ -579,27 +574,24 @@ check_relation_LHS_FIELD(dfwork_t *dfw, test_op_t st_op,
|
|||
}
|
||||
|
||||
if (!can_func(ftype1)) {
|
||||
dfilter_fail(dfw, "%s (type=%s) cannot participate in '%s' comparison.",
|
||||
FAIL(dfw, "%s (type=%s) cannot participate in '%s' comparison.",
|
||||
hfinfo1->abbrev, ftype_pretty_name(ftype1),
|
||||
sttype_test_todisplay(st_op));
|
||||
THROW(TypeError);
|
||||
}
|
||||
|
||||
if (type2 == STTYPE_FIELD) {
|
||||
hfinfo2 = (header_field_info*)stnode_data(st_arg2);
|
||||
hfinfo2 = stnode_data(st_arg2);
|
||||
ftype2 = hfinfo2->type;
|
||||
|
||||
if (!compatible_ftypes(ftype1, ftype2)) {
|
||||
dfilter_fail(dfw, "%s and %s are not of compatible types.",
|
||||
FAIL(dfw, "%s and %s are not of compatible types.",
|
||||
hfinfo1->abbrev, hfinfo2->abbrev);
|
||||
THROW(TypeError);
|
||||
}
|
||||
/* Do this check even though you'd think that if
|
||||
* they're compatible, then can_func() would pass. */
|
||||
if (!can_func(ftype2)) {
|
||||
dfilter_fail(dfw, "%s (type=%s) cannot participate in specified comparison.",
|
||||
FAIL(dfw, "%s (type=%s) cannot participate in specified comparison.",
|
||||
hfinfo2->abbrev, ftype_pretty_name(ftype2));
|
||||
THROW(TypeError);
|
||||
}
|
||||
}
|
||||
else if (type2 == STTYPE_STRING || type2 == STTYPE_UNPARSED) {
|
||||
|
@ -623,10 +615,9 @@ check_relation_LHS_FIELD(dfwork_t *dfw, test_op_t st_op,
|
|||
check_drange_sanity(dfw, st_arg2);
|
||||
if (!is_bytes_type(ftype1)) {
|
||||
if (!ftype_can_slice(ftype1)) {
|
||||
dfilter_fail(dfw, "\"%s\" is a %s and cannot be converted into a sequence of bytes.",
|
||||
FAIL(dfw, "\"%s\" is a %s and cannot be converted into a sequence of bytes.",
|
||||
hfinfo1->abbrev,
|
||||
ftype_pretty_name(ftype1));
|
||||
THROW(TypeError);
|
||||
}
|
||||
|
||||
/* Convert entire field to bytes */
|
||||
|
@ -638,16 +629,14 @@ check_relation_LHS_FIELD(dfwork_t *dfw, test_op_t st_op,
|
|||
ftype2 = funcdef->retval_ftype;
|
||||
|
||||
if (!compatible_ftypes(ftype1, ftype2)) {
|
||||
dfilter_fail(dfw, "%s (type=%s) and return value of %s() (type=%s) are not of compatible types.",
|
||||
FAIL(dfw, "%s (type=%s) and return value of %s() (type=%s) are not of compatible types.",
|
||||
hfinfo1->abbrev, ftype_pretty_name(ftype1),
|
||||
funcdef->name, ftype_pretty_name(ftype2));
|
||||
THROW(TypeError);
|
||||
}
|
||||
|
||||
if (!can_func(ftype2)) {
|
||||
dfilter_fail(dfw, "return value of %s() (type=%s) cannot participate in specified comparison.",
|
||||
FAIL(dfw, "return value of %s() (type=%s) cannot participate in specified comparison.",
|
||||
funcdef->name, ftype_pretty_name(ftype2));
|
||||
THROW(TypeError);
|
||||
}
|
||||
|
||||
check_function(dfw, st_arg2);
|
||||
|
@ -677,14 +666,13 @@ check_relation_LHS_STRING(dfwork_t *dfw, test_op_t st_op,
|
|||
ws_debug("5 check_relation_LHS_STRING()");
|
||||
|
||||
if (type2 == STTYPE_FIELD) {
|
||||
hfinfo2 = (header_field_info*)stnode_data(st_arg2);
|
||||
hfinfo2 = stnode_data(st_arg2);
|
||||
ftype2 = hfinfo2->type;
|
||||
|
||||
if (!can_func(ftype2)) {
|
||||
dfilter_fail(dfw, "%s (type=%s) cannot participate in '%s' comparison.",
|
||||
FAIL(dfw, "%s (type=%s) cannot participate in '%s' comparison.",
|
||||
hfinfo2->abbrev, ftype_pretty_name(ftype2),
|
||||
sttype_test_todisplay(st_op));
|
||||
THROW(TypeError);
|
||||
}
|
||||
|
||||
fvalue = dfilter_fvalue_from_string(dfw, ftype2, st_arg1, hfinfo2);
|
||||
|
@ -692,10 +680,9 @@ check_relation_LHS_STRING(dfwork_t *dfw, test_op_t st_op,
|
|||
}
|
||||
else if (type2 == STTYPE_STRING || type2 == STTYPE_UNPARSED) {
|
||||
/* Well now that's silly... */
|
||||
dfilter_fail(dfw, "Neither \"%s\" nor \"%s\" are field or protocol names.",
|
||||
(char *)stnode_data(st_arg1),
|
||||
(char *)stnode_data(st_arg2));
|
||||
THROW(TypeError);
|
||||
FAIL(dfw, "Neither %s nor %s are field or protocol names.",
|
||||
stnode_todisplay(st_arg1),
|
||||
stnode_todisplay(st_arg2));
|
||||
}
|
||||
else if (type2 == STTYPE_RANGE) {
|
||||
check_drange_sanity(dfw, st_arg2);
|
||||
|
@ -709,10 +696,9 @@ check_relation_LHS_STRING(dfwork_t *dfw, test_op_t st_op,
|
|||
ftype2 = funcdef->retval_ftype;
|
||||
|
||||
if (!can_func(ftype2)) {
|
||||
dfilter_fail(dfw, "Return value of function %s (type=%s) cannot participate in '%s' comparison.",
|
||||
FAIL(dfw, "Return value of function %s (type=%s) cannot participate in '%s' comparison.",
|
||||
funcdef->name, ftype_pretty_name(ftype2),
|
||||
sttype_test_todisplay(st_op));
|
||||
THROW(TypeError);
|
||||
}
|
||||
|
||||
fvalue = dfilter_fvalue_from_string(dfw, ftype2, st_arg1, NULL);
|
||||
|
@ -740,14 +726,13 @@ check_relation_LHS_UNPARSED(dfwork_t *dfw, test_op_t st_op,
|
|||
ws_debug("5 check_relation_LHS_UNPARSED()");
|
||||
|
||||
if (type2 == STTYPE_FIELD) {
|
||||
hfinfo2 = (header_field_info*)stnode_data(st_arg2);
|
||||
hfinfo2 = stnode_data(st_arg2);
|
||||
ftype2 = hfinfo2->type;
|
||||
|
||||
if (!can_func(ftype2)) {
|
||||
dfilter_fail(dfw, "%s (type=%s) cannot participate in '%s' comparison.",
|
||||
FAIL(dfw, "%s (type=%s) cannot participate in '%s' comparison.",
|
||||
hfinfo2->abbrev, ftype_pretty_name(ftype2),
|
||||
sttype_test_todisplay(st_op));
|
||||
THROW(TypeError);
|
||||
}
|
||||
|
||||
fvalue = dfilter_fvalue_from_unparsed(dfw, ftype2, st_arg1, allow_partial_value, hfinfo2);
|
||||
|
@ -755,10 +740,9 @@ check_relation_LHS_UNPARSED(dfwork_t *dfw, test_op_t st_op,
|
|||
}
|
||||
else if (type2 == STTYPE_STRING || type2 == STTYPE_UNPARSED) {
|
||||
/* Well now that's silly... */
|
||||
dfilter_fail(dfw, "Neither \"%s\" nor \"%s\" are field or protocol names.",
|
||||
(char *)stnode_data(st_arg1),
|
||||
(char *)stnode_data(st_arg2));
|
||||
THROW(TypeError);
|
||||
FAIL(dfw, "Neither %s nor %s are field or protocol names.",
|
||||
stnode_todisplay(st_arg1),
|
||||
stnode_todisplay(st_arg2));
|
||||
}
|
||||
else if (type2 == STTYPE_RANGE) {
|
||||
check_drange_sanity(dfw, st_arg2);
|
||||
|
@ -772,9 +756,8 @@ check_relation_LHS_UNPARSED(dfwork_t *dfw, test_op_t st_op,
|
|||
ftype2 = funcdef->retval_ftype;
|
||||
|
||||
if (!can_func(ftype2)) {
|
||||
dfilter_fail(dfw, "return value of function %s() (type=%s) cannot participate in '%s' comparison.",
|
||||
FAIL(dfw, "return value of function %s() (type=%s) cannot participate in '%s' comparison.",
|
||||
funcdef->name, ftype_pretty_name(ftype2), sttype_test_todisplay(st_op));
|
||||
THROW(TypeError);
|
||||
}
|
||||
|
||||
fvalue = dfilter_fvalue_from_unparsed(dfw, ftype2, st_arg1, allow_partial_value, NULL);
|
||||
|
@ -804,15 +787,14 @@ check_relation_LHS_RANGE(dfwork_t *dfw, test_op_t st_op,
|
|||
type2 = stnode_type_id(st_arg2);
|
||||
|
||||
if (type2 == STTYPE_FIELD) {
|
||||
hfinfo2 = (header_field_info*)stnode_data(st_arg2);
|
||||
hfinfo2 = stnode_data(st_arg2);
|
||||
ftype2 = hfinfo2->type;
|
||||
|
||||
if (!is_bytes_type(ftype2)) {
|
||||
if (!ftype_can_slice(ftype2)) {
|
||||
dfilter_fail(dfw, "\"%s\" is a %s and cannot be converted into a sequence of bytes.",
|
||||
FAIL(dfw, "\"%s\" is a %s and cannot be converted into a sequence of bytes.",
|
||||
hfinfo2->abbrev,
|
||||
ftype_pretty_name(ftype2));
|
||||
THROW(TypeError);
|
||||
}
|
||||
|
||||
/* Convert entire field to bytes */
|
||||
|
@ -836,10 +818,9 @@ check_relation_LHS_RANGE(dfwork_t *dfw, test_op_t st_op,
|
|||
|
||||
if (!is_bytes_type(ftype2)) {
|
||||
if (!ftype_can_slice(ftype2)) {
|
||||
dfilter_fail(dfw, "Return value of function \"%s\" is a %s and cannot be converted into a sequence of bytes.",
|
||||
FAIL(dfw, "Return value of function \"%s\" is a %s and cannot be converted into a sequence of bytes.",
|
||||
funcdef->name,
|
||||
ftype_pretty_name(ftype2));
|
||||
THROW(TypeError);
|
||||
}
|
||||
|
||||
/* Convert function result to bytes */
|
||||
|
@ -881,27 +862,24 @@ check_relation_LHS_FUNCTION(dfwork_t *dfw, test_op_t st_op,
|
|||
ws_debug("5 check_relation_LHS_FUNCTION(%s)", sttype_test_todisplay(st_op));
|
||||
|
||||
if (!can_func(ftype1)) {
|
||||
dfilter_fail(dfw, "Function %s (type=%s) cannot participate in '%s' comparison.",
|
||||
FAIL(dfw, "Function %s (type=%s) cannot participate in '%s' comparison.",
|
||||
funcdef->name, ftype_pretty_name(ftype1),
|
||||
sttype_test_todisplay(st_op));
|
||||
THROW(TypeError);
|
||||
}
|
||||
|
||||
if (type2 == STTYPE_FIELD) {
|
||||
hfinfo2 = (header_field_info*)stnode_data(st_arg2);
|
||||
hfinfo2 = stnode_data(st_arg2);
|
||||
ftype2 = hfinfo2->type;
|
||||
|
||||
if (!compatible_ftypes(ftype1, ftype2)) {
|
||||
dfilter_fail(dfw, "Function %s and %s are not of compatible types.",
|
||||
FAIL(dfw, "Function %s and %s are not of compatible types.",
|
||||
funcdef->name, hfinfo2->abbrev);
|
||||
THROW(TypeError);
|
||||
}
|
||||
/* Do this check even though you'd think that if
|
||||
* they're compatible, then can_func() would pass. */
|
||||
if (!can_func(ftype2)) {
|
||||
dfilter_fail(dfw, "%s (type=%s) cannot participate in specified comparison.",
|
||||
FAIL(dfw, "%s (type=%s) cannot participate in specified comparison.",
|
||||
hfinfo2->abbrev, ftype_pretty_name(ftype2));
|
||||
THROW(TypeError);
|
||||
}
|
||||
}
|
||||
else if (type2 == STTYPE_STRING) {
|
||||
|
@ -916,10 +894,9 @@ check_relation_LHS_FUNCTION(dfwork_t *dfw, test_op_t st_op,
|
|||
check_drange_sanity(dfw, st_arg2);
|
||||
if (!is_bytes_type(ftype1)) {
|
||||
if (!ftype_can_slice(ftype1)) {
|
||||
dfilter_fail(dfw, "Function \"%s\" is a %s and cannot be converted into a sequence of bytes.",
|
||||
FAIL(dfw, "Function \"%s\" is a %s and cannot be converted into a sequence of bytes.",
|
||||
funcdef->name,
|
||||
ftype_pretty_name(ftype1));
|
||||
THROW(TypeError);
|
||||
}
|
||||
|
||||
/* Convert function result to bytes */
|
||||
|
@ -931,17 +908,15 @@ check_relation_LHS_FUNCTION(dfwork_t *dfw, test_op_t st_op,
|
|||
ftype2 = funcdef2->retval_ftype;
|
||||
|
||||
if (!compatible_ftypes(ftype1, ftype2)) {
|
||||
dfilter_fail(dfw, "Return values of function %s (type=%s) and function %s (type=%s) are not of compatible types.",
|
||||
FAIL(dfw, "Return values of function %s (type=%s) and function %s (type=%s) are not of compatible types.",
|
||||
funcdef->name, ftype_pretty_name(ftype1), funcdef2->name, ftype_pretty_name(ftype2));
|
||||
THROW(TypeError);
|
||||
}
|
||||
|
||||
/* Do this check even though you'd think that if
|
||||
* they're compatible, then can_func() would pass. */
|
||||
if (!can_func(ftype2)) {
|
||||
dfilter_fail(dfw, "Return value of %s (type=%s) cannot participate in specified comparison.",
|
||||
FAIL(dfw, "Return value of %s (type=%s) cannot participate in specified comparison.",
|
||||
funcdef2->name, ftype_pretty_name(ftype2));
|
||||
THROW(TypeError);
|
||||
}
|
||||
|
||||
check_function(dfw, st_arg2);
|
||||
|
@ -1033,7 +1008,7 @@ check_relation_contains(dfwork_t *dfw, stnode_t *st_node,
|
|||
* functions will take care of it as if it didn't
|
||||
* match a protocol string.
|
||||
*/
|
||||
stnode_replace(st_arg2, STTYPE_UNPARSED, (char *)hfinfo->abbrev);
|
||||
stnode_replace_unparsed(st_arg2, hfinfo->abbrev);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1052,8 +1027,7 @@ check_relation_contains(dfwork_t *dfw, stnode_t *st_node,
|
|||
break;
|
||||
case STTYPE_STRING:
|
||||
case STTYPE_UNPARSED:
|
||||
dfilter_fail(dfw, "%s is not a valid operand for contains.", stnode_todisplay(st_arg1));
|
||||
THROW(TypeError);
|
||||
FAIL(dfw, "%s is not a valid operand for contains.", stnode_todisplay(st_arg1));
|
||||
break;
|
||||
default:
|
||||
ws_assert_not_reached();
|
||||
|
@ -1074,8 +1048,7 @@ check_relation_matches(dfwork_t *dfw, stnode_t *st_node,
|
|||
log_stnode(st_arg2);
|
||||
|
||||
if (stnode_type_id(st_arg2) != STTYPE_STRING) {
|
||||
dfilter_fail(dfw, "Expected a double quoted string not %s", stnode_todisplay(st_arg2));
|
||||
THROW(TypeError);
|
||||
FAIL(dfw, "Expected a double quoted string not %s", stnode_todisplay(st_arg2));
|
||||
}
|
||||
|
||||
patt = stnode_data(st_arg2);
|
||||
|
@ -1105,8 +1078,7 @@ check_relation_matches(dfwork_t *dfw, stnode_t *st_node,
|
|||
break;
|
||||
case STTYPE_STRING:
|
||||
case STTYPE_UNPARSED:
|
||||
dfilter_fail(dfw, "%s is not a valid operand for matches.", stnode_todisplay(st_arg1));
|
||||
THROW(TypeError);
|
||||
FAIL(dfw, "%s is not a valid operand for matches.", stnode_todisplay(st_arg1));
|
||||
break;
|
||||
default:
|
||||
ws_assert_not_reached();
|
||||
|
@ -1121,8 +1093,7 @@ check_relation_in(dfwork_t *dfw, stnode_t *st_node _U_,
|
|||
stnode_t *node, *node_right;
|
||||
|
||||
if (stnode_type_id(st_arg1) != STTYPE_FIELD) {
|
||||
dfilter_fail(dfw, "Only a field may be tested for membership in a set.");
|
||||
THROW(TypeError);
|
||||
FAIL(dfw, "Only a field may be tested for membership in a set.");
|
||||
}
|
||||
/* Checked in the grammar parser. */
|
||||
ws_assert(stnode_type_id(st_arg2) == STTYPE_SET);
|
||||
|
@ -1137,8 +1108,7 @@ check_relation_in(dfwork_t *dfw, stnode_t *st_node _U_,
|
|||
|
||||
/* Don't let a range on the RHS affect the LHS field. */
|
||||
if (stnode_type_id(node) == STTYPE_RANGE) {
|
||||
dfilter_fail(dfw, "A range may not appear inside a set.");
|
||||
THROW(TypeError);
|
||||
FAIL(dfw, "A range may not appear inside a set.");
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -9,12 +9,6 @@
|
|||
|
||||
#include "syntax-tree.h"
|
||||
|
||||
static gpointer
|
||||
string_new(gpointer string)
|
||||
{
|
||||
return g_strdup(string);
|
||||
}
|
||||
|
||||
static gpointer
|
||||
string_dup(gconstpointer string)
|
||||
{
|
||||
|
@ -48,7 +42,7 @@ sttype_register_string(void)
|
|||
static sttype_t string_type = {
|
||||
STTYPE_STRING,
|
||||
"STRING",
|
||||
string_new,
|
||||
NULL,
|
||||
string_free,
|
||||
string_dup,
|
||||
string_tostr
|
||||
|
@ -57,7 +51,7 @@ sttype_register_string(void)
|
|||
static sttype_t unparsed_type = {
|
||||
STTYPE_UNPARSED,
|
||||
"UNPARSED",
|
||||
string_new,
|
||||
NULL,
|
||||
string_free,
|
||||
string_dup,
|
||||
unparsed_tostr
|
||||
|
|
|
@ -134,6 +134,18 @@ stnode_replace(stnode_t *node, sttype_id_t type_id, gpointer data)
|
|||
node->flags = flags;
|
||||
}
|
||||
|
||||
void
|
||||
stnode_replace_string(stnode_t *node, const char *str)
|
||||
{
|
||||
stnode_replace(node, STTYPE_STRING, g_strdup(str));
|
||||
}
|
||||
|
||||
void
|
||||
stnode_replace_unparsed(stnode_t *node, const char *str)
|
||||
{
|
||||
stnode_replace(node, STTYPE_UNPARSED, g_strdup(str));
|
||||
}
|
||||
|
||||
stnode_t*
|
||||
stnode_new(sttype_id_t type_id, gpointer data)
|
||||
{
|
||||
|
@ -160,6 +172,18 @@ stnode_new_test(test_op_t op, stnode_t *val1, stnode_t *val2)
|
|||
return node;
|
||||
}
|
||||
|
||||
stnode_t *
|
||||
stnode_new_string(const char *str)
|
||||
{
|
||||
return stnode_new(STTYPE_STRING, g_strdup(str));
|
||||
}
|
||||
|
||||
stnode_t *
|
||||
stnode_new_unparsed(const char *str)
|
||||
{
|
||||
return stnode_new(STTYPE_UNPARSED, g_strdup(str));
|
||||
}
|
||||
|
||||
stnode_t*
|
||||
stnode_dup(const stnode_t *node)
|
||||
{
|
||||
|
|
|
@ -104,6 +104,12 @@ stnode_new(sttype_id_t type_id, gpointer data);
|
|||
stnode_t *
|
||||
stnode_new_test(test_op_t op, stnode_t *val1, stnode_t *val2);
|
||||
|
||||
stnode_t *
|
||||
stnode_new_string(const char *str);
|
||||
|
||||
stnode_t *
|
||||
stnode_new_unparsed(const char *str);
|
||||
|
||||
stnode_t*
|
||||
stnode_dup(const stnode_t *org);
|
||||
|
||||
|
@ -116,6 +122,12 @@ stnode_init(stnode_t *node, sttype_id_t type_id, gpointer data);
|
|||
void
|
||||
stnode_replace(stnode_t *node, sttype_id_t type_id, gpointer data);
|
||||
|
||||
void
|
||||
stnode_replace_string(stnode_t *node, const char *str);
|
||||
|
||||
void
|
||||
stnode_replace_unparsed(stnode_t *node, const char *str);
|
||||
|
||||
void
|
||||
stnode_free(stnode_t *node);
|
||||
|
||||
|
|
Loading…
Reference in New Issue