Adaptive Framework  0.9.0
All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
afw_value.c
Go to the documentation of this file.
1 // See the 'COPYING' file in the project root for licensing information.
2 /*
3  * Adaptive Framework Value Functions
4  *
5  * Copyright (c) 2010-2023 Clemson University
6  *
7  */
8 
14 #include "afw_internal.h"
15 #include <libxml/xmlregexp.h>
16 
17 
18 
19 static const afw_utf8_t impl_s_a_quote = AFW_UTF8_LITERAL("\"");
20 
21 static const afw_value_null_t
22 impl_value_null = {
24  NULL
25 };
26 
29 { (const afw_value_t *)&impl_value_null };
30 
31 static const afw_value_string_t
32 impl_value_undefined_string = {
34  AFW_UTF8_LITERAL("<undefined>")
35 };
36 
39 { (const afw_value_t *)&impl_value_undefined_string };
40 
41 static const afw_value_string_t
42 impl_value_empty_string = {
45 };
46 
49 { (const afw_value_t *)&impl_value_empty_string };
50 
51 static const afw_value_boolean_t
52 impl_value_true = {
54  AFW_TRUE
55 };
56 
59 { (const afw_value_t *)&impl_value_true };
60 
61 static const afw_value_boolean_t
62 impl_value_false = {
64  AFW_FALSE
65 };
66 
69 { (const afw_value_t *)&impl_value_false };
70 
71 
72 /* Compile a value. */
73 AFW_DEFINE(const afw_value_t *)
75  const afw_value_t *value,
76  const afw_utf8_t *source_location,
77  const afw_pool_t *p,
78  afw_xctx_t *xctx)
79 {
80  const afw_value_t *evaluated;
81  const afw_value_t *compiled_value;
82  const afw_data_type_t *data_type;
83  const afw_utf8_t *source;
84 
85  evaluated = afw_value_evaluate(value, p, xctx);
86  data_type = afw_value_get_data_type(evaluated, xctx);
87  if (!data_type || data_type->compile_type == afw_compile_type_error)
88  {
89  AFW_THROW_ERROR_Z(general, "Value can not be compiled", xctx);
90  }
91  source = &((const afw_value_string_t *)evaluated)->internal;
92  compiled_value = afw_compile_to_value_with_callback(
93  source, NULL, NULL,
94  source_location, data_type->compile_type,
95  afw_compile_residual_check_to_full, \
96  NULL, NULL, p, xctx);
97 
98  return compiled_value;
99 }
100 
101 
102 /* Compile a value using specified compile type. */
103 AFW_DEFINE(const afw_value_t *)
105  const afw_value_t *value,
106  const afw_utf8_t *source_location,
107  afw_compile_type_t compile_type,
108  const afw_pool_t *p,
109  afw_xctx_t *xctx)
110 {
111  const afw_value_t *evaluated;
112  const afw_value_t *compiled_value;
113  const afw_data_type_t *data_type;
114  const afw_utf8_t *source;
115 
116  /* Compile type must match passed or be string*/
117  evaluated = afw_value_evaluate(value, p, xctx);
118  data_type = afw_value_get_data_type(evaluated, xctx);
119  if (!afw_data_type_is_string(data_type)) {
120  if (!data_type || data_type->compile_type != compile_type )
121  {
122  AFW_THROW_ERROR_Z(general,
123  "Value data type does not match compile_type", xctx);
124  }
125  }
126 
127  /* All data types with a compile type must have afw_utf8_t source. */
128  source = &((const afw_value_string_t *)evaluated)->internal;
129 
130  /* Compile source. */
131  compiled_value = afw_compile_to_value_with_callback(
132  source, NULL, NULL,
133  source_location, compile_type,
134  afw_compile_residual_check_to_full, \
135  NULL, NULL, p, xctx);
136 
137  return compiled_value;
138 }
139 
140 
141 
142 
143 /* Compile and evaluate a value. */
144 AFW_DEFINE(const afw_value_t *)
146  const afw_value_t *value,
147  const afw_utf8_t *source_location,
148  const afw_pool_t *p,
149  afw_xctx_t *xctx)
150 {
151  const afw_value_t *compiled_value;
152  const afw_value_t *result;
153 
154  compiled_value = afw_value_compile(value, source_location, p, xctx);
155  result = afw_value_evaluate(compiled_value, p, xctx);
156 
157  return result;
158 }
159 
160 
161 
162 
163 /* Compile and evaluate a value using specified compile type. */
164 AFW_DEFINE(const afw_value_t *)
166  const afw_value_t *value,
167  const afw_utf8_t *source_location,
168  afw_compile_type_t compile_type,
169  const afw_pool_t *p,
170  afw_xctx_t *xctx)
171 {
172  const afw_value_t *compiled_value;
173  const afw_value_t *result;
174 
175  compiled_value = afw_value_compile_as(value, source_location, compile_type,
176  p, xctx);
177  result = afw_value_evaluate(compiled_value, p, xctx);
178 
179  return result;
180 }
181 
182 
183 
184 /* Return undecorated value. */
185 AFW_DEFINE(const afw_value_t *)
187 {
188  AFW_VALUE_UNDECORATE(value)
189 
190  return value;
191 }
192 
193 
194 
195 /* Determine if value's undecorated inf is the supplied one. */
198  const afw_value_t *value,
199  const afw_value_inf_t *inf)
200 {
201  if (!value) return false;
202 
203  if (value->inf == &afw_value_compiled_value_inf) {
204  value = ((const afw_value_compiled_value_t *)value)->root_value;
205  }
206 
207  if (value->inf == &afw_value_annotated_inf) {
208  value = ((const afw_value_annotated_t *)value)->value;
209  }
210 
211  return value->inf == inf;
212 }
213 
214 
215 
216 /* Determine if value and all of it contained values are evaluated. */
219  const afw_value_t *value,
220  afw_xctx_t *xctx)
221 {
222  afw_boolean_t result;
223  const afw_iterator_t *iterator;
224  const afw_utf8_t *property_name;
225  const afw_value_t *v;
226 
227  result = true;
228 
230  result = false;
231  }
232 
233  else if (afw_value_is_object(value))
234  {
235  for (iterator = NULL;;) {
237  ((const afw_value_object_t *)value)->internal,
238  &iterator, &property_name, xctx);
239  if (!v) {
240  break;
241  }
242  if (!afw_value_is_fully_evaluated(v, xctx)) {
243  result = false;
244  break;
245  }
246  }
247  }
248 
249  else if (afw_value_is_list(value))
250  {
251  for (iterator = NULL;;) {
253  ((const afw_value_list_t *)value)->internal,
254  &iterator, xctx->p, xctx);
255  if (!v) {
256  break;
257  }
258  if (!afw_value_is_fully_evaluated(v, xctx)) {
259  result = false;
260  break;
261  }
262  }
263  }
264 
265  return result;
266 }
267 
268 
269 /* Determine if value is scalar. */
272 {
273  const afw_data_type_t *data_type;
274 
275  data_type = afw_value_get_data_type(value, xctx);
276  return (data_type) ? data_type->scalar : false;
277 };
278 
279 
280 /* Clone a value to specified pool. */
281 AFW_DEFINE(const afw_value_t *)
283  const afw_pool_t *p, afw_xctx_t *xctx)
284 {
285  afw_value_evaluated_t *evaluated;
286  const afw_value_t *result;
287  const afw_data_type_t *data_type;
288 
289  data_type = afw_value_get_data_type(value, xctx);
290 
291  /* Evaluated value clone. */
293  evaluated = afw_value_evaluated_allocate(data_type, p, xctx);
294  result = (const afw_value_t *)evaluated;
296  (void *)&evaluated->internal,
297  (const void *)&((const afw_value_evaluated_t *)value)->internal,
298  p, xctx);
299  }
300 
301  /* Other values not supported. */
302  else {
303  AFW_THROW_ERROR_Z(general,
304  "Can only clone an evaluated value", xctx);
305  }
306 
307  /* Return result. */
308  return result;
309 }
310 
311 
312 
313 /* Convert value->internal to afw_utf8_z_t * */
314 AFW_DEFINE(const afw_utf8_z_t *)
316  const afw_pool_t *p, afw_xctx_t *xctx)
317 {
318  const afw_utf8_t *string;
319  const afw_utf8_z_t *result;
320 
321  result = NULL;
322  string = afw_value_as_utf8(value, p, xctx);
323  if (string) {
324  result = afw_utf8_z_create(string->s, string->len, p, xctx);
325  }
326 
327  /* Return result or NULL if invalid. */
328  return result;
329 }
330 
331 
332 /* Convert value to casted utf8 in specified pool. */
333 AFW_DEFINE(const afw_utf8_t *)
335  const afw_value_t *value, const afw_pool_t *p, afw_xctx_t *xctx)
336 {
337  const afw_utf8_t *result;
338  const afw_data_type_t *data_type;
339  const afw_utf8_t * const *s;
340  afw_size_t n;
341  afw_size_t len;
342  afw_utf8_octet_t *c;
343 
344  value = afw_value_evaluate(value, p, xctx);
345  if (!value) {
346  return NULL;
347  }
348  data_type = afw_value_get_data_type(value, xctx);
349 
351  if (afw_value_is_list(value)) {
352  s = afw_value_as_array_of_utf8(value, p, xctx);
353 
354  if (!s[0]) {
355  len = 5; /* "bag()" */
356  }
357  else {
358  for (n = 0, len = 3 /* "bag" */; s[n]; n++) {
359  /*
360  * '<datatype>("<string value>") plus surrounding '()' for bag
361  * or ', '
362  */
363  len += s[n]->len + 6 + data_type->data_type_id.len;
364  }
365  }
366 
367  c = afw_pool_calloc(p, len, xctx);
368  result = afw_utf8_create(c, len, p, xctx);
369 
370  memcpy(c, "bag(", 4);
371  c += 4;
372 
373  for (n = 0; s[n]; n++) {
374  if (n != 0) {
375  *c++ = ',';
376  *c++ = ' ';
377  }
378  memcpy(c, data_type->data_type_id.s,
379  data_type->data_type_id.len);
380  c += data_type->data_type_id.len;
381  *c++ = '(';
382  *c++ = '\"';
383  memcpy(c, s[n]->s, s[n]->len);
384  c += s[n]->len;
385  *c++ = '\"';
386  *c++ = ')';
387  }
388 
389  *c++ = ')';
390  }
391 
392  else {
393  result = afw_utf8_concat(p, xctx,
394  &data_type->data_type_id,
395  &afw_s_a_open_parenthesis, &impl_s_a_quote,
396  afw_value_as_utf8(value, p, xctx),
397  &impl_s_a_quote, &afw_s_a_close_parenthesis,
398  NULL);
399  }
400 
401  return result;
402 }
403 
404 
405 /* Return single value from one entry list or single value. */
406 AFW_DEFINE(const afw_value_t *)
408  const afw_value_t *value, const afw_pool_t *p, afw_xctx_t *xctx)
409 {
410  const afw_iterator_t *iterator;
411  const afw_list_t *list;
412  const afw_value_t *result;
413 
414  /* Result is NULL if value is NULL. */
415  if (!value) return NULL;
416  result = NULL;
417  value = afw_value_evaluate(value, p, xctx);
418 
419  /* If list, use it's first value if there is exactly one entry. */
420  if (afw_value_is_list(value)) {
421  iterator = NULL;
422  list = ((const afw_value_list_t *)value)->internal;
423  result = afw_list_get_next_value(list, &iterator, p, xctx);
424  if (result) {
425  if (afw_list_get_next_value(list, &iterator, p, xctx)) {
426  result = NULL;
427  }
428  }
429  }
430  /* Else result is just value. */
431  else {
432  result = value;
433  }
434 
435  return result;
436 }
437 
438 
439 /* Return result of afw_value_one_and_only() as string. */
440 AFW_DEFINE(const afw_utf8_t *)
442  const afw_value_t *value, const afw_pool_t *p, afw_xctx_t *xctx)
443 {
444  const afw_value_t *v;
445  const afw_utf8_t *result;
446 
447  value = afw_value_evaluate(value, p, xctx);
448  v = afw_value_one_and_only(value, p, xctx);
449  result = afw_value_as_utf8(v, p, xctx);
450  return result;
451 }
452 
453 
454 /* Convert value->internal to afw_utf8_t * */
455 AFW_DEFINE(const afw_utf8_t *)
457  const afw_pool_t *p, afw_xctx_t *xctx)
458 {
459  const afw_utf8_t *result;
460  const afw_data_type_t *data_type;
461 
462  /* Result is NULL if value is NULL. */
463  if (!value) return NULL;
464  value = afw_value_evaluate(value, p, xctx);
465  data_type = afw_value_get_data_type(value, xctx);
466  if (!data_type) {
467  AFW_THROW_ERROR_Z(general, "Expecting data type", xctx);
468  }
470  data_type, AFW_VALUE_INTERNAL(value), p, xctx);
471  return result;
472 }
473 
474 
475 
476 /* Make an afw_value_evaluated_t String using string in specified pool. */
477 AFW_DEFINE(const afw_value_t *)
479  const afw_utf8_octet_t *s,
480  afw_size_t len,
481  const afw_pool_t *p,
482  afw_xctx_t *xctx)
483 {
484  afw_value_string_t *single;
485 
486  single = afw_pool_malloc_type(p, afw_value_string_t, xctx);
487  single->inf = &afw_value_evaluated_string_inf;
488  single->internal.s = s;
489  single->internal.len = (len == AFW_UTF8_Z_LEN) ? strlen(s) : len;
490  return (const afw_value_t *)single;
491 
492 }
493 
494 /* Make an afw_value_evaluated_t String using copy of string in specified pool. */
495 AFW_DEFINE(const afw_value_t *)
497  const afw_utf8_octet_t *s,
498  afw_size_t len,
499  const afw_pool_t *p,
500  afw_xctx_t *xctx)
501 {
502  afw_value_string_t *single;
503 
504  single = afw_pool_malloc_type(p, afw_value_string_t, xctx);
505  single->inf = &afw_value_evaluated_string_inf;
506  single->internal.len = (len == AFW_UTF8_Z_LEN) ? strlen(s) : len;
507  single->internal.s = (single->internal.len > 0)
508  ? afw_memory_dup(s, single->internal.len, p, xctx)
509  : NULL;
510 
511  return (const afw_value_t *)single;
512 
513 }
514 
515 
516 
517 /* Make an afw_value_string_t from in specified pool. */
518 AFW_DEFINE(const afw_value_t *)
520  const afw_utf8_z_t *string_z,
521  const afw_pool_t *p,
522  afw_xctx_t *xctx)
523 {
524  const afw_utf8_t *string;
525 
526  string = afw_utf8_create(string_z, AFW_UTF8_Z_LEN, p, xctx);
527  return afw_value_create_string(string, p, xctx);
528 }
529 
530 
531 
532 /* Evaluate a value with additional insecure context. */
533 AFW_DEFINE(const afw_value_t *)
535  const afw_value_t *value,
536  const afw_value_t *untrusted_qualified_variables,
537  const afw_pool_t *p, afw_xctx_t *xctx)
538 {
539  const afw_iterator_t *iterator;
540  const afw_object_t *object;
541  const afw_utf8_t *property_name;
542  const afw_object_t *qualifier_object;
543  const afw_value_t *result;
544  int top;
545 
546  result = NULL;
547  if (untrusted_qualified_variables) {
548  AFW_VALUE_ASSERT_IS_DATA_TYPE(untrusted_qualified_variables, object, xctx);
549 
551  AFW_TRY {
552 
553  iterator = NULL;
555  ((const afw_value_object_t *)untrusted_qualified_variables)->internal,
556  &iterator, &property_name, xctx)))
557  {
558  qualifier_object = afw_compile_object_all_hybrid_properties(
559  object, NULL, NULL, p, xctx);
560  afw_xctx_push_qualifier_object(property_name, qualifier_object,
561  false, p, xctx);
562  }
563 
564  result = afw_value_evaluate(value, p, xctx);
565  }
566 
567  AFW_FINALLY{
569  }
570 
571  AFW_ENDTRY;
572  }
573 
574  else {
575  result = afw_value_evaluate(value, p, xctx);
576  }
577 
578  return result;
579 }
580 
581 
582 /* Convert a value to a value/data type. */
583 AFW_DEFINE(const afw_value_t *)
585  const afw_value_t *value,
586  const afw_data_type_t *to_data_type,
587  afw_boolean_t required,
588  const afw_pool_t *p, afw_xctx_t *xctx)
589 {
590  const afw_value_t *result;
591  const afw_data_type_t *v_data_type;
592  afw_value_evaluated_t *single;
593  const afw_list_t *list;
594  const afw_iterator_t *iterator;
595  const void *internal;
596  const afw_data_type_t *data_type;
597  afw_size_t evaluate_count;
598 
599  /* Evaluate value. */
600  result = value;
601  AFW_VALUE_UNDECORATE(result);
602  for (evaluate_count = 0;
603  result && !afw_value_is_defined_and_evaluated(result);
604  evaluate_count++)
605  {
606  if (evaluate_count >= 20) {
607  AFW_THROW_ERROR_FZ(general, xctx,
608  "afw_value_convert() value required > %d evaluations",
609  20);
610  }
611  result = afw_value_evaluate(result, p, xctx);
612  AFW_VALUE_UNDECORATE(result);
613  }
614 
615  if (!result) {
616  if (!required) {
617  return NULL;
618  }
619  AFW_THROW_ERROR_Z(undefined, "Result is undefined", xctx);
620  }
621 
622  /* If to_data_type is any, return result now. */
623  if (!to_data_type || to_data_type == afw_data_type_any) {
624  return result;
625  }
626 
627  v_data_type = afw_value_get_data_type(result, xctx);
628 
629  if (v_data_type != to_data_type) {
630 
631  /* Upconvert to one entry list. */
632  if (to_data_type == afw_data_type_list) {
634  &((afw_value_evaluated_t *)value)->internal, false,
635  v_data_type, 1, p, xctx);
636  result = afw_value_create_list(list, p, xctx);
637  }
638 
639  /* Down convert from a single entry list. */
640  else if (v_data_type == afw_data_type_list &&
641  !afw_data_type_is_string(to_data_type))
642  {
643  list = ((const afw_value_list_t *)value)->internal;
644  if (afw_list_get_count(list, xctx) != 1) {
645  AFW_THROW_ERROR_Z(general,
646  "Can't down convert a list with more than one entry",
647  xctx);
648  }
649  iterator = NULL;
651  &iterator, &data_type, &internal, xctx);
652  single = afw_value_evaluated_allocate(to_data_type, p, xctx);
653  if (data_type == to_data_type) {
654  memcpy(AFW_VALUE_INTERNAL(single), internal, data_type->c_type_size);
655  }
656  else {
658  data_type,
659  &single->internal,
660  internal,
661  to_data_type,
662  p, xctx);
663  }
664  result = (const afw_value_t *)single;
665  }
666 
667  /* Not list. */
668  else {
669  single = afw_value_evaluated_allocate(to_data_type, p, xctx);
671  v_data_type,
672  &single->internal,
673  &((const afw_value_evaluated_t *)value)->internal,
674  to_data_type,
675  p, xctx);
676  result = (const afw_value_t *)single;
677  }
678  }
679 
680  /* Return either original or converted value. */
681  return result;
682 }
683 
684 
685 
686 /* Convert a value to a string value. */
687 AFW_DEFINE(const afw_value_t *)
689  const afw_value_t *value,
690  afw_boolean_t allow_undefined,
691  const afw_pool_t *p, afw_xctx_t *xctx)
692 {
693  const afw_value_t *result;
694 
695  result = afw_value_convert(value, afw_data_type_string, false, p, xctx);
696  if (!result) {
697  if (allow_undefined) {
699  }
700  AFW_THROW_ERROR_Z(undefined, "Value is undefined", xctx);
701  }
702 
703  return result;
704 }
705 
706 
707 
709 AFW_DEFINE(const afw_value_t *)
711  const afw_value_t *value, const afw_pool_t *p, afw_xctx_t *xctx)
712 {
713  const afw_utf8_t *string;
714  const afw_value_t *result;
715 
716  /* If already String, just return it. */
717  if (afw_value_is_string(value)) {
718  result = value;
719  }
720 
721  /* If not, convert value to string and return single_string value. */
722  else {
724  afw_value_get_data_type(value, xctx), value,
725  p, xctx);
726  result = afw_value_create_string(string, p, xctx);
727  }
728 
729  return result;
730 }
731 
732 
733 
734 /* Create a dateTime value with current time. */
735 AFW_DEFINE(const afw_value_t *)
737  const afw_pool_t *p, afw_xctx_t *xctx)
738 {
739  afw_dateTime_t dateTime;
740 
741  afw_dateTime_set_now(NULL, &dateTime, xctx);
742  return afw_value_create_dateTime(&dateTime, p, xctx);
743 }
744 
745 
746 
747 /* Create a dateTime value with current local time. */
748 AFW_DEFINE(const afw_value_t *)
750  const afw_pool_t *p, afw_xctx_t *xctx)
751 {
752  afw_dateTime_t dateTime;
753 
754  afw_dateTime_set_now(&dateTime, NULL, xctx);
755  return afw_value_create_dateTime(&dateTime, p, xctx);
756 }
757 
758 
759 
760 static const afw_value_t **
761 impl_value_as_array_of_values(
762  const afw_value_t *value, const afw_pool_t *p, afw_xctx_t *xctx)
763 {
764  afw_size_t count;
765  const afw_value_t **e;
766  const afw_value_t **result;
767  const afw_iterator_t *iterator;
768 
769  /* If value is NULL, n is 0. */
770  if (!value) {
771  count = 0;
772  }
773 
774  /* If value is a list, count is number of entries in list. */
775  else if (afw_value_is_list(value)) {
776  count = afw_list_get_count(
777  ((const afw_value_list_t *)value)->internal, xctx);
778  }
779 
780  /* For other types of values, count is 1. */
781  else {
782  count = 1;
783  }
784 
785  /* Allocate storage for result array with n + 1 entries. */
786  e = result = afw_pool_malloc(p, sizeof(afw_value_t *)*(count + 1), xctx);
787  e[count] = NULL;
788 
789  /* Return now if count is 0. */
790  if (count == 0) {
791  return result;
792  }
793 
794  /* If value is a list, added list values. */
795  else if (afw_value_is_list(value)) {
796  for (iterator = NULL; ; e++) {
798  ((const afw_value_list_t *)value)->internal,
799  &iterator, p, xctx);
800  if (!*e) break;
801  }
802  }
803 
804  /* For other types of values, just add them. */
805  else {
806  *e = value;
807  }
808 
809  /* Return result. */
810  return result;
811 }
812 
813 
814 
815 /* Return a NULL terminated list of values in a specified pool. */
816 AFW_DEFINE(const afw_value_t * const *)
818  const afw_pool_t *p, afw_xctx_t *xctx)
819 {
820  return impl_value_as_array_of_values(value, p, xctx);
821 }
822 
823 
824 
825 /* Return a NULL terminated list of strings in a specified pool. */
826 AFW_DEFINE(const afw_utf8_t * const *)
828  const afw_pool_t *p, afw_xctx_t *xctx)
829 {
830  const afw_utf8_t **result;
831  const afw_utf8_t **e;
832 
833  /*
834  * Get NULL terminated array for value pointers and replace the pointers
835  * in place with the result of calling as_string() on the value.
836  */
837  result = (const afw_utf8_t **)impl_value_as_array_of_values(value,
838  p, xctx);
839  for (e = result; *e; e++) {
840  *e = afw_value_as_utf8((const afw_value_t *)*e, p, xctx);
841  }
842 
843  /* Return result. */
844  return result;
845 }
846 
847 
848 
849 /* Test whether two values are equal. */
851 afw_value_equal(const afw_value_t *value1, const afw_value_t *value2,
852  afw_xctx_t *xctx)
853 {
854  const char *i1, *i2;
855  afw_boolean_t result;
856 
857  if (value1 == value2)
858  {
859  result = true;
860  }
861 
862  else if (!value1 || !value2)
863  {
864  result = false;
865  }
866 
867  else if (value1->inf->fully_evaluated_data_type)
868  {
869  if (value1->inf->fully_evaluated_data_type ==
870  value2->inf->fully_evaluated_data_type)
871  {
872  i1 = (const char *)&((const afw_value_evaluated_t *)value1)->internal;
873  i2 = (const char *)&((const afw_value_evaluated_t *)value2)->internal;
875  value1->inf->fully_evaluated_data_type, i1, i2, xctx) == 0;
876  }
877  else
878  {
879  result = false;
880  }
881  }
882 
883  else
884  {
885  result = false;
886  }
887 
888  return result;
889 }
890 
891 /* Compare two values. */
892 AFW_DEFINE(int)
894  const afw_value_t *value1, const afw_value_t *value2,
895  afw_xctx_t *xctx)
896 {
897  int result;
898  const void *i1, *i2;
899 
900 
901  /* Make sure value1 and value2 are undecorated. */
902  AFW_VALUE_UNDECORATE(value1);
903  AFW_VALUE_UNDECORATE(value2);
904 
906  {
907  AFW_THROW_ERROR_Z(general, "value 1 and 2 are not same type", xctx);
908  }
909 
911  i1 = (const void *)&((const afw_value_evaluated_t *)value1)->internal;
912  i2 = (const void *)&((const afw_value_evaluated_t *)value2)->internal;
914  afw_value_get_data_type(value1, xctx),
915  i1, i2, xctx);
916  }
917 
918  else {
919  AFW_THROW_ERROR_Z(general,
920  "afw_value_compare() only supports evaluated values",
921  xctx);
922  }
923 
924  return result;
925 }
926 
927 
928 
929 /* Check to see if a value contains a substring. */
932  const afw_value_t *value,
933  const afw_value_t *substring,
934  afw_xctx_t *xctx)
935 {
936  const afw_data_type_t *value_data_type;
937  const afw_data_type_t *substring_data_type;
938  const afw_utf8_t *v;
939  const afw_utf8_t *ss;
940  afw_size_t i;
941  afw_boolean_t result;
942 
943  value_data_type = afw_value_get_data_type(value, xctx);
944  if (!value_data_type ||
945  !afw_utf8_equal(&value_data_type->cType, &afw_s_afw_utf8_t))
946  {
947  AFW_THROW_ERROR_Z(general,
948  "value must have a data type with cType of afw_utf8_t",
949  xctx);
950  }
951 
952  substring_data_type = afw_value_get_data_type(substring, xctx);
953  if (!substring_data_type ||
954  !afw_utf8_equal(&substring_data_type->cType, &afw_s_afw_utf8_t))
955  {
956  AFW_THROW_ERROR_Z(general,
957  "substring must have a data type with cType of afw_utf8_t",
958  xctx);
959  }
960 
961  v = &((const afw_value_string_t *)value)->internal;
962  ss = &((const afw_value_string_t *)substring)->internal;
963 
964  for (result = false, i = 0; v->len - i >= ss->len; i++) {
965  if (memcmp(v->s + i, ss->s, ss->len) == 0) {
966  result = true;
967  break;
968  }
969  }
970 
971  return result;
972 }
973 
974 
975 /* Register core value infs. */
976 AFW_DEFINE(void)
977 afw_value_register_core_value_infs(afw_xctx_t *xctx)
978 {
980  &afw_value_annotated_inf.rti.implementation_id,
981  &afw_value_annotated_inf, xctx);
982 
984  &afw_value_assignment_target_inf.rti.implementation_id,
986 
988  &afw_value_compiled_value_inf.rti.implementation_id,
990 
992  &afw_value_call_inf.rti.implementation_id,
993  &afw_value_call_inf, xctx);
994 
996  &afw_value_expression_definition_inf.rti.implementation_id,
998 
1000  &afw_value_function_definition_inf.rti.implementation_id,
1002 
1004  &afw_value_script_function_definition_inf.rti.implementation_id,
1006 
1008  &afw_value_list_expression_inf.rti.implementation_id,
1010 
1012  &afw_value_object_expression_inf.rti.implementation_id,
1014 
1016  &afw_value_reference_by_key_inf.rti.implementation_id,
1018 
1020  &afw_value_template_definition_inf.rti.implementation_id,
1022 
1024  &afw_value_qualified_variable_reference_inf.rti.implementation_id,
1026 }
AFW_DEFINE(const afw_object_t *)
#define AFW_DEFINE_CONST_DATA(type)
Define a public afw variable.
Adaptive Framework Core Internal.
afw_data_type_any
Data type struct for any.
afw_value_evaluated_boolean_inf
Unmanaged evaluated value inf for data type boolean.
afw_value_create_dateTime(const afw_dateTime_t *internal, const afw_pool_t *p, afw_xctx_t *xctx)
Create function for unmanaged data type dateTime value.
afw_value_create_list(const afw_list_t *internal, const afw_pool_t *p, afw_xctx_t *xctx)
Create function for unmanaged data type list value.
#define afw_value_is_list(A_VALUE)
Macro to determine if value is evaluated list.
afw_data_type_list
Data type struct for list.
afw_value_evaluated_null_inf
Unmanaged evaluated value inf for data type null.
#define afw_value_is_object(A_VALUE)
Macro to determine if value is evaluated object.
#define afw_object_old_get_next_property_as_object(object, iterator, property_name, xctx)
Get next property function for data type object value.
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.
afw_data_type_string
Data type struct for string.
afw_value_evaluated_string_inf
Unmanaged evaluated value inf for data type string.
#define afw_data_type_is_string(A_DATA_TYPE)
Macro to determine if data type is string.
#define afw_value_is_string(A_VALUE)
Macro to determine if value is evaluated string.
#define AFW_FALSE
Definition: afw_common.h:392
#define AFW_UTF8_Z_LEN
String is NUL (0) terminate.
Definition: afw_common.h:266
#define AFW_UTF8_LITERAL(A_STRING)
String literal initializer.
Definition: afw_common.h:582
struct afw_iterator_s afw_iterator_t
#define AFW_TRUE
Definition: afw_common.h:383
_Bool afw_boolean_t
Definition: afw_common.h:373
afw_utf8_octet_t afw_utf8_z_t
NFC normalized UTF-8 null terminated string.
Definition: afw_common.h:523
enum afw_compile_type_e afw_compile_type_t
Compile type enum.
char afw_utf8_octet_t
8 bits of utf-8 codepoint.
Definition: afw_common.h:236
apr_size_t afw_size_t
size_t.
Definition: afw_common.h:151
afw_compile_object_all_hybrid_properties(const afw_object_t *object, const afw_utf8_t *source_location, const afw_compile_shared_t *shared, const afw_pool_t *p, afw_xctx_t *xctx)
Compile an object with all hybrid properties.
Definition: afw_compile.c:499
afw_compile_to_value_with_callback(const afw_utf8_t *string, afw_utf8_octet_get_cb_t callback, void *callback_data, const afw_utf8_t *source_location, afw_compile_type_t compile_type, afw_compile_residual_check_t residual_check, const afw_value_compiled_value_t *parent, const afw_compile_shared_t *shared, const afw_pool_t *p, afw_xctx_t *xctx)
Compile string to adaptive value with callback.
Definition: afw_compile.c:140
#define afw_data_type_clone_internal(instance, to_internal, from_internal, p, xctx)
Call method clone_internal of interface afw_data_type.
#define afw_data_type_compare_internal(instance, internal1, internal2, xctx)
Call method compare_internal of interface afw_data_type.
#define afw_data_type_convert_internal(instance, to_internal, from_internal, to_data_type, p, xctx)
Call method convert_internal of interface afw_data_type.
#define afw_data_type_internal_to_utf8(instance, from_internal, p, xctx)
Call method internal_to_utf8 of interface afw_data_type.
void afw_environment_register_value_inf(const afw_utf8_t *value_inf_id, const afw_value_inf_t *value_inf, afw_xctx_t *xctx)
Register a value inf.
#define AFW_FINALLY
Always executed regardless of error.
Definition: afw_error.h:702
#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_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_list_get_next_internal(instance, iterator, data_type, internal, xctx)
Call method get_next_internal of interface afw_list.
#define afw_list_get_next_value(instance, iterator, p, xctx)
Call method get_next_value of interface afw_list.
#define afw_list_get_count(instance, xctx)
Call method get_count of interface afw_list.
afw_list_create_wrapper_for_array(const void *array, afw_boolean_t indirect, const afw_data_type_t *data_type, afw_size_t count, const afw_pool_t *p, afw_xctx_t *xctx)
Create a immutable list wrapper for an array.
void * afw_memory_dup(const void *from, apr_size_t size, const afw_pool_t *p, afw_xctx_t *xctx)
Duplicate a block of memory into specified pool.
Definition: afw_memory.h:88
#define afw_object_get_next_property(instance, iterator, property_name, xctx)
Call method get_next_property of interface afw_object.
#define afw_pool_malloc(instance, size, xctx)
Call method malloc of interface afw_pool.
#define afw_pool_calloc(instance, size, xctx)
Call method calloc of interface afw_pool.
#define afw_pool_malloc_type(instance, type, xctx)
Macro to allocate uncleared memory to hold type in pool.
Definition: afw_pool.h:182
afw_dateTime_set_now(afw_dateTime_t *dateTime_local, afw_dateTime_t *dateTime_utc, afw_xctx_t *xctx)
Set local and/or utc dateTime to now.
Definition: afw_time.c:523
const afw_utf8_t * afw_utf8_concat(const afw_pool_t *p, afw_xctx_t *xctx,...)
Concatenate strings with result in specifed pool.
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_utf8_z_create(const afw_utf8_octet_t *s, afw_size_t len, const afw_pool_t *p, afw_xctx_t *xctx)
Create a NFC Normalized zero terminated UTF-8 string in specified pool.
Definition: afw_utf8.c:366
#define afw_utf8_create(s, len, p, xctx)
Create utf-8 string without copy unless necessary in pool specified.
Definition: afw_utf8.h:239
#define afw_value_get_data_type(instance, xctx)
Call method get_data_type of interface afw_value.
afw_value_as_array_of_utf8(const afw_value_t *value, const afw_pool_t *p, afw_xctx_t *xctx)
Return a NULL terminated list of utf8 in a specified pool.
Definition: afw_value.c:827
afw_value_convert_to_string(const afw_value_t *value, afw_boolean_t allow_undefined, const afw_pool_t *p, afw_xctx_t *xctx)
Convert a value to a string value.
Definition: afw_value.c:688
afw_value_one_and_only(const afw_value_t *value, const afw_pool_t *p, afw_xctx_t *xctx)
Return value from one entry list or single value.
Definition: afw_value.c:407
afw_value_assignment_target_inf
Value annotated inf.
Definition: afw_value.h:225
#define AFW_VALUE_UNDECORATE(a_value)
Undecorated value in place.
Definition: afw_value.h:375
afw_value_undecorate(const afw_value_t *value)
Return undecorated value.
Definition: afw_value.c:186
afw_value_compile_and_evaluate_as(const afw_value_t *value, const afw_utf8_t *source_location, afw_compile_type_t compile_type, const afw_pool_t *p, afw_xctx_t *xctx)
Compile and evaluate a value using specified compile type.
Definition: afw_value.c:165
#define afw_value_quick_data_type(A_VALUE)
Get the easily accessible data type for a value.
Definition: afw_value.h:739
#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
afw_value_compile_as(const afw_value_t *value, const afw_utf8_t *source_location, afw_compile_type_t compile_type, const afw_pool_t *p, afw_xctx_t *xctx)
Compile a value using specified compile type.
Definition: afw_value.c:104
afw_value_undefined_as_string
Adaptive value containing <undefined> string.
Definition: afw_value.h:336
afw_value_reference_by_key_inf
Value evaluation_reference_by_key inf.
Definition: afw_value.h:297
afw_value_clone(const afw_value_t *value, const afw_pool_t *p, afw_xctx_t *xctx)
Clone a value to specified pool.
Definition: afw_value.c:282
afw_value_annotated_inf
Value annotated inf.
Definition: afw_value.h:219
afw_value_compile_and_evaluate(const afw_value_t *value, const afw_utf8_t *source_location, const afw_pool_t *p, afw_xctx_t *xctx)
Compile and evaluate a value.
Definition: afw_value.c:145
afw_value_as_utf8(const afw_value_t *value, const afw_pool_t *p, afw_xctx_t *xctx)
Definition: afw_value.c:456
afw_value_evaluated_t * afw_value_evaluated_allocate(const afw_data_type_t *data_type, const afw_pool_t *p, afw_xctx_t *xctx)
Allocate function for an evaluated data type value.
afw_value_compile(const afw_value_t *value, const afw_utf8_t *source_location, const afw_pool_t *p, afw_xctx_t *xctx)
Compile a value.
Definition: afw_value.c:74
afw_value_expression_definition_inf
Value expression inf.
Definition: afw_value.h:255
afw_value_false
Adaptive value false.
Definition: afw_value.h:354
afw_value_object_expression_inf
Value object expression inf.
Definition: afw_value.h:285
afw_value_as_utf8_z(const afw_value_t *value, const afw_pool_t *p, afw_xctx_t *xctx)
Definition: afw_value.c:315
afw_value_call_inf
Value call inf.
Definition: afw_value.h:237
afw_value_one_and_only_as_utf8(const afw_value_t *value, const afw_pool_t *p, afw_xctx_t *xctx)
Return result of afw_value_one_and_only() as utf8.
Definition: afw_value.c:441
afw_value_function_definition_inf
Value function inf.
Definition: afw_value.h:261
#define afw_value_is_defined_and_evaluated(A_VALUE)
Macro to determine if value is defined and evaluated.
Definition: afw_value.h:481
afw_value_create_dateTime_now_local(const afw_pool_t *p, afw_xctx_t *xctx)
Create a dateTime value with current local time.
Definition: afw_value.c:749
afw_value_empty_string
Adaptive value empty string.
Definition: afw_value.h:342
afw_value_create_dateTime_now_utc(const afw_pool_t *p, afw_xctx_t *xctx)
Create a dateTime value with current time.
Definition: afw_value.c:736
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_undecorated_inf_is(const afw_value_t *value, const afw_value_inf_t *inf)
Determine if value's undecorated inf is the supplied one.
Definition: afw_value.c:197
afw_value_contains(const afw_value_t *value, const afw_value_t *substring, afw_xctx_t *xctx)
Check to see if a value contains a substring.
Definition: afw_value.c:931
afw_value_make_string_copy(const afw_utf8_octet_t *s, afw_size_t len, const afw_pool_t *p, afw_xctx_t *xctx)
Definition: afw_value.c:496
afw_value_script_function_definition_inf
Value lambda inf.
Definition: afw_value.h:273
#define AFW_VALUE_INTERNAL(_VALUE_)
Macro to get const void * of the internal of a value.
Definition: afw_value.h:856
afw_value_compare(const afw_value_t *value1, const afw_value_t *value2, afw_xctx_t *xctx)
Compare two evaluated values.
Definition: afw_value.c:893
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_list_expression_inf
Value list expression inf.
Definition: afw_value.h:279
afw_value_is_scalar(const afw_value_t *value, afw_xctx_t *xctx)
Determine if value is scalar.
Definition: afw_value.c:271
afw_value_qualified_variable_reference_inf
Value qualified_variable_reference inf.
Definition: afw_value.h:291
#define AFW_VALUE_ASSERT_IS_DATA_TYPE(A_VALUE, A_DATA_TYPE, A_SCOPE)
Throw and error if A_VALUE is not evaluated data type A_DATA_TYPE.
Definition: afw_value.h:768
afw_value_null
Adaptive value null.
Definition: afw_value.h:320
afw_value_template_definition_inf
Value template inf.
Definition: afw_value.h:303
afw_value_make_single_string(const afw_utf8_octet_t *s, afw_size_t len, const afw_pool_t *p, afw_xctx_t *xctx)
Definition: afw_value.c:478
afw_value_string_from_internal(const afw_value_t *value, const afw_pool_t *p, afw_xctx_t *xctx)
Definition: afw_value.c:710
afw_value_compiled_value_inf
Value call inf.
Definition: afw_value.h:249
afw_value_is_fully_evaluated(const afw_value_t *value, afw_xctx_t *xctx)
Determine if value and all of it contained values are evaluated.
Definition: afw_value.c:218
afw_value_true
Adaptive value true.
Definition: afw_value.h:348
afw_value_create_string_from_u8z(const afw_utf8_z_t *string_z, const afw_pool_t *p, afw_xctx_t *xctx)
Definition: afw_value.c:519
afw_value_as_array_of_values(const afw_value_t *value, const afw_pool_t *p, afw_xctx_t *xctx)
Return a NULL terminated list of values in a specified pool.
Definition: afw_value.c:817
afw_xctx_get_qualifier_stack_top(afw_xctx_t *xctx)
Get qualifier stack top.
Definition: afw_xctx.c:316
afw_xctx_push_qualifier_object(const afw_utf8_t *qualifier_name, const afw_object_t *qualifier_object, afw_boolean_t secure, const afw_pool_t *p, afw_xctx_t *xctx)
Push qualifier object on to stack.
Definition: afw_xctx.c:406
afw_xctx_set_qualifier_stack_top(int top, afw_xctx_t *xctx)
Set stack top index.
Definition: afw_xctx.c:325
Interface afw_data_type public struct.
date, time, and time zone.
Definition: afw_common.h:1760
Interface afw_list public struct.
Interface afw_object public struct.
Interface afw_pool public struct.
NFC normalized UTF-8 string.
Definition: afw_common.h:545
Struct for annotated value.
struct for data type boolean values.
Struct to access internal of all evaluated values.
Definition: afw_value.h:60
Interface afw_value_inf_s struct.
Struct for compiled value value.
struct for data type list values.
struct for data type null values.
struct for data type object values.
Interface afw_value public struct.
struct for data type string values.
Interface afw_xctx public struct.