mirror of
https://gitlab.isc.org/isc-projects/dhcp
synced 2025-08-22 01:49:35 +00:00
1491 lines
37 KiB
C
1491 lines
37 KiB
C
/*
|
|
* Copyright (C) 2017-2022 Internet Systems Consortium, Inc. ("ISC")
|
|
*
|
|
* Permission to use, copy, modify, and distribute this software for any
|
|
* purpose with or without fee is hereby granted, provided that the above
|
|
* copyright notice and this permission notice appear in all copies.
|
|
*
|
|
* THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
|
|
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
|
|
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
|
|
* OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
*
|
|
* Internet Systems Consortium, Inc.
|
|
* PO Box 360
|
|
* Newmarket, NH 03857 USA
|
|
* <info@isc.org>
|
|
* https://www.isc.org/
|
|
*
|
|
*/
|
|
|
|
#include "keama.h"
|
|
|
|
#include <sys/errno.h>
|
|
#include <sys/types.h>
|
|
#include <arpa/inet.h>
|
|
#include <ctype.h>
|
|
#include <netdb.h>
|
|
#include <stdarg.h>
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <unistd.h>
|
|
|
|
static void debug(const char* fmt, ...);
|
|
|
|
const char *
|
|
print_expression(struct element *expr, isc_boolean_t *lose)
|
|
{
|
|
if (expr->type == ELEMENT_BOOLEAN)
|
|
return print_boolean_expression(expr, lose);
|
|
if (expr->type == ELEMENT_INTEGER)
|
|
return print_numeric_expression(expr, lose);
|
|
if (expr->type == ELEMENT_STRING)
|
|
return print_data_expression(expr, lose);
|
|
|
|
if (is_boolean_expression(expr))
|
|
return print_boolean_expression(expr, lose);
|
|
if (is_numeric_expression(expr))
|
|
return print_numeric_expression(expr, lose);
|
|
if (is_data_expression(expr))
|
|
return print_data_expression(expr, lose);
|
|
*lose = ISC_TRUE;
|
|
return "???";
|
|
}
|
|
|
|
const char *
|
|
print_boolean_expression(struct element *expr, isc_boolean_t *lose)
|
|
{
|
|
struct string *result;
|
|
|
|
if (expr->type == ELEMENT_BOOLEAN) {
|
|
if (boolValue(expr))
|
|
return "true";
|
|
else
|
|
return "false";
|
|
}
|
|
|
|
/*
|
|
* From is_boolean_expression
|
|
*/
|
|
if (expr->type != ELEMENT_MAP) {
|
|
*lose = ISC_TRUE;
|
|
return "???";
|
|
}
|
|
result = allocString();
|
|
|
|
/* check */
|
|
if (mapContains(expr, "check")) {
|
|
struct element *name;
|
|
|
|
appendString(result, "check ");
|
|
name = mapGet(expr, "check");
|
|
if ((name == NULL) || (name->type != ELEMENT_STRING)) {
|
|
*lose = ISC_TRUE;
|
|
appendString(result, "???");
|
|
} else
|
|
concatString(result, stringValue(name));
|
|
return result->content;
|
|
}
|
|
|
|
/* exists */
|
|
if (mapContains(expr, "exists")) {
|
|
struct element *arg;
|
|
struct element *universe;
|
|
struct element *name;
|
|
|
|
appendString(result, "exists ");
|
|
arg = mapGet(expr, "exists");
|
|
if ((arg == NULL) || (arg->type != ELEMENT_MAP)) {
|
|
*lose = ISC_TRUE;
|
|
appendString(result, "???");
|
|
return result->content;
|
|
}
|
|
universe = mapGet(arg, "universe");
|
|
if ((universe == NULL) || (universe->type != ELEMENT_STRING)) {
|
|
*lose = ISC_TRUE;
|
|
appendString(result, "???");
|
|
return result->content;
|
|
}
|
|
concatString(result, stringValue(universe));
|
|
appendString(result, ".");
|
|
name = mapGet(arg, "name");
|
|
if ((name == NULL) || (name->type != ELEMENT_STRING)) {
|
|
*lose = ISC_TRUE;
|
|
appendString(result, "???");
|
|
return result->content;
|
|
}
|
|
concatString(result, stringValue(name));
|
|
return result->content;
|
|
}
|
|
|
|
/* variable-exists */
|
|
if (mapContains(expr, "variable-exists")) {
|
|
struct element *name;
|
|
|
|
appendString(result, "variable-exists ");
|
|
name = mapGet(expr, "variable-exists");
|
|
if ((name == NULL) || (name->type != ELEMENT_STRING)) {
|
|
*lose = ISC_TRUE;
|
|
appendString(result, "???");
|
|
} else
|
|
concatString(result, stringValue(name));
|
|
return result->content;
|
|
}
|
|
|
|
/* equal */
|
|
if (mapContains(expr, "equal")) {
|
|
struct element *arg;
|
|
struct element *left;
|
|
struct element *right;
|
|
isc_boolean_t add_parenthesis;
|
|
|
|
appendString(result, "equal ");
|
|
arg = mapGet(expr, "equal");
|
|
if ((arg == NULL) || (arg->type != ELEMENT_MAP)) {
|
|
*lose = ISC_TRUE;
|
|
appendString(result, "???");
|
|
return result->content;
|
|
}
|
|
left = mapGet(arg, "left");
|
|
if (left == NULL) {
|
|
*lose = ISC_TRUE;
|
|
appendString(result, "???");
|
|
return result->content;
|
|
}
|
|
result = allocString();
|
|
add_parenthesis = ISC_TF(expr_precedence(expr_equal,
|
|
left) < 0);
|
|
if (add_parenthesis)
|
|
appendString(result, "(");
|
|
appendString(result, print_expression(left, lose));
|
|
if (add_parenthesis)
|
|
appendString(result, ")");
|
|
appendString(result, " = ");
|
|
right = mapGet(arg, "right");
|
|
if (right == NULL) {
|
|
*lose = ISC_TRUE;
|
|
appendString(result, "???");
|
|
return result->content;
|
|
}
|
|
add_parenthesis = ISC_TF(expr_precedence(expr_equal,
|
|
right) < 0);
|
|
if (add_parenthesis)
|
|
appendString(result, "(");
|
|
appendString(result, print_expression(right, lose));
|
|
if (add_parenthesis)
|
|
appendString(result, ")");
|
|
return result->content;
|
|
}
|
|
|
|
/* not-equal */
|
|
if (mapContains(expr, "not-equal")) {
|
|
struct element *arg;
|
|
struct element *left;
|
|
struct element *right;
|
|
isc_boolean_t add_parenthesis;
|
|
|
|
appendString(result, "not-equal ");
|
|
arg = mapGet(expr, "not-equal");
|
|
if ((arg == NULL) || (arg->type != ELEMENT_MAP)) {
|
|
*lose = ISC_TRUE;
|
|
appendString(result, "???");
|
|
return result->content;
|
|
}
|
|
left = mapGet(arg, "left");
|
|
if (left == NULL) {
|
|
*lose = ISC_TRUE;
|
|
appendString(result, "???");
|
|
return result->content;
|
|
}
|
|
result = allocString();
|
|
add_parenthesis = ISC_TF(expr_precedence(expr_not_equal,
|
|
left) < 0);
|
|
if (add_parenthesis)
|
|
appendString(result, "(");
|
|
appendString(result, print_expression(left, lose));
|
|
if (add_parenthesis)
|
|
appendString(result, ")");
|
|
appendString(result, " != ");
|
|
right = mapGet(arg, "right");
|
|
if (right == NULL) {
|
|
*lose = ISC_TRUE;
|
|
appendString(result, "???");
|
|
return result->content;
|
|
}
|
|
add_parenthesis = ISC_TF(expr_precedence(expr_not_equal,
|
|
right) < 0);
|
|
if (add_parenthesis)
|
|
appendString(result, "(");
|
|
appendString(result, print_expression(right, lose));
|
|
if (add_parenthesis)
|
|
appendString(result, ")");
|
|
return result->content;
|
|
}
|
|
|
|
/* regex-match */
|
|
if (mapContains(expr, "regex-match")) {
|
|
struct element *arg;
|
|
struct element *left;
|
|
struct element *right;
|
|
isc_boolean_t add_parenthesis;
|
|
|
|
appendString(result, "regex-match ");
|
|
arg = mapGet(expr, "regex-match");
|
|
if ((arg == NULL) || (arg->type != ELEMENT_MAP)) {
|
|
*lose = ISC_TRUE;
|
|
appendString(result, "???");
|
|
return result->content;
|
|
}
|
|
left = mapGet(arg, "left");
|
|
if (left == NULL) {
|
|
*lose = ISC_TRUE;
|
|
appendString(result, "???");
|
|
return result->content;
|
|
}
|
|
result = allocString();
|
|
add_parenthesis = ISC_TF(expr_precedence(expr_regex_match,
|
|
left) < 0);
|
|
if (add_parenthesis)
|
|
appendString(result, "(");
|
|
appendString(result, print_expression(left, lose));
|
|
if (add_parenthesis)
|
|
appendString(result, ")");
|
|
appendString(result, " ~= ");
|
|
right = mapGet(arg, "right");
|
|
if (right == NULL) {
|
|
*lose = ISC_TRUE;
|
|
appendString(result, "???");
|
|
return result->content;
|
|
}
|
|
appendString(result, print_expression(right, lose));
|
|
return result->content;
|
|
}
|
|
|
|
/* iregex-match */
|
|
if (mapContains(expr, "iregex-match")) {
|
|
struct element *arg;
|
|
struct element *left;
|
|
struct element *right;
|
|
isc_boolean_t add_parenthesis;
|
|
|
|
appendString(result, "iregex-match ");
|
|
arg = mapGet(expr, "iregex-match");
|
|
if ((arg == NULL) || (arg->type != ELEMENT_MAP)) {
|
|
*lose = ISC_TRUE;
|
|
appendString(result, "???");
|
|
return result->content;
|
|
}
|
|
left = mapGet(arg, "left");
|
|
if (left == NULL) {
|
|
*lose = ISC_TRUE;
|
|
appendString(result, "???");
|
|
return result->content;
|
|
}
|
|
result = allocString();
|
|
add_parenthesis = ISC_TF(expr_precedence(expr_iregex_match,
|
|
left) < 0);
|
|
if (add_parenthesis)
|
|
appendString(result, "(");
|
|
appendString(result, print_expression(left, lose));
|
|
if (add_parenthesis)
|
|
appendString(result, ")");
|
|
appendString(result, " ~~ ");
|
|
right = mapGet(arg, "right");
|
|
if (right == NULL) {
|
|
*lose = ISC_TRUE;
|
|
appendString(result, "???");
|
|
return result->content;
|
|
}
|
|
appendString(result, print_expression(right, lose));
|
|
return result->content;
|
|
}
|
|
|
|
/* and */
|
|
if (mapContains(expr, "and")) {
|
|
struct element *arg;
|
|
struct element *left;
|
|
struct element *right;
|
|
isc_boolean_t add_parenthesis;
|
|
|
|
appendString(result, "and ");
|
|
arg = mapGet(expr, "and");
|
|
if ((arg == NULL) || (arg->type != ELEMENT_MAP)) {
|
|
*lose = ISC_TRUE;
|
|
appendString(result, "???");
|
|
return result->content;
|
|
}
|
|
left = mapGet(arg, "left");
|
|
if (left == NULL) {
|
|
*lose = ISC_TRUE;
|
|
appendString(result, "???");
|
|
return result->content;
|
|
}
|
|
result = allocString();
|
|
add_parenthesis = ISC_TF(expr_precedence(expr_and,
|
|
left) < 0);
|
|
if (add_parenthesis)
|
|
appendString(result, "(");
|
|
appendString(result, print_expression(left, lose));
|
|
if (add_parenthesis)
|
|
appendString(result, ")");
|
|
appendString(result, " and ");
|
|
right = mapGet(arg, "right");
|
|
if (right == NULL) {
|
|
*lose = ISC_TRUE;
|
|
appendString(result, "???");
|
|
return result->content;
|
|
}
|
|
add_parenthesis = ISC_TF(expr_precedence(expr_and,
|
|
right) < 0);
|
|
if (add_parenthesis)
|
|
appendString(result, "(");
|
|
appendString(result, print_expression(right, lose));
|
|
if (add_parenthesis)
|
|
appendString(result, ")");
|
|
return result->content;
|
|
}
|
|
|
|
/* or */
|
|
if (mapContains(expr, "or")) {
|
|
struct element *arg;
|
|
struct element *left;
|
|
struct element *right;
|
|
isc_boolean_t add_parenthesis;
|
|
|
|
appendString(result, "or ");
|
|
arg = mapGet(expr, "or");
|
|
if ((arg == NULL) || (arg->type != ELEMENT_MAP)) {
|
|
*lose = ISC_TRUE;
|
|
appendString(result, "???");
|
|
return result->content;
|
|
}
|
|
left = mapGet(arg, "left");
|
|
if (left == NULL) {
|
|
*lose = ISC_TRUE;
|
|
appendString(result, "???");
|
|
return result->content;
|
|
}
|
|
result = allocString();
|
|
add_parenthesis = ISC_TF(expr_precedence(expr_or,
|
|
left) < 0);
|
|
if (add_parenthesis)
|
|
appendString(result, "(");
|
|
appendString(result, print_expression(left, lose));
|
|
if (add_parenthesis)
|
|
appendString(result, ")");
|
|
appendString(result, " or ");
|
|
right = mapGet(arg, "right");
|
|
if (right == NULL) {
|
|
*lose = ISC_TRUE;
|
|
appendString(result, "???");
|
|
return result->content;
|
|
}
|
|
add_parenthesis = ISC_TF(expr_precedence(expr_or,
|
|
right) < 0);
|
|
if (add_parenthesis)
|
|
appendString(result, "(");
|
|
appendString(result, print_expression(right, lose));
|
|
if (add_parenthesis)
|
|
appendString(result, ")");
|
|
return result->content;
|
|
}
|
|
|
|
/* not */
|
|
if (mapContains(expr, "not")) {
|
|
struct element *arg;
|
|
isc_boolean_t add_parenthesis;
|
|
|
|
appendString(result, "not ");
|
|
arg = mapGet(expr, "not");
|
|
if (arg == NULL) {
|
|
*lose = ISC_TRUE;
|
|
appendString(result, "???");
|
|
return result->content;
|
|
}
|
|
add_parenthesis = ISC_TF(expr_precedence(expr_not,
|
|
arg) < 0);
|
|
if (add_parenthesis)
|
|
appendString(result, "(");
|
|
appendString(result, print_expression(arg, lose));
|
|
if (add_parenthesis)
|
|
appendString(result, ")");
|
|
return result->content;
|
|
}
|
|
|
|
/* known */
|
|
if (mapContains(expr, "known")) {
|
|
return "known";
|
|
}
|
|
|
|
/* static */
|
|
if (mapContains(expr, "static")) {
|
|
return "static";
|
|
}
|
|
|
|
/* variable-reference */
|
|
if (mapContains(expr, "variable-reference")) {
|
|
struct element *name;
|
|
|
|
appendString(result, "variable-reference ");
|
|
name = mapGet(expr, "variable-reference");
|
|
if ((name == NULL) || (name->type != ELEMENT_STRING)) {
|
|
*lose = ISC_TRUE;
|
|
appendString(result, "???");
|
|
return result->content;
|
|
}
|
|
return stringValue(name)->content;
|
|
}
|
|
|
|
/* funcall */
|
|
if (mapContains(expr, "funcall")) {
|
|
struct element *arg;
|
|
struct element *name;
|
|
struct element *args;
|
|
size_t i;
|
|
|
|
appendString(result, "funcall ");
|
|
arg = mapGet(expr, "funcall");
|
|
if ((arg == NULL) || (arg->type != ELEMENT_MAP)) {
|
|
*lose = ISC_TRUE;
|
|
appendString(result, "???");
|
|
return result->content;
|
|
}
|
|
name = mapGet(arg, "name");
|
|
if ((name == NULL) || (name->type != ELEMENT_STRING)) {
|
|
*lose = ISC_TRUE;
|
|
appendString(result, "???");
|
|
return result->content;
|
|
}
|
|
result = allocString();
|
|
concatString(result, stringValue(name));
|
|
appendString(result, "(");
|
|
args = mapGet(arg, "arguments");
|
|
if ((args == NULL) || (args->type != ELEMENT_LIST)) {
|
|
*lose = ISC_TRUE;
|
|
appendString(result, "???" ")");
|
|
return result->content;
|
|
}
|
|
for (i = 0; i < listSize(args); i++) {
|
|
struct element *item;
|
|
|
|
if (i != 0)
|
|
appendString(result, ", ");
|
|
item = listGet(args, i);
|
|
if (item == NULL) {
|
|
debug("funcall null argument %u",
|
|
(unsigned)i);
|
|
*lose = ISC_TRUE;
|
|
appendString(result, "???");
|
|
continue;
|
|
}
|
|
appendString(result, print_expression(item, lose));
|
|
}
|
|
appendString(result, ")");
|
|
return result->content;
|
|
}
|
|
|
|
*lose = ISC_TRUE;
|
|
appendString(result, "???");
|
|
return result->content;
|
|
}
|
|
|
|
const char *
|
|
print_data_expression(struct element *expr, isc_boolean_t *lose)
|
|
{
|
|
struct string *result;
|
|
|
|
if (expr->type == ELEMENT_STRING)
|
|
return quote(stringValue(expr))->content;
|
|
|
|
/*
|
|
* From is_data_expression
|
|
*/
|
|
if (expr->type != ELEMENT_MAP) {
|
|
*lose = ISC_TRUE;
|
|
return "???";
|
|
}
|
|
result = allocString();
|
|
|
|
/* substring */
|
|
if (mapContains(expr, "substring")) {
|
|
struct element *arg;
|
|
struct element *string;
|
|
struct element *offset;
|
|
struct element *length;
|
|
|
|
appendString(result, "substring(");
|
|
arg = mapGet(expr, "substring");
|
|
if ((arg == NULL) || (arg->type != ELEMENT_MAP)) {
|
|
*lose = ISC_TRUE;
|
|
appendString(result, "???" ")");
|
|
return result->content;
|
|
}
|
|
string = mapGet(arg, "expression");
|
|
if (string == NULL) {
|
|
*lose = ISC_TRUE;
|
|
appendString(result, "???" ")");
|
|
return result->content;
|
|
}
|
|
appendString(result, print_data_expression(string, lose));
|
|
appendString(result, ", ");
|
|
offset = mapGet(arg, "offset");
|
|
if (offset == NULL) {
|
|
*lose = ISC_TRUE;
|
|
appendString(result, "???" ")");
|
|
return result->content;
|
|
}
|
|
appendString(result, print_numeric_expression(offset, lose));
|
|
appendString(result, ", ");
|
|
length = mapGet(arg, "length");
|
|
if (length == NULL) {
|
|
*lose = ISC_TRUE;
|
|
appendString(result, "???" ")");
|
|
return result->content;
|
|
}
|
|
appendString(result, print_numeric_expression(length, lose));
|
|
appendString(result, ")");
|
|
return result->content;
|
|
}
|
|
|
|
/* suffix */
|
|
if (mapContains(expr, "suffix")) {
|
|
struct element *arg;
|
|
struct element *string;
|
|
struct element *length;
|
|
|
|
appendString(result, "suffix(");
|
|
arg = mapGet(expr, "suffix");
|
|
if ((arg == NULL) || (arg->type != ELEMENT_MAP)) {
|
|
*lose = ISC_TRUE;
|
|
appendString(result, "???" ")");
|
|
return result->content;
|
|
}
|
|
string = mapGet(arg, "expression");
|
|
if (string == NULL) {
|
|
*lose = ISC_TRUE;
|
|
appendString(result, "???" ")");
|
|
return result->content;
|
|
}
|
|
appendString(result, print_data_expression(string, lose));
|
|
appendString(result, ", ");
|
|
length = mapGet(arg, "length");
|
|
if (length == NULL) {
|
|
*lose = ISC_TRUE;
|
|
appendString(result, "???" ")");
|
|
return result->content;
|
|
}
|
|
appendString(result, print_numeric_expression(length, lose));
|
|
appendString(result, ")");
|
|
return result->content;
|
|
}
|
|
|
|
/* lowercase */
|
|
if (mapContains(expr, "lowercase")) {
|
|
struct element *arg;
|
|
|
|
appendString(result, "lowercase(");
|
|
arg = mapGet(expr, "lowercase");
|
|
if (arg == NULL) {
|
|
*lose = ISC_TRUE;
|
|
appendString(result, "???" ")");
|
|
return result->content;
|
|
}
|
|
appendString(result, print_data_expression(arg, lose));
|
|
appendString(result, ")");
|
|
return result->content;
|
|
}
|
|
|
|
/* uppercase */
|
|
if (mapContains(expr, "uppercase")) {
|
|
struct element *arg;
|
|
|
|
appendString(result, "uppercase(");
|
|
arg = mapGet(expr, "uppercase");
|
|
if (arg == NULL) {
|
|
*lose = ISC_TRUE;
|
|
appendString(result, "???" ")");
|
|
return result->content;
|
|
}
|
|
appendString(result, print_data_expression(arg, lose));
|
|
appendString(result, ")");
|
|
return result->content;
|
|
}
|
|
|
|
/* option */
|
|
if (mapContains(expr, "option")) {
|
|
struct element *arg;
|
|
struct element *universe;
|
|
struct element *name;
|
|
|
|
appendString(result, "option ");
|
|
arg = mapGet(expr, "option");
|
|
if ((arg == NULL) || (arg->type != ELEMENT_MAP)) {
|
|
*lose = ISC_TRUE;
|
|
appendString(result, "???");
|
|
return result->content;
|
|
}
|
|
universe = mapGet(arg, "universe");
|
|
if ((universe == NULL) || (universe->type != ELEMENT_STRING)) {
|
|
*lose = ISC_TRUE;
|
|
appendString(result, "???");
|
|
return result->content;
|
|
}
|
|
concatString(result, stringValue(universe));
|
|
appendString(result, ".");
|
|
name = mapGet(arg, "name");
|
|
if ((name == NULL) || (name->type != ELEMENT_STRING)) {
|
|
*lose = ISC_TRUE;
|
|
appendString(result, "???");
|
|
return result->content;
|
|
}
|
|
concatString(result, stringValue(name));
|
|
return result->content;
|
|
}
|
|
|
|
/* hardware */
|
|
if (mapContains(expr, "hardware"))
|
|
return "hardware";
|
|
|
|
/* hw-type */
|
|
if (mapContains(expr, "hw-type"))
|
|
return "hw-type";
|
|
|
|
/* hw-address */
|
|
if (mapContains(expr, "hw-address"))
|
|
return "hw-address";
|
|
|
|
/* const-data */
|
|
if (mapContains(expr, "const-data")) {
|
|
struct element *arg;
|
|
|
|
arg = mapGet(expr, "const-data");
|
|
if ((arg == NULL) || (arg->type != ELEMENT_STRING)) {
|
|
*lose = ISC_TRUE;
|
|
appendString(result, "???");
|
|
return result->content;
|
|
}
|
|
concatString(result, stringValue(arg));
|
|
return result->content;
|
|
}
|
|
|
|
/* packet */
|
|
if (mapContains(expr, "packet")) {
|
|
struct element *arg;
|
|
struct element *offset;
|
|
struct element *length;
|
|
|
|
appendString(result, "packet(");
|
|
arg = mapGet(expr, "packet");
|
|
if ((arg == NULL) || (arg->type != ELEMENT_MAP)) {
|
|
*lose = ISC_TRUE;
|
|
appendString(result, "???" ")");
|
|
return result->content;
|
|
}
|
|
offset = mapGet(arg, "offset");
|
|
if (offset == NULL) {
|
|
*lose = ISC_TRUE;
|
|
appendString(result, "???" ")");
|
|
return result->content;
|
|
}
|
|
appendString(result, print_numeric_expression(offset, lose));
|
|
appendString(result, ", ");
|
|
length = mapGet(arg, "length");
|
|
if (length == NULL) {
|
|
*lose = ISC_TRUE;
|
|
appendString(result, "???" ")");
|
|
return result->content;
|
|
}
|
|
appendString(result, print_numeric_expression(length, lose));
|
|
appendString(result, ")");
|
|
return result->content;
|
|
}
|
|
|
|
/* concat */
|
|
if (mapContains(expr, "concat")) {
|
|
struct element *arg;
|
|
struct element *left;
|
|
struct element *right;
|
|
|
|
appendString(result, "concat(");
|
|
arg = mapGet(expr, "concat");
|
|
if ((arg == NULL) || (arg->type != ELEMENT_MAP)) {
|
|
*lose = ISC_TRUE;
|
|
appendString(result, "???" ")");
|
|
return result->content;
|
|
}
|
|
left = mapGet(arg, "left");
|
|
if (left == NULL) {
|
|
*lose = ISC_TRUE;
|
|
appendString(result, "???" ")");
|
|
return result->content;
|
|
}
|
|
appendString(result, print_data_expression(left, lose));
|
|
appendString(result, ", ");
|
|
right = mapGet(arg, "right");
|
|
if (right == NULL) {
|
|
*lose = ISC_TRUE;
|
|
appendString(result, "???" ")");
|
|
return result->content;
|
|
}
|
|
appendString(result, print_data_expression(right, lose));
|
|
appendString(result, ")");
|
|
return result->content;
|
|
}
|
|
|
|
/* encapsulate */
|
|
if (mapContains(expr, "encapsulate")) {
|
|
struct element *arg;
|
|
|
|
appendString(result, "encapsulate ");
|
|
arg = mapGet(expr, "encapsulate");
|
|
if (arg == NULL) {
|
|
*lose = ISC_TRUE;
|
|
appendString(result, "???");
|
|
return result->content;
|
|
}
|
|
appendString(result, print_data_expression(arg, lose));
|
|
return result->content;
|
|
}
|
|
|
|
/* encode-int8 */
|
|
if (mapContains(expr, "encode-int8")) {
|
|
struct element *arg;
|
|
|
|
appendString(result, "encode-int(");
|
|
arg = mapGet(expr, "encode-int8");
|
|
if (arg == NULL) {
|
|
*lose = ISC_TRUE;
|
|
appendString(result, "???, 8)");
|
|
return result->content;
|
|
}
|
|
appendString(result, print_numeric_expression(arg, lose));
|
|
appendString(result, ", 8)");
|
|
return result->content;
|
|
}
|
|
|
|
/* encode-int16 */
|
|
if (mapContains(expr, "encode-int16")) {
|
|
struct element *arg;
|
|
|
|
appendString(result, "encode-int(");
|
|
arg = mapGet(expr, "encode-int16");
|
|
if (arg == NULL) {
|
|
*lose = ISC_TRUE;
|
|
appendString(result, "???, 16)");
|
|
return result->content;
|
|
}
|
|
appendString(result, print_numeric_expression(arg, lose));
|
|
appendString(result, ", 16)");
|
|
return result->content;
|
|
}
|
|
|
|
/* encode-int32 */
|
|
if (mapContains(expr, "encode-int32")) {
|
|
struct element *arg;
|
|
|
|
appendString(result, "encode-int(");
|
|
arg = mapGet(expr, "encode-int32");
|
|
if (arg == NULL) {
|
|
*lose = ISC_TRUE;
|
|
appendString(result, "???, 32)");
|
|
return result->content;
|
|
}
|
|
appendString(result, print_numeric_expression(arg, lose));
|
|
appendString(result, ", 32)");
|
|
return result->content;
|
|
}
|
|
|
|
/* gethostbyname */
|
|
if (mapContains(expr, "gethostbyname")) {
|
|
struct element *arg;
|
|
|
|
appendString(result, "gethostbyname(");
|
|
arg = mapGet(expr, "gethostbyname");
|
|
if (arg == NULL) {
|
|
*lose = ISC_TRUE;
|
|
appendString(result, "???");
|
|
return result->content;
|
|
}
|
|
appendString(result, print_data_expression(arg, lose));
|
|
appendString(result, ")");
|
|
return result->content;
|
|
}
|
|
|
|
/* binary-to-ascii */
|
|
if (mapContains(expr, "binary-to-ascii")) {
|
|
struct element *arg;
|
|
struct element *base;
|
|
struct element *width;
|
|
struct element *separator;
|
|
struct element *buffer;
|
|
|
|
appendString(result, "binary-to-ascii(");
|
|
arg = mapGet(expr, "binary-to-ascii");
|
|
if ((arg == NULL) || (arg->type != ELEMENT_MAP)) {
|
|
*lose = ISC_TRUE;
|
|
appendString(result, "???" ")");
|
|
return result->content;
|
|
}
|
|
base = mapGet(arg, "base");
|
|
if (base == NULL) {
|
|
*lose = ISC_TRUE;
|
|
appendString(result, "???" ")");
|
|
return result->content;
|
|
}
|
|
appendString(result, print_numeric_expression(base, lose));
|
|
appendString(result, ", ");
|
|
width = mapGet(arg, "width");
|
|
if (width == NULL) {
|
|
*lose = ISC_TRUE;
|
|
appendString(result, "???" ")");
|
|
return result->content;
|
|
}
|
|
appendString(result, print_numeric_expression(width, lose));
|
|
appendString(result, ", ");
|
|
separator = mapGet(arg, "separator");
|
|
if (separator == NULL) {
|
|
*lose = ISC_TRUE;
|
|
appendString(result, "???" ")");
|
|
return result->content;
|
|
}
|
|
appendString(result, print_data_expression(separator, lose));
|
|
appendString(result, ", ");
|
|
buffer = mapGet(arg, "buffer");
|
|
if (buffer == NULL) {
|
|
*lose = ISC_TRUE;
|
|
appendString(result, "???" ")");
|
|
return result->content;
|
|
}
|
|
appendString(result, print_data_expression(buffer, lose));
|
|
appendString(result, ")");
|
|
return result->content;
|
|
}
|
|
|
|
/* filename */
|
|
if (mapContains(expr, "filename"))
|
|
return "filename";
|
|
|
|
/* server-name */
|
|
if (mapContains(expr, "server-name"))
|
|
return "server-name";
|
|
|
|
/* reverse */
|
|
if (mapContains(expr, "reverse")) {
|
|
struct element *arg;
|
|
struct element *width;
|
|
struct element *buffer;
|
|
|
|
appendString(result, "reverse(");
|
|
arg = mapGet(expr, "reverse");
|
|
if ((arg == NULL) || (arg->type != ELEMENT_MAP)) {
|
|
*lose = ISC_TRUE;
|
|
appendString(result, "???" ")");
|
|
return result->content;
|
|
}
|
|
width = mapGet(arg, "width");
|
|
if (width == NULL) {
|
|
*lose = ISC_TRUE;
|
|
appendString(result, "???" ")");
|
|
return result->content;
|
|
}
|
|
appendString(result, print_numeric_expression(width, lose));
|
|
appendString(result, ", ");
|
|
buffer = mapGet(arg, "buffer");
|
|
if (buffer == NULL) {
|
|
*lose = ISC_TRUE;
|
|
appendString(result, "???" ")");
|
|
return result->content;
|
|
}
|
|
appendString(result, print_data_expression(buffer, lose));
|
|
appendString(result, ")");
|
|
return result->content;
|
|
}
|
|
|
|
/* pick-first-value */
|
|
if (mapContains(expr, "pick-first-value")) {
|
|
struct element *arg;
|
|
size_t i;
|
|
|
|
appendString(result, "pick-first-value(");
|
|
arg = mapGet(expr, "pick-first-value");
|
|
if ((arg == NULL) || (arg->type != ELEMENT_LIST)) {
|
|
*lose = ISC_TRUE;
|
|
appendString(result, "???" ")");
|
|
return result->content;
|
|
}
|
|
for (i = 0; i < listSize(arg); i++) {
|
|
struct element *item;
|
|
|
|
if (i != 0)
|
|
appendString(result, ", ");
|
|
item = listGet(arg, i);
|
|
if (item == NULL) {
|
|
*lose = ISC_TRUE;
|
|
appendString(result, "???");
|
|
continue;
|
|
}
|
|
appendString(result,
|
|
print_data_expression(item, lose));
|
|
}
|
|
appendString(result, ")");
|
|
return result->content;
|
|
}
|
|
|
|
/* host-decl-name */
|
|
if (mapContains(expr, "host-decl-name"))
|
|
return "host-decl-name";
|
|
|
|
/* leased-address */
|
|
if (mapContains(expr, "leased-address"))
|
|
return "leased-address";
|
|
|
|
/* config-option */
|
|
if (mapContains(expr, "config-option")) {
|
|
struct element *arg;
|
|
struct element *universe;
|
|
struct element *name;
|
|
|
|
appendString(result, "config-option ");
|
|
arg = mapGet(expr, "config-option");
|
|
if ((arg == NULL) || (arg->type != ELEMENT_MAP)) {
|
|
*lose = ISC_TRUE;
|
|
appendString(result, "???");
|
|
return result->content;
|
|
}
|
|
universe = mapGet(arg, "universe");
|
|
if ((universe == NULL) || (universe->type != ELEMENT_STRING)) {
|
|
*lose = ISC_TRUE;
|
|
appendString(result, "???");
|
|
return result->content;
|
|
}
|
|
concatString(result, stringValue(universe));
|
|
appendString(result, ".");
|
|
name = mapGet(arg, "name");
|
|
if ((name == NULL) || (name->type != ELEMENT_STRING)) {
|
|
*lose = ISC_TRUE;
|
|
appendString(result, "???");
|
|
return result->content;
|
|
}
|
|
concatString(result, stringValue(name));
|
|
return result->content;
|
|
}
|
|
|
|
/* null */
|
|
if (mapContains(expr, "null"))
|
|
return "null";
|
|
|
|
/* gethostname */
|
|
if (mapContains(expr, "gethostname"))
|
|
return "gethostname";
|
|
|
|
/* v6relay */
|
|
if (mapContains(expr, "v6relay")) {
|
|
struct element *arg;
|
|
struct element *relay;
|
|
struct element *option;
|
|
|
|
|
|
appendString(result, "v6relay(");
|
|
arg = mapGet(expr, "v6relay");
|
|
if ((arg == NULL) || (arg->type != ELEMENT_MAP)) {
|
|
*lose = ISC_TRUE;
|
|
appendString(result, "???" ")");
|
|
return result->content;
|
|
}
|
|
relay = mapGet(arg, "relay");
|
|
if (relay == NULL) {
|
|
*lose = ISC_TRUE;
|
|
appendString(result, "???" ")");
|
|
return result->content;
|
|
}
|
|
appendString(result, print_numeric_expression(relay, lose));
|
|
appendString(result, ", ");
|
|
option = mapGet(arg, "relay-option");
|
|
if (option == NULL) {
|
|
*lose = ISC_TRUE;
|
|
appendString(result, "???" ")");
|
|
return result->content;
|
|
}
|
|
appendString(result, print_data_expression(option, lose));
|
|
appendString(result, ")");
|
|
return result->content;
|
|
}
|
|
|
|
*lose = ISC_TRUE;
|
|
appendString(result, "???");
|
|
return result->content;
|
|
}
|
|
|
|
const char *
|
|
print_numeric_expression(struct element *expr, isc_boolean_t *lose)
|
|
{
|
|
struct string *result;
|
|
|
|
if (expr->type == ELEMENT_INTEGER) {
|
|
char buf[20];
|
|
|
|
snprintf(buf, sizeof(buf), "%lld", (long long)intValue(expr));
|
|
result = makeString(-1, buf);
|
|
return result->content;
|
|
}
|
|
|
|
/*
|
|
* From is_numeric_expression
|
|
*/
|
|
if (expr->type != ELEMENT_MAP) {
|
|
*lose = ISC_TRUE;
|
|
return "???";
|
|
}
|
|
result = allocString();
|
|
|
|
/* extract-int8 */
|
|
if (mapContains(expr, "extract-int8")) {
|
|
struct element *arg;
|
|
|
|
appendString(result, "extract-int(");
|
|
arg = mapGet(expr, "extract-int8");
|
|
if (arg == NULL) {
|
|
*lose = ISC_TRUE;
|
|
appendString(result, "???, 8)");
|
|
return result->content;
|
|
}
|
|
appendString(result, print_data_expression(arg, lose));
|
|
appendString(result, ", 8)");
|
|
return result->content;
|
|
}
|
|
|
|
/* extract-int16 */
|
|
if (mapContains(expr, "extract-int16")) {
|
|
struct element *arg;
|
|
|
|
appendString(result, "extract-int(");
|
|
arg = mapGet(expr, "extract-int16");
|
|
if (arg == NULL) {
|
|
*lose = ISC_TRUE;
|
|
appendString(result, "???, 16)");
|
|
return result->content;
|
|
}
|
|
appendString(result, print_data_expression(arg, lose));
|
|
appendString(result, ", 16)");
|
|
return result->content;
|
|
}
|
|
|
|
/* extract-int32 */
|
|
if (mapContains(expr, "extract-int32")) {
|
|
struct element *arg;
|
|
|
|
appendString(result, "extract-int(");
|
|
arg = mapGet(expr, "extract-int32");
|
|
if (arg == NULL) {
|
|
*lose = ISC_TRUE;
|
|
appendString(result, "???, 32)");
|
|
return result->content;
|
|
}
|
|
appendString(result, print_data_expression(arg, lose));
|
|
appendString(result, ", 32)");
|
|
return result->content;
|
|
}
|
|
|
|
/* const-int */
|
|
if (mapContains(expr, "const-int")) {
|
|
struct element *arg;
|
|
char buf[20];
|
|
|
|
arg = mapGet(expr, "const-int");
|
|
if ((arg == NULL) || (arg->type != ELEMENT_INTEGER)) {
|
|
*lose = ISC_TRUE;
|
|
appendString(result, "???");
|
|
return result->content;
|
|
}
|
|
snprintf(buf, sizeof(buf), "%lld", (long long)intValue(arg));
|
|
result = makeString(-1, buf);
|
|
return result->content;
|
|
}
|
|
|
|
/* lease-time */
|
|
if (mapContains(expr, "lease-time"))
|
|
return "lease-time";
|
|
|
|
/* add */
|
|
if (mapContains(expr, "add")) {
|
|
struct element *arg;
|
|
struct element *left;
|
|
struct element *right;
|
|
isc_boolean_t add_parenthesis;
|
|
|
|
appendString(result, "add ");
|
|
arg = mapGet(expr, "add");
|
|
if ((arg == NULL) || (arg->type != ELEMENT_MAP)) {
|
|
*lose = ISC_TRUE;
|
|
appendString(result, "???");
|
|
return result->content;
|
|
}
|
|
left = mapGet(arg, "left");
|
|
if (left == NULL) {
|
|
*lose = ISC_TRUE;
|
|
appendString(result, "???");
|
|
return result->content;
|
|
}
|
|
result = allocString();
|
|
add_parenthesis = ISC_TF(expr_precedence(expr_add,
|
|
left) < 0);
|
|
if (add_parenthesis)
|
|
appendString(result, "(");
|
|
appendString(result, print_expression(left, lose));
|
|
if (add_parenthesis)
|
|
appendString(result, ")");
|
|
appendString(result, " + ");
|
|
right = mapGet(arg, "right");
|
|
if (right == NULL) {
|
|
*lose = ISC_TRUE;
|
|
appendString(result, "???");
|
|
return result->content;
|
|
}
|
|
add_parenthesis = ISC_TF(expr_precedence(expr_add,
|
|
right) < 0);
|
|
if (add_parenthesis)
|
|
appendString(result, "(");
|
|
appendString(result, print_expression(right, lose));
|
|
if (add_parenthesis)
|
|
appendString(result, ")");
|
|
return result->content;
|
|
}
|
|
|
|
/* subtract */
|
|
if (mapContains(expr, "subtract")) {
|
|
struct element *arg;
|
|
struct element *left;
|
|
struct element *right;
|
|
isc_boolean_t add_parenthesis;
|
|
|
|
appendString(result, "subtract ");
|
|
arg = mapGet(expr, "subtract");
|
|
if ((arg == NULL) || (arg->type != ELEMENT_MAP)) {
|
|
*lose = ISC_TRUE;
|
|
appendString(result, "???");
|
|
return result->content;
|
|
}
|
|
left = mapGet(arg, "left");
|
|
if (left == NULL) {
|
|
*lose = ISC_TRUE;
|
|
appendString(result, "???");
|
|
return result->content;
|
|
}
|
|
result = allocString();
|
|
add_parenthesis = ISC_TF(expr_precedence(expr_subtract,
|
|
left) < 0);
|
|
if (add_parenthesis)
|
|
appendString(result, "(");
|
|
appendString(result, print_expression(left, lose));
|
|
if (add_parenthesis)
|
|
appendString(result, ")");
|
|
appendString(result, " - ");
|
|
right = mapGet(arg, "right");
|
|
if (right == NULL) {
|
|
*lose = ISC_TRUE;
|
|
appendString(result, "???");
|
|
return result->content;
|
|
}
|
|
add_parenthesis = ISC_TF(expr_precedence(expr_subtract,
|
|
right) < 0);
|
|
if (add_parenthesis)
|
|
appendString(result, "(");
|
|
appendString(result, print_expression(right, lose));
|
|
if (add_parenthesis)
|
|
appendString(result, ")");
|
|
return result->content;
|
|
}
|
|
|
|
/* multiply */
|
|
if (mapContains(expr, "multiply")) {
|
|
struct element *arg;
|
|
struct element *left;
|
|
struct element *right;
|
|
isc_boolean_t add_parenthesis;
|
|
|
|
appendString(result, "multiply ");
|
|
arg = mapGet(expr, "multiply");
|
|
if ((arg == NULL) || (arg->type != ELEMENT_MAP)) {
|
|
*lose = ISC_TRUE;
|
|
appendString(result, "???");
|
|
return result->content;
|
|
}
|
|
left = mapGet(arg, "left");
|
|
if (left == NULL) {
|
|
*lose = ISC_TRUE;
|
|
appendString(result, "???");
|
|
return result->content;
|
|
}
|
|
result = allocString();
|
|
add_parenthesis = ISC_TF(expr_precedence(expr_multiply,
|
|
left) < 0);
|
|
if (add_parenthesis)
|
|
appendString(result, "(");
|
|
appendString(result, print_expression(left, lose));
|
|
if (add_parenthesis)
|
|
appendString(result, ")");
|
|
appendString(result, " * ");
|
|
right = mapGet(arg, "right");
|
|
if (right == NULL) {
|
|
*lose = ISC_TRUE;
|
|
appendString(result, "???");
|
|
return result->content;
|
|
}
|
|
add_parenthesis = ISC_TF(expr_precedence(expr_multiply,
|
|
right) < 0);
|
|
if (add_parenthesis)
|
|
appendString(result, "(");
|
|
appendString(result, print_expression(right, lose));
|
|
if (add_parenthesis)
|
|
appendString(result, ")");
|
|
return result->content;
|
|
}
|
|
|
|
/* divide */
|
|
if (mapContains(expr, "divide")) {
|
|
struct element *arg;
|
|
struct element *left;
|
|
struct element *right;
|
|
isc_boolean_t add_parenthesis;
|
|
|
|
appendString(result, "divide ");
|
|
arg = mapGet(expr, "divide");
|
|
if ((arg == NULL) || (arg->type != ELEMENT_MAP)) {
|
|
*lose = ISC_TRUE;
|
|
appendString(result, "???");
|
|
return result->content;
|
|
}
|
|
left = mapGet(arg, "left");
|
|
if (left == NULL) {
|
|
*lose = ISC_TRUE;
|
|
appendString(result, "???");
|
|
return result->content;
|
|
}
|
|
result = allocString();
|
|
add_parenthesis = ISC_TF(expr_precedence(expr_divide,
|
|
left) < 0);
|
|
if (add_parenthesis)
|
|
appendString(result, "(");
|
|
appendString(result, print_expression(left, lose));
|
|
if (add_parenthesis)
|
|
appendString(result, ")");
|
|
appendString(result, " / ");
|
|
right = mapGet(arg, "right");
|
|
if (right == NULL) {
|
|
*lose = ISC_TRUE;
|
|
appendString(result, "???");
|
|
return result->content;
|
|
}
|
|
add_parenthesis = ISC_TF(expr_precedence(expr_divide,
|
|
right) < 0);
|
|
if (add_parenthesis)
|
|
appendString(result, "(");
|
|
appendString(result, print_expression(right, lose));
|
|
if (add_parenthesis)
|
|
appendString(result, ")");
|
|
return result->content;
|
|
}
|
|
|
|
/* remainder */
|
|
if (mapContains(expr, "remainder")) {
|
|
struct element *arg;
|
|
struct element *left;
|
|
struct element *right;
|
|
isc_boolean_t add_parenthesis;
|
|
|
|
appendString(result, "remainder ");
|
|
arg = mapGet(expr, "remainder");
|
|
if ((arg == NULL) || (arg->type != ELEMENT_MAP)) {
|
|
*lose = ISC_TRUE;
|
|
appendString(result, "???");
|
|
return result->content;
|
|
}
|
|
left = mapGet(arg, "left");
|
|
if (left == NULL) {
|
|
*lose = ISC_TRUE;
|
|
appendString(result, "???");
|
|
return result->content;
|
|
}
|
|
result = allocString();
|
|
add_parenthesis = ISC_TF(expr_precedence(expr_remainder,
|
|
left) < 0);
|
|
if (add_parenthesis)
|
|
appendString(result, "(");
|
|
appendString(result, print_expression(left, lose));
|
|
if (add_parenthesis)
|
|
appendString(result, ")");
|
|
appendString(result, " % ");
|
|
right = mapGet(arg, "right");
|
|
if (right == NULL) {
|
|
*lose = ISC_TRUE;
|
|
appendString(result, "???");
|
|
return result->content;
|
|
}
|
|
add_parenthesis = ISC_TF(expr_precedence(expr_remainder,
|
|
right) < 0);
|
|
if (add_parenthesis)
|
|
appendString(result, "(");
|
|
appendString(result, print_expression(right, lose));
|
|
if (add_parenthesis)
|
|
appendString(result, ")");
|
|
return result->content;
|
|
}
|
|
|
|
/* binary-and */
|
|
if (mapContains(expr, "binary-and")) {
|
|
struct element *arg;
|
|
struct element *left;
|
|
struct element *right;
|
|
isc_boolean_t add_parenthesis;
|
|
|
|
appendString(result, "binary-and ");
|
|
arg = mapGet(expr, "binary-and");
|
|
if ((arg == NULL) || (arg->type != ELEMENT_MAP)) {
|
|
*lose = ISC_TRUE;
|
|
appendString(result, "???");
|
|
return result->content;
|
|
}
|
|
left = mapGet(arg, "left");
|
|
if (left == NULL) {
|
|
*lose = ISC_TRUE;
|
|
appendString(result, "???");
|
|
return result->content;
|
|
}
|
|
result = allocString();
|
|
add_parenthesis = ISC_TF(expr_precedence(expr_binary_and,
|
|
left) < 0);
|
|
if (add_parenthesis)
|
|
appendString(result, "(");
|
|
appendString(result, print_expression(left, lose));
|
|
if (add_parenthesis)
|
|
appendString(result, ")");
|
|
appendString(result, " & ");
|
|
right = mapGet(arg, "right");
|
|
if (right == NULL) {
|
|
*lose = ISC_TRUE;
|
|
appendString(result, "???");
|
|
return result->content;
|
|
}
|
|
add_parenthesis = ISC_TF(expr_precedence(expr_binary_and,
|
|
right) < 0);
|
|
if (add_parenthesis)
|
|
appendString(result, "(");
|
|
appendString(result, print_expression(right, lose));
|
|
if (add_parenthesis)
|
|
appendString(result, ")");
|
|
return result->content;
|
|
}
|
|
|
|
/* binary-or */
|
|
if (mapContains(expr, "binary-or")) {
|
|
struct element *arg;
|
|
struct element *left;
|
|
struct element *right;
|
|
isc_boolean_t add_parenthesis;
|
|
|
|
appendString(result, "binary-or ");
|
|
arg = mapGet(expr, "binary-or");
|
|
if ((arg == NULL) || (arg->type != ELEMENT_MAP)) {
|
|
*lose = ISC_TRUE;
|
|
appendString(result, "???");
|
|
return result->content;
|
|
}
|
|
left = mapGet(arg, "left");
|
|
if (left == NULL) {
|
|
*lose = ISC_TRUE;
|
|
appendString(result, "???");
|
|
return result->content;
|
|
}
|
|
result = allocString();
|
|
add_parenthesis = ISC_TF(expr_precedence(expr_binary_or,
|
|
left) < 0);
|
|
if (add_parenthesis)
|
|
appendString(result, "(");
|
|
appendString(result, print_expression(left, lose));
|
|
if (add_parenthesis)
|
|
appendString(result, ")");
|
|
appendString(result, " | ");
|
|
right = mapGet(arg, "right");
|
|
if (right == NULL) {
|
|
*lose = ISC_TRUE;
|
|
appendString(result, "???");
|
|
return result->content;
|
|
}
|
|
add_parenthesis = ISC_TF(expr_precedence(expr_binary_or,
|
|
right) < 0);
|
|
if (add_parenthesis)
|
|
appendString(result, "(");
|
|
appendString(result, print_expression(right, lose));
|
|
if (add_parenthesis)
|
|
appendString(result, ")");
|
|
return result->content;
|
|
}
|
|
|
|
/* binary-xor */
|
|
if (mapContains(expr, "binary-xor")) {
|
|
struct element *arg;
|
|
struct element *left;
|
|
struct element *right;
|
|
isc_boolean_t add_parenthesis;
|
|
|
|
appendString(result, "binary-xor ");
|
|
arg = mapGet(expr, "binary-xor");
|
|
if ((arg == NULL) || (arg->type != ELEMENT_MAP)) {
|
|
*lose = ISC_TRUE;
|
|
appendString(result, "???");
|
|
return result->content;
|
|
}
|
|
left = mapGet(arg, "left");
|
|
if (left == NULL) {
|
|
*lose = ISC_TRUE;
|
|
appendString(result, "???");
|
|
return result->content;
|
|
}
|
|
result = allocString();
|
|
add_parenthesis = ISC_TF(expr_precedence(expr_binary_xor,
|
|
left) < 0);
|
|
if (add_parenthesis)
|
|
appendString(result, "(");
|
|
appendString(result, print_expression(left, lose));
|
|
if (add_parenthesis)
|
|
appendString(result, ")");
|
|
appendString(result, " ^ ");
|
|
right = mapGet(arg, "right");
|
|
if (right == NULL) {
|
|
*lose = ISC_TRUE;
|
|
appendString(result, "???");
|
|
return result->content;
|
|
}
|
|
add_parenthesis = ISC_TF(expr_precedence(expr_binary_xor,
|
|
right) < 0);
|
|
if (add_parenthesis)
|
|
appendString(result, "(");
|
|
appendString(result, print_expression(right, lose));
|
|
if (add_parenthesis)
|
|
appendString(result, ")");
|
|
return result->content;
|
|
}
|
|
|
|
/* client-state */
|
|
if (mapContains(expr, "client-state"))
|
|
return "client-state";
|
|
|
|
*lose = ISC_TRUE;
|
|
appendString(result, "???");
|
|
return result->content;
|
|
}
|
|
|
|
static void
|
|
debug(const char* fmt, ...)
|
|
{
|
|
va_list list;
|
|
|
|
va_start(list, fmt);
|
|
vfprintf(stderr, fmt, list);
|
|
fprintf(stderr, "\n");
|
|
va_end(list);
|
|
}
|