Hi Jeffrey and others,<br><br><div class="gmail_quote"><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
- Add values for the new operators to the expr_op enum in includes/tree.h<br>
- Modify parse_expression() in common/parse.c to recognize <, >, <=, and<br>
>= as operators (for <= and >=, look at how it already handles BANG to<br>
distinguish ! from !=) and turn them into expressions using the new<br>
operators<br>
- Add cases to the various functions in common/tree.c to handle recognizing<br>
the new operators as boolean expressions, evaluating them, and rejecting<br>
them when another expression type is called for.<br>
- Add cases to print_subexpression() in common/print.c to handle printing<br>
expressions involving the new operators. Don't forget this, or you'll<br>
get incorrect lease file entries for leases which have triggers using<br>
the new operators.</blockquote><div> </div><div>I did the code changes. Right now, I want only '<=' and '>=' to be supported. <br>
Please see below the code changes for the functions parse_expression, evaluate_boolean_expression and write_expression.<br>
Please let me know if you have any comments, if the code is ok.<br><br>Function parse_expression:<br> case LESS:<br> token = next_token (&val, (unsigned *)0, cfile);<br> token = peek_token (&val, (unsigned *)0, cfile);<br>
if (token != EQUAL) {<br> parse_warn (cfile, "< in boolean context without =");<br> *lose = 1;<br> skip_to_semi (cfile);<br> if (lhs)<br> expression_dereference (&lhs, MDL);<br>
return 0;<br> }<br> next_op = expr_less_equal;<br> context = expression_context (rhs);<br><br> break;<br><br> case GREATER:<br> token = next_token (&val, (unsigned *)0, cfile);<br>
token = peek_token (&val, (unsigned *)0, cfile);<br> if (token != EQUAL) {<br> parse_warn (cfile, "> in boolean context without =");<br> *lose = 1;<br> skip_to_semi (cfile);<br>
if (lhs)<br> expression_dereference (&lhs, MDL);<br> return 0;<br> }<br> next_op = expr_greater_equal;<br> context = expression_context (rhs);<br>..... <br> case expr_not_equal:<br>
case expr_equal:<br> case expr_greater_equal:<br> case expr_less_equal:<br> <br> if ((rhs_context != context_data_or_numeric) &&<br> (rhs_context != context_data) &&<br>
(rhs_context != context_numeric) &&<br> (rhs_context != context_any)) {<br> parse_warn (cfile, "expecting data/numeric expression");<br> skip_to_semi (cfile);<br>
expression_dereference (&rhs, MDL);<br> *lose = 1;<br> return 0;<br> }<br> break;<br><br>Function evaluate_boolean_expression:<br> case expr_less_equal:<br> case expr_greater_equal:<br>
bv = obv = (struct binding_value *)0;<br> sleft = evaluate_expression (&bv, packet, lease, client_state,<br> in_options, cfg_options, scope,<br> expr -> data.equal [0], MDL);<br>
sright = evaluate_expression (&obv, packet, lease,<br> client_state, in_options,<br> cfg_options, scope,<br> expr -> data.equal [1], MDL);<br>
if (sleft && sright) {<br> if (bv -> type != obv -> type)<br> *result = 0;<br> else {<br> switch (obv -> type) {<br> case binding_boolean: /* this may not be applicable in real */<br>
if (bv -> value.boolean < obv -> value.boolean)<br> *result = expr -> op == expr_less_equal;<br> else if(bv -> value.boolean > obv -> value.boolean)<br> *result = expr -> op == expr_greater_equal;<br>
else<br> *result = 1;<br> break;<br><br> case binding_data:/* for now do comparison only if len is equal */<br> if ((bv -> value.data.len == obv -> value.data.len) &&<br>
memcmp (bv -> value.data.data,<br> obv -> value.data.data,<br> obv -> value.data.len) < 0)<br> *result = expr -> op == expr_less_equal;<br>
else if ((bv -> value.data.len == obv -> value.data.len) &&<br> memcmp (bv -> value.data.data,<br> obv -> value.data.data,<br> obv -> value.data.len) > 0)<br>
*result = expr -> op == expr_greater_equal;<br> else if(bv -> value.data.len == obv -> value.data.len)<br> *result = 1;<br> else<br> *result = 0;<br>
break;<br><br> case binding_numeric:<br> if (bv -> value.intval < obv -> value.intval)<br> *result = expr -> op == expr_less_equal;<br> else if (bv -> value.intval > obv -> value.intval<br>
*result = expr -> op == expr_greater_equal;<br> else<br> *result = 1;<br> break;<br><br> case binding_dns: /* no support for now */<br>#if defined (NSUPDATE)<br>
*result = 0;<br>#else<br> *result = 0;<br>#endif<br> break;<br><br> case binding_function: /* no support for now */<br> *result = 0;<br> break;<br>
default:<br> *result = 0;<br> break;<br> }<br> }<br> } else if (!sleft && !sright)<br> *result = 1;<br> else /* should the result be zero for this ? */<br>
*result = 0;<br><br>#if defined (DEBUG_EXPRESSIONS)<br> log_debug ("bool: %sequal = %s",<br> expr -> op == expr_less_equal ? "less" : "greater",<br> (*result ? "true" : "false"));<br>
#endif<br> if (sleft)<br> binding_value_dereference (&bv, MDL);<br> if (sright)<br> binding_value_dereference (&obv, MDL);<br> return 1;<br><br>Function write_expression:<br>
case expr_less_equal:<br> s = "<=";<br> goto binary;<br><br> case expr_greater_equal:<br> s = ">=";<br> goto binary;<br><br></div></div>