expression.c 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. /*
  2. * ZMap Copyright 2013 Regents of the University of Michigan
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License"); you may not
  5. * use this file except in compliance with the License. You may obtain a copy
  6. * of the License at http://www.apache.org/licenses/LICENSE-2.0
  7. */
  8. #include "expression.h"
  9. #include "fieldset.h"
  10. #include "../lib/xalloc.h"
  11. /* Static helper functions */
  12. static node_t* alloc_node();
  13. static int eval_gt_node(node_t *node, fieldset_t *fields);
  14. static int eval_lt_node(node_t *node, fieldset_t *fields);
  15. static int eval_eq_node(node_t *node, fieldset_t *fields);
  16. static int eval_lt_eq_node(node_t *node, fieldset_t *fields);
  17. static int eval_gt_eq_node(node_t *node, fieldset_t *fields);
  18. static node_t* alloc_node()
  19. {
  20. node_t *node = xmalloc(sizeof(node_t));
  21. return node;
  22. }
  23. static int eval_gt_node(node_t *node, fieldset_t *fields)
  24. {
  25. int index = node->left_child->value.field.index;
  26. uint64_t expected = node->right_child->value.int_literal;
  27. uint64_t actual = fs_get_uint64_by_index(fields, index);
  28. return (actual > expected);
  29. }
  30. static int eval_lt_node(node_t *node, fieldset_t *fields)
  31. {
  32. int index = node->left_child->value.field.index;
  33. uint64_t expected = node->right_child->value.int_literal;
  34. uint64_t actual = fs_get_uint64_by_index(fields, index);
  35. return (actual < expected);
  36. }
  37. static int eval_eq_node(node_t *node, fieldset_t *fields)
  38. {
  39. node_t *literal = node->right_child;
  40. int index = node->left_child->value.field.index;
  41. char *expected, *actual;
  42. switch (literal->type) {
  43. case STRING:
  44. expected = literal->value.string_literal;
  45. actual = fs_get_string_by_index(fields, index);
  46. return (strcmp(expected, actual) == 0);
  47. break;
  48. case INT:
  49. return (fs_get_uint64_by_index(fields, index) == literal->value.int_literal);
  50. break;
  51. default:
  52. printf("wat\n");
  53. break;
  54. }
  55. return 0;
  56. }
  57. static int eval_lt_eq_node(node_t *node, fieldset_t *fields)
  58. {
  59. return !(eval_gt_node(node, fields));
  60. }
  61. static int eval_gt_eq_node(node_t *node, fieldset_t *fields)
  62. {
  63. return !(eval_lt_node(node, fields));
  64. }
  65. /* Exposed functions */
  66. node_t* make_op_node(enum operation op)
  67. {
  68. node_t* node = alloc_node();
  69. node->type = OP;
  70. node->value.op = op;
  71. return node;
  72. }
  73. node_t* make_field_node(char *fieldname)
  74. {
  75. node_t *node = alloc_node();
  76. node->type = FIELD;
  77. node->value.field.fieldname = fieldname;
  78. return node;
  79. }
  80. node_t* make_string_node(char *literal)
  81. {
  82. node_t *node = alloc_node();
  83. node->type = STRING;
  84. node->value.string_literal = literal;
  85. return node;
  86. }
  87. node_t* make_int_node(int literal)
  88. {
  89. node_t *node = alloc_node();
  90. node->type = INT;
  91. node->value.int_literal = literal;
  92. return node;
  93. }
  94. int evaluate_expression(node_t *root, fieldset_t *fields)
  95. {
  96. if (!root) return 1;
  97. switch (root->type) { /* XXX Not sure if runs */
  98. case FIELD:
  99. case STRING:
  100. case INT:
  101. return 1;
  102. case OP:
  103. break;
  104. }
  105. switch (root->value.op) {
  106. case GT:
  107. return eval_gt_node(root, fields);
  108. case LT:
  109. return eval_lt_node(root, fields);
  110. case EQ:
  111. return eval_eq_node(root, fields);
  112. case NEQ:
  113. return (!eval_eq_node(root, fields));
  114. case LT_EQ:
  115. return eval_lt_eq_node(root, fields);
  116. case GT_EQ:
  117. return eval_gt_eq_node(root, fields);
  118. case AND:
  119. return (evaluate_expression(root->left_child, fields)
  120. && evaluate_expression(root->right_child, fields));
  121. case OR:
  122. return (evaluate_expression(root->left_child, fields)
  123. || evaluate_expression(root->right_child, fields));
  124. }
  125. return 0;
  126. }
  127. void print_expression(node_t *root)
  128. {
  129. if (!root) return;
  130. printf("%s", "( ");
  131. print_expression(root->left_child);
  132. switch (root->type) {
  133. case OP:
  134. printf(" %i ", root->value.op);
  135. break;
  136. case FIELD:
  137. printf(" (%s", root->value.field.fieldname);
  138. break;
  139. case STRING:
  140. printf("%s) ", root->value.string_literal);
  141. break;
  142. case INT:
  143. printf(" %llu) ", (long long unsigned) root->value.int_literal);
  144. break;
  145. default:
  146. break;
  147. }
  148. print_expression(root->right_child);
  149. printf("%s", " )");
  150. }