2
0
mirror of https://gitlab.isc.org/isc-projects/dhcp synced 2025-08-29 13:28:14 +00:00

Add support for functions, as well as arithmetic operators.

This commit is contained in:
Ted Lemon 2000-02-15 19:39:48 +00:00
parent 56a7da7d3c
commit 800f0de793

View File

@ -22,7 +22,7 @@
#ifndef lint #ifndef lint
static char copyright[] = static char copyright[] =
"$Id: tree.c,v 1.76 2000/02/05 17:45:20 mellon Exp $ Copyright (c) 1995, 1996, 1997, 1998 The Internet Software Consortium. All rights reserved.\n"; "$Id: tree.c,v 1.77 2000/02/15 19:39:48 mellon Exp $ Copyright (c) 1995, 1996, 1997, 1998 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */ #endif /* not lint */
#include "dhcpd.h" #include "dhcpd.h"
@ -457,7 +457,7 @@ int evaluate_expression (result, packet, lease,
} }
arg = expr -> data.funcall.arglist; arg = expr -> data.funcall.arglist;
s = binding -> value -> value.fundef.args; s = binding -> value -> value.fundef -> args;
while (arg && s) { while (arg && s) {
nb = dmalloc (sizeof *nb, MDL); nb = dmalloc (sizeof *nb, MDL);
if (!nb) { if (!nb) {
@ -499,7 +499,7 @@ int evaluate_expression (result, packet, lease,
ns -> outer = scope; ns -> outer = scope;
if (execute_statements if (execute_statements
(packet, lease, in_options, cfg_options, ns, (packet, lease, in_options, cfg_options, ns,
binding -> value -> value.fundef.statements)) { binding -> value -> value.fundef -> statements)) {
if (ns -> bindings && ns -> bindings -> name) { if (ns -> bindings && ns -> bindings -> name) {
binding_value_reference (result, binding_value_reference (result,
ns -> bindings -> value, ns -> bindings -> value,
@ -511,6 +511,12 @@ int evaluate_expression (result, packet, lease,
status = 0; status = 0;
binding_scope_dereference (&ns, MDL); binding_scope_dereference (&ns, MDL);
return status; return status;
} else if (expr -> op == expr_funcall) {
if (!binding_value_allocate (&bv, MDL))
return 0;
bv -> type = binding_function;
fundef_reference (&bv -> value.fundef, expr -> data.func, MDL);
return 1;
} else if (is_boolean_expression (expr)) { } else if (is_boolean_expression (expr)) {
if (!binding_value_allocate (&bv, MDL)) if (!binding_value_allocate (&bv, MDL))
return 0; return 0;
@ -823,6 +829,11 @@ int evaluate_dns_expression (result, packet, lease, in_options,
case expr_const_int: case expr_const_int:
case expr_lease_time: case expr_lease_time:
case expr_dns_transaction: case expr_dns_transaction:
case expr_add:
case expr_subtract:
case expr_multiply:
case expr_divide:
case expr_remainder:
log_error ("Numeric opcode in evaluate_dns_expression: %d", log_error ("Numeric opcode in evaluate_dns_expression: %d",
expr -> op); expr -> op);
return 0; return 0;
@ -1107,6 +1118,11 @@ int evaluate_boolean_expression (result, packet, lease, in_options,
case expr_const_int: case expr_const_int:
case expr_lease_time: case expr_lease_time:
case expr_dns_transaction: case expr_dns_transaction:
case expr_add:
case expr_subtract:
case expr_multiply:
case expr_divide:
case expr_remainder:
log_error ("Numeric opcode in evaluate_boolean_expression: %d", log_error ("Numeric opcode in evaluate_boolean_expression: %d",
expr -> op); expr -> op);
return 0; return 0;
@ -1119,6 +1135,10 @@ int evaluate_boolean_expression (result, packet, lease, in_options,
expr -> op); expr -> op);
return 0; return 0;
case expr_function:
log_error ("function definition in evaluate_boolean_expr");
return 0;
case expr_arg: case expr_arg:
break; break;
} }
@ -1903,6 +1923,11 @@ int evaluate_data_expression (result, packet, lease,
case expr_const_int: case expr_const_int:
case expr_lease_time: case expr_lease_time:
case expr_dns_transaction: case expr_dns_transaction:
case expr_add:
case expr_subtract:
case expr_multiply:
case expr_divide:
case expr_remainder:
log_error ("Numeric opcode in evaluate_data_expression: %d", log_error ("Numeric opcode in evaluate_data_expression: %d",
expr -> op); expr -> op);
return 0; return 0;
@ -1914,8 +1939,13 @@ int evaluate_data_expression (result, packet, lease,
log_error ("dns update opcode in evaluate_data_expression: %d", log_error ("dns update opcode in evaluate_data_expression: %d",
expr -> op); expr -> op);
return 0; return 0;
case expr_arg:
break; case expr_function:
log_error ("function definition in evaluate_data_expression");
return 0;
case expr_arg:
break;
} }
log_error ("Bogus opcode in evaluate_data_expression: %d", expr -> op); log_error ("Bogus opcode in evaluate_data_expression: %d", expr -> op);
@ -1943,6 +1973,7 @@ int evaluate_numeric_expression (result, packet, lease,
struct expression *cur, *next; struct expression *cur, *next;
struct binding *binding; struct binding *binding;
struct binding_value *bv; struct binding_value *bv;
unsigned long ileft, iright;
switch (expr -> op) { switch (expr -> op) {
case expr_check: case expr_check:
@ -2125,8 +2156,8 @@ int evaluate_numeric_expression (result, packet, lease,
case expr_funcall: case expr_funcall:
bv = (struct binding_value *)0; bv = (struct binding_value *)0;
status = evaluate_expression (&bv, packet, lease, status = evaluate_expression (&bv, packet, lease,
in_options, cfg_options, in_options, cfg_options,
scope, expr); scope, expr);
if (status) { if (status) {
if (bv -> type != binding_numeric) if (bv -> type != binding_numeric)
log_error ("%s() returned type %d in %s.", log_error ("%s() returned type %d in %s.",
@ -2143,6 +2174,111 @@ int evaluate_numeric_expression (result, packet, lease,
#endif #endif
break; break;
case expr_add:
sleft = evaluate_numeric_expression (&ileft, packet, lease,
in_options, cfg_options,
scope,
expr -> data.and [0]);
sright = evaluate_numeric_expression (&iright, packet, lease,
in_options, cfg_options,
scope,
expr -> data.and [1]);
#if defined (DEBUG_EXPRESSIONS)
log_debug ("num: %d + %d = %d",
ileft, iright,
((sleft && sright) ? (ileft + iright) : 0));
#endif
if (sleft && sright) {
*result = ileft + iright;
return 1;
}
return 0;
case expr_subtract:
sleft = evaluate_numeric_expression (&ileft, packet, lease,
in_options, cfg_options,
scope,
expr -> data.and [0]);
sright = evaluate_numeric_expression (&iright, packet, lease,
in_options, cfg_options,
scope,
expr -> data.and [1]);
#if defined (DEBUG_EXPRESSIONS)
log_debug ("num: %d - %d = %d",
ileft, iright,
((sleft && sright) ? (ileft - iright) : 0));
#endif
if (sleft && sright) {
*result = ileft - iright;
return 1;
}
return 0;
case expr_multiply:
sleft = evaluate_numeric_expression (&ileft, packet, lease,
in_options, cfg_options,
scope,
expr -> data.and [0]);
sright = evaluate_numeric_expression (&iright, packet, lease,
in_options, cfg_options,
scope,
expr -> data.and [1]);
#if defined (DEBUG_EXPRESSIONS)
log_debug ("num: %d * %d = %d",
ileft, iright,
((sleft && sright) ? (ileft * iright) : 0));
#endif
if (sleft && sright) {
*result = ileft * iright;
return 1;
}
return 0;
case expr_divide:
sleft = evaluate_numeric_expression (&ileft, packet, lease,
in_options, cfg_options,
scope,
expr -> data.and [0]);
sright = evaluate_numeric_expression (&iright, packet, lease,
in_options, cfg_options,
scope,
expr -> data.and [1]);
#if defined (DEBUG_EXPRESSIONS)
log_debug ("num: %d / %d = %d",
ileft, iright,
((sleft && sright && iright) ? (ileft / iright) : 0));
#endif
if (sleft && sright && iright) {
*result = ileft / iright;
return 1;
}
return 0;
case expr_remainder:
sleft = evaluate_numeric_expression (&ileft, packet, lease,
in_options, cfg_options,
scope,
expr -> data.and [0]);
sright = evaluate_numeric_expression (&iright, packet, lease,
in_options, cfg_options,
scope,
expr -> data.and [1]);
#if defined (DEBUG_EXPRESSIONS)
log_debug ("num: %d %% %d = %d",
ileft, iright,
((sleft && sright && iright) ? (ileft % iright) : 0));
#endif
if (sleft && sright && iright) {
*result = ileft % iright;
return 1;
}
return 0;
case expr_ns_add: case expr_ns_add:
case expr_ns_delete: case expr_ns_delete:
case expr_ns_exists: case expr_ns_exists:
@ -2151,6 +2287,10 @@ int evaluate_numeric_expression (result, packet, lease,
expr -> op); expr -> op);
return 0; return 0;
case expr_function:
log_error ("function definition in evaluate_numeric_expr");
return 0;
case expr_arg: case expr_arg:
break; break;
} }
@ -2298,6 +2438,11 @@ void expression_dereference (eptr, file, line)
case expr_concat: case expr_concat:
case expr_and: case expr_and:
case expr_or: case expr_or:
case expr_add:
case expr_subtract:
case expr_multiply:
case expr_divide:
case expr_remainder:
if (expr -> data.equal [0]) if (expr -> data.equal [0])
expression_dereference (&expr -> data.equal [0], expression_dereference (&expr -> data.equal [0],
file, line); file, line);
@ -2456,6 +2601,10 @@ void expression_dereference (eptr, file, line)
file, line); file, line);
break; break;
case expr_function:
fundef_dereference (&expr -> data.func, file, line);
break;
/* No subexpressions. */ /* No subexpressions. */
case expr_leased_address: case expr_leased_address:
case expr_lease_time: case expr_lease_time:
@ -2609,6 +2758,7 @@ static int op_val (op)
case expr_ns_not_exists: case expr_ns_not_exists:
case expr_arg: case expr_arg:
case expr_funcall: case expr_funcall:
case expr_function:
return 100; return 100;
case expr_equal: case expr_equal:
@ -2616,9 +2766,14 @@ static int op_val (op)
return 3; return 3;
case expr_and: case expr_and:
case expr_multiply:
case expr_divide:
case expr_remainder:
return 1; return 1;
case expr_or: case expr_or:
case expr_add:
case expr_subtract:
return 2; return 2;
} }
return 100; return 100;
@ -2679,6 +2834,7 @@ enum expression_context op_context (op)
case expr_dns_transaction: case expr_dns_transaction:
case expr_arg: case expr_arg:
case expr_funcall: case expr_funcall:
case expr_function:
return context_any; return context_any;
case expr_equal: case expr_equal:
@ -2690,6 +2846,13 @@ enum expression_context op_context (op)
case expr_or: case expr_or:
return context_boolean; return context_boolean;
case expr_add:
case expr_subtract:
case expr_multiply:
case expr_divide:
case expr_remainder:
return context_numeric;
} }
return context_any; return context_any;
} }
@ -2803,6 +2966,26 @@ int write_expression (file, expr, col, indent, firstp)
col = token_print_indent (file, col, indent, "", "", ")"); col = token_print_indent (file, col, indent, "", "", ")");
break; break;
case expr_add:
s = "+";
goto binary;
case expr_subtract:
s = "-";
goto binary;
case expr_multiply:
s = "*";
goto binary;
case expr_divide:
s = "/";
goto binary;
case expr_remainder:
s = "%";
goto binary;
case expr_and: case expr_and:
s = "and"; s = "and";
goto binary; goto binary;
@ -3198,4 +3381,57 @@ int binding_scope_dereference (ptr, file, line)
return 1; return 1;
} }
int fundef_dereference (ptr, file, line)
struct fundef **ptr;
const char *file;
int line;
{
struct fundef *bp;
struct string_list *sp, *next;
if (!ptr) {
log_error ("%s(%d): null pointer", file, line);
#if defined (POINTER_DEBUG)
abort ();
#else
return 0;
#endif
}
if (!bp) {
log_error ("%s(%d): null pointer", file, line);
#if defined (POINTER_DEBUG)
abort ();
#else
return 0;
#endif
}
bp -> refcnt--;
rc_register (file, line, ptr, bp, bp -> refcnt);
if (bp -> refcnt < 0) {
log_error ("%s(%d): negative refcnt!", file, line);
#if defined (DEBUG_RC_HISTORY)
dump_rc_history ();
#endif
#if defined (POINTER_DEBUG)
abort ();
#else
return 0;
#endif
}
if (!bp -> refcnt) {
for (sp = bp -> args; sp; sp = next) {
next = sp -> next;
dfree (sp, file, line);
}
if (bp -> statements)
executable_statement_dereference (&bp -> statements,
file, line);
dfree (bp, file, line);
}
*ptr = (struct fundef *)0;
return 1;
}
/* vim: set tabstop=8: */ /* vim: set tabstop=8: */