zmap-mark-ii/src/expression.c
2024-02-21 18:23:18 -06:00

171 lines
3.9 KiB
C

/*
* ZMap Copyright 2013 Regents of the University of Michigan
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy
* of the License at http://www.apache.org/licenses/LICENSE-2.0
*/
#include "expression.h"
#include "fieldset.h"
#include "../lib/xalloc.h"
/* Static helper functions */
static node_t *alloc_node(void);
static int eval_gt_node(node_t *node, fieldset_t *fields);
static int eval_lt_node(node_t *node, fieldset_t *fields);
static int eval_eq_node(node_t *node, fieldset_t *fields);
static int eval_lt_eq_node(node_t *node, fieldset_t *fields);
static int eval_gt_eq_node(node_t *node, fieldset_t *fields);
static node_t *alloc_node(void)
{
node_t *node = xmalloc(sizeof(node_t));
return node;
}
static int eval_gt_node(node_t *node, fieldset_t *fields)
{
int index = node->left_child->value.field.index;
uint64_t expected = node->right_child->value.int_literal;
uint64_t actual = fs_get_uint64_by_index(fields, index);
return (actual > expected);
}
static int eval_lt_node(node_t *node, fieldset_t *fields)
{
int index = node->left_child->value.field.index;
uint64_t expected = node->right_child->value.int_literal;
uint64_t actual = fs_get_uint64_by_index(fields, index);
return (actual < expected);
}
static int eval_eq_node(node_t *node, fieldset_t *fields)
{
node_t *literal = node->right_child;
int index = node->left_child->value.field.index;
char *expected, *actual;
switch (literal->type) {
case STRING:
expected = literal->value.string_literal;
actual = fs_get_string_by_index(fields, index);
return (strcmp(expected, actual) == 0);
break;
case INT:
return (fs_get_uint64_by_index(fields, index) ==
literal->value.int_literal);
break;
default:
printf("wat\n");
break;
}
return 0;
}
static int eval_lt_eq_node(node_t *node, fieldset_t *fields)
{
return !(eval_gt_node(node, fields));
}
static int eval_gt_eq_node(node_t *node, fieldset_t *fields)
{
return !(eval_lt_node(node, fields));
}
/* Exposed functions */
node_t *make_op_node(enum operation op)
{
node_t *node = alloc_node();
node->type = OP;
node->value.op = op;
return node;
}
node_t *make_field_node(char *fieldname)
{
node_t *node = alloc_node();
node->type = FIELD;
node->value.field.fieldname = fieldname;
return node;
}
node_t *make_string_node(char *literal)
{
node_t *node = alloc_node();
node->type = STRING;
node->value.string_literal = literal;
return node;
}
node_t *make_int_node(int literal)
{
node_t *node = alloc_node();
node->type = INT;
node->value.int_literal = literal;
return node;
}
int evaluate_expression(node_t *root, fieldset_t *fields)
{
if (!root)
return 1;
switch (root->type) { /* XXX Not sure if runs */
case FIELD:
case STRING:
case INT:
return 1;
case OP:
break;
}
switch (root->value.op) {
case GT:
return eval_gt_node(root, fields);
case LT:
return eval_lt_node(root, fields);
case EQ:
return eval_eq_node(root, fields);
case NEQ:
return (!eval_eq_node(root, fields));
case LT_EQ:
return eval_lt_eq_node(root, fields);
case GT_EQ:
return eval_gt_eq_node(root, fields);
case AND:
return (evaluate_expression(root->left_child, fields) &&
evaluate_expression(root->right_child, fields));
case OR:
return (evaluate_expression(root->left_child, fields) ||
evaluate_expression(root->right_child, fields));
}
return 0;
}
void print_expression(node_t *root)
{
if (!root)
return;
printf("%s", "( ");
print_expression(root->left_child);
switch (root->type) {
case OP:
printf(" %i ", root->value.op);
break;
case FIELD:
printf(" (%s", root->value.field.fieldname);
break;
case STRING:
printf("%s) ", root->value.string_literal);
break;
case INT:
printf(" %llu) ", (long long unsigned)root->value.int_literal);
break;
default:
break;
}
print_expression(root->right_child);
printf("%s", " )");
}