Adaptive Framework  0.9.0
All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
afw_function_compiler.c
Go to the documentation of this file.
1 // See the 'COPYING' file in the project root for licensing information.
2 /*
3  * afw_function_execute_* functions for compiler
4  *
5  * Copyright (c) 2010-2023 Clemson University
6  *
7  */
8 
14 #include "afw_internal.h"
15 
16 
17 
18 
19 
20 /*
21  * Adaptive function: assert
22  *
23  * afw_function_execute_assert
24  *
25  * See afw_function_bindings.h for more information.
26  *
27  * Assert that a value is true. If not, an assertion_failed error is thrown.
28  *
29  * This function is not pure, so it may return a different result
30  * given exactly the same parameters.
31  *
32  * Declaration:
33  *
34  * ```
35  * function assert(
36  * assertion: boolean,
37  * reason?: string
38  * ): null;
39  * ```
40  *
41  * Parameters:
42  *
43  * assertion - (boolean) This is the assertion to make. If not true, an
44  * assertion_failed error is thrown.
45  *
46  * reason - (optional string) This is an optional reason to include in the
47  * assertion_failed message.
48  *
49  * Returns:
50  *
51  * (null)
52  */
53 const afw_value_t *
56 {
57  const afw_value_t *assertion;
58  const afw_value_string_t *reason;
59 
60  AFW_FUNCTION_EVALUATE_PARAMETER(assertion, 1);
61 
62  if (!assertion ||
63  !afw_value_is_boolean(assertion) ||
64  !((const afw_value_boolean_t *)assertion)->internal)
65  {
67  if (reason) {
68  AFW_THROW_ERROR_FZ(assertion_failed, x->xctx,
69  "Assertion failed: %" AFW_UTF8_FMT,
70  AFW_UTF8_FMT_ARG(&reason->internal));
71  }
72  else {
73  AFW_THROW_ERROR_Z(assertion_failed, "Assertion failed", x->xctx);
74  }
75  }
76 
77  return afw_value_null;
78 }
79 
80 
81 
82 AFW_DEFINE(const afw_utf8_t *)
83 afw_function_evaluate_whitespace_parameter(
85  afw_size_t n)
86 {
87  const afw_value_t *value;
88  const afw_utf8_t *result;
89  afw_size_t len;
90 
91  result = NULL;
94  if (afw_value_is_string(value) &&
95  ((const afw_value_string_t *)value)->internal.len < 10)
96  {
97  result = &((const afw_value_string_t *)value)->internal;
98  }
99  else if (afw_value_is_integer(value) &&
100  ((const afw_value_integer_t *)value)->internal >= 0 &&
101  ((const afw_value_integer_t *)value)->internal <= 10)
102  {
103  len = (afw_size_t)((const afw_value_integer_t *)value)->
104  internal;
105  if (len != 0) {
106  result = afw_utf8_create(" ", len, x->p, x->xctx);
107  }
108  }
109  else if (afw_value_is_boolean(value)) {
110  if (((const afw_value_boolean_t *)value)->internal) {
111  result = &afw_s_a_tab;
112  }
113  }
114  else {
115  AFW_THROW_ERROR_FZ(general, x->xctx,
116  "parameter %"
118  " must be a string no longer than 10 or an "
119  "integer between 0 and 10",
120  n);
121  }
122  }
123 
124  return result;
125 }
126 
127 
128 
129 /*
130  * Adaptive function: compile_expression_tuple
131  *
132  * afw_function_execute_compile_expression_tuple
133  *
134  * See afw_function_bindings.h for more information.
135  *
136  * Compile a string containing adaptive expression tuple syntax and return
137  * either an unevaluated expression tuple adaptive value or a string containing
138  * the compiler listing.
139  *
140  * This function is pure, so it will always return the same result
141  * given exactly the same parameters and has no side effects.
142  *
143  * Declaration:
144  *
145  * ```
146  * function compile_expression_tuple(
147  * expression_tuple: list,
148  * listing?: any
149  * ): any;
150  * ```
151  *
152  * Parameters:
153  *
154  * expression_tuple - (list) expression tuple to compile.
155  *
156  * listing - (optional any dataType) If specified, a compiler listing is
157  * produced instead of an unevaluated expression tuple value.
158  *
159  * This parameter can be an integer between 0 and 10 of a string that is
160  * used for indentation. If 0 is specified, no whitespace is added to the
161  * resulting string. If 1 through 10 is specified, that number of spaces
162  * is used.
163  *
164  * Returns:
165  *
166  * (any dataType) An unevaluated expression tuple value ready for use by
167  * function evaluate() or a string containing the compiler listing.
168  */
169 const afw_value_t *
172 {
173  const afw_value_list_t *expression_tuple;
174  const afw_utf8_t *s;
175  const afw_value_t *result;
176  const afw_utf8_t *listing;
177 
178  AFW_FUNCTION_EVALUATE_REQUIRED_DATA_TYPE_PARAMETER(expression_tuple, 1, list);
179 
180  s = afw_json_from_value((const afw_value_t *)expression_tuple, NULL,
181  x->p, x->xctx);
182 
183  result = afw_compile_to_value(
184  s, AFW_FUNCTION_SOURCE_LOCATION, afw_compile_type_hybrid,
185  NULL, NULL, x->p, x->xctx);
186 
188  listing = afw_function_evaluate_whitespace_parameter(x, 2);
189  result = afw_value_create_string(
190  afw_value_compiler_listing_to_string(result, listing,
191  x->p, x->xctx),
192  x->p, x->xctx);
193  }
194 
195  return result;
196 }
197 
198 
199 
200 /*
201  * Adaptive function: compile_json
202  *
203  * afw_function_execute_compile_json
204  *
205  * See afw_function_bindings.h for more information.
206  *
207  * Compile a string containing adaptive JSON syntax and return either an
208  * unevaluated JSON adaptive value or a string containing the compiler listing.
209  *
210  * This function is pure, so it will always return the same result
211  * given exactly the same parameters and has no side effects.
212  *
213  * Declaration:
214  *
215  * ```
216  * function compile_json(
217  * json: string,
218  * listing?: any
219  * ): any;
220  * ```
221  *
222  * Parameters:
223  *
224  * json - (string) JSON string to compile.
225  *
226  * listing - (optional any dataType) If specified, a compiler listing is
227  * produced instead of an unevaluated JSON value.
228  *
229  * This parameter can be an integer between 0 and 10 of a string that is
230  * used for indentation. If 0 is specified, no whitespace is added to the
231  * resulting string. If 1 through 10 is specified, that number of spaces
232  * is used.
233  *
234  * Returns:
235  *
236  * (any dataType) An unevaluated JSON value ready for use by function
237  * evaluate() or a string containing the compiler listing.
238  */
239 const afw_value_t *
242 {
243  const afw_value_string_t *json;
244  const afw_value_t *result;
245  const afw_utf8_t *listing;
246 
248 
249  result = afw_compile_to_value(
250  &json->internal, AFW_FUNCTION_SOURCE_LOCATION,
251  afw_compile_type_json,
252  NULL, NULL, x->p, x->xctx);
253 
255  listing = afw_function_evaluate_whitespace_parameter(x, 2);
256  result = afw_value_create_string(
257  afw_value_compiler_listing_to_string(result, listing,
258  x->p, x->xctx),
259  x->p, x->xctx);
260  }
261 
262  return result;
263 }
264 
265 
266 
267 /*
268  * Adaptive function: compile_relaxed_json
269  *
270  * afw_function_execute_compile_relaxed_json
271  *
272  * See afw_function_bindings.h for more information.
273  *
274  * Compile an adaptive relaxed JSON syntax string and return an adaptive value.
275  *
276  * This function is pure, so it will always return the same result
277  * given exactly the same parameters and has no side effects.
278  *
279  * Declaration:
280  *
281  * ```
282  * function compile_relaxed_json(
283  * json: string,
284  * listing?: any
285  * ): any;
286  * ```
287  *
288  * Parameters:
289  *
290  * json - (string) Adaptive relaxed JSON syntax string to compile.
291  *
292  * listing - (optional any dataType) If specified, a compiler listing is
293  * produced instead of an unevaluated relaxed JSON value.
294  *
295  * This parameter can be an integer between 0 and 10 of a string that is
296  * used for indentation. If 0 is specified, no whitespace is added to the
297  * resulting string. If 1 through 10 is specified, that number of spaces
298  * is used.
299  *
300  * Returns:
301  *
302  * (any dataType) An unevaluated relaxed JSON value ready for use by function
303  * evaluate() or a string containing the compiler listing.
304  */
305 const afw_value_t *
308 {
309  const afw_value_string_t *json;
310  const afw_value_t *result;
311  const afw_utf8_t *listing;
312 
314 
315  result = afw_compile_to_value(
316  &json->internal, AFW_FUNCTION_SOURCE_LOCATION,
317  afw_compile_type_relaxed_json,
318  NULL, NULL, x->p, x->xctx);
319 
321  listing = afw_function_evaluate_whitespace_parameter(x, 2);
322  result = afw_value_create_string(
323  afw_value_compiler_listing_to_string(result, listing,
324  x->p, x->xctx),
325  x->p, x->xctx);
326  }
327 
328  return result;
329 }
330 
331 
332 
333 /*
334  * Adaptive function: convert_syntax_hybrid_to_expression
335  *
336  * afw_function_execute_convert_syntax_hybrid_to_expression
337  *
338  * See afw_function_bindings.h for more information.
339  *
340  * Convert a string containing adaptive hybrid syntax, which can be an adaptive
341  * template or adaptive expression tuple, to adaptive expression syntax.
342  *
343  * This function is pure, so it will always return the same result
344  * given exactly the same parameters and has no side effects.
345  *
346  * Declaration:
347  *
348  * ```
349  * function convert_syntax_hybrid_to_expression(
350  * hybrid: string,
351  * whitespace?: any
352  * ): expression;
353  * ```
354  *
355  * Parameters:
356  *
357  * hybrid - (string) The hybrid to convert.
358  *
359  * whitespace - (optional any dataType) Add whitespace for readability if
360  * present and not 0. This parameter can be an integer between 0 and 10
361  * or a string that is used for indentation. If 0 is specified, no
362  * whitespace is added to the resulting string. If 1 through 10 is
363  * specified, that number of spaces is used.
364  *
365  * Returns:
366  *
367  * (expression) The converted value in adaptive expression syntax.
368  */
369 const afw_value_t *
372 {
373  const afw_utf8_t *s;
374  const afw_value_t *value;
375  const afw_value_string_t *hybrid;
376  const afw_utf8_t *whitespace;
377 
379  whitespace = afw_function_evaluate_whitespace_parameter(x, 2);
380 
381  value = afw_compile_to_value(
382  &hybrid->internal, AFW_FUNCTION_SOURCE_LOCATION,
383  afw_compile_type_hybrid,
384  NULL, NULL, x->p, x->xctx);
385 
386  s = afw_value_decompile_to_string(value, whitespace, x->p, x->xctx);
387 
388  return afw_value_create_string(s, x->p, x->xctx);
389 }
390 
391 
392 
393 /*
394  * Adaptive function: decompile
395  *
396  * afw_function_execute_decompile
397  *
398  * See afw_function_bindings.h for more information.
399  *
400  * Decompile an adaptive value to string.
401  *
402  * This function is pure, so it will always return the same result
403  * given exactly the same parameters and has no side effects.
404  *
405  * Declaration:
406  *
407  * ```
408  * function decompile(
409  * value: any,
410  * whitespace?: any
411  * ): string;
412  * ```
413  *
414  * Parameters:
415  *
416  * value - (any dataType) Value to decompile.
417  *
418  * whitespace - (optional any dataType) Add whitespace for readability if
419  * present and not 0. This parameter can be an integer between 0 and 10
420  * or a string that is used for indentation. If 0 is specified, no
421  * whitespace is added to the resulting string. If 1 through 10 is
422  * specified, that number of spaces is used.
423  *
424  * Returns:
425  *
426  * (string) Decompiled value.
427  */
428 const afw_value_t *
431 {
432  const afw_utf8_t *whitespace;
433  const afw_utf8_t *s;
434 
435  whitespace = afw_function_evaluate_whitespace_parameter(x, 2);
436  s = afw_value_decompile_to_string(x->argv[1], whitespace, x->p, x->xctx);
437 
438  return afw_value_create_string(s, x->p, x->xctx);
439 }
440 
441 
442 
443 /*
444  * Adaptive function: evaluate_expression_tuple
445  *
446  * afw_function_execute_evaluate_expression_tuple
447  *
448  * See afw_function_bindings.h for more information.
449  *
450  * Compile a string containing adaptive expression tuple syntax and then
451  * evaluate the result.
452  *
453  * This function is not pure, so it may return a different result
454  * given exactly the same parameters.
455  *
456  * Declaration:
457  *
458  * ```
459  * function evaluate_expression_tuple(
460  * expression_tuple: string,
461  * additionalUntrustedQualifiedVariables?: (object _AdaptiveHybridPropertiesObjects_)
462  * ): any;
463  * ```
464  *
465  * Parameters:
466  *
467  * expression_tuple - (string) Expression tuple to compile and evaluate.
468  *
469  * additionalUntrustedQualifiedVariables - (optional object
470  * _AdaptiveHybridPropertiesObjects_) This parameter supplies additional
471  * qualified variables that can be accessed during evaluation. These
472  * variables will not be used by anything that needs to ensure its
473  * qualified variables must come from a trusted source, such as
474  * authorization. This parameter is intended to be used for testing only
475  * and should not be used for anything running in production.
476  *
477  * Returns:
478  *
479  * (any dataType) Evaluated adaptive expression tuple.
480  */
481 const afw_value_t *
484 {
485  const afw_value_string_t *arg;
486  const afw_value_t *compiled;
487  const afw_value_t *value;
488 
490 
491  compiled = afw_compile_to_value(
492  &arg->internal, AFW_FUNCTION_SOURCE_LOCATION,
493  afw_compile_type_expression_tuple,
494  NULL, NULL, x->p, x->xctx);
495 
498  compiled, x->argv[2], x->p, x->xctx);
499  }
500  else {
501  value = afw_value_evaluate(compiled, x->p, x->xctx);
502  }
503 
504  return value;
505 }
506 
507 
508 
509 /*
510  * Adaptive function: evaluate_value
511  *
512  * afw_function_execute_evaluate_value
513  *
514  * See afw_function_bindings.h for more information.
515  *
516  * Evaluate an adaptive value.
517  *
518  * This function is not pure, so it may return a different result
519  * given exactly the same parameters.
520  *
521  * Declaration:
522  *
523  * ```
524  * function evaluate_value(
525  * value: any,
526  * additionalUntrustedQualifiedVariables?: (object _AdaptiveHybridPropertiesObjects_)
527  * ): any;
528  * ```
529  *
530  * Parameters:
531  *
532  * value - (any dataType)
533  *
534  * additionalUntrustedQualifiedVariables - (optional object
535  * _AdaptiveHybridPropertiesObjects_) This parameter supplies additional
536  * qualified variables that can be accessed during evaluation. These
537  * variables will not be used by anything that needs to ensure its
538  * qualified variables must come from a trusted source, such as
539  * authorization. This parameter is intended to be used for testing only
540  * and should not be used for anything running in production.
541  *
542  * Returns:
543  *
544  * (any dataType) Evaluated adaptive value.
545  */
546 const afw_value_t *
549 {
550  const afw_value_t *value;
551 
553  value =
555  x->argv[1], x->argv[2], x->p, x->xctx);
556  }
557  else {
558  value = afw_value_evaluate(x->argv[0], x->p, x->xctx);
559  }
560 
561  return value;
562 }
563 
564 
565 
566 /*
567  * Adaptive function: evaluate_with_retry
568  *
569  * afw_function_execute_evaluate_with_retry
570  *
571  * See afw_function_bindings.h for more information.
572  *
573  * Evaluate a value and retry up to a limit if an exception occurs.
574  *
575  * This function is not pure, so it may return a different result
576  * given exactly the same parameters.
577  *
578  * Declaration:
579  *
580  * ```
581  * function evaluate_with_retry(
582  * value: any,
583  * limit: integer
584  * ): any;
585  * ```
586  *
587  * Parameters:
588  *
589  * value - (any dataType) Value to evaluated.
590  *
591  * limit - (integer) Maximum number to retry if an exception occurs.
592  *
593  * Returns:
594  *
595  * (any dataType) Evaluated value.
596  */
597 const afw_value_t *
600 {
601  afw_xctx_t *xctx = x->xctx;
602  const afw_value_t *value;
603  const afw_value_integer_t *limit;
604  afw_integer_t failures;
605  afw_boolean_t success;
606 
608 
609  value = NULL;
610  failures = 0;
611 
612  /* Try to evaluate value up to limit. */
613  for (success = false; !success;) {
614 
615  AFW_TRY {
617  success = true;
618  }
619 
621  failures++;
622  if (failures > limit->internal) {
624  }
625  }
626 
627  AFW_ENDTRY;
628  }
629 
630  if (!value) {
631  AFW_THROW_ERROR_Z(general,
632  "Evaluation produced an undefined result", xctx);
633  }
634 
635  return value;
636 }
637 
638 
639 
640 /*
641  * Adaptive function: safe_evaluate
642  *
643  * afw_function_execute_safe_evaluate
644  *
645  * See afw_function_bindings.h for more information.
646  *
647  * Return the evaluated adaptive value. If an exception occurs, return
648  * evaluated error instead.
649  *
650  * This function is not pure, so it may return a different result
651  * given exactly the same parameters.
652  *
653  * Declaration:
654  *
655  * ```
656  * function safe_evaluate(
657  * value: any,
658  * error: any
659  * ): any;
660  * ```
661  *
662  * Parameters:
663  *
664  * value - (any dataType) Value to evaluated.
665  *
666  * error - (any dataType) Value to evaluate and return if exception occurs.
667  * If an error occurs evaluating this value, the exception will continue.
668  *
669  * Returns:
670  *
671  * (any dataType) Evaluated adaptive value or error value.
672  */
673 const afw_value_t *
676 {
677  afw_xctx_t *xctx = x->xctx;
678  const afw_value_t *value;
679 
680  value = NULL;
681  AFW_TRY {
683  }
684 
687  }
688 
689  AFW_ENDTRY;
690 
691  if (!value) {
692  AFW_THROW_ERROR_Z(general,
693  "Evaluation produced an undefined result", xctx);
694  }
695  return value;
696 }
697 
698 
699 
700 /*
701  * Adaptive function: stringify
702  *
703  * afw_function_execute_stringify
704  *
705  * See afw_function_bindings.h for more information.
706  *
707  * Evaluate and decompile an adaptive value to string. For most values this has
708  * the effect of producing a string containing json.
709  *
710  * This function is pure, so it will always return the same result
711  * given exactly the same parameters and has no side effects.
712  *
713  * Declaration:
714  *
715  * ```
716  * function stringify(
717  * value: any,
718  * replacer?: any,
719  * whitespace?: any
720  * ): string;
721  * ```
722  *
723  * Parameters:
724  *
725  * value - (any dataType) Value to stringify.
726  *
727  * replacer - (optional any dataType) Optional replacer function.
728  *
729  * whitespace - (optional any dataType) Add whitespace for readability if
730  * present and not 0. This parameter can be an integer between 0 and 10
731  * or a string that is used for indentation. If 0 is specified, no
732  * whitespace is added to the resulting string. If 1 through 10 is
733  * specified, that number of spaces is used.
734  *
735  * Returns:
736  *
737  * (string) Evaluated and decompiled value.
738  */
739 const afw_value_t *
742 {
743 
744  const afw_utf8_t *whitespace;
745  const afw_utf8_t *s;
746  const afw_value_t *value;
747  const afw_value_t *replacer;
748 
750 
751  if (!value) {
752  return afw_value_empty_string;
753  }
754 
756  AFW_FUNCTION_EVALUATE_PARAMETER(replacer, 2);
757  if (!afw_value_is_nullish(replacer)) {
758  AFW_THROW_ERROR_Z(general,
759  "replacer parameter is not implemented yet",
760  x->xctx);
761  }
762 
763  whitespace = NULL;
765  whitespace = afw_function_evaluate_whitespace_parameter(x, 3);
766  }
767 
768  s = afw_value_decompile_to_string(value, whitespace, x->p, x->xctx);
769 
770  return afw_value_create_string(s, x->p, x->xctx);
771 }
772 
773 
774 
775 /*
776  * Adaptive function: test_expression
777  *
778  * afw_function_execute_test_expression
779  *
780  * See afw_function_bindings.h for more information.
781  *
782  * Compile and evaluate an adaptive expression and compare the results to an
783  * expected value. Return object with the test's results.
784  *
785  * This function is not pure, so it may return a different result
786  * given exactly the same parameters.
787  *
788  * Declaration:
789  *
790  * ```
791  * function test_expression(
792  * id: string,
793  * description: string,
794  * expression: string,
795  * expected: any,
796  * additionalUntrustedQualifiedVariables?: (object _AdaptiveHybridPropertiesObjects_)
797  * ): object;
798  * ```
799  *
800  * Parameters:
801  *
802  * id - (string) Id of test.
803  *
804  * description - (string) Description of test.
805  *
806  * expression - (string) Expression to compile and evaluate.
807  *
808  * expected - (any dataType) Expected result.
809  *
810  * additionalUntrustedQualifiedVariables - (optional object
811  * _AdaptiveHybridPropertiesObjects_) This parameter supplies additional
812  * qualified variables that can be accessed during evaluation. These
813  * variables will not be used by anything that needs to ensure its
814  * qualified variables must come from a trusted source, such as
815  * authorization. This parameter is intended to be used for testing only
816  * and should not be used for anything running in production.
817  *
818  * Returns:
819  *
820  * (object) Test results.
821  */
822 const afw_value_t *
825 {
826  afw_xctx_t *xctx = x->xctx;
827  const afw_object_t *result;
828  const afw_value_string_t *id;
829  const afw_value_string_t *description;
830  const afw_value_string_t *expression;
831  const afw_value_t *expected;
832  const afw_value_t *compiled;
833  const afw_value_t *evaluated;
834 
839 
840  result = afw_object_create_managed(x->p, x->xctx);
841  afw_object_set_property(result, &afw_s_passed, afw_value_true, x->xctx);
843  &afw_s_id, &id->internal, x->xctx);
845  &afw_s_description, &description->internal, xctx);
847  &afw_s_expression, &expression->internal, xctx);
849  &afw_s_expected,
850  afw_value_as_casted_utf8(expected, x->p, x->xctx),
851  xctx);
852 
853  AFW_TRY {
854 
855  compiled = afw_compile_to_value(
856  &expression->internal, AFW_FUNCTION_SOURCE_LOCATION,
857  afw_compile_type_expression,
858  NULL, NULL, x->p, x->xctx);
859 
862  compiled, x->argv[5], x->p, x->xctx);
863  }
864  else {
865  evaluated = afw_value_evaluate(compiled, x->p, x->xctx);
866  }
867 
868  afw_object_set_property_as_string(result, &afw_s_result,
869  afw_value_as_casted_utf8(evaluated, x->p, x->xctx),
870  xctx);
871 
872  if (!afw_value_equal(evaluated, expected, xctx)) {
873  afw_object_set_property(result, &afw_s_passed, afw_value_false,
874  xctx);
875  }
876  }
877 
879 
880  /* If 'error' is not expected value, set passed false. */
881  if (!afw_value_is_string(expected) ||
883  &((const afw_value_string_t *)expected)->internal,
884  &afw_s_error))
885  {
886  afw_object_set_property(result, &afw_s_passed, afw_value_false,
887  xctx);
888  }
889 
890  /* Set error property. */
891  afw_object_set_property_as_object(result, &afw_s_error,
893  }
894 
895  AFW_ENDTRY;
896 
897  return afw_value_create_object(result, x->p, x->xctx);
898 }
899 
900 
901 
902 /*
903  * Adaptive function: test_expression_tuple
904  *
905  * afw_function_execute_test_expression_tuple
906  *
907  * See afw_function_bindings.h for more information.
908  *
909  * Compile and evaluate an adaptive expression tuple and compare the results to
910  * an expected value. Return object with the test's results.
911  *
912  * This function is not pure, so it may return a different result
913  * given exactly the same parameters.
914  *
915  * Declaration:
916  *
917  * ```
918  * function test_expression_tuple(
919  * id: string,
920  * description: string,
921  * expression: string,
922  * expected: any,
923  * additionalUntrustedQualifiedVariables?: (object _AdaptiveHybridPropertiesObjects_)
924  * ): object;
925  * ```
926  *
927  * Parameters:
928  *
929  * id - (string) Id of test.
930  *
931  * description - (string) Description of test.
932  *
933  * expression - (string) Expression tuple to compile and evaluate.
934  *
935  * expected - (any dataType) Expected result.
936  *
937  * additionalUntrustedQualifiedVariables - (optional object
938  * _AdaptiveHybridPropertiesObjects_) This parameter supplies additional
939  * qualified variables that can be accessed during evaluation. These
940  * variables will not be used by anything that needs to ensure its
941  * qualified variables must come from a trusted source, such as
942  * authorization. This parameter is intended to be used for testing only
943  * and should not be used for anything running in production.
944  *
945  * Returns:
946  *
947  * (object) Test results.
948  */
949 const afw_value_t *
952 {
953  afw_xctx_t *xctx = x->xctx;
954  const afw_object_t *result;
955  const afw_value_string_t *id;
956  const afw_value_string_t *description;
957  const afw_value_string_t *expression;
958  const afw_value_t *expected;
959  const afw_value_t *compiled;
960  const afw_value_t *evaluated;
961 
966 
967  result = afw_object_create_managed(x->p, xctx);
968  afw_object_set_property(result, &afw_s_passed, afw_value_true, xctx);
970  &afw_s_id, &id->internal, xctx);
972  &afw_s_description, &description->internal, xctx);
974  &afw_s_expression, &expression->internal, xctx);
976  &afw_s_expected,
977  afw_value_as_casted_utf8(expected, x->p, xctx),
978  xctx);
979 
980  AFW_TRY{
981 
982  compiled = afw_compile_to_value(
983  &expression->internal, AFW_FUNCTION_SOURCE_LOCATION,
984  afw_compile_type_expression_tuple,
985  NULL, NULL, x->p, xctx);
986 
989  compiled, x->argv[5], x->p, xctx);
990  }
991  else {
992  evaluated = afw_value_evaluate(compiled, x->p, xctx);
993  }
994 
995  afw_object_set_property_as_string(result, &afw_s_result,
996  afw_value_as_casted_utf8(evaluated, x->p, xctx),
997  xctx);
998 
999  if (!afw_value_equal(evaluated, expected, xctx)) {
1000  afw_object_set_property(result, &afw_s_passed, afw_value_false,
1001  xctx);
1002  }
1003  }
1004 
1006 
1007  /* If 'error' is not expected value, set passed false. */
1008  if (!afw_value_is_string(expected) ||
1009  !afw_utf8_equal(
1010  &((const afw_value_string_t *)expected)->internal,
1011  &afw_s_error))
1012  {
1013  afw_object_set_property(result, &afw_s_passed, afw_value_false,
1014  xctx);
1015  }
1016 
1017  /* Set error property. */
1018  afw_object_set_property_as_object(result, &afw_s_error,
1019  afw_error_to_object(AFW_ERROR_THROWN, x->p, xctx), xctx);
1020  }
1021 
1022  AFW_ENDTRY;
1023 
1024  return afw_value_create_object(result, x->p, xctx);
1025 }
1026 
1027 
1028 
1029 /*
1030  * Adaptive function: test_hybrid
1031  *
1032  * afw_function_execute_test_hybrid
1033  *
1034  * See afw_function_bindings.h for more information.
1035  *
1036  * Compile and evaluate a string containing adaptive hybrid syntax which can be
1037  * an adaptive template or adaptive expression tuple and then compare the
1038  * results to an expected value. Return object with the test's results.
1039  *
1040  * This function is not pure, so it may return a different result
1041  * given exactly the same parameters.
1042  *
1043  * Declaration:
1044  *
1045  * ```
1046  * function test_hybrid(
1047  * id: string,
1048  * description: string,
1049  * hybrid: string,
1050  * expected: any,
1051  * additionalUntrustedQualifiedVariables?: (object _AdaptiveHybridPropertiesObjects_)
1052  * ): object;
1053  * ```
1054  *
1055  * Parameters:
1056  *
1057  * id - (string) Id of test.
1058  *
1059  * description - (string) Description of test.
1060  *
1061  * hybrid - (string) Hybrid to compile and evaluate.
1062  *
1063  * expected - (any dataType) Expected evaluated result.
1064  *
1065  * additionalUntrustedQualifiedVariables - (optional object
1066  * _AdaptiveHybridPropertiesObjects_) This parameter supplies additional
1067  * qualified variables that can be accessed during evaluation. These
1068  * variables will not be used by anything that needs to ensure its
1069  * qualified variables must come from a trusted source, such as
1070  * authorization. This parameter is intended to be used for testing only
1071  * and should not be used for anything running in production.
1072  *
1073  * Returns:
1074  *
1075  * (object) Test results.
1076  */
1077 const afw_value_t *
1080 {
1081  afw_xctx_t *xctx = x->xctx;
1082  const afw_object_t *result;
1083  const afw_value_string_t *id;
1084  const afw_value_string_t *description;
1085  const afw_value_string_t *hybrid;
1086  const afw_value_t *expected;
1087  const afw_value_t *compiled;
1088  const afw_value_t *evaluated;
1089 
1094 
1095  result = afw_object_create_managed(x->p, xctx);
1096  afw_object_set_property(result, &afw_s_passed, afw_value_true, xctx);
1098  &afw_s_id, &id->internal, xctx);
1100  &afw_s_description, &description->internal, xctx);
1102  &afw_s_hybrid, &hybrid->internal, xctx);
1104  &afw_s_expected,
1105  afw_value_as_casted_utf8(expected, x->p, xctx),
1106  xctx);
1107 
1108  AFW_TRY {
1109 
1110  compiled = afw_compile_to_value(
1111  &hybrid->internal, AFW_FUNCTION_SOURCE_LOCATION,
1112  afw_compile_type_hybrid,
1113  NULL, NULL, x->p, xctx);
1114 
1117  compiled, x->argv[5], x->p, xctx);
1118  }
1119  else {
1120  evaluated = afw_value_evaluate(compiled, x->p, xctx);
1121  }
1122 
1123  afw_object_set_property_as_string(result, &afw_s_result,
1124  afw_value_as_casted_utf8(evaluated, x->p, x->xctx),
1125  xctx);
1126 
1127  if (!afw_value_equal(evaluated, expected, xctx)) {
1128  afw_object_set_property(result, &afw_s_passed, afw_value_false,
1129  xctx);
1130  }
1131  }
1132 
1134 
1135  /* If 'error' is not expected value, set passed false. */
1136  if (!afw_value_is_string(expected) ||
1137  !afw_utf8_equal(
1138  &((const afw_value_string_t *)expected)->internal,
1139  &afw_s_error))
1140  {
1141  afw_object_set_property(result, &afw_s_passed, afw_value_false,
1142  xctx);
1143  }
1144 
1145  /* Set error property. */
1146  afw_object_set_property_as_object(result, &afw_s_error,
1147  afw_error_to_object(AFW_ERROR_THROWN, x->p, xctx), xctx);
1148  }
1149 
1150  AFW_ENDTRY;
1151 
1152  return afw_value_create_object(result, x->p, xctx);
1153 }
1154 
1155 
1156 
1157 /*
1158  * Adaptive function: test_script
1159  *
1160  * afw_function_execute_test_script
1161  *
1162  * See afw_function_bindings.h for more information.
1163  *
1164  * Compile and evaluate an adaptive script and compare the results to an
1165  * expected value. Return object with the test's results.
1166  *
1167  * This function is not pure, so it may return a different result
1168  * given exactly the same parameters.
1169  *
1170  * Declaration:
1171  *
1172  * ```
1173  * function test_script(
1174  * id: string,
1175  * description: string,
1176  * script: string,
1177  * expected: any,
1178  * additionalUntrustedQualifiedVariables?: (object _AdaptiveHybridPropertiesObjects_)
1179  * ): object;
1180  * ```
1181  *
1182  * Parameters:
1183  *
1184  * id - (string) Id of test.
1185  *
1186  * description - (string) Description of test.
1187  *
1188  * script - (string) Script to compile and evaluate.
1189  *
1190  * expected - (any dataType) Expected result.
1191  *
1192  * additionalUntrustedQualifiedVariables - (optional object
1193  * _AdaptiveHybridPropertiesObjects_) This parameter supplies additional
1194  * qualified variables that can be accessed during evaluation. These
1195  * variables will not be used by anything that needs to ensure its
1196  * qualified variables must come from a trusted source, such as
1197  * authorization. This parameter is intended to be used for testing only
1198  * and should not be used for anything running in production.
1199  *
1200  * Returns:
1201  *
1202  * (object) Test results.
1203  */
1204 const afw_value_t *
1207 {
1208  afw_xctx_t *xctx = x->xctx;
1209  const afw_object_t *result;
1210  const afw_value_string_t *id;
1211  const afw_value_string_t *description;
1212  const afw_value_string_t *expression;
1213  const afw_value_t *expected;
1214  const afw_value_t *compiled;
1215  const afw_value_t *evaluated;
1216 
1221 
1222  result = afw_object_create_managed(x->p, xctx);
1223  afw_object_set_property(result, &afw_s_passed, afw_value_true, xctx);
1225  &afw_s_id, &id->internal, xctx);
1227  &afw_s_description, &description->internal, xctx);
1229  &afw_s_expression, &expression->internal, xctx);
1231  &afw_s_expected,
1232  afw_value_as_casted_utf8(expected, x->p, xctx),
1233  xctx);
1234 
1235  AFW_TRY{
1236 
1237  compiled = afw_compile_to_value(
1238  &expression->internal, AFW_FUNCTION_SOURCE_LOCATION,
1239  afw_compile_type_script,
1240  NULL, NULL, x->p, xctx);
1241 
1244  compiled, x->argv[5], x->p, xctx);
1245  }
1246  else {
1247  evaluated = afw_value_evaluate(compiled, x->p, xctx);
1248  }
1249 
1250  afw_object_set_property_as_string(result, &afw_s_result,
1251  afw_value_as_casted_utf8(evaluated, x->p, xctx),
1252  xctx);
1253 
1254  if (!afw_value_equal(evaluated, expected, xctx)) {
1255  afw_object_set_property(result, &afw_s_passed, afw_value_false,
1256  xctx);
1257  }
1258  }
1259 
1261 
1262  /* If 'error' is not expected value, set passed false. */
1263  if (!afw_value_is_string(expected) ||
1264  !afw_utf8_equal(
1265  &((const afw_value_string_t *)expected)->internal,
1266  &afw_s_error))
1267  {
1268  afw_object_set_property(result, &afw_s_passed, afw_value_false,
1269  xctx);
1270  }
1271 
1272  /* Set error property. */
1273  afw_object_set_property_as_object(result, &afw_s_error,
1274  afw_error_to_object(AFW_ERROR_THROWN, x->p, xctx), xctx);
1275  }
1276 
1277  AFW_ENDTRY;
1278 
1279  return afw_value_create_object(result, x->p, xctx);
1280 }
1281 
1282 
1283 
1284 /*
1285  * Adaptive function: test_template
1286  *
1287  * afw_function_execute_test_template
1288  *
1289  * See afw_function_bindings.h for more information.
1290  *
1291  * Compile and evaluate an adaptive template and compare the results to an
1292  * expected value. Return object with the test's results.
1293  *
1294  * This function is not pure, so it may return a different result
1295  * given exactly the same parameters.
1296  *
1297  * Declaration:
1298  *
1299  * ```
1300  * function test_template(
1301  * id: string,
1302  * description: string,
1303  * template: string,
1304  * expected: any,
1305  * additionalUntrustedQualifiedVariables?: (object _AdaptiveHybridPropertiesObjects_)
1306  * ): object;
1307  * ```
1308  *
1309  * Parameters:
1310  *
1311  * id - (string) Id of test.
1312  *
1313  * description - (string) Description of test.
1314  *
1315  * template - (string) Template to compile and evaluate.
1316  *
1317  * expected - (any dataType) Expected evaluated result.
1318  *
1319  * additionalUntrustedQualifiedVariables - (optional object
1320  * _AdaptiveHybridPropertiesObjects_) This parameter supplies additional
1321  * qualified variables that can be accessed during evaluation. These
1322  * variables will not be used by anything that needs to ensure its
1323  * qualified variables must come from a trusted source, such as
1324  * authorization. This parameter is intended to be used for testing only
1325  * and should not be used for anything running in production.
1326  *
1327  * Returns:
1328  *
1329  * (object) Test results.
1330  */
1331 const afw_value_t *
1334 {
1335  afw_xctx_t *xctx = x->xctx;
1336  const afw_object_t *result;
1337  const afw_value_string_t *id;
1338  const afw_value_string_t *description;
1339  const afw_value_string_t *template;
1340  const afw_value_t *expected;
1341  const afw_value_t *compiled;
1342  const afw_value_t *evaluated;
1343 
1348 
1349  result = afw_object_create_managed(x->p, xctx);
1350  afw_object_set_property(result, &afw_s_passed, afw_value_true, xctx);
1352  &afw_s_id, &id->internal, xctx);
1354  &afw_s_description, &description->internal, xctx);
1356  &afw_s_template, &template->internal, xctx);
1357 
1359  &afw_s_expected,
1360  afw_value_as_casted_utf8(expected, x->p, xctx),
1361  xctx);
1362 
1363  AFW_TRY {
1364  compiled = afw_compile_to_value(
1365  &template->internal, AFW_FUNCTION_SOURCE_LOCATION,
1366  afw_compile_type_template,
1367  NULL, NULL, x->p, xctx);
1368 
1371  compiled, x->argv[5], x->p, xctx);
1372  }
1373  else {
1374  evaluated = afw_value_evaluate(compiled, x->p, xctx);
1375  }
1376 
1377  afw_object_set_property_as_string(result, &afw_s_result,
1378  afw_value_as_casted_utf8(evaluated, x->p, xctx),
1379  xctx);
1380 
1381  if (!afw_value_equal(evaluated, expected, xctx)) {
1382  afw_object_set_property(result, &afw_s_passed, afw_value_false,
1383  xctx);
1384  }
1385  }
1386 
1388 
1389  /* If 'error' is not expected value, set passed false. */
1390  if (!afw_value_is_string(expected) ||
1391  !afw_utf8_equal(
1392  &((const afw_value_string_t *)expected)->internal,
1393  &afw_s_error))
1394  {
1395  afw_object_set_property(result, &afw_s_passed, afw_value_false,
1396  xctx);
1397  }
1398 
1399  /* Set error property. */
1400  afw_object_set_property_as_object(result, &afw_s_error,
1401  afw_error_to_object(AFW_ERROR_THROWN, x->p, xctx), xctx);
1402  }
1403 
1404  AFW_ENDTRY;
1405 
1406  return afw_value_create_object(result, x->p, xctx);
1407 }
1408 
1409 
1410 
1411 /*
1412  * Adaptive function: test_value
1413  *
1414  * afw_function_execute_test_value
1415  *
1416  * See afw_function_bindings.h for more information.
1417  *
1418  * Evaluate an adaptive value and compare it to an expected value. Return
1419  * object with the test's results.
1420  *
1421  * This function is not pure, so it may return a different result
1422  * given exactly the same parameters.
1423  *
1424  * Declaration:
1425  *
1426  * ```
1427  * function test_value(
1428  * id: string,
1429  * description: string,
1430  * value: string,
1431  * expected: any,
1432  * additionalUntrustedQualifiedVariables?: (object _AdaptiveHybridPropertiesObjects_)
1433  * ): object;
1434  * ```
1435  *
1436  * Parameters:
1437  *
1438  * id - (string) Id of test.
1439  *
1440  * description - (string) Description of test.
1441  *
1442  * value - (string) Value to evaluate.
1443  *
1444  * expected - (any dataType) Expected result.
1445  *
1446  * additionalUntrustedQualifiedVariables - (optional object
1447  * _AdaptiveHybridPropertiesObjects_) This parameter supplies additional
1448  * qualified variables that can be accessed during evaluation. These
1449  * variables will not be used by anything that needs to ensure its
1450  * qualified variables must come from a trusted source, such as
1451  * authorization. This parameter is intended to be used for testing only
1452  * and should not be used for anything running in production.
1453  *
1454  * Returns:
1455  *
1456  * (object) Test results.
1457  */
1458 const afw_value_t *
1461 {
1462  afw_xctx_t *xctx = x->xctx;
1463  const afw_object_t *result;
1464  const afw_value_string_t *id;
1465  const afw_value_string_t *description;
1466  const afw_value_t *value;
1467  const afw_value_t *expected;
1468  afw_utf8_t value_source;
1469 
1474 
1475  result = afw_object_create_managed(x->p, xctx);
1476  afw_object_set_property(result, &afw_s_passed, afw_value_true, xctx);
1478  &afw_s_id, &id->internal, xctx);
1480  &afw_s_description, &description->internal, xctx);
1481 
1483  afw_value_contextual_resolve_value_source(&value_source,
1484  ((const afw_value_call_t *)x->argv[3])->args.contextual);
1486  &afw_s_value, &value_source, xctx);
1487  }
1488 
1490  &afw_s_expected,
1491  afw_value_as_casted_utf8(expected, x->p, xctx),
1492  xctx);
1493 
1494  AFW_TRY {
1495 
1496  /* If additional context, evaluate with context ahead of time. */
1499  value, x->argv[5], x->p, xctx);
1500  }
1501 
1502  afw_object_set_property_as_string(result, &afw_s_result,
1503  afw_value_as_casted_utf8(value, x->p, xctx),
1504  xctx);
1505 
1506  if (!afw_value_equal(value, expected, xctx)) {
1507  afw_object_set_property(result, &afw_s_passed, afw_value_false,
1508  xctx);
1509  }
1510 
1511  }
1512 
1514 
1515  /* If 'error' is not expected value, set passed false. */
1516  if (!afw_value_is_string(expected) ||
1517  !afw_utf8_equal(
1518  &((const afw_value_string_t *)expected)->internal,
1519  &afw_s_error))
1520  {
1521  afw_object_set_property(result, &afw_s_passed, afw_value_false,
1522  xctx);
1523  }
1524 
1525  /* Set error property. */
1526  afw_object_set_property_as_object(result, &afw_s_error,
1527  afw_error_to_object(AFW_ERROR_THROWN, x->p, xctx), xctx);
1528  }
1529 
1530  AFW_ENDTRY;
1531 
1532  return afw_value_create_object(result, x->p, xctx);
1533 }
1534 
1535 
1536 
1537 /*
1538  * Adaptive function: qualifier
1539  *
1540  * afw_function_execute_qualifier
1541  *
1542  * See afw_function_bindings.h for more information.
1543  *
1544  * This function allows the active variables for a qualifier to be accessed as
1545  * the properties of an object.
1546  *
1547  * This function is not pure, so it may return a different result
1548  * given exactly the same parameters.
1549  *
1550  * Declaration:
1551  *
1552  * ```
1553  * function qualifier(
1554  * qualifier: string,
1555  * forTesting?: boolean
1556  * ): object;
1557  * ```
1558  *
1559  * Parameters:
1560  *
1561  * qualifier - (string) This is the qualifier whose variables are to be
1562  * accessed as properties of the returned object.
1563  *
1564  * forTesting - (optional boolean) If specified and true, the object returned
1565  * will be suitable to pass as the additionalUntrustedQualifiedVariables
1566  * parameter of evaluate*() functions. This is intended for testing
1567  * purposes and should not be used in production.
1568  *
1569  * Returns:
1570  *
1571  * (object) Each property is the name of a variable with the value influenced
1572  * by the forTesting property.
1573  */
1574 const afw_value_t *
1577 {
1578  const afw_value_string_t *qualifier;
1579  const afw_value_boolean_t *forTesting;
1580  const afw_object_t *object;
1581 
1583  1, string);
1585  2, boolean);
1586 
1588  &qualifier->internal,
1589  (forTesting && forTesting->internal),
1590  x->p, x->xctx);
1591 
1592  return afw_value_create_object(object, x->p, x->xctx);
1593 }
1594 
1595 
1596 
1597 /*
1598  * Adaptive function: qualifiers
1599  *
1600  * afw_function_execute_qualifiers
1601  *
1602  * See afw_function_bindings.h for more information.
1603  *
1604  * This function allows the active qualifiers to be accessed as properties of
1605  * an object. The value of each of these properties is an object whose
1606  * properties are the variables for the corresponding qualifier.
1607  *
1608  * This function is not pure, so it may return a different result
1609  * given exactly the same parameters.
1610  *
1611  * Declaration:
1612  *
1613  * ```
1614  * function qualifiers(
1615  * forTesting?: boolean
1616  * ): object;
1617  * ```
1618  *
1619  * Parameters:
1620  *
1621  * forTesting - (optional boolean) If specified and true, the object returned
1622  * will be suitable to pass as the additionalUntrustedQualifiedVariables
1623  * parameter of evaluate*() functions. This is intended for testing
1624  * purposes and should not be used in production.
1625  *
1626  * Returns:
1627  *
1628  * (object) Each property is the name of a qualifier with a value that is an
1629  * object whose properties are the variables of that qualifier. The value
1630  * of the variable properties is influenced by the forTesting property.
1631  */
1632 const afw_value_t *
1635 {
1636  const afw_value_boolean_t *forTesting;
1637  const afw_object_t *object;
1638 
1640  1, boolean);
1641 
1643  (forTesting && forTesting->internal),
1644  x->p, x->xctx);
1645 
1646  return afw_value_create_object(object, x->p, x->xctx);
1647 }
1648 
1649 
1650 
1651 /*
1652  * Adaptive function: test_script_runtime_support
1653  *
1654  * afw_function_execute_test_script_runtime_support
1655  *
1656  * See afw_function_bindings.h for more information.
1657  *
1658  * This is a function called internally as the result of a test_script compile.
1659  * This function is not intended to be called directly.
1660  *
1661  * This function is not pure, so it may return a different result
1662  * given exactly the same parameters and has side effects.
1663  *
1664  * Declaration:
1665  *
1666  * ```
1667  * function test_script_runtime_support(
1668  * testScriptObject: (object _AdaptiveTestScriptResult_)
1669  * ): (object _AdaptiveTestScriptResult_);
1670  * ```
1671  *
1672  * Parameters:
1673  *
1674  * testScriptObject - (object _AdaptiveTestScriptResult_) A test script
1675  * results object with the required evaluation result properties missing.
1676  * The sources will be evaluated and the corresponding test result
1677  * properties will be set.
1678  *
1679  * Returns:
1680  *
1681  * (object _AdaptiveTestScriptResult_) The testScriptObject object with test
1682  * result properties set.
1683  */
1684 const afw_value_t *
1687 {
1688  afw_xctx_t *xctx = x->xctx;
1689  const afw_value_object_t *testScriptObject;
1690  const afw_iterator_t *iterator;
1691  const afw_list_t *tests;
1692  const afw_object_t *test;
1693  const afw_value_t *value;
1694  const afw_utf8_t *default_source_type;
1695  const afw_utf8_t *source_type;
1696  const afw_utf8_t *source;
1697  const afw_utf8_t *expect;
1698  const afw_utf8_t *sourceLocation;
1699  const afw_value_t *expected_value;
1700  const afw_value_t *compiled_value;
1701  const afw_value_t *evaluated_value;
1702  const afw_object_t *test_script;
1703  const afw_value_t *passed_value;
1704  const afw_utf8_t *errorReason;
1705  const afw_compile_type_info_t *info;
1706  afw_compile_value_contextual_t *contextual;
1707  const afw_value_t *argv[2];
1708  afw_integer_t expectUTF8OctetLengthInTestScript;
1709  afw_integer_t expectUTF8OctetOffsetInTestScript;
1710  afw_integer_t sourceUTF8OctetOffsetInTestScript;
1711  afw_integer_t sourceUTF8OctetLengthInTestScript;
1712  afw_utf8_t expect_message;
1713 
1714  enum {
1715  error_in_other,
1716  error_in_compile_expect,
1717  error_in_evaluate_expect,
1718  error_in_compile_source,
1719  error_in_evaluate_source
1720  } error_in;
1721 
1722  afw_boolean_t found;
1723 
1725  1, object);
1726 
1727  test_script = testScriptObject->internal;
1728  tests = afw_object_old_get_property_as_list(test_script,
1729  &afw_s_tests, xctx);
1730  default_source_type = afw_object_old_get_property_as_string(
1731  test_script, &afw_s_sourceType, xctx);
1732  if (!default_source_type) {
1733  default_source_type = &afw_s_script;
1734  }
1735  for (iterator = NULL;;) {
1736  value = afw_list_get_next_value(tests, &iterator, x->p, xctx);
1737  if (!value) {
1738  break;
1739  }
1740  test = afw_value_as_object(value, xctx);
1741  source_type = afw_object_old_get_property_as_string(test,
1742  &afw_s_sourceType, xctx);
1743  if (!source_type) {
1744  source_type = default_source_type;
1745  }
1746  info = afw_compile_type_get_info_by_pneumonic(source_type, xctx);
1747 
1749  &afw_s_expect, xctx);
1750  if (!expect) {
1751  AFW_THROW_ERROR_Z(general, "expect required", xctx);
1752  }
1753 
1754  expectUTF8OctetLengthInTestScript = afw_object_old_get_property_as_integer(
1755  test, &afw_s_expectUTF8OctetLengthInTestScript, &found, xctx);
1756  if (!found) {
1757  AFW_THROW_ERROR_Z(code, "Internal error", xctx);
1758  }
1759  expectUTF8OctetOffsetInTestScript = afw_object_old_get_property_as_integer(
1760  test, &afw_s_expectUTF8OctetOffsetInTestScript, &found, xctx);
1761  if (!found) {
1762  AFW_THROW_ERROR_Z(code, "Internal error", xctx);
1763  }
1764 
1766  &afw_s_source, xctx);
1767  if (!source) {
1768  AFW_THROW_ERROR_Z(general, "source required", xctx);
1769  }
1770  sourceLocation = afw_object_old_get_property_as_string(test,
1771  &afw_s_sourceLocation, xctx);
1772  if (!sourceLocation) {
1773  sourceLocation = &afw_s_test_script;
1774  }
1775  sourceUTF8OctetOffsetInTestScript = afw_object_old_get_property_as_integer(
1776  test, &afw_s_sourceUTF8OctetOffsetInTestScript, &found, xctx);
1777  if (!found) {
1778  AFW_THROW_ERROR_Z(code, "Internal error", xctx);
1779  }
1780  sourceUTF8OctetLengthInTestScript = afw_object_old_get_property_as_integer(
1781  test, &afw_s_sourceUTF8OctetLengthInTestScript, &found, xctx);
1782  if (!found) {
1783  AFW_THROW_ERROR_Z(code, "Internal error", xctx);
1784  }
1785 
1786  /* Skip processing test is requested. */
1788  &afw_s_skip, &found, xctx))
1789  {
1790  continue;
1791  }
1792 
1793  if (info->compile_type == afw_compile_type_error) {
1794  AFW_THROW_ERROR_FZ(general, xctx,
1795  "source_type=%" AFW_UTF8_FMT " is invalid",
1796  AFW_UTF8_FMT_ARG(source_type));
1797  }
1798 
1799  AFW_TRY{
1800  error_in = error_in_other;
1801  if (afw_utf8_starts_with(expect, &afw_s_error)) {
1802  expected_value = NULL;
1803  }
1804  else {
1805  error_in = error_in_compile_expect;
1806  contextual = afw_pool_calloc_type(x->p,
1808  afw_memory_copy(contextual, x->self->args.contextual);
1810  expectUTF8OctetOffsetInTestScript, xctx);
1812  expectUTF8OctetLengthInTestScript, xctx);
1813  value = afw_value_create_string(expect, x->p, xctx);
1814  argv[0] = (const afw_value_t *)info->compile_function;
1815  argv[1] = afw_value_convert(value, info->data_type, true,
1816  x->p, xctx);
1817  compiled_value = afw_value_call_built_in_function(
1818  contextual, info->compile_function, 1, argv, x->p, xctx);
1819  error_in = error_in_evaluate_expect;
1820  expected_value = afw_value_evaluate(compiled_value,
1821  x->p, xctx);
1822  }
1823 
1824  error_in = error_in_compile_source;
1825  contextual = afw_pool_calloc_type(x->p,
1827  afw_memory_copy(contextual, x->self->args.contextual);
1829  sourceUTF8OctetOffsetInTestScript, xctx);
1831  sourceUTF8OctetLengthInTestScript, xctx);
1832  value = afw_value_create_string(source, x->p, xctx);
1833  argv[0] = (const afw_value_t *)info->compile_function;
1834  argv[1] = afw_value_convert(value, info->data_type, true,
1835  x->p, xctx);
1836  compiled_value = afw_value_call_built_in_function(
1837  contextual, info->compile_function, 1, argv, x->p, xctx);
1838  error_in = error_in_evaluate_source;
1839  evaluated_value = afw_value_evaluate(compiled_value,
1840  x->p, xctx);
1841  error_in = error_in_other;
1842 
1843  afw_object_set_property(test, &afw_s_result,
1844  evaluated_value, xctx);
1845 
1846  afw_object_set_property(test, &afw_s_passed,
1848  xctx);
1849 
1850  passed_value =
1851  expected_value &&
1852  afw_value_equal(evaluated_value, expected_value, xctx)
1853  ? afw_value_true
1854  : afw_value_false;
1855  afw_object_set_property(test, &afw_s_passed, passed_value,
1856  xctx);
1857  }
1858 
1860 
1861  afw_boolean_t expected_error;
1862 
1863  /* If 'error' is not expected value, set passed false. */
1864  expected_error = false;
1865  if (afw_utf8_starts_with(expect, &afw_s_error)) {
1866  if (expect->len == afw_s_error.len) {
1867  expected_error = true;
1868  }
1869  else {
1870  expect_message.s = expect->s + afw_s_error.len + 1;
1871  expect_message.len = expect->len - afw_s_error.len - 1;
1872  if (strlen(AFW_ERROR_THROWN->message_z) == expect_message.len &&
1873  memcmp(expect_message.s, AFW_ERROR_THROWN->message_z,
1874  expect_message.len) == 0)
1875  {
1876  expected_error = true;
1877  }
1878  }
1879  }
1880 
1881  /* Set passed only if this is an expected error. */
1882  passed_value =
1883  expected_error
1884  ? afw_value_true
1885  : afw_value_false;
1886  afw_object_set_property(test, &afw_s_passed, passed_value, xctx);
1887 
1888  /* errorReason */
1889  switch (error_in) {
1890  case error_in_compile_expect:
1891  errorReason = &afw_s_a_compile_expect_error;
1892  break;
1893 
1894  case error_in_evaluate_expect:
1895  errorReason = &afw_s_a_evaluate_expect_error;
1896  break;
1897 
1898  case error_in_compile_source:
1899  errorReason = &afw_s_a_compile_source_error;
1900  break;
1901 
1902  case error_in_evaluate_source:
1903  errorReason = &afw_s_a_evaluate_source_error;
1904  break;
1905 
1906  default:
1907  errorReason = &afw_s_a_other_error;
1908  break;
1909  };
1911  &afw_s_errorReason, errorReason, xctx);
1912 
1913  /* Set error property. */
1914  afw_object_set_property_as_object(test, &afw_s_error,
1915  afw_error_to_object(AFW_ERROR_THROWN, x->p, xctx), xctx);
1916  }
1917 
1918  AFW_ENDTRY;
1919  }
1920 
1921  return (const afw_value_t *)testScriptObject;
1922 }
AFW_DEFINE(const afw_object_t *)
Adaptive Framework Core Internal.
#define afw_value_is_boolean(A_VALUE)
Macro to determine if value is evaluated boolean.
#define afw_object_old_get_property_as_boolean(object, property_name, found, xctx)
Get property function for data type boolean value.
#define afw_object_old_get_property_as_integer(object, property_name, found, xctx)
Get property function for data type integer value.
#define afw_value_is_integer(A_VALUE)
Macro to determine if value is evaluated integer.
#define afw_object_old_get_property_as_list(object, property_name, xctx)
Get property function for data type list value.
afw_object_set_property_as_object(const afw_object_t *object, const afw_utf8_t *property_name, const afw_object_t *internal, afw_xctx_t *xctx)
Set property function for data type object values.
afw_value_create_object(const afw_object_t *internal, const afw_pool_t *p, afw_xctx_t *xctx)
Create function for unmanaged data type object value.
afw_value_as_object(const afw_value_t *value, afw_xctx_t *xctx)
Typesafe cast of data type object.
afw_value_create_string(const afw_utf8_t *internal, const afw_pool_t *p, afw_xctx_t *xctx)
Create function for unmanaged data type string value.
#define afw_object_old_get_property_as_string(object, property_name, xctx)
Get property function for data type string value.
#define afw_value_is_string(A_VALUE)
Macro to determine if value is evaluated string.
afw_object_set_property_as_string(const afw_object_t *object, const afw_utf8_t *property_name, const afw_utf8_t *internal, afw_xctx_t *xctx)
Set property function for data type string values.
#define AFW_UTF8_FMT_ARG(A_STRING)
Convenience Macro for use with AFW_UTF8_FMT to specify arg.
Definition: afw_common.h:605
struct afw_iterator_s afw_iterator_t
_Bool afw_boolean_t
Definition: afw_common.h:373
#define AFW_UTF8_FMT
Format string specifier used for afw_utf8_t.
Definition: afw_common.h:588
apr_size_t afw_size_t
size_t.
Definition: afw_common.h:151
#define AFW_SIZE_T_FMT
Format string specifier used for afw_size_t.
Definition: afw_common.h:341
apr_int64_t afw_integer_t
typedef for big signed int.
Definition: afw_common.h:321
#define afw_compile_to_value(string, source_location, compile_type, parent, shared, p, xctx)
Compile string to adaptive value.
Definition: afw_compile.h:189
afw_compile_type_get_info_by_pneumonic(const afw_utf8_t *pneumonic, const afw_xctx_t *xctx)
Return compile type info for a pneumonic.
Definition: afw_compile.c:97
#define AFW_CATCH_UNHANDLED
Catch an unhandled error that occurs in a AFW_TRY block.
Definition: afw_error.h:684
#define AFW_ENDTRY
Ends an AFW try block.
Definition: afw_error.h:727
#define AFW_TRY
Begin an AFW TRY block.
Definition: afw_error.h:634
#define AFW_THROW_ERROR_FZ(code, xctx, format_z,...)
Macro used to set error and 0 rv in xctx and throw it.
Definition: afw_error.h:319
#define AFW_MARK_UNHANDLED
Use in an AFW_CATCH or AFW_CATCH_UNHANDLED block to mark error as unhandled and break.
Definition: afw_error.h:750
const afw_object_t * afw_error_to_object(const afw_error_t *error, const afw_pool_t *p, afw_xctx_t *xctx)
Create an object with error info in specified pool.
Definition: afw_error.c:998
#define AFW_ERROR_THROWN
Access the thrown error. See AFW_TRY.
Definition: afw_error.h:554
#define AFW_THROW_ERROR_Z(code, message_z, xctx)
Macro used to set error and 0 rv in xctx and throw it.
Definition: afw_error.h:283
#define AFW_FUNCTION_EVALUATE_DATA_TYPE_PARAMETER(A_RESULT, A_N, A_TYPE)
Evaluate an arg for a particular data type.
Definition: afw_function.h:261
#define AFW_FUNCTION_SOURCE_LOCATION
Source location of a value.
Definition: afw_function.h:341
#define AFW_FUNCTION_EVALUATE_REQUIRED_DATA_TYPE_PARAMETER(A_RESULT, A_N, A_TYPE)
Evaluate an arg for a particular data type.
Definition: afw_function.h:328
#define AFW_FUNCTION_ARGV(A_N)
Get the unevaluated argv value or NULL.
Definition: afw_function.h:159
#define AFW_FUNCTION_PARAMETER_IS_PRESENT(A_N)
Determine if a specific parameter value is present.
Definition: afw_function.h:242
#define AFW_FUNCTION_EVALUATE_PARAMETER(A_RESULT, A_N)
Evaluate a parameter.
Definition: afw_function.h:279
#define AFW_FUNCTION_EVALUATE_REQUIRED_PARAMETER(A_RESULT, A_N)
Evaluate an required parameter.
Definition: afw_function.h:295
const afw_value_t * afw_function_execute_compile_relaxed_json(afw_function_execute_t *x)
Adaptive Function compile_relaxed_json
const afw_value_t * afw_function_execute_assert(afw_function_execute_t *x)
Adaptive Function assert
const afw_value_t * afw_function_execute_stringify(afw_function_execute_t *x)
Adaptive Function stringify
const afw_value_t * afw_function_execute_evaluate_with_retry(afw_function_execute_t *x)
Adaptive Function evaluate_with_retry
const afw_value_t * afw_function_execute_test_expression(afw_function_execute_t *x)
Adaptive Function test_expression
const afw_value_t * afw_function_execute_compile_expression_tuple(afw_function_execute_t *x)
Adaptive Function compile_expression_tuple
const afw_value_t * afw_function_execute_test_hybrid(afw_function_execute_t *x)
Adaptive Function test_hybrid
const afw_value_t * afw_function_execute_decompile(afw_function_execute_t *x)
Adaptive Function decompile
const afw_value_t * afw_function_execute_test_template(afw_function_execute_t *x)
Adaptive Function test_template
const afw_value_t * afw_function_execute_evaluate_expression_tuple(afw_function_execute_t *x)
Adaptive Function evaluate_expression_tuple
const afw_value_t * afw_function_execute_convert_syntax_hybrid_to_expression(afw_function_execute_t *x)
Adaptive Function convert_syntax_hybrid_to_expression
const afw_value_t * afw_function_execute_compile_json(afw_function_execute_t *x)
Adaptive Function compile_json
const afw_value_t * afw_function_execute_safe_evaluate(afw_function_execute_t *x)
Adaptive Function safe_evaluate
const afw_value_t * afw_function_execute_test_script(afw_function_execute_t *x)
Adaptive Function test_script
const afw_value_t * afw_function_execute_evaluate_value(afw_function_execute_t *x)
Adaptive Function evaluate_value
const afw_value_t * afw_function_execute_qualifiers(afw_function_execute_t *x)
Adaptive Function qualifiers
const afw_value_t * afw_function_execute_test_expression_tuple(afw_function_execute_t *x)
Adaptive Function test_expression_tuple
const afw_value_t * afw_function_execute_qualifier(afw_function_execute_t *x)
Adaptive Function qualifier
const afw_value_t * afw_function_execute_test_value(afw_function_execute_t *x)
Adaptive Function test_value
const afw_value_t * afw_function_execute_test_script_runtime_support(afw_function_execute_t *x)
Adaptive Function test_script_runtime_support
const afw_utf8_t * afw_json_from_value(const afw_value_t *value, const afw_object_options_t *options, const afw_pool_t *p, afw_xctx_t *xctx)
Convert an adaptive value to JSON.
#define afw_list_get_next_value(instance, iterator, p, xctx)
Call method get_next_value of interface afw_list.
#define afw_memory_copy(to, from)
Copy to preallocated memory of same type.
Definition: afw_memory.h:39
#define afw_object_create_managed(p, xctx)
Create an empty entity object in its own pool.
Definition: afw_object.h:913
afw_object_set_property(const afw_object_t *instance, const afw_utf8_t *property_name, const afw_value_t *value, afw_xctx_t *xctx)
Set the value of an object's property.
Definition: afw_object.c:46
#define afw_pool_calloc_type(instance, type, xctx)
Macro to allocate cleared memory to hold type in pool.
Definition: afw_pool.h:167
afw_size_t afw_safe_cast_integer_to_size(afw_integer_t integer, afw_xctx_t *xctx)
Safely cast afw_integer_t to afw_size_t.
Definition: afw_safe_cast.h:68
afw_boolean_t afw_utf8_equal(const afw_utf8_t *s1, const afw_utf8_t *s2)
Check to see if a string equals another string.
afw_boolean_t afw_utf8_starts_with(const afw_utf8_t *string, const afw_utf8_t *starts_with)
Check to see if a string starts with another string.
#define afw_utf8_create(s, len, p, xctx)
Create utf-8 string without copy unless necessary in pool specified.
Definition: afw_utf8.h:239
afw_value_compiler_listing_to_string(const afw_value_t *value, const afw_utf8_t *tab, const afw_pool_t *p, afw_xctx_t *xctx)
Decompile a value to a compiler listing string.
#define afw_value_evaluate(value, p, xctx)
Evaluate value if needed using specific pool.
Definition: afw_value.h:841
afw_value_equal(const afw_value_t *value1, const afw_value_t *value2, afw_xctx_t *xctx)
Test whether two values are equal.
Definition: afw_value.c:851
const afw_utf8_t * afw_value_decompile_to_string(const afw_value_t *value, const afw_utf8_t *tab, const afw_pool_t *p, afw_xctx_t *xctx)
Decompile a value to a string.
afw_value_false
Adaptive value false.
Definition: afw_value.h:354
#define afw_value_is_nullish(A_VALUE)
Determine if value is undefined or null.
Definition: afw_value.h:422
afw_value_empty_string
Adaptive value empty string.
Definition: afw_value.h:342
afw_value_convert(const afw_value_t *value, const afw_data_type_t *to_data_type, afw_boolean_t required, const afw_pool_t *p, afw_xctx_t *xctx)
Convert a value to a value/data type.
Definition: afw_value.c:584
afw_value_as_casted_utf8(const afw_value_t *value, const afw_pool_t *p, afw_xctx_t *xctx)
Convert value to casted utf8 in specified pool.
Definition: afw_value.c:334
afw_value_evaluate_with_additional_untrusted_qualified_variables(const afw_value_t *value, const afw_value_t *untrusted_qualified_variables, const afw_pool_t *p, afw_xctx_t *xctx)
Evaluate a value with additional insecure context.
Definition: afw_value.c:534
afw_value_null
Adaptive value null.
Definition: afw_value.h:320
#define afw_value_is_any_call(A_VALUE)
Macro to determine if value is a call.
Definition: afw_value.h:572
afw_value_true
Adaptive value true.
Definition: afw_value.h:348
afw_xctx_qualifiers_object_create(afw_boolean_t for_testing, const afw_pool_t *p, afw_xctx_t *xctx)
Create object to access active qualified variables.
afw_xctx_qualifier_object_create(const afw_utf8_t *qualifier, afw_boolean_t for_testing, const afw_pool_t *p, afw_xctx_t *xctx)
Create object to access active variables for a qualifier.
Contextual information provided in some values.
afw_size_t value_size
Size in full_source of value source.
afw_size_t value_offset
Offset in full source of compiled value to this value.
Struc for afw_compile_type_info_t.
Definition: afw_compile.h:30
Function execute parameter.
Definition: afw_function.h:53
const afw_value_t *const * argv
This is the function parameters.
Definition: afw_function.h:86
afw_xctx_t * xctx
The execution context (xctx) of caller.
Definition: afw_function.h:62
const afw_pool_t * p
Pool for result.
Definition: afw_function.h:59
const afw_value_call_built_in_function_t * self
self of call_built_in_function.
Definition: afw_function.h:56
Interface afw_list public struct.
Interface afw_object public struct.
NFC normalized UTF-8 string.
Definition: afw_common.h:545
struct for data type boolean values.
const afw_compile_value_contextual_t * contextual
Struct for call value.
struct for data type integer values.
struct for data type list values.
struct for data type object values.
Interface afw_value public struct.
struct for data type string values.
Interface afw_xctx public struct.