]> git.ipfire.org Git - thirdparty/dhcp.git/blob - keama/print.c
[#64,!35] Restored work
[thirdparty/dhcp.git] / keama / print.c
1 /*
2 * Copyright (c) 2017 by Internet Systems Consortium, Inc. ("ISC")
3 *
4 * Permission to use, copy, modify, and distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
14 * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 *
16 * Internet Systems Consortium, Inc.
17 * 950 Charter Street
18 * Redwood City, CA 94063
19 * <info@isc.org>
20 * https://www.isc.org/
21 *
22 */
23
24 #include "keama.h"
25
26 #include <sys/errno.h>
27 #include <sys/types.h>
28 #include <arpa/inet.h>
29 #include <ctype.h>
30 #include <netdb.h>
31 #include <stdarg.h>
32 #include <stdio.h>
33 #include <string.h>
34 #include <unistd.h>
35
36 static void debug(const char* fmt, ...);
37
38 const char *
39 print_expression(struct element *expr, isc_boolean_t *lose)
40 {
41 if (expr->type == ELEMENT_BOOLEAN)
42 return print_boolean_expression(expr, lose);
43 if (expr->type == ELEMENT_INTEGER)
44 return print_numeric_expression(expr, lose);
45 if (expr->type == ELEMENT_STRING)
46 return print_data_expression(expr, lose);
47
48 if (is_boolean_expression(expr))
49 return print_boolean_expression(expr, lose);
50 if (is_numeric_expression(expr))
51 return print_numeric_expression(expr, lose);
52 if (is_data_expression(expr))
53 return print_data_expression(expr, lose);
54 *lose = ISC_TRUE;
55 return "???";
56 }
57
58 const char *
59 print_boolean_expression(struct element *expr, isc_boolean_t *lose)
60 {
61 struct string *result;
62
63 if (expr->type == ELEMENT_BOOLEAN) {
64 if (boolValue(expr))
65 return "true";
66 else
67 return "false";
68 }
69
70 /*
71 * From is_boolean_expression
72 */
73 if (expr->type != ELEMENT_MAP) {
74 *lose = ISC_TRUE;
75 return "???";
76 }
77 result = allocString();
78
79 /* check */
80 if (mapContains(expr, "check")) {
81 struct element *name;
82
83 appendString(result, "check ");
84 name = mapGet(expr, "check");
85 if ((name == NULL) || (name->type != ELEMENT_STRING)) {
86 *lose = ISC_TRUE;
87 appendString(result, "???");
88 } else
89 concatString(result, stringValue(name));
90 return result->content;
91 }
92
93 /* exists */
94 if (mapContains(expr, "exists")) {
95 struct element *arg;
96 struct element *universe;
97 struct element *name;
98
99 appendString(result, "exists ");
100 arg = mapGet(expr, "exists");
101 if ((arg == NULL) || (arg->type != ELEMENT_MAP)) {
102 *lose = ISC_TRUE;
103 appendString(result, "???");
104 return result->content;
105 }
106 universe = mapGet(arg, "universe");
107 if ((universe == NULL) || (universe->type != ELEMENT_STRING)) {
108 *lose = ISC_TRUE;
109 appendString(result, "???");
110 return result->content;
111 }
112 concatString(result, stringValue(universe));
113 appendString(result, ".");
114 name = mapGet(arg, "name");
115 if ((name == NULL) || (name->type != ELEMENT_STRING)) {
116 *lose = ISC_TRUE;
117 appendString(result, "???");
118 return result->content;
119 }
120 concatString(result, stringValue(name));
121 return result->content;
122 }
123
124 /* variable-exists */
125 if (mapContains(expr, "variable-exists")) {
126 struct element *name;
127
128 appendString(result, "variable-exists ");
129 name = mapGet(expr, "variable-exists");
130 if ((name == NULL) || (name->type != ELEMENT_STRING)) {
131 *lose = ISC_TRUE;
132 appendString(result, "???");
133 } else
134 concatString(result, stringValue(name));
135 return result->content;
136 }
137
138 /* equal */
139 if (mapContains(expr, "equal")) {
140 struct element *arg;
141 struct element *left;
142 struct element *right;
143 isc_boolean_t add_parenthesis;
144
145 appendString(result, "equal ");
146 arg = mapGet(expr, "equal");
147 if ((arg == NULL) || (arg->type != ELEMENT_MAP)) {
148 *lose = ISC_TRUE;
149 appendString(result, "???");
150 return result->content;
151 }
152 left = mapGet(arg, "left");
153 if (left == NULL) {
154 *lose = ISC_TRUE;
155 appendString(result, "???");
156 return result->content;
157 }
158 result = allocString();
159 add_parenthesis = ISC_TF(expr_precedence(expr_equal,
160 left) < 0);
161 if (add_parenthesis)
162 appendString(result, "(");
163 appendString(result, print_expression(left, lose));
164 if (add_parenthesis)
165 appendString(result, ")");
166 appendString(result, " = ");
167 right = mapGet(arg, "right");
168 if (right == NULL) {
169 *lose = ISC_TRUE;
170 appendString(result, "???");
171 return result->content;
172 }
173 add_parenthesis = ISC_TF(expr_precedence(expr_equal,
174 right) < 0);
175 if (add_parenthesis)
176 appendString(result, "(");
177 appendString(result, print_expression(right, lose));
178 if (add_parenthesis)
179 appendString(result, ")");
180 return result->content;
181 }
182
183 /* not-equal */
184 if (mapContains(expr, "not-equal")) {
185 struct element *arg;
186 struct element *left;
187 struct element *right;
188 isc_boolean_t add_parenthesis;
189
190 appendString(result, "not-equal ");
191 arg = mapGet(expr, "not-equal");
192 if ((arg == NULL) || (arg->type != ELEMENT_MAP)) {
193 *lose = ISC_TRUE;
194 appendString(result, "???");
195 return result->content;
196 }
197 left = mapGet(arg, "left");
198 if (left == NULL) {
199 *lose = ISC_TRUE;
200 appendString(result, "???");
201 return result->content;
202 }
203 result = allocString();
204 add_parenthesis = ISC_TF(expr_precedence(expr_not_equal,
205 left) < 0);
206 if (add_parenthesis)
207 appendString(result, "(");
208 appendString(result, print_expression(left, lose));
209 if (add_parenthesis)
210 appendString(result, ")");
211 appendString(result, " != ");
212 right = mapGet(arg, "right");
213 if (right == NULL) {
214 *lose = ISC_TRUE;
215 appendString(result, "???");
216 return result->content;
217 }
218 add_parenthesis = ISC_TF(expr_precedence(expr_not_equal,
219 right) < 0);
220 if (add_parenthesis)
221 appendString(result, "(");
222 appendString(result, print_expression(right, lose));
223 if (add_parenthesis)
224 appendString(result, ")");
225 return result->content;
226 }
227
228 /* regex-match */
229 if (mapContains(expr, "regex-match")) {
230 struct element *arg;
231 struct element *left;
232 struct element *right;
233 isc_boolean_t add_parenthesis;
234
235 appendString(result, "regex-match ");
236 arg = mapGet(expr, "regex-match");
237 if ((arg == NULL) || (arg->type != ELEMENT_MAP)) {
238 *lose = ISC_TRUE;
239 appendString(result, "???");
240 return result->content;
241 }
242 left = mapGet(arg, "left");
243 if (left == NULL) {
244 *lose = ISC_TRUE;
245 appendString(result, "???");
246 return result->content;
247 }
248 result = allocString();
249 add_parenthesis = ISC_TF(expr_precedence(expr_regex_match,
250 left) < 0);
251 if (add_parenthesis)
252 appendString(result, "(");
253 appendString(result, print_expression(left, lose));
254 if (add_parenthesis)
255 appendString(result, ")");
256 appendString(result, " ~= ");
257 right = mapGet(arg, "right");
258 if (right == NULL) {
259 *lose = ISC_TRUE;
260 appendString(result, "???");
261 return result->content;
262 }
263 appendString(result, print_expression(right, lose));
264 return result->content;
265 }
266
267 /* iregex-match */
268 if (mapContains(expr, "iregex-match")) {
269 struct element *arg;
270 struct element *left;
271 struct element *right;
272 isc_boolean_t add_parenthesis;
273
274 appendString(result, "iregex-match ");
275 arg = mapGet(expr, "iregex-match");
276 if ((arg == NULL) || (arg->type != ELEMENT_MAP)) {
277 *lose = ISC_TRUE;
278 appendString(result, "???");
279 return result->content;
280 }
281 left = mapGet(arg, "left");
282 if (left == NULL) {
283 *lose = ISC_TRUE;
284 appendString(result, "???");
285 return result->content;
286 }
287 result = allocString();
288 add_parenthesis = ISC_TF(expr_precedence(expr_iregex_match,
289 left) < 0);
290 if (add_parenthesis)
291 appendString(result, "(");
292 appendString(result, print_expression(left, lose));
293 if (add_parenthesis)
294 appendString(result, ")");
295 appendString(result, " ~~ ");
296 right = mapGet(arg, "right");
297 if (right == NULL) {
298 *lose = ISC_TRUE;
299 appendString(result, "???");
300 return result->content;
301 }
302 appendString(result, print_expression(right, lose));
303 return result->content;
304 }
305
306 /* and */
307 if (mapContains(expr, "and")) {
308 struct element *arg;
309 struct element *left;
310 struct element *right;
311 isc_boolean_t add_parenthesis;
312
313 appendString(result, "and ");
314 arg = mapGet(expr, "and");
315 if ((arg == NULL) || (arg->type != ELEMENT_MAP)) {
316 *lose = ISC_TRUE;
317 appendString(result, "???");
318 return result->content;
319 }
320 left = mapGet(arg, "left");
321 if (left == NULL) {
322 *lose = ISC_TRUE;
323 appendString(result, "???");
324 return result->content;
325 }
326 result = allocString();
327 add_parenthesis = ISC_TF(expr_precedence(expr_and,
328 left) < 0);
329 if (add_parenthesis)
330 appendString(result, "(");
331 appendString(result, print_expression(left, lose));
332 if (add_parenthesis)
333 appendString(result, ")");
334 appendString(result, " and ");
335 right = mapGet(arg, "right");
336 if (right == NULL) {
337 *lose = ISC_TRUE;
338 appendString(result, "???");
339 return result->content;
340 }
341 add_parenthesis = ISC_TF(expr_precedence(expr_and,
342 right) < 0);
343 if (add_parenthesis)
344 appendString(result, "(");
345 appendString(result, print_expression(right, lose));
346 if (add_parenthesis)
347 appendString(result, ")");
348 return result->content;
349 }
350
351 /* or */
352 if (mapContains(expr, "or")) {
353 struct element *arg;
354 struct element *left;
355 struct element *right;
356 isc_boolean_t add_parenthesis;
357
358 appendString(result, "or ");
359 arg = mapGet(expr, "or");
360 if ((arg == NULL) || (arg->type != ELEMENT_MAP)) {
361 *lose = ISC_TRUE;
362 appendString(result, "???");
363 return result->content;
364 }
365 left = mapGet(arg, "left");
366 if (left == NULL) {
367 *lose = ISC_TRUE;
368 appendString(result, "???");
369 return result->content;
370 }
371 result = allocString();
372 add_parenthesis = ISC_TF(expr_precedence(expr_or,
373 left) < 0);
374 if (add_parenthesis)
375 appendString(result, "(");
376 appendString(result, print_expression(left, lose));
377 if (add_parenthesis)
378 appendString(result, ")");
379 appendString(result, " or ");
380 right = mapGet(arg, "right");
381 if (right == NULL) {
382 *lose = ISC_TRUE;
383 appendString(result, "???");
384 return result->content;
385 }
386 add_parenthesis = ISC_TF(expr_precedence(expr_or,
387 right) < 0);
388 if (add_parenthesis)
389 appendString(result, "(");
390 appendString(result, print_expression(right, lose));
391 if (add_parenthesis)
392 appendString(result, ")");
393 return result->content;
394 }
395
396 /* not */
397 if (mapContains(expr, "not")) {
398 struct element *arg;
399 isc_boolean_t add_parenthesis;
400
401 appendString(result, "not ");
402 arg = mapGet(expr, "not");
403 if (arg == NULL) {
404 *lose = ISC_TRUE;
405 appendString(result, "???");
406 return result->content;
407 }
408 add_parenthesis = ISC_TF(expr_precedence(expr_not,
409 arg) < 0);
410 if (add_parenthesis)
411 appendString(result, "(");
412 appendString(result, print_expression(arg, lose));
413 if (add_parenthesis)
414 appendString(result, ")");
415 return result->content;
416 }
417
418 /* known */
419 if (mapContains(expr, "known")) {
420 return "known";
421 }
422
423 /* static */
424 if (mapContains(expr, "static")) {
425 return "static";
426 }
427
428 /* variable-reference */
429 if (mapContains(expr, "variable-reference")) {
430 struct element *name;
431
432 appendString(result, "variable-reference ");
433 name = mapGet(expr, "variable-reference");
434 if ((name == NULL) || (name->type != ELEMENT_STRING)) {
435 *lose = ISC_TRUE;
436 appendString(result, "???");
437 return result->content;
438 }
439 return stringValue(name)->content;
440 }
441
442 /* funcall */
443 if (mapContains(expr, "funcall")) {
444 struct element *arg;
445 struct element *name;
446 struct element *args;
447 size_t i;
448
449 appendString(result, "funcall ");
450 arg = mapGet(expr, "funcall");
451 if ((arg == NULL) || (arg->type != ELEMENT_MAP)) {
452 *lose = ISC_TRUE;
453 appendString(result, "???");
454 return result->content;
455 }
456 name = mapGet(arg, "name");
457 if ((name == NULL) || (name->type != ELEMENT_STRING)) {
458 *lose = ISC_TRUE;
459 appendString(result, "???");
460 return result->content;
461 }
462 result = allocString();
463 concatString(result, stringValue(name));
464 appendString(result, "(");
465 args = mapGet(arg, "arguments");
466 if ((args == NULL) || (args->type != ELEMENT_LIST)) {
467 *lose = ISC_TRUE;
468 appendString(result, "???" ")");
469 return result->content;
470 }
471 for (i = 0; i < listSize(args); i++) {
472 struct element *item;
473
474 if (i != 0)
475 appendString(result, ", ");
476 item = listGet(args, i);
477 if (item == NULL) {
478 debug("funcall null argument %u",
479 (unsigned)i);
480 *lose = ISC_TRUE;
481 appendString(result, "???");
482 continue;
483 }
484 appendString(result, print_expression(item, lose));
485 }
486 appendString(result, ")");
487 return result->content;
488 }
489
490 *lose = ISC_TRUE;
491 appendString(result, "???");
492 return result->content;
493 }
494
495 const char *
496 print_data_expression(struct element *expr, isc_boolean_t *lose)
497 {
498 struct string *result;
499
500 if (expr->type == ELEMENT_STRING)
501 return quote(stringValue(expr))->content;
502
503 /*
504 * From is_data_expression
505 */
506 if (expr->type != ELEMENT_MAP) {
507 *lose = ISC_TRUE;
508 return "???";
509 }
510 result = allocString();
511
512 /* substring */
513 if (mapContains(expr, "substring")) {
514 struct element *arg;
515 struct element *string;
516 struct element *offset;
517 struct element *length;
518
519 appendString(result, "substring(");
520 arg = mapGet(expr, "substring");
521 if ((arg == NULL) || (arg->type != ELEMENT_MAP)) {
522 *lose = ISC_TRUE;
523 appendString(result, "???" ")");
524 return result->content;
525 }
526 string = mapGet(arg, "expression");
527 if (string == NULL) {
528 *lose = ISC_TRUE;
529 appendString(result, "???" ")");
530 return result->content;
531 }
532 appendString(result, print_data_expression(string, lose));
533 appendString(result, ", ");
534 offset = mapGet(arg, "offset");
535 if (offset == NULL) {
536 *lose = ISC_TRUE;
537 appendString(result, "???" ")");
538 return result->content;
539 }
540 appendString(result, print_numeric_expression(offset, lose));
541 appendString(result, ", ");
542 length = mapGet(arg, "length");
543 if (length == NULL) {
544 *lose = ISC_TRUE;
545 appendString(result, "???" ")");
546 return result->content;
547 }
548 appendString(result, print_numeric_expression(length, lose));
549 appendString(result, ")");
550 return result->content;
551 }
552
553 /* suffix */
554 if (mapContains(expr, "suffix")) {
555 struct element *arg;
556 struct element *string;
557 struct element *length;
558
559 appendString(result, "suffix(");
560 arg = mapGet(expr, "suffix");
561 if ((arg == NULL) || (arg->type != ELEMENT_MAP)) {
562 *lose = ISC_TRUE;
563 appendString(result, "???" ")");
564 return result->content;
565 }
566 string = mapGet(arg, "expression");
567 if (string == NULL) {
568 *lose = ISC_TRUE;
569 appendString(result, "???" ")");
570 return result->content;
571 }
572 appendString(result, print_data_expression(string, lose));
573 appendString(result, ", ");
574 length = mapGet(arg, "length");
575 if (length == NULL) {
576 *lose = ISC_TRUE;
577 appendString(result, "???" ")");
578 return result->content;
579 }
580 appendString(result, print_numeric_expression(length, lose));
581 appendString(result, ")");
582 return result->content;
583 }
584
585 /* lowercase */
586 if (mapContains(expr, "lowercase")) {
587 struct element *arg;
588
589 appendString(result, "lowercase(");
590 arg = mapGet(expr, "lowercase");
591 if (arg == NULL) {
592 *lose = ISC_TRUE;
593 appendString(result, "???" ")");
594 return result->content;
595 }
596 appendString(result, print_data_expression(arg, lose));
597 appendString(result, ")");
598 return result->content;
599 }
600
601 /* uppercase */
602 if (mapContains(expr, "uppercase")) {
603 struct element *arg;
604
605 appendString(result, "uppercase(");
606 arg = mapGet(expr, "uppercase");
607 if (arg == NULL) {
608 *lose = ISC_TRUE;
609 appendString(result, "???" ")");
610 return result->content;
611 }
612 appendString(result, print_data_expression(arg, lose));
613 appendString(result, ")");
614 return result->content;
615 }
616
617 /* option */
618 if (mapContains(expr, "option")) {
619 struct element *arg;
620 struct element *universe;
621 struct element *name;
622
623 appendString(result, "option ");
624 arg = mapGet(expr, "option");
625 if ((arg == NULL) || (arg->type != ELEMENT_MAP)) {
626 *lose = ISC_TRUE;
627 appendString(result, "???");
628 return result->content;
629 }
630 universe = mapGet(arg, "universe");
631 if ((universe == NULL) || (universe->type != ELEMENT_STRING)) {
632 *lose = ISC_TRUE;
633 appendString(result, "???");
634 return result->content;
635 }
636 concatString(result, stringValue(universe));
637 appendString(result, ".");
638 name = mapGet(arg, "name");
639 if ((name == NULL) || (name->type != ELEMENT_STRING)) {
640 *lose = ISC_TRUE;
641 appendString(result, "???");
642 return result->content;
643 }
644 concatString(result, stringValue(name));
645 return result->content;
646 }
647
648 /* hardware */
649 if (mapContains(expr, "hardware"))
650 return "hardware";
651
652 /* hw-type */
653 if (mapContains(expr, "hw-type"))
654 return "hw-type";
655
656 /* hw-address */
657 if (mapContains(expr, "hw-address"))
658 return "hw-address";
659
660 /* const-data */
661 if (mapContains(expr, "const-data")) {
662 struct element *arg;
663
664 arg = mapGet(expr, "const-data");
665 if ((arg == NULL) || (arg->type != ELEMENT_STRING)) {
666 *lose = ISC_TRUE;
667 appendString(result, "???");
668 return result->content;
669 }
670 concatString(result, stringValue(arg));
671 return result->content;
672 }
673
674 /* packet */
675 if (mapContains(expr, "packet")) {
676 struct element *arg;
677 struct element *offset;
678 struct element *length;
679
680 appendString(result, "packet(");
681 arg = mapGet(expr, "packet");
682 if ((arg == NULL) || (arg->type != ELEMENT_MAP)) {
683 *lose = ISC_TRUE;
684 appendString(result, "???" ")");
685 return result->content;
686 }
687 offset = mapGet(arg, "offset");
688 if (offset == NULL) {
689 *lose = ISC_TRUE;
690 appendString(result, "???" ")");
691 return result->content;
692 }
693 appendString(result, print_numeric_expression(offset, lose));
694 appendString(result, ", ");
695 length = mapGet(arg, "length");
696 if (length == NULL) {
697 *lose = ISC_TRUE;
698 appendString(result, "???" ")");
699 return result->content;
700 }
701 appendString(result, print_numeric_expression(length, lose));
702 appendString(result, ")");
703 return result->content;
704 }
705
706 /* concat */
707 if (mapContains(expr, "concat")) {
708 struct element *arg;
709 struct element *left;
710 struct element *right;
711
712 appendString(result, "concat(");
713 arg = mapGet(expr, "concat");
714 if ((arg == NULL) || (arg->type != ELEMENT_MAP)) {
715 *lose = ISC_TRUE;
716 appendString(result, "???" ")");
717 return result->content;
718 }
719 left = mapGet(arg, "left");
720 if (left == NULL) {
721 *lose = ISC_TRUE;
722 appendString(result, "???" ")");
723 return result->content;
724 }
725 appendString(result, print_data_expression(left, lose));
726 appendString(result, ", ");
727 right = mapGet(arg, "right");
728 if (right == NULL) {
729 *lose = ISC_TRUE;
730 appendString(result, "???" ")");
731 return result->content;
732 }
733 appendString(result, print_data_expression(right, lose));
734 appendString(result, ")");
735 return result->content;
736 }
737
738 /* encapsulate */
739 if (mapContains(expr, "encapsulate")) {
740 struct element *arg;
741
742 appendString(result, "encapsulate ");
743 arg = mapGet(expr, "encapsulate");
744 if (arg == NULL) {
745 *lose = ISC_TRUE;
746 appendString(result, "???");
747 return result->content;
748 }
749 appendString(result, print_data_expression(arg, lose));
750 return result->content;
751 }
752
753 /* encode-int8 */
754 if (mapContains(expr, "encode-int8")) {
755 struct element *arg;
756
757 appendString(result, "encode-int(");
758 arg = mapGet(expr, "encode-int8");
759 if (arg == NULL) {
760 *lose = ISC_TRUE;
761 appendString(result, "???, 8)");
762 return result->content;
763 }
764 appendString(result, print_numeric_expression(arg, lose));
765 appendString(result, ", 8)");
766 return result->content;
767 }
768
769 /* encode-int16 */
770 if (mapContains(expr, "encode-int16")) {
771 struct element *arg;
772
773 appendString(result, "encode-int(");
774 arg = mapGet(expr, "encode-int16");
775 if (arg == NULL) {
776 *lose = ISC_TRUE;
777 appendString(result, "???, 16)");
778 return result->content;
779 }
780 appendString(result, print_numeric_expression(arg, lose));
781 appendString(result, ", 16)");
782 return result->content;
783 }
784
785 /* encode-int32 */
786 if (mapContains(expr, "encode-int32")) {
787 struct element *arg;
788
789 appendString(result, "encode-int(");
790 arg = mapGet(expr, "encode-int32");
791 if (arg == NULL) {
792 *lose = ISC_TRUE;
793 appendString(result, "???, 32)");
794 return result->content;
795 }
796 appendString(result, print_numeric_expression(arg, lose));
797 appendString(result, ", 32)");
798 return result->content;
799 }
800
801 /* gethostbyname */
802 if (mapContains(expr, "gethostbyname")) {
803 struct element *arg;
804
805 appendString(result, "gethostbyname(");
806 arg = mapGet(expr, "gethostbyname");
807 if (arg == NULL) {
808 *lose = ISC_TRUE;
809 appendString(result, "???");
810 return result->content;
811 }
812 appendString(result, print_data_expression(arg, lose));
813 appendString(result, ")");
814 return result->content;
815 }
816
817 /* binary-to-ascii */
818 if (mapContains(expr, "binary-to-ascii")) {
819 struct element *arg;
820 struct element *base;
821 struct element *width;
822 struct element *separator;
823 struct element *buffer;
824
825 appendString(result, "binary-to-ascii(");
826 arg = mapGet(expr, "binary-to-ascii");
827 if ((arg == NULL) || (arg->type != ELEMENT_MAP)) {
828 *lose = ISC_TRUE;
829 appendString(result, "???" ")");
830 return result->content;
831 }
832 base = mapGet(arg, "base");
833 if (base == NULL) {
834 *lose = ISC_TRUE;
835 appendString(result, "???" ")");
836 return result->content;
837 }
838 appendString(result, print_numeric_expression(base, lose));
839 appendString(result, ", ");
840 width = mapGet(arg, "width");
841 if (width == NULL) {
842 *lose = ISC_TRUE;
843 appendString(result, "???" ")");
844 return result->content;
845 }
846 appendString(result, print_numeric_expression(width, lose));
847 appendString(result, ", ");
848 separator = mapGet(arg, "separator");
849 if (separator == NULL) {
850 *lose = ISC_TRUE;
851 appendString(result, "???" ")");
852 return result->content;
853 }
854 appendString(result, print_data_expression(separator, lose));
855 appendString(result, ", ");
856 buffer = mapGet(arg, "buffer");
857 if (buffer == NULL) {
858 *lose = ISC_TRUE;
859 appendString(result, "???" ")");
860 return result->content;
861 }
862 appendString(result, print_data_expression(buffer, lose));
863 appendString(result, ")");
864 return result->content;
865 }
866
867 /* filename */
868 if (mapContains(expr, "filename"))
869 return "filename";
870
871 /* server-name */
872 if (mapContains(expr, "server-name"))
873 return "server-name";
874
875 /* reverse */
876 if (mapContains(expr, "reverse")) {
877 struct element *arg;
878 struct element *width;
879 struct element *buffer;
880
881 appendString(result, "reverse(");
882 arg = mapGet(expr, "reverse");
883 if ((arg == NULL) || (arg->type != ELEMENT_MAP)) {
884 *lose = ISC_TRUE;
885 appendString(result, "???" ")");
886 return result->content;
887 }
888 width = mapGet(arg, "width");
889 if (width == NULL) {
890 *lose = ISC_TRUE;
891 appendString(result, "???" ")");
892 return result->content;
893 }
894 appendString(result, print_numeric_expression(width, lose));
895 appendString(result, ", ");
896 buffer = mapGet(arg, "buffer");
897 if (buffer == NULL) {
898 *lose = ISC_TRUE;
899 appendString(result, "???" ")");
900 return result->content;
901 }
902 appendString(result, print_data_expression(buffer, lose));
903 appendString(result, ")");
904 return result->content;
905 }
906
907 /* pick-first-value */
908 if (mapContains(expr, "pick-first-value")) {
909 struct element *arg;
910 size_t i;
911
912 appendString(result, "pick-first-value(");
913 arg = mapGet(expr, "pick-first-value");
914 if ((arg == NULL) || (arg->type != ELEMENT_LIST)) {
915 *lose = ISC_TRUE;
916 appendString(result, "???" ")");
917 return result->content;
918 }
919 for (i = 0; i < listSize(arg); i++) {
920 struct element *item;
921
922 if (i != 0)
923 appendString(result, ", ");
924 item = listGet(arg, i);
925 if (item == NULL) {
926 *lose = ISC_TRUE;
927 appendString(result, "???");
928 continue;
929 }
930 appendString(result,
931 print_data_expression(item, lose));
932 }
933 appendString(result, ")");
934 return result->content;
935 }
936
937 /* host-decl-name */
938 if (mapContains(expr, "host-decl-name"))
939 return "host-decl-name";
940
941 /* leased-address */
942 if (mapContains(expr, "leased-address"))
943 return "leased-address";
944
945 /* config-option */
946 if (mapContains(expr, "config-option")) {
947 struct element *arg;
948 struct element *universe;
949 struct element *name;
950
951 appendString(result, "config-option ");
952 arg = mapGet(expr, "config-option");
953 if ((arg == NULL) || (arg->type != ELEMENT_MAP)) {
954 *lose = ISC_TRUE;
955 appendString(result, "???");
956 return result->content;
957 }
958 universe = mapGet(arg, "universe");
959 if ((universe == NULL) || (universe->type != ELEMENT_STRING)) {
960 *lose = ISC_TRUE;
961 appendString(result, "???");
962 return result->content;
963 }
964 concatString(result, stringValue(universe));
965 appendString(result, ".");
966 name = mapGet(arg, "name");
967 if ((name == NULL) || (name->type != ELEMENT_STRING)) {
968 *lose = ISC_TRUE;
969 appendString(result, "???");
970 return result->content;
971 }
972 concatString(result, stringValue(name));
973 return result->content;
974 }
975
976 /* null */
977 if (mapContains(expr, "null"))
978 return "null";
979
980 /* gethostname */
981 if (mapContains(expr, "gethostname"))
982 return "gethostname";
983
984 /* v6relay */
985 if (mapContains(expr, "v6relay")) {
986 struct element *arg;
987 struct element *relay;
988 struct element *option;
989
990
991 appendString(result, "v6relay(");
992 arg = mapGet(expr, "v6relay");
993 if ((arg == NULL) || (arg->type != ELEMENT_MAP)) {
994 *lose = ISC_TRUE;
995 appendString(result, "???" ")");
996 return result->content;
997 }
998 relay = mapGet(arg, "relay");
999 if (relay == NULL) {
1000 *lose = ISC_TRUE;
1001 appendString(result, "???" ")");
1002 return result->content;
1003 }
1004 appendString(result, print_numeric_expression(relay, lose));
1005 appendString(result, ", ");
1006 option = mapGet(arg, "relay-option");
1007 if (option == NULL) {
1008 *lose = ISC_TRUE;
1009 appendString(result, "???" ")");
1010 return result->content;
1011 }
1012 appendString(result, print_data_expression(option, lose));
1013 appendString(result, ")");
1014 return result->content;
1015 }
1016
1017 *lose = ISC_TRUE;
1018 appendString(result, "???");
1019 return result->content;
1020 }
1021
1022 const char *
1023 print_numeric_expression(struct element *expr, isc_boolean_t *lose)
1024 {
1025 struct string *result;
1026
1027 if (expr->type == ELEMENT_INTEGER) {
1028 char buf[20];
1029
1030 snprintf(buf, sizeof(buf), "%lld", (long long)intValue(expr));
1031 result = makeString(-1, buf);
1032 return result->content;
1033 }
1034
1035 /*
1036 * From is_numeric_expression
1037 */
1038 if (expr->type != ELEMENT_MAP) {
1039 *lose = ISC_TRUE;
1040 return "???";
1041 }
1042 result = allocString();
1043
1044 /* extract-int8 */
1045 if (mapContains(expr, "extract-int8")) {
1046 struct element *arg;
1047
1048 appendString(result, "extract-int(");
1049 arg = mapGet(expr, "extract-int8");
1050 if (arg == NULL) {
1051 *lose = ISC_TRUE;
1052 appendString(result, "???, 8)");
1053 return result->content;
1054 }
1055 appendString(result, print_data_expression(arg, lose));
1056 appendString(result, ", 8)");
1057 return result->content;
1058 }
1059
1060 /* extract-int16 */
1061 if (mapContains(expr, "extract-int16")) {
1062 struct element *arg;
1063
1064 appendString(result, "extract-int(");
1065 arg = mapGet(expr, "extract-int16");
1066 if (arg == NULL) {
1067 *lose = ISC_TRUE;
1068 appendString(result, "???, 16)");
1069 return result->content;
1070 }
1071 appendString(result, print_data_expression(arg, lose));
1072 appendString(result, ", 16)");
1073 return result->content;
1074 }
1075
1076 /* extract-int32 */
1077 if (mapContains(expr, "extract-int32")) {
1078 struct element *arg;
1079
1080 appendString(result, "extract-int(");
1081 arg = mapGet(expr, "extract-int32");
1082 if (arg == NULL) {
1083 *lose = ISC_TRUE;
1084 appendString(result, "???, 32)");
1085 return result->content;
1086 }
1087 appendString(result, print_data_expression(arg, lose));
1088 appendString(result, ", 32)");
1089 return result->content;
1090 }
1091
1092 /* const-int */
1093 if (mapContains(expr, "const-int")) {
1094 struct element *arg;
1095 char buf[20];
1096
1097 arg = mapGet(expr, "const-int");
1098 if ((arg == NULL) || (arg->type != ELEMENT_INTEGER)) {
1099 *lose = ISC_TRUE;
1100 appendString(result, "???");
1101 return result->content;
1102 }
1103 snprintf(buf, sizeof(buf), "%lld", (long long)intValue(arg));
1104 result = makeString(-1, buf);
1105 return result->content;
1106 }
1107
1108 /* lease-time */
1109 if (mapContains(expr, "lease-time"))
1110 return "lease-time";
1111
1112 /* add */
1113 if (mapContains(expr, "add")) {
1114 struct element *arg;
1115 struct element *left;
1116 struct element *right;
1117 isc_boolean_t add_parenthesis;
1118
1119 appendString(result, "add ");
1120 arg = mapGet(expr, "add");
1121 if ((arg == NULL) || (arg->type != ELEMENT_MAP)) {
1122 *lose = ISC_TRUE;
1123 appendString(result, "???");
1124 return result->content;
1125 }
1126 left = mapGet(arg, "left");
1127 if (left == NULL) {
1128 *lose = ISC_TRUE;
1129 appendString(result, "???");
1130 return result->content;
1131 }
1132 result = allocString();
1133 add_parenthesis = ISC_TF(expr_precedence(expr_add,
1134 left) < 0);
1135 if (add_parenthesis)
1136 appendString(result, "(");
1137 appendString(result, print_expression(left, lose));
1138 if (add_parenthesis)
1139 appendString(result, ")");
1140 appendString(result, " + ");
1141 right = mapGet(arg, "right");
1142 if (right == NULL) {
1143 *lose = ISC_TRUE;
1144 appendString(result, "???");
1145 return result->content;
1146 }
1147 add_parenthesis = ISC_TF(expr_precedence(expr_add,
1148 right) < 0);
1149 if (add_parenthesis)
1150 appendString(result, "(");
1151 appendString(result, print_expression(right, lose));
1152 if (add_parenthesis)
1153 appendString(result, ")");
1154 return result->content;
1155 }
1156
1157 /* subtract */
1158 if (mapContains(expr, "subtract")) {
1159 struct element *arg;
1160 struct element *left;
1161 struct element *right;
1162 isc_boolean_t add_parenthesis;
1163
1164 appendString(result, "subtract ");
1165 arg = mapGet(expr, "subtract");
1166 if ((arg == NULL) || (arg->type != ELEMENT_MAP)) {
1167 *lose = ISC_TRUE;
1168 appendString(result, "???");
1169 return result->content;
1170 }
1171 left = mapGet(arg, "left");
1172 if (left == NULL) {
1173 *lose = ISC_TRUE;
1174 appendString(result, "???");
1175 return result->content;
1176 }
1177 result = allocString();
1178 add_parenthesis = ISC_TF(expr_precedence(expr_subtract,
1179 left) < 0);
1180 if (add_parenthesis)
1181 appendString(result, "(");
1182 appendString(result, print_expression(left, lose));
1183 if (add_parenthesis)
1184 appendString(result, ")");
1185 appendString(result, " - ");
1186 right = mapGet(arg, "right");
1187 if (right == NULL) {
1188 *lose = ISC_TRUE;
1189 appendString(result, "???");
1190 return result->content;
1191 }
1192 add_parenthesis = ISC_TF(expr_precedence(expr_subtract,
1193 right) < 0);
1194 if (add_parenthesis)
1195 appendString(result, "(");
1196 appendString(result, print_expression(right, lose));
1197 if (add_parenthesis)
1198 appendString(result, ")");
1199 return result->content;
1200 }
1201
1202 /* multiply */
1203 if (mapContains(expr, "multiply")) {
1204 struct element *arg;
1205 struct element *left;
1206 struct element *right;
1207 isc_boolean_t add_parenthesis;
1208
1209 appendString(result, "multiply ");
1210 arg = mapGet(expr, "multiply");
1211 if ((arg == NULL) || (arg->type != ELEMENT_MAP)) {
1212 *lose = ISC_TRUE;
1213 appendString(result, "???");
1214 return result->content;
1215 }
1216 left = mapGet(arg, "left");
1217 if (left == NULL) {
1218 *lose = ISC_TRUE;
1219 appendString(result, "???");
1220 return result->content;
1221 }
1222 result = allocString();
1223 add_parenthesis = ISC_TF(expr_precedence(expr_multiply,
1224 left) < 0);
1225 if (add_parenthesis)
1226 appendString(result, "(");
1227 appendString(result, print_expression(left, lose));
1228 if (add_parenthesis)
1229 appendString(result, ")");
1230 appendString(result, " * ");
1231 right = mapGet(arg, "right");
1232 if (right == NULL) {
1233 *lose = ISC_TRUE;
1234 appendString(result, "???");
1235 return result->content;
1236 }
1237 add_parenthesis = ISC_TF(expr_precedence(expr_multiply,
1238 right) < 0);
1239 if (add_parenthesis)
1240 appendString(result, "(");
1241 appendString(result, print_expression(right, lose));
1242 if (add_parenthesis)
1243 appendString(result, ")");
1244 return result->content;
1245 }
1246
1247 /* divide */
1248 if (mapContains(expr, "divide")) {
1249 struct element *arg;
1250 struct element *left;
1251 struct element *right;
1252 isc_boolean_t add_parenthesis;
1253
1254 appendString(result, "divide ");
1255 arg = mapGet(expr, "divide");
1256 if ((arg == NULL) || (arg->type != ELEMENT_MAP)) {
1257 *lose = ISC_TRUE;
1258 appendString(result, "???");
1259 return result->content;
1260 }
1261 left = mapGet(arg, "left");
1262 if (left == NULL) {
1263 *lose = ISC_TRUE;
1264 appendString(result, "???");
1265 return result->content;
1266 }
1267 result = allocString();
1268 add_parenthesis = ISC_TF(expr_precedence(expr_divide,
1269 left) < 0);
1270 if (add_parenthesis)
1271 appendString(result, "(");
1272 appendString(result, print_expression(left, lose));
1273 if (add_parenthesis)
1274 appendString(result, ")");
1275 appendString(result, " / ");
1276 right = mapGet(arg, "right");
1277 if (right == NULL) {
1278 *lose = ISC_TRUE;
1279 appendString(result, "???");
1280 return result->content;
1281 }
1282 add_parenthesis = ISC_TF(expr_precedence(expr_divide,
1283 right) < 0);
1284 if (add_parenthesis)
1285 appendString(result, "(");
1286 appendString(result, print_expression(right, lose));
1287 if (add_parenthesis)
1288 appendString(result, ")");
1289 return result->content;
1290 }
1291
1292 /* remainder */
1293 if (mapContains(expr, "remainder")) {
1294 struct element *arg;
1295 struct element *left;
1296 struct element *right;
1297 isc_boolean_t add_parenthesis;
1298
1299 appendString(result, "remainder ");
1300 arg = mapGet(expr, "remainder");
1301 if ((arg == NULL) || (arg->type != ELEMENT_MAP)) {
1302 *lose = ISC_TRUE;
1303 appendString(result, "???");
1304 return result->content;
1305 }
1306 left = mapGet(arg, "left");
1307 if (left == NULL) {
1308 *lose = ISC_TRUE;
1309 appendString(result, "???");
1310 return result->content;
1311 }
1312 result = allocString();
1313 add_parenthesis = ISC_TF(expr_precedence(expr_remainder,
1314 left) < 0);
1315 if (add_parenthesis)
1316 appendString(result, "(");
1317 appendString(result, print_expression(left, lose));
1318 if (add_parenthesis)
1319 appendString(result, ")");
1320 appendString(result, " % ");
1321 right = mapGet(arg, "right");
1322 if (right == NULL) {
1323 *lose = ISC_TRUE;
1324 appendString(result, "???");
1325 return result->content;
1326 }
1327 add_parenthesis = ISC_TF(expr_precedence(expr_remainder,
1328 right) < 0);
1329 if (add_parenthesis)
1330 appendString(result, "(");
1331 appendString(result, print_expression(right, lose));
1332 if (add_parenthesis)
1333 appendString(result, ")");
1334 return result->content;
1335 }
1336
1337 /* binary-and */
1338 if (mapContains(expr, "binary-and")) {
1339 struct element *arg;
1340 struct element *left;
1341 struct element *right;
1342 isc_boolean_t add_parenthesis;
1343
1344 appendString(result, "binary-and ");
1345 arg = mapGet(expr, "binary-and");
1346 if ((arg == NULL) || (arg->type != ELEMENT_MAP)) {
1347 *lose = ISC_TRUE;
1348 appendString(result, "???");
1349 return result->content;
1350 }
1351 left = mapGet(arg, "left");
1352 if (left == NULL) {
1353 *lose = ISC_TRUE;
1354 appendString(result, "???");
1355 return result->content;
1356 }
1357 result = allocString();
1358 add_parenthesis = ISC_TF(expr_precedence(expr_binary_and,
1359 left) < 0);
1360 if (add_parenthesis)
1361 appendString(result, "(");
1362 appendString(result, print_expression(left, lose));
1363 if (add_parenthesis)
1364 appendString(result, ")");
1365 appendString(result, " & ");
1366 right = mapGet(arg, "right");
1367 if (right == NULL) {
1368 *lose = ISC_TRUE;
1369 appendString(result, "???");
1370 return result->content;
1371 }
1372 add_parenthesis = ISC_TF(expr_precedence(expr_binary_and,
1373 right) < 0);
1374 if (add_parenthesis)
1375 appendString(result, "(");
1376 appendString(result, print_expression(right, lose));
1377 if (add_parenthesis)
1378 appendString(result, ")");
1379 return result->content;
1380 }
1381
1382 /* binary-or */
1383 if (mapContains(expr, "binary-or")) {
1384 struct element *arg;
1385 struct element *left;
1386 struct element *right;
1387 isc_boolean_t add_parenthesis;
1388
1389 appendString(result, "binary-or ");
1390 arg = mapGet(expr, "binary-or");
1391 if ((arg == NULL) || (arg->type != ELEMENT_MAP)) {
1392 *lose = ISC_TRUE;
1393 appendString(result, "???");
1394 return result->content;
1395 }
1396 left = mapGet(arg, "left");
1397 if (left == NULL) {
1398 *lose = ISC_TRUE;
1399 appendString(result, "???");
1400 return result->content;
1401 }
1402 result = allocString();
1403 add_parenthesis = ISC_TF(expr_precedence(expr_binary_or,
1404 left) < 0);
1405 if (add_parenthesis)
1406 appendString(result, "(");
1407 appendString(result, print_expression(left, lose));
1408 if (add_parenthesis)
1409 appendString(result, ")");
1410 appendString(result, " | ");
1411 right = mapGet(arg, "right");
1412 if (right == NULL) {
1413 *lose = ISC_TRUE;
1414 appendString(result, "???");
1415 return result->content;
1416 }
1417 add_parenthesis = ISC_TF(expr_precedence(expr_binary_or,
1418 right) < 0);
1419 if (add_parenthesis)
1420 appendString(result, "(");
1421 appendString(result, print_expression(right, lose));
1422 if (add_parenthesis)
1423 appendString(result, ")");
1424 return result->content;
1425 }
1426
1427 /* binary-xor */
1428 if (mapContains(expr, "binary-xor")) {
1429 struct element *arg;
1430 struct element *left;
1431 struct element *right;
1432 isc_boolean_t add_parenthesis;
1433
1434 appendString(result, "binary-xor ");
1435 arg = mapGet(expr, "binary-xor");
1436 if ((arg == NULL) || (arg->type != ELEMENT_MAP)) {
1437 *lose = ISC_TRUE;
1438 appendString(result, "???");
1439 return result->content;
1440 }
1441 left = mapGet(arg, "left");
1442 if (left == NULL) {
1443 *lose = ISC_TRUE;
1444 appendString(result, "???");
1445 return result->content;
1446 }
1447 result = allocString();
1448 add_parenthesis = ISC_TF(expr_precedence(expr_binary_xor,
1449 left) < 0);
1450 if (add_parenthesis)
1451 appendString(result, "(");
1452 appendString(result, print_expression(left, lose));
1453 if (add_parenthesis)
1454 appendString(result, ")");
1455 appendString(result, " ^ ");
1456 right = mapGet(arg, "right");
1457 if (right == NULL) {
1458 *lose = ISC_TRUE;
1459 appendString(result, "???");
1460 return result->content;
1461 }
1462 add_parenthesis = ISC_TF(expr_precedence(expr_binary_xor,
1463 right) < 0);
1464 if (add_parenthesis)
1465 appendString(result, "(");
1466 appendString(result, print_expression(right, lose));
1467 if (add_parenthesis)
1468 appendString(result, ")");
1469 return result->content;
1470 }
1471
1472 /* client-state */
1473 if (mapContains(expr, "client-state"))
1474 return "client-state";
1475
1476 *lose = ISC_TRUE;
1477 appendString(result, "???");
1478 return result->content;
1479 }
1480
1481 static void
1482 debug(const char* fmt, ...)
1483 {
1484 va_list list;
1485
1486 va_start(list, fmt);
1487 vfprintf(stderr, fmt, list);
1488 fprintf(stderr, "\n");
1489 va_end(list);
1490 }