54 #include <sys/signalfd.h>
67 #include <amxc/amxc.h>
77 #include <amxc/amxc_macros.h>
84 assert_string_equal(expression.
expression,
"true");
93 assert_ptr_equal(expr, NULL);
107 {
false,
"true && false" },
108 {
true,
"true || false" },
110 {
true,
"True || False" },
111 {
false,
"True && False" }
114 for(uint32_t i = 0; i <
sizeof(evals) /
sizeof(evals[0]); i++) {
115 printf(
"Evaluating \"%s\"\n", evals[i].text);
117 assert_true(
amxp_expr_eval(&expression, &status) == evals[i].result);
118 assert_int_equal(status, 0);
128 {
true,
"true || false && true" },
129 {
true,
"(true || false) && true"},
130 {
false,
"false || true && false" },
131 {
false,
"(false || true) && false" },
132 {
false,
"false || false && false" },
133 {
false,
"true && false || true && false"},
134 {
false,
"false || false && true || false"},
135 {
true,
"!(false || false) && true || false"},
136 {
true,
"!false && true"},
137 {
true,
"!false || false"},
138 {
true,
"!false || true"},
139 {
false,
"!(false || true)"},
140 {
true,
"true || false && false || false" },
141 {
false,
"(true || false) && (false || false)" },
144 for(uint32_t i = 0; i <
sizeof(evals) /
sizeof(evals[0]); i++) {
145 printf(
"Evaluating \"%s\"\n", evals[i].text);
147 assert_true(
amxp_expr_eval(&expression, &status) == evals[i].result);
148 assert_int_equal(status, 0);
160 {
false,
"10 > 10" },
163 {
true,
"10 >= 10" },
164 {
true,
"10 <= 10" },
165 {
true,
"\"bagpipe\" >= \"b\"" },
166 {
true,
"\"bagpipe\" >= \"bagpipe\""},
167 {
false,
"\"bagpipe\" <= \"aardvark\"" },
168 {
true,
"\"bagpipe\" >= \"aardvark\""},
169 {
true,
"\"This is some tekst\" != \"Diferent & Also, Text\""},
170 {
true,
"'Text' in ['bagpipe', 'aardvark', 'Text', 10]"},
171 {
false,
"'rabbit' in ['bagpipe', 'aardvark', 'Text', 10]"},
172 {
true,
"'the rabbit went into the rabbit hole' starts with 'the rabbit'"},
173 {
false,
"'Alice went into the rabbit hole' starts with 'the rabbit'"},
174 {
true,
"'the rabbit went into the rabbit hole' starts\t with 'the rabbit'"},
175 {
true,
"'rabbit' in 'the rabbit went into the rabbit hole'"},
176 {
true,
"'hole' in 'the rabbit went into the rabbit hole'"},
177 {
false,
"'Alice' in 'the rabbit went into the rabbit hole'"},
178 {
false,
"'Alice' in 'Al'"},
179 {
true,
"'Alice' starts with ['Al', 'Ra']" },
180 {
true,
"'Rabbit' starts with ['Al', 'Ra']" },
181 {
true,
"is_empty([])"},
182 {
false,
"is_empty([1,2])"},
183 {
true,
"'the rabbit went into the rabbit hole' ends with 'rabbit hole'"},
184 {
false,
"'the rabbit went into the rabbit hole' ends with 'rabbit pit'"},
185 {
false,
"'the rabbit' ends with 'very long string that does not crash'"},
186 {
true,
"'Rabbit' ends with ['ce', 'it']" }
189 for(uint32_t i = 0; i <
sizeof(evals) /
sizeof(evals[0]); i++) {
190 printf(
"Evaluating \"%s\"\n", evals[i].text);
193 assert_true(
amxp_expr_eval(&expression, &status) == evals[i].result);
194 assert_int_equal(status, 0);
203 amxc_var_t* subtable;
204 amxc_var_t* subarray;
209 {
true,
"'brown' in CSVText"},
210 {
true,
"TextField == \"This is text\"" },
211 {
true,
"MyTable.Text == \"Hello World\"" },
212 {
true,
".MyTable.Number == 100" },
213 {
true,
"MyTable.Boolean" },
214 {
true,
"MyArray.0 == \"Item1\""},
215 {
true,
".MyArray.1 == \"-20000\""},
216 {
true,
"MyArray.2"},
217 {
true,
"MyArray.3 > \"1970-01-01T00:00:00Z\""},
218 {
true,
"\"This is text\" == TextField" },
219 {
true,
"\"Hello World\" == MyTable.Text;" },
220 {
true,
"100 == MyTable.Number" },
221 {
true,
"\"Item1\" == MyArray.0"},
222 {
true,
"\"-20000\" == MyArray.1;"},
223 {
true,
"\"1970-01-01T00:00:00Z\" < MyArray.3"},
224 {
false,
"MyTable.Number > MyArray.1" },
225 {
true,
"MyArray.1 < MyTable.Number" },
226 {
true,
"TextField matches \"This.*\""},
227 {
false,
"TextField matches \"Not This.*\""},
228 {
true,
"TextField starts with 'This'"},
229 {
false,
"TextField starts with 'But Not This'"},
230 {
true,
"'fox' in CSVText"},
231 {
false,
"'red' in CSVText"}
234 amxc_var_init(&data);
235 amxc_var_set_type(&data, AMXC_VAR_ID_HTABLE);
238 amxc_var_add_key(cstring_t, &data,
"TextField",
"This is text");
239 subtable = amxc_var_add_key(amxc_htable_t, &data,
"MyTable", NULL);
240 amxc_var_add_key(cstring_t, subtable,
"Text",
"Hello World");
241 amxc_var_add_key(uint32_t, subtable,
"Number", 100);
242 amxc_var_add_key(
bool, subtable,
"Boolean",
true);
243 subarray = amxc_var_add_key(amxc_llist_t, &data,
"MyArray", NULL);
244 amxc_var_add(cstring_t, subarray,
"Item1");
245 amxc_var_add(int64_t, subarray, -20000);
246 amxc_var_add(
bool, subarray,
true);
247 amxc_var_add(amxc_ts_t, subarray, &now);
248 amxc_var_add_key(csv_string_t, &data,
"CSVText",
"The,big,brown,fox,jumped");
250 printf(
"Test data = ");
252 amxc_var_dump(&data, STDOUT_FILENO);
254 for(uint32_t i = 0; i <
sizeof(evals) /
sizeof(evals[0]); i++) {
256 printf(
"Evaluating \"%s\" (expecting %s - ", evals[i].text, evals[i].result ?
"true" :
"false");
261 assert_int_equal(status, 0);
262 printf(
"got %s)\n", result ?
"true" :
"false");
264 assert_true(result == evals[i].result);
268 subarray = GETP_ARG(&data,
"CSVText");
269 assert_int_equal(amxc_var_type_of(subarray), AMXC_VAR_ID_CSV_STRING);
271 amxc_var_clean(&data);
277 amxc_var_t* subtable;
278 amxc_var_t* subarray;
283 {
false,
"MyArray.NotExisting == \"Item1\""},
284 {
false,
"MyTable.99"},
285 {
false,
"\"TEXT\" matches Not.Existing.Field.0"},
288 amxc_var_init(&data);
289 amxc_var_set_type(&data, AMXC_VAR_ID_HTABLE);
292 amxc_var_add_key(cstring_t, &data,
"TextField",
"This is text");
293 subtable = amxc_var_add_key(amxc_htable_t, &data,
"MyTable", NULL);
294 amxc_var_add_key(cstring_t, subtable,
"Text",
"Hello World");
295 amxc_var_add_key(uint32_t, subtable,
"Number", 100);
296 amxc_var_add_key(
bool, subtable,
"Boolean",
true);
297 subarray = amxc_var_add_key(amxc_llist_t, &data,
"MyArray", NULL);
298 amxc_var_add(cstring_t, subarray,
"Item1");
299 amxc_var_add(int64_t, subarray, -20000);
300 amxc_var_add(
bool, subarray,
true);
301 amxc_var_add(amxc_ts_t, subarray, &now);
302 amxc_var_dump(&data, STDOUT_FILENO);
304 for(uint32_t i = 0; i <
sizeof(evals) /
sizeof(evals[0]); i++) {
305 printf(
"Evaluating \"%s\"\n", evals[i].text);
308 assert_int_not_equal(status, 0);
313 amxc_var_clean(&data);
320 {
false,
"Hello <> Goobey"},
321 {
false,
"\"Text\"Field @ Hello World"},
323 {
false,
"['a', 'b', 'c'] in 'abc'"},
324 {
false,
"'Alice' in 1024"}
327 for(uint32_t i = 0; i <
sizeof(evals) /
sizeof(evals[0]); i++) {
328 printf(
"Evaluating \"%s\"\n", evals[i].text);
329 assert_int_not_equal(
amxp_expr_init(&expression, evals[i].text), 0);
333 for(uint32_t i = 0; i <
sizeof(evals) /
sizeof(evals[0]); i++) {
334 assert_int_not_equal(
amxp_expr_new(&expr, evals[i].text), 0);
335 assert_ptr_equal(expr, NULL);
345 {
false,
"'Some text' == ['Some', 'text']"},
346 {
false,
"[1,2,3,4] > 10"},
347 {
false,
"[1,2,3,4] matches ['Part1', 'Part2']"}
350 for(uint32_t i = 0; i <
sizeof(evals) /
sizeof(evals[0]); i++) {
355 for(uint32_t i = 0; i <
sizeof(evals) /
sizeof(evals[0]); i++) {
357 assert_ptr_equal(expr, NULL);
367 amxc_var_t* data = (amxc_var_t*) priv;
368 amxc_var_t* field = amxc_var_get_path(data,
path, AMXC_VAR_FLAG_DEFAULT);
369 if(amxc_var_is_null(field)) {
370 if(strcmp(
path,
"available") == 0) {
371 amxc_var_set(
bool, value,
true);
373 amxc_var_set(
bool, value,
false);
377 if(amxc_var_copy(value, field) == 0) {
388 amxc_var_t* subtable;
389 amxc_var_t* subarray;
394 {
true,
"available"},
395 {
false,
"NOT_available"},
396 {
true,
".MyTable.Number > 100 || available"},
397 {
true,
"MyTable.Number > 100 || available"},
398 {
false,
".MyTable.Number > 100 || !available"},
399 {
false,
"MyTable.Number > 100 || !available"},
400 {
false,
"{MyTable.Number} > 100 || not_available"}
403 amxc_var_init(&data);
404 amxc_var_set_type(&data, AMXC_VAR_ID_HTABLE);
407 amxc_var_add_key(cstring_t, &data,
"TextField",
"This is text");
408 subtable = amxc_var_add_key(amxc_htable_t, &data,
"MyTable", NULL);
409 amxc_var_add_key(cstring_t, subtable,
"Text",
"Hello World");
410 amxc_var_add_key(uint32_t, subtable,
"Number", 100);
411 amxc_var_add_key(
bool, subtable,
"Boolean",
true);
412 subarray = amxc_var_add_key(amxc_llist_t, &data,
"MyArray", NULL);
413 amxc_var_add(cstring_t, subarray,
"Item1");
414 amxc_var_add(int64_t, subarray, -20000);
415 amxc_var_add(
bool, subarray,
true);
416 amxc_var_add(amxc_ts_t, subarray, &now);
418 for(uint32_t i = 0; i <
sizeof(evals) /
sizeof(evals[0]); i++) {
419 printf(
"Evaluating \"%s\"\n", evals[i].text);
422 assert_int_equal(status, 0);
427 amxc_var_clean(&data);
436 assert_ptr_equal(expr, NULL);
439 assert_ptr_not_equal(expr, NULL);
442 assert_ptr_equal(expr, NULL);
454 amxc_var_t* subtable;
455 amxc_var_t* subarray;
460 {
false,
"first_existing(MyTable.Text, .MyArray.0) == \"Item1\""},
461 {
true,
"first_existing(MyTable.Text, MyArray.0) == \"Hello World\""},
462 {
true,
"first_existing(.MyTable.NotExistingText, MyArray.0) == \"Item1\""},
463 {
true,
"first_existing(.MyTable.NotExistingText, MyArray.99, FakeItem.0.NotExisting, 'Item1') == \"Item1\""},
464 {
false,
"first_existing(.MyTable.NotExistingText, MyArray.99, FakeItem.0.NotExisting, MyTable.Text) == \"Item1\""},
467 amxc_var_init(&data);
468 amxc_var_set_type(&data, AMXC_VAR_ID_HTABLE);
471 amxc_var_add_key(cstring_t, &data,
"TextField",
"This is text");
472 subtable = amxc_var_add_key(amxc_htable_t, &data,
"MyTable", NULL);
473 amxc_var_add_key(cstring_t, subtable,
"Text",
"Hello World");
474 amxc_var_add_key(uint32_t, subtable,
"Number", 100);
475 amxc_var_add_key(
bool, subtable,
"Boolean",
true);
476 subarray = amxc_var_add_key(amxc_llist_t, &data,
"MyArray", NULL);
477 amxc_var_add(cstring_t, subarray,
"Item1");
478 amxc_var_add(int64_t, subarray, -20000);
479 amxc_var_add(
bool, subarray,
true);
480 amxc_var_add(amxc_ts_t, subarray, &now);
481 amxc_var_dump(&data, 1);
483 for(uint32_t i = 0; i <
sizeof(evals) /
sizeof(evals[0]); i++) {
484 printf(
"Evaluating \"%s\"\n", evals[i].text);
487 assert_int_equal(status, 0);
492 amxc_var_clean(&data);
498 amxc_var_t* subtable;
499 amxc_var_t* subarray;
502 amxc_var_init(&data);
503 amxc_var_set_type(&data, AMXC_VAR_ID_HTABLE);
506 amxc_var_add_key(cstring_t, &data,
"TextField",
"This is text");
507 subtable = amxc_var_add_key(amxc_htable_t, &data,
"MyTable", NULL);
508 amxc_var_add_key(cstring_t, subtable,
"Text",
"Hello World");
509 amxc_var_add_key(uint32_t, subtable,
"Number", 100);
510 amxc_var_add_key(
bool, subtable,
"Boolean",
true);
511 subarray = amxc_var_add_key(amxc_llist_t, &data,
"MyArray", NULL);
512 amxc_var_add(cstring_t, subarray,
"Item1");
513 amxc_var_add(int64_t, subarray, -20000);
514 amxc_var_add(
bool, subarray,
true);
515 amxc_var_add(amxc_ts_t, subarray, &now);
517 assert_int_not_equal(
amxp_expr_init(&expression,
"MyTable.Text matches \"[(adadasd.[\""), 0);
519 amxc_var_clean(&data);
527 {
true,
"is_empty([])"},
528 {
false,
"is_empty([1,2])"}
531 for(uint32_t i = 0; i <
sizeof(evals) /
sizeof(evals[0]); i++) {
532 printf(
"Evaluating \"%s\"\n", evals[i].text);
534 assert_true(
amxp_expr_eval(&expression, &status) == evals[i].result);
535 assert_int_equal(status, 0);
544 amxc_var_t* subtable;
545 amxc_var_t* subarray;
549 {
false,
"is_empty({MyTable})"},
550 {
false,
"is_empty({MyArray})"},
551 {
true,
"is_empty({EmptyArray})"},
552 {
true,
"is_empty({EmptyTable})"},
553 {
true,
"is_empty({MyTable.NotExisting})"},
554 {
true,
"is_empty({MyArray.99})"},
555 {
false,
"is_empty({})"},
556 {
true,
"is_empty()"},
559 amxc_var_init(&data);
560 amxc_var_set_type(&data, AMXC_VAR_ID_HTABLE);
563 amxc_var_add_key(cstring_t, &data,
"TextField",
"This is text");
564 subtable = amxc_var_add_key(amxc_htable_t, &data,
"MyTable", NULL);
565 amxc_var_add_key(cstring_t, subtable,
"Text",
"Hello World");
566 amxc_var_add_key(uint32_t, subtable,
"Number", 100);
567 amxc_var_add_key(
bool, subtable,
"Boolean",
true);
568 subarray = amxc_var_add_key(amxc_llist_t, &data,
"MyArray", NULL);
569 amxc_var_add(cstring_t, subarray,
"Item1");
570 amxc_var_add(int64_t, subarray, -20000);
571 amxc_var_add(
bool, subarray,
true);
572 amxc_var_add(amxc_ts_t, subarray, &now);
573 amxc_var_add_key(amxc_llist_t, &data,
"EmptyArray", NULL);
574 amxc_var_add_key(amxc_htable_t, &data,
"EmptyTable", NULL);
576 for(uint32_t i = 0; i <
sizeof(evals) /
sizeof(evals[0]); i++) {
577 printf(
"Evaluating \"%s\"\n", evals[i].text);
580 assert_int_equal(status, 0);
584 amxc_var_clean(&data);
590 amxc_var_t* subtable;
591 amxc_var_t* subarray;
596 {
true,
"contains('MyTable.Text')"},
597 {
false,
"contains('MyTable.Text.Extra')"},
598 {
true,
"contains('MyArray.0')"},
599 {
false,
"contains('MyArray.0.Extra')"},
600 {
false,
"contains('MyArray.99')"},
601 {
true,
"contains('Test', 'MyArray.0')"},
602 {
false,
"contains('MyArray.99', 'MyTable.Text.Extra', 'MyArray.0.Extra')"},
605 amxc_var_init(&data);
606 amxc_var_set_type(&data, AMXC_VAR_ID_HTABLE);
609 amxc_var_add_key(cstring_t, &data,
"TextField",
"This is text");
610 subtable = amxc_var_add_key(amxc_htable_t, &data,
"MyTable", NULL);
611 amxc_var_add_key(cstring_t, subtable,
"Text",
"Hello World");
612 amxc_var_add_key(uint32_t, subtable,
"Number", 100);
613 amxc_var_add_key(
bool, subtable,
"Boolean",
true);
614 subarray = amxc_var_add_key(amxc_llist_t, &data,
"MyArray", NULL);
615 amxc_var_add(cstring_t, subarray,
"Item1");
616 amxc_var_add(int64_t, subarray, -20000);
617 amxc_var_add(
bool, subarray,
true);
618 amxc_var_add(amxc_ts_t, subarray, &now);
620 for(uint32_t i = 0; i <
sizeof(evals) /
sizeof(evals[0]); i++) {
621 printf(
"Evaluating \"%s\"\n", evals[i].text);
624 assert_int_equal(status, 0);
628 amxc_var_clean(&data);
635 amxc_var_t* subtable = NULL;
638 {
false,
"contains('MyTable.Text')"},
639 {
false,
"contains('MyTable.Text.Extra')"},
640 {
false,
"contains('MyArray.0')"},
641 {
false,
"contains('MyArray.0.Extra')"},
642 {
false,
"contains('MyArray.99')"},
645 amxc_var_init(&data);
646 amxc_var_set_type(&data, AMXC_VAR_ID_HTABLE);
647 subtable = amxc_var_add_key(amxc_htable_t, &data,
"MyTable", NULL);
648 amxc_var_add_key(cstring_t, subtable,
"Text",
"Hello World");
650 for(uint32_t i = 0; i <
sizeof(evals) /
sizeof(evals[0]); i++) {
651 printf(
"Evaluating \"%s\"\n", evals[i].text);
653 assert_true(
amxp_expr_evaluate(&expression, NULL, &data, &status) == evals[i].result);
654 assert_int_equal(status, 0);
658 amxc_var_clean(&data);
666 {
false,
"contains('MyTable.Text')"},
667 {
false,
"contains('MyTable.Text.Extra')"},
668 {
false,
"contains('MyArray.0')"},
669 {
false,
"contains('MyArray.0.Extra')"},
670 {
false,
"contains('MyArray.99')"},
673 for(uint32_t i = 0; i <
sizeof(evals) /
sizeof(evals[0]); i++) {
674 printf(
"Evaluating \"%s\"\n", evals[i].text);
677 assert_int_equal(status, 0);
687 amxc_var_init(&data);
688 amxc_var_set_type(&data, AMXC_VAR_ID_HTABLE);
692 assert_int_equal(status, 0);
695 assert_int_equal(
amxp_expr_init(&expression,
"contains(100)"), 0);
697 assert_int_equal(status, 0);
700 amxc_var_clean(&data);
708 amxc_set_init(&set,
false);
709 amxc_set_parse(&set,
"bridge ipv6 global lan interface");
711 assert_int_equal(
amxp_expr_init(&expression,
"ipv4 || (ipv6 && global)"), 0);
714 amxc_set_remove_flag(&set,
"ipv6");
718 amxc_set_clean(&set);
727 amxc_set_init(&set,
false);
728 amxc_set_parse(&set,
"bridge ipv6 global lan interface");
733 amxc_set_remove_flag(&set,
"ipv6");
737 amxc_set_clean(&set);
745 {
true,
"'Some text' in ['Some text', 'other value']"},
746 {
false,
"'Some text' in ['some value', 'other value']"},
747 {
true,
"['Some text', 'other value'] ~= 'Some text'"},
748 {
false,
"['some value', 'other value'] ~= 'Some text'"},
751 for(uint32_t i = 0; i <
sizeof(evals) /
sizeof(evals[0]); i++) {
752 printf(
"Evaluating \"%s\"\n", evals[i].text);
755 assert_int_equal(status, 0);
762 const char* expr_fmt =
"'Some text' in ['%s', '%s']";
764 printf(
"Building \"%s\"\n", expr_fmt);
771 const char* expr_fmt =
"'Some text' in ['%s', '%s']";
773 printf(
"Building \"%s\"\n", expr_fmt);
780 const char* expr_fmt =
"password == '%s'";
782 printf(
"Building \"%s\"\n", expr_fmt);
789 const char* expr_fmt =
"test == '%s'";
791 printf(
"Building \"%s\"\n", expr_fmt);
792 assert_int_equal(
amxp_expr_buildf(&expression, expr_fmt,
"Whitelisted according to specs:"
793 "!#$%&()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_abcdefghijklmnopqrstuvwxyz{|}~",
800 const char* bad_expr_fmt =
"test == '%s']";
801 const char* good_expr_fmt =
"test == '%s'";
815 if(expect_accepted) {
816 assert_true(matched);
820 assert_false(matched);
829 s_testhelper_buildf(
true,
"Whitelisted according to specs: !#$%&()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_abcdefghijklmnopqrstuvwxyz{|}~");
840 const char* expr_string = NULL;
850 assert_string_equal(
"username == 'Alice'", expr_string);
856 const char* expr_string = NULL;
865 assert_null(expr_string);
881 {
true,
"'HELLO world' ^= 'HELLO world'"},
883 {
true,
"'HELLO world' ^= 'hello WORLD'"},
884 {
true,
"'HELLO WORLD' ^= 'hello world'"},
885 {
true,
"'hello world' ^= 'HELLO WORLD'"},
887 {
false,
"'hello world' ^= 'hallo world'"},
889 {
false,
"'abcd' ^= 'abc'"},
890 {
false,
"'abcd' ^= 'bcd'"},
891 {
false,
"'abcd' ^= 'bc'"},
892 {
false,
"'abcd' ^= ''"},
894 {
false,
"'abc' ^= 'abcd'"},
895 {
false,
"'bcd' ^= 'abcd'"},
896 {
false,
"'bc' ^= 'abcd'"},
897 {
false,
"'' ^= 'abcd'"},
899 {
true,
"'~♥!@#$%^&*(){}?+_SZVWwvzs-/=][' ^= '~♥!@#$%^&*(){}?+_SZVWwvzs-/=]['"},
900 {
false,
"'~♥!@#$%^&*(){}?+_SZVWwvzs-/=][' ^= '~♥!@#$%^&*(){}?+_SZVWwvzs-/=[]'"},
902 {
true,
"'He said: \"Hello.\"' ^= 'He said: \"Hello.\"'"},
903 {
true,
"\"He said: 'Hello.'\" ^= \"He said: 'Hello.'\""},
904 {
false,
"\"He said: 'Hello.'\" ^= 'He said: \"Hello.\"'"},
906 {
true,
"Number ^= '100'" },
907 {
true,
"Boolean ^= \"false\"" },
908 {
true,
"Boolean ^= \"FaLsE\"" },
909 {
false,
"Boolean ^= \"true\"" },
910 {
true,
"CSVText ^= \"the,BIG,brown,fox,jumped\""},
913 amxc_var_init(&data);
914 amxc_var_set_type(&data, AMXC_VAR_ID_HTABLE);
915 amxc_var_add_key(uint32_t, &data,
"Number", 100);
916 amxc_var_add_key(
bool, &data,
"Boolean",
false);
917 amxc_var_add_key(csv_string_t, &data,
"CSVText",
"The,big,brown,fox,jumped");
919 for(uint32_t i = 0; i <
sizeof(evals) /
sizeof(evals[0]); i++) {
922 printf(
"Evaluating \"%s\"\n", evals[i].text);
925 assert_int_equal(status, 0);
929 amxc_var_clean(&data);
Ambiorix expression parser and evaluate API header file.
const char * amxp_expr_get_string(amxp_expr_t *expr)
Returns the string representation of the given expression.
amxp_expr_status_t amxp_expr_new(amxp_expr_t **expr, const char *expression)
Allocates and initializes an expression.
bool amxp_expr_eval(amxp_expr_t *expr, amxp_expr_status_t *status)
Evaluates an expression.
amxp_expr_status_t amxp_expr_buildf_new(amxp_expr_t **expr, const char *expr_fmt,...) __attribute__((format(printf
Allocates and initializes an expression with format-string and safety checks.
amxp_expr_status_t amxp_expr_buildf(amxp_expr_t *expr, const char *expr_fmt,...) __attribute__((format(printf
Initializes an expression structure.
bool amxp_expr_eval_set(amxp_expr_t *expr, const amxc_set_t *const data, amxp_expr_status_t *status)
Evaluates an expression against a set.
bool amxp_expr_eval_var(amxp_expr_t *expr, const amxc_var_t *const data, amxp_expr_status_t *status)
Evaluates an expression against a composite variant.
void amxp_expr_clean(amxp_expr_t *expr)
Clean-up the expression structure.
amxp_expr_status_t amxp_expr_init(amxp_expr_t *expr, const char *expression)
Initializes an expression structure.
bool amxp_expr_evaluate(amxp_expr_t *expr, amxp_expr_get_field_t fn, void *priv, amxp_expr_status_t *status)
Evaluates an expression.
void amxp_expr_dump_tree(amxp_expr_t *expr)
Dumps the binary tree in dot formatted text file to stdout.
enum _expr_status amxp_expr_status_t
Expression status/error codes.
void amxp_expr_delete(amxp_expr_t **expr)
Deletes a previously allocated expression structure.
@ amxp_expr_status_invalid_value
@ amxp_expr_status_unknown_error
static void s_testhelper_buildf(bool expect_accepted, const char *string)
static amxp_expr_status_t custom_field_fetcher(UNUSED amxp_expr_t *expr, amxc_var_t *value, const char *path, void *priv)
void test_invalid_value_types(UNUSED void **state)
void test_api_arguments_validation(UNUSED void **state)
void test_buildf_expression_allocate(UNUSED void **state)
void test_buildf_are_strings_safe(UNUSED void **state)
void test_get_string_null(UNUSED void **state)
void test_in_operators(UNUSED void **state)
void test_expression_with_invalid_list_does_not_memory_leak(UNUSED void **state)
void test_can_fetch_fields(UNUSED void **state)
void test_get_string(UNUSED void **state)
void test_can_create_expression(UNUSED void **state)
void test_buildf_expression_invalid_args(UNUSED void **state)
void test_precedence_is_respected(UNUSED void **state)
void test_contains(UNUSED void **state)
void test_selects_first_in_first_existing(UNUSED void **state)
void test_contains_no_data(UNUSED void **state)
void test_invalid_field_names(UNUSED void **state)
void test_flag_expressions_no_operators(UNUSED void **state)
void test_invalid_syntax(UNUSED void **state)
void test_buildf_expression(UNUSED void **state)
void test_comperators_are_correct(UNUSED void **state)
void test_buildf_expression_all_whitelisted(UNUSED void **state)
void test_buildf_expression_invalid_value(UNUSED void **state)
void test_contains_invalid_usage(UNUSED void **state)
void test_is_empty_function(UNUSED void **state)
void test_can_evaluate_expression(UNUSED void **state)
void test_flag_expressions(UNUSED void **state)
void test_contains_no_get_field(UNUSED void **state)
void test_can_use_custom_field_fetcher(UNUSED void **state)
void test_fails_with_invalid_regexp(UNUSED void **state)
void test_is_empty_function_with_var(UNUSED void **state)
void test_equals_ignorecase(void **state)
static amxc_string_t path