Adaptive Framework  0.9.0
All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
afw_function_polymorphic.c
Go to the documentation of this file.
1 // See the 'COPYING' file in the project root for licensing information.
2 /*
3  * afw_common polymorphic function_execute_* 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 static afw_boolean_t
19 impl_is_in_list(
20  const afw_data_type_t *data_type,
21  const void *internal,
22  const afw_list_t *list,
23  afw_xctx_t *xctx)
24 {
25  const afw_iterator_t *iterator;
26  const void *entry_internal;
27  const afw_data_type_t *entry_data_type;
28 
29  if (!data_type) {
30  AFW_THROW_ERROR_Z(general,
31  "impl_is_in_list() called with NULL data_type",
32  xctx);
33  }
34 
35  for (iterator = NULL;;) {
36  afw_list_get_next_internal(list, &iterator,
37  &entry_data_type, &entry_internal, xctx);
38  if (!entry_internal) {
39  return false;
40  }
41  if (data_type != entry_data_type) {
42  continue;
43  }
44  if (afw_data_type_compare_internal(data_type,
45  internal, entry_internal, xctx) == 0)
46  {
47  return true;
48  }
49  }
50 }
51 
52 
53 
54 static afw_boolean_t
55 impl_is_subset_list(
56  const afw_list_t *list1,
57  const afw_list_t *list2,
58  afw_xctx_t *xctx)
59 {
60  const afw_iterator_t *iterator;
61  const void *internal;
62  const afw_data_type_t *data_type;
63 
64  for (iterator = NULL;;) {
65  afw_list_get_next_internal(list1, &iterator,
66  &data_type, &internal, xctx);
67  if (!internal) {
68  return true;
69  }
70  if (!impl_is_in_list(data_type, internal, list2, xctx)) {
71  return false;
72  }
73  }
74 }
75 
76 
77 /* Add non-duplicates. */
78 static void
79 impl_add_nondups_to_list(
80  const afw_data_type_t *data_type,
81  const afw_list_t *from,
82  const afw_list_t *to,
83  afw_xctx_t *xctx)
84 {
85  const afw_iterator_t *iterator;
86  const void *internal;
87 
88  for (iterator = NULL;;) {
89  afw_list_get_next_internal(from, &iterator,
90  NULL, &internal, xctx);
91  if (!internal) {
92  break;
93  }
94  if (!impl_is_in_list(data_type, internal, to, xctx)) {
95  afw_list_add_internal(to, data_type, internal, xctx);
96  }
97  }
98 }
99 
100 
101 
102 /*
103  * Common polymorphic function for at_least_one_member_of
104  *
105  * afw_function_execute_at_least_one_member_of
106  *
107  * See afw_function_bindings.h for more information.
108  *
109  * Returns boolean true if at least one value in `<dataType>` list1 is in
110  * `<dataType>` list2.
111  *
112  * This function is pure, so it will always return the same result
113  * given exactly the same parameters and has no side effects.
114  *
115  * Supported `<dataType>`:
116  *
117  * anyURI, base64Binary, boolean, date, dateTime, dayTimeDuration, double,
118  * hexBinary, integer, rfc822Name, string, time, x500Name, yearMonthDuration.
119  *
120  * Declaration:
121  *
122  * ```
123  * function at_least_one_member_of <dataType>(
124  * list1: list,
125  * list2: list
126  * ): boolean;
127  * ```
128  *
129  * Parameters:
130  *
131  * list1 - (list ``<Type>``) The first list.
132  *
133  * list2 - (list ``<Type>``) The second list.
134  *
135  * Returns:
136  *
137  * (boolean)
138  */
139 const afw_value_t *
142 {
143  const afw_value_list_t *list1;
144  const afw_value_list_t *list2;
145  const afw_iterator_t *iterator;
146  const afw_data_type_t *data_type;
147  const void *internal;
148 
151 
152  for (iterator = NULL;;) {
153  afw_list_get_next_internal(list1->internal, &iterator,
154  &data_type, &internal, x->xctx);
155  if (!internal) {
156  return afw_value_false;
157  }
158  if (impl_is_in_list(data_type, internal, list2->internal, x->xctx)) {
159  return afw_value_true;
160  }
161  }
162 }
163 
164 
165 
166 /*
167  * Common polymorphic function for bag
168  *
169  * afw_function_execute_bag
170  *
171  * See afw_function_bindings.h for more information.
172  *
173  * Takes any number of `<dataType>` values and returns a list of list.
174  *
175  * This function is pure, so it will always return the same result
176  * given exactly the same parameters and has no side effects.
177  *
178  * Supported `<dataType>`:
179  *
180  * anyURI, base64Binary, boolean, date, dateTime, dayTimeDuration, dnsName,
181  * double, expression, function, hexBinary, hybrid, ia5String, integer,
182  * ipAddress, list, null, object, objectId, objectPath, password, rfc822Name,
183  * script, string, template, time, x500Name, xpathExpression,
184  * yearMonthDuration.
185  *
186  * Declaration:
187  *
188  * ```
189  * function bag <dataType>(
190  * ...values: (list of list)
191  * ): list;
192  * ```
193  *
194  * Parameters:
195  *
196  * values - (0 or more list ``<Type>``)
197  *
198  * Returns:
199  *
200  * (list ``<Type>``)
201  */
202 const afw_value_t *
205 {
206  const afw_list_t *list;
207  const afw_value_t *value;
208  afw_size_t i;
209 
210  if (x->argc == 0) {
211  return x->data_type->empty_list_value;
212  }
213 
214  list = afw_list_of_create(x->data_type, x->p, x->xctx);
215 
216  for (i = 1; i <= x->argc; i++) {
219  AFW_VALUE_INTERNAL(value), x->xctx);
220  }
221 
222  return afw_value_create_list(list, x->p, x->xctx);
223 }
224 
225 
226 
227 /*
228  * Common polymorphic function for bag_size
229  *
230  * afw_function_execute_bag_size
231  *
232  * See afw_function_bindings.h for more information.
233  *
234  * This returns the integer number of values in list.
235  *
236  * This function is pure, so it will always return the same result
237  * given exactly the same parameters and has no side effects.
238  *
239  * Supported `<dataType>`:
240  *
241  * anyURI, base64Binary, boolean, date, dateTime, dayTimeDuration, dnsName,
242  * double, expression, function, hexBinary, hybrid, ia5String, integer,
243  * ipAddress, list, null, object, objectId, objectPath, password, rfc822Name,
244  * script, string, template, time, x500Name, xpathExpression,
245  * yearMonthDuration.
246  *
247  * Declaration:
248  *
249  * ```
250  * function bag_size <dataType>(
251  * value: list
252  * ): integer;
253  * ```
254  *
255  * Parameters:
256  *
257  * value - (list ``<Type>``)
258  *
259  * Returns:
260  *
261  * (integer)
262  */
263 const afw_value_t *
266 {
267  const afw_value_list_t *arg;
268  afw_size_t count;
269 
271 
272  count = afw_list_get_count(arg->internal, x->xctx);
273 
274  return afw_value_create_integer((afw_integer_t)count, x->p, x->xctx);
275 }
276 
277 
278 
279 /*
280  * Common polymorphic function for clone
281  *
282  * afw_function_execute_clone
283  *
284  * See afw_function_bindings.h for more information.
285  *
286  * Deep clone a `<dataType>` value.
287  *
288  * This function is pure, so it will always return the same result
289  * given exactly the same parameters and has no side effects.
290  *
291  * Supported `<dataType>`:
292  *
293  * list, object.
294  *
295  * Declaration:
296  *
297  * ```
298  * function clone <dataType>(
299  * value: dataType
300  * ): dataType;
301  * ```
302  *
303  * Parameters:
304  *
305  * value - (``<Type>``) The `<dataType>` value to clone.
306  *
307  * Returns:
308  *
309  * (``<Type>``) The cloned `<dataType>` value.
310  */
311 const afw_value_t *
314 {
315  const afw_value_t *value;
316  const afw_value_t *result;
317 
319 
320  result = afw_value_clone(value, x->p, x->xctx);
321 
322  return result;
323 }
324 
325 
326 
327 /*
328  * Common polymorphic function for compile
329  *
330  * afw_function_execute_compile
331  *
332  * See afw_function_bindings.h for more information.
333  *
334  * Compile <Type> value and return either an unevaluated adaptive value or a
335  * string containing the compiler listing.
336  *
337  * This function is pure, so it will always return the same result
338  * given exactly the same parameters and has no side effects.
339  *
340  * Supported <Type>:
341  *
342  * expression, function, hybrid, script, template, xpathExpression.
343  *
344  * Parameters:
345  * source - (<Type>) <Type> string to compile.
346  * listing - (any dataType) If specified, a compiler listing is produced
347  * instead of an unevaluated expression value.
348  *
349  * This parameter can be an integer between 0 and 10 of a string that
350  * is used for indentation. If 0 is specified, no whitespace is added
351  * to the resulting string. If 1 through 10 is specified, that number
352  * of spaces is used.
353  *
354  * Returns:
355  * (unevaluated)
356  */
357 const afw_value_t *
360 {
361  const afw_value_t *source;
362  const afw_value_t *result;
363  const afw_utf8_t *listing;
364 
366 
368  result = afw_value_compile(
369  source, &afw_s_a_empty_string, x->p, x->xctx);
371  listing = afw_function_evaluate_whitespace_parameter(x, 2);
372  result = afw_value_create_string(
373  afw_value_compiler_listing_to_string(result, listing,
374  x->p, x->xctx),
375  x->p, x->xctx);
376  }
377 
378  return result;
379 }
380 
381 
382 
383 /*
384  * Common polymorphic function for ends_with
385  *
386  * afw_function_execute_ends_with
387  *
388  * See afw_function_bindings.h for more information.
389  *
390  * Checks whether `<dataType>` value ends with a `<dataType>` and return the
391  * boolean result.
392  *
393  * This function is pure, so it will always return the same result
394  * given exactly the same parameters and has no side effects.
395  *
396  * Supported `<dataType>`:
397  *
398  * anyURI, string.
399  *
400  * Declaration:
401  *
402  * ```
403  * function ends_with <dataType>(
404  * value: dataType,
405  * subString: string
406  * ): boolean;
407  * ```
408  *
409  * Parameters:
410  *
411  * value - (``<Type>``)
412  *
413  * subString - (string)
414  *
415  * Returns:
416  *
417  * (boolean)
418  */
419 const afw_value_t *
422 {
423  const afw_value_t *arg1;
424  const afw_value_t *arg2;
425  const afw_value_string_t *a1;
426  const afw_value_string_t *a2;
427 
432 
433  a1 = (const afw_value_string_t *)arg1;
434  a2 = (const afw_value_string_t *)arg2;
435 
436  return
437  (
438  a1->internal.len >= a2->internal.len &&
439  memcmp(a1->internal.s + (a1->internal.len - a2->internal.len),
440  a2->internal.s, a2->internal.len) == 0
441  )
443  : afw_value_false;
444 }
445 
446 
447 
448 /*
449  * Common polymorphic function for eq
450  *
451  * afw_function_execute_eq
452  *
453  * See afw_function_bindings.h for more information.
454  *
455  * Determine if `<dataType>` arg1 is equal to the value of arg2 converted to
456  * the data type of arg1 then return the boolean result. Use "eqx" ("===")
457  * instead if you want false to be returned if arg1 and arg2's data type don't
458  * match.
459  *
460  * This function is pure, so it will always return the same result
461  * given exactly the same parameters and has no side effects.
462  *
463  * Supported `<dataType>`:
464  *
465  * anyURI, base64Binary, boolean, date, dateTime, dayTimeDuration, dnsName,
466  * double, expression, function, hexBinary, hybrid, ia5String, integer,
467  * ipAddress, list, object, objectId, objectPath, password, regexp,
468  * rfc822Name, script, string, template, time, x500Name, xpathExpression,
469  * yearMonthDuration.
470  *
471  * Declaration:
472  *
473  * ```
474  * function eq <dataType>(
475  * arg1: dataType,
476  * arg2: any
477  * ): boolean;
478  * ```
479  *
480  * Parameters:
481  *
482  * arg1 - (``<Type>``)
483  *
484  * arg2 - (any dataType)
485  *
486  * Returns:
487  *
488  * (boolean)
489  *
490  * Errors thrown:
491  *
492  * conversion - arg2 cannot be converted to the data type of arg1.
493  */
494 const afw_value_t *
497 {
498  const afw_value_t *arg1;
499  const afw_value_t *arg2;
500  const afw_data_type_t *arg1_data_type;
501  const afw_data_type_t *arg2_data_type;
502  int cmp;
503 
506 
507  /* Handle undefined/null special case. */
508  if (!arg1 || afw_value_is_null(arg1)) {
509  return (!arg2 || afw_value_is_null(arg2))
511  : afw_value_false;
512  }
513  if (!arg2 || afw_value_is_null(arg2)) {
514  return afw_value_false;
515  }
516 
517  /* If either arg is NaN, return false. */
518  if (
519  (afw_value_is_double(arg1) &&
520  afw_number_is_NaN(((afw_value_double_t *)arg1)->internal))
521  ||
522  (afw_value_is_double(arg2) &&
523  afw_number_is_NaN(((afw_value_double_t *)arg2)->internal))
524  )
525  {
526  return afw_value_false;
527  }
528 
529  arg1_data_type = afw_value_get_data_type(arg1, x->xctx);
530  arg2_data_type = afw_value_get_data_type(arg2, x->xctx);
531 
532  if (arg1_data_type != arg2_data_type) {
533  arg2 = afw_function_evaluate_required_parameter(x, 2, arg1_data_type);
534  }
535 
536  cmp = afw_data_type_compare_internal(arg1_data_type,
537  AFW_VALUE_INTERNAL(arg1), AFW_VALUE_INTERNAL(arg2), x->xctx);
538 
539  return (cmp == 0) ? afw_value_true : afw_value_false;
540 }
541 
542 
543 
544 /*
545  * Common polymorphic function for eqx
546  *
547  * afw_function_execute_eqx
548  *
549  * See afw_function_bindings.h for more information.
550  *
551  * Determine if for `<dataType>` arg1 is equal to the value and data type of
552  * arg2 then return the boolean result. Use "eq" ("==") instead if you want
553  * arg2 to be converted to the data type of arg1 before comparison.
554  *
555  * This function is pure, so it will always return the same result
556  * given exactly the same parameters and has no side effects.
557  *
558  * Supported `<dataType>`:
559  *
560  * anyURI, base64Binary, boolean, date, dateTime, dayTimeDuration, dnsName,
561  * double, expression, function, hexBinary, hybrid, ia5String, integer,
562  * ipAddress, list, object, objectId, objectPath, password, regexp,
563  * rfc822Name, script, string, template, time, x500Name, xpathExpression,
564  * yearMonthDuration.
565  *
566  * Declaration:
567  *
568  * ```
569  * function eqx <dataType>(
570  * arg1: dataType,
571  * arg2: any
572  * ): boolean;
573  * ```
574  *
575  * Parameters:
576  *
577  * arg1 - (``<Type>``)
578  *
579  * arg2 - (any dataType)
580  *
581  * Returns:
582  *
583  * (boolean)
584  */
585 const afw_value_t *
588 {
589  const afw_value_t *arg1;
590  const afw_value_t *arg2;
591  const afw_data_type_t *arg1_data_type;
592  const afw_data_type_t *arg2_data_type;
593  int cmp;
594 
597 
598  /* Handle undefined/null special case. */
599  if (!arg1) {
600  return (!arg2)
602  : afw_value_false;
603  }
604  if (!arg2) {
605  return afw_value_false;
606  }
607 
608  /* If either arg is NaN, return false. */
609  if (
610  (afw_value_is_double(arg1) &&
611  afw_number_is_NaN(((afw_value_double_t *)arg1)->internal))
612  ||
613  (afw_value_is_double(arg2) &&
614  afw_number_is_NaN(((afw_value_double_t *)arg2)->internal))
615  )
616  {
617  return afw_value_false;
618  }
619 
620  arg1_data_type = afw_value_get_data_type(arg1, x->xctx);
621  arg2_data_type = afw_value_get_data_type(arg2, x->xctx);
622 
623  if (arg1_data_type != arg2_data_type) {
624  cmp = 1;
625  }
626 
627  else {
628  cmp = afw_data_type_compare_internal(arg1_data_type,
629  AFW_VALUE_INTERNAL(arg1), AFW_VALUE_INTERNAL(arg2), x->xctx);
630  }
631 
632  return (cmp == 0) ? afw_value_true : afw_value_false;
633 }
634 
635 
636 
637 /*
638  * Common polymorphic function for ge
639  *
640  * afw_function_execute_ge
641  *
642  * See afw_function_bindings.h for more information.
643  *
644  * Checks for `<dataType>` arg1 is greater than or equal to `<dataType>` arg2
645  * and return the boolean result.
646  *
647  * This function is pure, so it will always return the same result
648  * given exactly the same parameters and has no side effects.
649  *
650  * Supported `<dataType>`:
651  *
652  * anyURI, base64Binary, boolean, date, dateTime, dayTimeDuration, dnsName,
653  * double, expression, function, hexBinary, hybrid, ia5String, integer,
654  * ipAddress, list, object, objectId, objectPath, password, regexp,
655  * rfc822Name, script, string, template, time, x500Name, xpathExpression,
656  * yearMonthDuration.
657  *
658  * Declaration:
659  *
660  * ```
661  * function ge <dataType>(
662  * arg1: dataType,
663  * arg2: dataType
664  * ): boolean;
665  * ```
666  *
667  * Parameters:
668  *
669  * arg1 - (``<Type>``)
670  *
671  * arg2 - (``<Type>``)
672  *
673  * Returns:
674  *
675  * (boolean)
676  */
677 const afw_value_t *
680 {
681  const afw_value_t *arg1;
682  const afw_value_t *arg2;
683  const afw_data_type_t *arg1_data_type;
684  const afw_data_type_t *arg2_data_type;
685  int cmp;
686 
689 
690  /* If either arg is NaN, return false. */
691  if (
692  (afw_value_is_double(arg1) &&
693  afw_number_is_NaN(((afw_value_double_t *)arg1)->internal))
694  ||
695  (afw_value_is_double(arg2) &&
696  afw_number_is_NaN(((afw_value_double_t *)arg2)->internal))
697  )
698  {
699  return afw_value_false;
700  }
701 
702  arg1_data_type = afw_value_get_data_type(arg1, x->xctx);
703  arg2_data_type = afw_value_get_data_type(arg2, x->xctx);
704 
705  if (arg1_data_type != arg2_data_type) {
706  arg2 = afw_function_evaluate_required_parameter(x, 2, arg1_data_type);
707  }
708 
710  arg1_data_type,
711  AFW_VALUE_INTERNAL(arg1), AFW_VALUE_INTERNAL(arg2), x->xctx);
712 
713  return (cmp >= 0) ? afw_value_true : afw_value_false;
714 }
715 
716 
717 
718 /*
719  * Common polymorphic function for gt
720  *
721  * afw_function_execute_gt
722  *
723  * See afw_function_bindings.h for more information.
724  *
725  * Checks for `<dataType>` arg1 is greater than `<dataType>` arg2 and return
726  * the boolean result.
727  *
728  * This function is pure, so it will always return the same result
729  * given exactly the same parameters and has no side effects.
730  *
731  * Supported `<dataType>`:
732  *
733  * anyURI, base64Binary, boolean, date, dateTime, dayTimeDuration, dnsName,
734  * double, expression, function, hexBinary, hybrid, ia5String, integer,
735  * ipAddress, list, object, objectId, objectPath, password, regexp,
736  * rfc822Name, script, string, template, time, x500Name, xpathExpression,
737  * yearMonthDuration.
738  *
739  * Declaration:
740  *
741  * ```
742  * function gt <dataType>(
743  * arg1: dataType,
744  * arg2: dataType
745  * ): boolean;
746  * ```
747  *
748  * Parameters:
749  *
750  * arg1 - (``<Type>``)
751  *
752  * arg2 - (``<Type>``)
753  *
754  * Returns:
755  *
756  * (boolean)
757  */
758 const afw_value_t *
761 {
762  const afw_value_t *arg1;
763  const afw_value_t *arg2;
764  const afw_data_type_t *arg1_data_type;
765  const afw_data_type_t *arg2_data_type;
766  int cmp;
767 
770 
771  /* If either arg is NaN, return false. */
772  if (
773  (afw_value_is_double(arg1) &&
774  afw_number_is_NaN(((afw_value_double_t *)arg1)->internal))
775  ||
776  (afw_value_is_double(arg2) &&
777  afw_number_is_NaN(((afw_value_double_t *)arg2)->internal))
778  )
779  {
780  return afw_value_false;
781  }
782 
783  arg1_data_type = afw_value_get_data_type(arg1, x->xctx);
784  arg2_data_type = afw_value_get_data_type(arg2, x->xctx);
785 
786  if (arg1_data_type != arg2_data_type) {
787  arg2 = afw_function_evaluate_required_parameter(x, 2, arg1_data_type);
788  }
789 
790  cmp = afw_data_type_compare_internal(arg1_data_type,
791  AFW_VALUE_INTERNAL(arg1), AFW_VALUE_INTERNAL(arg2), x->xctx);
792 
793  return (cmp > 0) ? afw_value_true : afw_value_false;
794 }
795 
796 
797 
798 /*
799  * Common polymorphic function for includes
800  *
801  * afw_function_execute_includes
802  *
803  * See afw_function_bindings.h for more information.
804  *
805  * Checks whether the `<dataType>` value includes a string and return the
806  * boolean result.
807  *
808  * This function is pure, so it will always return the same result
809  * given exactly the same parameters and has no side effects.
810  *
811  * Supported `<dataType>`:
812  *
813  * anyURI, list, string.
814  *
815  * Declaration:
816  *
817  * ```
818  * function includes <dataType>(
819  * searchString: dataType,
820  * subString: string,
821  * position?: integer
822  * ): boolean;
823  * ```
824  *
825  * Parameters:
826  *
827  * searchString - (``<Type>``) The `<dataType>` to search.
828  *
829  * subString - (string) Substring to find.
830  *
831  * position - (optional integer) Zero-based position in the search string to
832  * start search.
833  *
834  * Returns:
835  *
836  * (boolean) Indicates if the substring is contained in the search string.
837  */
838 const afw_value_t *
841 {
842  const afw_value_t *arg1;
843  const afw_value_t *arg2;
844  const afw_value_string_t *a1;
845  const afw_value_string_t *a2;
846  const afw_value_integer_t *position;
847  const afw_utf8_octet_t *c;
848  afw_integer_t start;
849  afw_size_t len;
850 
853  AFW_FUNCTION_EVALUATE_DATA_TYPE_PARAMETER(position, 3, integer);
854 
857 
858  a1 = (const afw_value_string_t *)arg1;
859  a2 = (const afw_value_string_t *)arg2;
860 
861  c = a1->internal.s;
862  len = a1->internal.len;
863 
864  if (position) {
865  start = abs((int)position->internal) % a1->internal.len;
866 
867  if (position->internal < 0 && start != 0) {
868  start = a1->internal.len - start;
869  }
870 
871  c += start;
872  len -= start;
873  }
874 
875  for ( ; a2->internal.len <= len; c++, len--) {
876  if (memcmp(c, a2->internal.s, a2->internal.len) == 0) {
877  return afw_value_true;
878  }
879  }
880 
881  return afw_value_false;
882 }
883 
884 
885 
886 /*
887  * Common polymorphic function for index_of
888  *
889  * afw_function_execute_index_of
890  *
891  * See afw_function_bindings.h for more information.
892  *
893  * Returns the zero-based index into `<dataType>` value of subString. If
894  * subString is not found, -1 is returned.
895  *
896  * This function is pure, so it will always return the same result
897  * given exactly the same parameters and has no side effects.
898  *
899  * Supported `<dataType>`:
900  *
901  * anyURI, string.
902  *
903  * Declaration:
904  *
905  * ```
906  * function index_of <dataType>(
907  * value: dataType,
908  * subString: string,
909  * startIndex?: integer
910  * ): integer;
911  * ```
912  *
913  * Parameters:
914  *
915  * value - (``<Type>``) The `<dataType>` value to search.
916  *
917  * subString - (string) Substring to search for.
918  *
919  * startIndex - (optional integer) Optional start index for search if
920  * different than start of string.
921  *
922  * Returns:
923  *
924  * (integer) Zero-based index of subString or -1 if not found.
925  */
926 const afw_value_t *
929 {
930  const afw_value_t *arg1;
931  const afw_value_string_t *value;
932  const afw_value_string_t *subString;
933  const afw_value_integer_t *startIndex;
934  afw_size_t index;
935  afw_integer_t result;
936  afw_size_t offset;
937 
940  value = (const afw_value_string_t *)arg1;
942  index = 0;
945  3, integer);
946  index = (afw_size_t)startIndex->internal;
947  }
948 
949  result = -1;
950 
951  for (offset = 0; offset < index; ) {
952  if (afw_utf8_next_code_point(value->internal.s, &offset,
953  value->internal.len, x->xctx) < 0)
954  {
955  goto return_result;
956  }
957  }
958 
959  for (;;) {
960 
961  if (offset + subString->internal.len > value->internal.len) {
962  break;
963  }
964 
965  if (memcmp(value->internal.s + offset,
966  subString->internal.s, subString->internal.len) == 0)
967  {
968  result = index;
969  break;
970  }
971 
972  index++;
973 
974  if (afw_utf8_next_code_point(value->internal.s, &offset,
975  value->internal.len, x->xctx) < 0)
976  {
977  break;
978  }
979  }
980 
981 return_result:
982  return afw_value_create_integer(result, x->p, x->xctx);
983 }
984 
985 
986 
987 /*
988  * Common polymorphic function for intersection
989  *
990  * afw_function_execute_intersection
991  *
992  * See afw_function_bindings.h for more information.
993  *
994  * Returns a list of `<dataType>` with the values that are common to both list
995  * of `<dataType>` list1 and list2.
996  *
997  * This function is pure, so it will always return the same result
998  * given exactly the same parameters and has no side effects.
999  *
1000  * Supported `<dataType>`:
1001  *
1002  * anyURI, base64Binary, boolean, date, dateTime, dayTimeDuration, double,
1003  * hexBinary, integer, rfc822Name, string, time, x500Name, yearMonthDuration.
1004  *
1005  * Declaration:
1006  *
1007  * ```
1008  * function intersection <dataType>(
1009  * list1: list,
1010  * list2: list
1011  * ): list;
1012  * ```
1013  *
1014  * Parameters:
1015  *
1016  * list1 - (list ``<Type>``) The first list.
1017  *
1018  * list2 - (list ``<Type>``) The second list.
1019  *
1020  * Returns:
1021  *
1022  * (list ``<Type>``)
1023  */
1024 const afw_value_t *
1027 {
1028  const afw_value_list_t *list1;
1029  const afw_value_list_t *list2;
1030  const afw_iterator_t *iterator;
1031  const afw_data_type_t *data_type;
1032  const void *internal;
1033  const afw_list_t *list;
1034 
1037 
1038  data_type = afw_list_get_data_type(list1->internal, x->xctx);
1039  if (!data_type ||
1040  data_type != afw_list_get_data_type(list2->internal, x->xctx))
1041  {
1042  AFW_THROW_ERROR_Z(general,
1043  "list1 and list2 must have a data type of the same type",
1044  x->xctx);
1045  }
1046  list = afw_list_of_create(data_type, x->p, x->xctx);
1047 
1048  for (iterator = NULL;;) {
1049  afw_list_get_next_internal(list1->internal, &iterator, NULL,
1050  &internal, x->xctx);
1051  if (!internal) {
1052  break;
1053  }
1054  if (impl_is_in_list(data_type, internal, list2->internal, x->xctx)) {
1055  if (!impl_is_in_list(data_type, internal, list, x->xctx)) {
1056  afw_list_add_internal(list, data_type, internal, x->xctx);
1057  }
1058  }
1059  }
1060 
1061  return afw_value_create_list(list, x->p, x->xctx);
1062 }
1063 
1064 
1065 
1066 /*
1067  * Common polymorphic function for is_in
1068  *
1069  * afw_function_execute_is_in
1070  *
1071  * See afw_function_bindings.h for more information.
1072  *
1073  * Checks whether `<dataType>` value is in list of `<dataType>` list and
1074  * returns the boolean result.
1075  *
1076  * This function is pure, so it will always return the same result
1077  * given exactly the same parameters and has no side effects.
1078  *
1079  * Supported `<dataType>`:
1080  *
1081  * anyURI, base64Binary, boolean, date, dateTime, dayTimeDuration, dnsName,
1082  * double, hexBinary, integer, ipAddress, rfc822Name, string, time, x500Name,
1083  * yearMonthDuration.
1084  *
1085  * Declaration:
1086  *
1087  * ```
1088  * function is_in <dataType>(
1089  * value: dataType,
1090  * list: list
1091  * ): boolean;
1092  * ```
1093  *
1094  * Parameters:
1095  *
1096  * value - (``<Type>``)
1097  *
1098  * list - (list ``<Type>``)
1099  *
1100  * Returns:
1101  *
1102  * (boolean)
1103  */
1104 const afw_value_t *
1107 {
1108  const afw_value_t *value;
1109  const afw_value_list_t *list;
1110  const afw_data_type_t *data_type;
1111 
1114 
1115  data_type = afw_list_get_data_type(list->internal, x->xctx);
1116  if (!data_type || afw_value_get_data_type(value, x->xctx) != data_type) {
1117  AFW_THROW_ERROR_Z(general,
1118  "list must be list of value's data type",
1119  x->xctx);
1120  }
1121 
1122  return impl_is_in_list(data_type, AFW_VALUE_INTERNAL(value),
1123  list->internal, x->xctx)
1124  ? afw_value_true
1125  : afw_value_false;
1126 }
1127 
1128 
1129 
1130 /*
1131  * Common polymorphic function for le
1132  *
1133  * afw_function_execute_le
1134  *
1135  * See afw_function_bindings.h for more information.
1136  *
1137  * Checks for `<dataType>` arg1 is less than or equal to `<dataType>` arg2 and
1138  * return the boolean result.
1139  *
1140  * This function is pure, so it will always return the same result
1141  * given exactly the same parameters and has no side effects.
1142  *
1143  * Supported `<dataType>`:
1144  *
1145  * anyURI, base64Binary, boolean, date, dateTime, dayTimeDuration, dnsName,
1146  * double, expression, function, hexBinary, hybrid, ia5String, integer,
1147  * ipAddress, list, object, objectId, objectPath, password, regexp,
1148  * rfc822Name, script, string, template, time, x500Name, xpathExpression,
1149  * yearMonthDuration.
1150  *
1151  * Declaration:
1152  *
1153  * ```
1154  * function le <dataType>(
1155  * arg1: dataType,
1156  * arg2: any
1157  * ): boolean;
1158  * ```
1159  *
1160  * Parameters:
1161  *
1162  * arg1 - (``<Type>``)
1163  *
1164  * arg2 - (any dataType)
1165  *
1166  * Returns:
1167  *
1168  * (boolean)
1169  */
1170 const afw_value_t *
1173 {
1174  const afw_value_t *arg1;
1175  const afw_value_t *arg2;
1176  const afw_data_type_t *arg1_data_type;
1177  const afw_data_type_t *arg2_data_type;
1178  int cmp;
1179 
1182 
1183  /* If either arg is NaN, return false. */
1184  if (
1185  (afw_value_is_double(arg1) &&
1186  afw_number_is_NaN(((afw_value_double_t *)arg1)->internal))
1187  ||
1188  (afw_value_is_double(arg2) &&
1189  afw_number_is_NaN(((afw_value_double_t *)arg2)->internal))
1190  )
1191  {
1192  return afw_value_false;
1193  }
1194 
1195  arg1_data_type = afw_value_get_data_type(arg1, x->xctx);
1196  arg2_data_type = afw_value_get_data_type(arg2, x->xctx);
1197 
1198  if (arg1_data_type != arg2_data_type) {
1199  arg2 = afw_function_evaluate_required_parameter(x, 2, arg1_data_type);
1200  }
1201 
1202  cmp = afw_data_type_compare_internal(arg1_data_type,
1203  AFW_VALUE_INTERNAL(arg1), AFW_VALUE_INTERNAL(arg2), x->xctx);
1204 
1205  return (cmp <= 0) ? afw_value_true : afw_value_false;
1206 }
1207 
1208 
1209 
1210 /*
1211  * Common polymorphic function for length
1212  *
1213  * afw_function_execute_length
1214  *
1215  * See afw_function_bindings.h for more information.
1216  *
1217  * This is a polymorphic function where `<dataType>` can be any of the
1218  * supported data types. Return the integer number of entries in datatype list
1219  * or codepoints in others.
1220  *
1221  * This function is pure, so it will always return the same result
1222  * given exactly the same parameters and has no side effects.
1223  *
1224  * Supported `<dataType>`:
1225  *
1226  * anyURI, list, string.
1227  *
1228  * Declaration:
1229  *
1230  * ```
1231  * function length <dataType>(
1232  * value: dataType
1233  * ): integer;
1234  * ```
1235  *
1236  * Parameters:
1237  *
1238  * value - (``<Type>``) Returns the number of entries in a list or code
1239  * points in others.
1240  *
1241  * Returns:
1242  *
1243  * (integer)
1244  */
1245 const afw_value_t *
1248 {
1249  const afw_value_t *single;
1250  const afw_utf8_t *s;
1251  afw_size_t offset;
1252  afw_integer_t length;
1253 
1255 
1256  if (afw_value_is_list(single)) {
1257  offset = afw_list_get_count(
1258  ((const afw_value_list_t *)single)->internal, x->xctx);
1259  length = afw_safe_cast_size_to_integer(offset, x->xctx);
1260  }
1261 
1262  else {
1264  s = &((const afw_value_string_t *)single)->internal;
1265 
1266  for (length = 0, offset = 0;
1267  afw_utf8_next_code_point(s->s, &offset, s->len, x->xctx) >= 0;
1268  length++)
1269  ;
1270  }
1271 
1272  return afw_value_create_integer(length, x->p, x->xctx);
1273 }
1274 
1275 
1276 
1277 /*
1278  * Common polymorphic function for lt
1279  *
1280  * afw_function_execute_lt
1281  *
1282  * See afw_function_bindings.h for more information.
1283  *
1284  * Checks for `<dataType>` arg1 is less that `<dataType>` arg2 and return the
1285  * boolean result.
1286  *
1287  * This function is pure, so it will always return the same result
1288  * given exactly the same parameters and has no side effects.
1289  *
1290  * Supported `<dataType>`:
1291  *
1292  * anyURI, base64Binary, boolean, date, dateTime, dayTimeDuration, dnsName,
1293  * double, expression, function, hexBinary, hybrid, ia5String, integer,
1294  * ipAddress, list, object, objectId, objectPath, password, regexp,
1295  * rfc822Name, script, string, template, time, x500Name, xpathExpression,
1296  * yearMonthDuration.
1297  *
1298  * Declaration:
1299  *
1300  * ```
1301  * function lt <dataType>(
1302  * arg1: dataType,
1303  * arg2: dataType
1304  * ): boolean;
1305  * ```
1306  *
1307  * Parameters:
1308  *
1309  * arg1 - (``<Type>``)
1310  *
1311  * arg2 - (``<Type>``)
1312  *
1313  * Returns:
1314  *
1315  * (boolean)
1316  */
1317 const afw_value_t *
1320 {
1321  const afw_value_t *arg1;
1322  const afw_value_t *arg2;
1323  const afw_data_type_t *arg1_data_type;
1324  const afw_data_type_t *arg2_data_type;
1325  int cmp;
1326 
1329 
1330  /* If either arg is NaN, return false. */
1331  if (
1332  (afw_value_is_double(arg1) &&
1333  afw_number_is_NaN(((afw_value_double_t *)arg1)->internal))
1334  ||
1335  (afw_value_is_double(arg2) &&
1336  afw_number_is_NaN(((afw_value_double_t *)arg2)->internal))
1337  )
1338  {
1339  return afw_value_false;
1340  }
1341 
1342  arg1_data_type = afw_value_get_data_type(arg1, x->xctx);
1343  arg2_data_type = afw_value_get_data_type(arg2, x->xctx);
1344 
1345  if (arg1_data_type != arg2_data_type) {
1346  arg2 = afw_function_evaluate_required_parameter(x, 2, arg1_data_type);
1347  }
1348 
1349  cmp = afw_data_type_compare_internal(arg1_data_type,
1350  AFW_VALUE_INTERNAL(arg1), AFW_VALUE_INTERNAL(arg2), x->xctx);
1351 
1352  return (cmp < 0) ? afw_value_true : afw_value_false;
1353 }
1354 
1355 
1356 
1357 /*
1358  * Common polymorphic function for max
1359  *
1360  * afw_function_execute_max
1361  *
1362  * See afw_function_bindings.h for more information.
1363  *
1364  * Return the `<dataType>` value that is greater than or equal to the others.
1365  *
1366  * This function is pure, so it will always return the same result
1367  * given exactly the same parameters and has no side effects.
1368  *
1369  * Supported `<dataType>`:
1370  *
1371  * date, dateTime, double, integer, string, time.
1372  *
1373  * Declaration:
1374  *
1375  * ```
1376  * function max <dataType>(
1377  * values_1: dataType,
1378  * ...values_rest: (list of dataType)
1379  * ): dataType;
1380  * ```
1381  *
1382  * Parameters:
1383  *
1384  * values - (1 or more ``<Type>``)
1385  *
1386  * Returns:
1387  *
1388  * (``<Type>``)
1389  */
1390 const afw_value_t *
1393 {
1394  const afw_value_t *arg_max;
1395  const afw_value_t *arg;
1396  const afw_data_type_t *data_type;
1397  afw_size_t i;
1398  int cmp;
1399 
1401  data_type = afw_value_get_data_type(arg_max, x->xctx);
1402 
1403  for (i = 2; i <= x->argc; i++) {
1405  arg = afw_value_convert(arg, data_type, true, x->p, x->xctx);
1406  cmp = afw_data_type_compare_internal(data_type,
1407  AFW_VALUE_INTERNAL(arg_max), AFW_VALUE_INTERNAL(arg), x->xctx);
1408  if (cmp < 0) {
1409  arg_max = arg;
1410  }
1411  }
1412 
1413  return arg_max;
1414 }
1415 
1416 
1417 
1418 /*
1419  * Common polymorphic function for min
1420  *
1421  * afw_function_execute_min
1422  *
1423  * See afw_function_bindings.h for more information.
1424  *
1425  * Return the `<dataType>` value that is less than or equal to the others.
1426  *
1427  * This function is pure, so it will always return the same result
1428  * given exactly the same parameters and has no side effects.
1429  *
1430  * Supported `<dataType>`:
1431  *
1432  * date, dateTime, double, integer, string, time.
1433  *
1434  * Declaration:
1435  *
1436  * ```
1437  * function min <dataType>(
1438  * values_1: dataType,
1439  * ...values_rest: (list of dataType)
1440  * ): dataType;
1441  * ```
1442  *
1443  * Parameters:
1444  *
1445  * values - (1 or more ``<Type>``)
1446  *
1447  * Returns:
1448  *
1449  * (``<Type>``)
1450  */
1451 const afw_value_t *
1454 {
1455  const afw_value_t *arg_min;
1456  const afw_value_t *arg;
1457  const afw_data_type_t *data_type;
1458  afw_size_t i;
1459  int cmp;
1460 
1462  data_type = afw_value_get_data_type(arg_min, x->xctx);
1463 
1464  for (i = 2; i <= x->argc; i++) {
1466  arg = afw_value_convert(arg, data_type, true, x->p, x->xctx);
1467  cmp = afw_data_type_compare_internal(data_type,
1468  AFW_VALUE_INTERNAL(arg_min), AFW_VALUE_INTERNAL(arg), x->xctx);
1469  if (cmp > 0) {
1470  arg_min = arg;
1471  }
1472  }
1473 
1474  return arg_min;
1475 }
1476 
1477 
1478 
1479 /*
1480  * Common polymorphic function for ne
1481  *
1482  * afw_function_execute_ne
1483  *
1484  * See afw_function_bindings.h for more information.
1485  *
1486  * Determine if `<dataType>` arg1 is not equal to the value of arg2 converted
1487  * to the data type of arg1 then return the boolean result. Use "nex" ("!==")
1488  * instead if you want true to be returned if arg1 and arg2's data type don't
1489  * match.
1490  *
1491  * This function is pure, so it will always return the same result
1492  * given exactly the same parameters and has no side effects.
1493  *
1494  * Supported `<dataType>`:
1495  *
1496  * anyURI, base64Binary, boolean, date, dateTime, dayTimeDuration, dnsName,
1497  * double, expression, function, hexBinary, hybrid, ia5String, integer,
1498  * ipAddress, list, object, objectId, objectPath, password, regexp,
1499  * rfc822Name, script, string, template, time, x500Name, xpathExpression,
1500  * yearMonthDuration.
1501  *
1502  * Declaration:
1503  *
1504  * ```
1505  * function ne <dataType>(
1506  * arg1: dataType,
1507  * arg2: any
1508  * ): boolean;
1509  * ```
1510  *
1511  * Parameters:
1512  *
1513  * arg1 - (``<Type>``)
1514  *
1515  * arg2 - (any dataType)
1516  *
1517  * Returns:
1518  *
1519  * (boolean)
1520  *
1521  * Errors thrown:
1522  *
1523  * conversion - arg2 cannot be converted to the data type of arg1.
1524  */
1525 const afw_value_t *
1528 {
1529  const afw_value_t *arg1;
1530  const afw_value_t *arg2;
1531  const afw_data_type_t *arg1_data_type;
1532  const afw_data_type_t *arg2_data_type;
1533  int cmp;
1534 
1537 
1538  /* Handle undefined/null special case. */
1539  if (!arg1 || afw_value_is_null(arg1)) {
1540  return (!arg2 || afw_value_is_null(arg2))
1541  ? afw_value_false
1542  : afw_value_true;
1543  }
1544  if (!arg2 || afw_value_is_null(arg2)) {
1545  return afw_value_true;
1546  }
1547 
1548  /* If either arg is NaN, return false. */
1549  if (
1550  (afw_value_is_double(arg1) &&
1551  afw_number_is_NaN(((afw_value_double_t *)arg1)->internal))
1552  ||
1553  (afw_value_is_double(arg2) &&
1554  afw_number_is_NaN(((afw_value_double_t *)arg2)->internal))
1555  )
1556  {
1557  return afw_value_true;
1558  }
1559 
1560  arg1_data_type = afw_value_get_data_type(arg1, x->xctx);
1561  arg2_data_type = afw_value_get_data_type(arg2, x->xctx);
1562 
1563  if (arg1_data_type != arg2_data_type) {
1564  arg2 = afw_function_evaluate_required_parameter(x, 2, arg1_data_type);
1565  }
1566 
1567  cmp = afw_data_type_compare_internal(arg1_data_type,
1568  AFW_VALUE_INTERNAL(arg1), AFW_VALUE_INTERNAL(arg2), x->xctx);
1569 
1570  return (cmp == 0)
1571  ? afw_value_false
1572  : afw_value_true;
1573 }
1574 
1575 
1576 
1577 /*
1578  * Common polymorphic function for nex
1579  *
1580  * afw_function_execute_nex
1581  *
1582  * See afw_function_bindings.h for more information.
1583  *
1584  * Determine if for `<dataType>` arg1 is not equal to the value or data type of
1585  * arg2 then return the boolean result. Use "ne" ("!=") instead if you want
1586  * arg2 to be converted to the data type of arg1 before comparison.
1587  *
1588  * This function is pure, so it will always return the same result
1589  * given exactly the same parameters and has no side effects.
1590  *
1591  * Supported `<dataType>`:
1592  *
1593  * anyURI, base64Binary, boolean, date, dateTime, dayTimeDuration, dnsName,
1594  * double, expression, function, hexBinary, hybrid, ia5String, integer,
1595  * ipAddress, list, object, objectId, objectPath, password, rfc822Name,
1596  * regexp, script, string, template, time, x500Name, xpathExpression,
1597  * yearMonthDuration.
1598  *
1599  * Declaration:
1600  *
1601  * ```
1602  * function nex <dataType>(
1603  * arg1: dataType,
1604  * arg2: any
1605  * ): boolean;
1606  * ```
1607  *
1608  * Parameters:
1609  *
1610  * arg1 - (``<Type>``)
1611  *
1612  * arg2 - (any dataType)
1613  *
1614  * Returns:
1615  *
1616  * (boolean)
1617  */
1618 const afw_value_t *
1621 {
1622  const afw_value_t *arg1;
1623  const afw_value_t *arg2;
1624  const afw_data_type_t *arg1_data_type;
1625  const afw_data_type_t *arg2_data_type;
1626  int cmp;
1627 
1630 
1631  /* Handle undefined/null special case. */
1632  if (!arg1) {
1633  return (!arg2)
1634  ? afw_value_false
1635  : afw_value_true;
1636  }
1637  if (!arg2) {
1638  return afw_value_true;
1639  }
1640 
1641  /* If either arg is NaN, return false. */
1642  if (
1643  (afw_value_is_double(arg1) &&
1644  afw_number_is_NaN(((afw_value_double_t *)arg1)->internal))
1645  ||
1646  (afw_value_is_double(arg2) &&
1647  afw_number_is_NaN(((afw_value_double_t *)arg2)->internal))
1648  )
1649  {
1650  return afw_value_true;
1651  }
1652 
1653  arg1_data_type = afw_value_get_data_type(arg1, x->xctx);
1654  arg2_data_type = afw_value_get_data_type(arg2, x->xctx);
1655 
1656  if (arg1_data_type != arg2_data_type) {
1657  cmp = 1;
1658  }
1659 
1660  else {
1661  cmp = afw_data_type_compare_internal(arg1_data_type,
1662  AFW_VALUE_INTERNAL(arg1), AFW_VALUE_INTERNAL(arg2), x->xctx);
1663  }
1664 
1665  return (cmp == 0) ? afw_value_false : afw_value_true;
1666 }
1667 
1668 
1669 
1670 /*
1671  * Common polymorphic function for one_and_only
1672  *
1673  * afw_function_execute_one_and_only
1674  *
1675  * See afw_function_bindings.h for more information.
1676  *
1677  * This converts a list of `<dataType>` values that contains one value to a
1678  * single `<dataType>` value.
1679  *
1680  * This function is pure, so it will always return the same result
1681  * given exactly the same parameters and has no side effects.
1682  *
1683  * Supported `<dataType>`:
1684  *
1685  * anyURI, base64Binary, boolean, date, dateTime, dayTimeDuration, dnsName,
1686  * double, hexBinary, integer, ipAddress, rfc822Name, string, time, x500Name,
1687  * yearMonthDuration.
1688  *
1689  * Declaration:
1690  *
1691  * ```
1692  * function one_and_only <dataType>(
1693  * list: (list list)
1694  * ): dataType;
1695  * ```
1696  *
1697  * Parameters:
1698  *
1699  * list - (list list)
1700  *
1701  * Returns:
1702  *
1703  * (``<Type>``)
1704  *
1705  * Errors thrown:
1706  *
1707  * arg_error - list does not contain exactly one value
1708  */
1709 const afw_value_t *
1712 {
1713  const afw_value_list_t *list;
1714  const afw_data_type_t *data_type;
1715  const void *internal;
1716  const afw_iterator_t *iterator;
1717 
1719  if (afw_list_get_count(list->internal, x->xctx) != 1) {
1720  AFW_THROW_ERROR_Z(arg_error,
1721  "arg must have exactly one value", x->xctx);
1722  }
1723 
1724  iterator = NULL;
1725  afw_list_get_next_internal(list->internal,
1726  &iterator, &data_type, &internal, x->xctx);
1727 
1728  return afw_value_evaluated_create(internal, data_type, x->p, x->xctx);
1729 }
1730 
1731 
1732 
1733 /*
1734  * Common polymorphic function for regexp_match
1735  *
1736  * afw_function_execute_regexp_match
1737  *
1738  * See afw_function_bindings.h for more information.
1739  *
1740  * Checks whether `<dataType>` value matches the regular expression regexp and
1741  * return the boolean result.
1742  *
1743  * This function is pure, so it will always return the same result
1744  * given exactly the same parameters and has no side effects.
1745  *
1746  * Supported `<dataType>`:
1747  *
1748  * anyURI, dnsName, ipAddress, rfc822Name, string, x500Name.
1749  *
1750  * Declaration:
1751  *
1752  * ```
1753  * function regexp_match <dataType>(
1754  * value: dataType,
1755  * regexp: string
1756  * ): boolean;
1757  * ```
1758  *
1759  * Parameters:
1760  *
1761  * value - (``<Type>``)
1762  *
1763  * regexp - (string)
1764  *
1765  * Returns:
1766  *
1767  * (boolean)
1768  */
1769 const afw_value_t *
1772 {
1773  xmlRegexpPtr rx = NULL;
1774  const afw_value_t *arg1;
1775  const afw_value_string_t *arg2;
1776  const xmlChar * s_z;
1777  const xmlChar * regexp_z;
1778  const afw_utf8_t *err_message;
1779  xmlErrorPtr err;
1780  const afw_value_t *result;
1781 
1785 
1786  s_z = BAD_CAST afw_utf8_to_utf8_z(
1787  (const afw_utf8_t *)AFW_VALUE_INTERNAL(arg1), x->p, x->xctx);
1788  regexp_z = BAD_CAST afw_utf8_to_utf8_z(&arg2->internal, x->p, x->xctx);
1789  rx = xmlRegexpCompile(regexp_z);
1790  if (rx == NULL) {
1791  err = xmlGetLastError();
1792  err_message = afw_utf8_create_copy(err->message, AFW_UTF8_Z_LEN,
1793  x->p, x->xctx);
1794  xmlResetError(err);
1795  xmlRegFreeRegexp(rx);
1796  AFW_THROW_ERROR_FZ(arg_error, x->xctx,
1797  "%" AFW_UTF8_FMT,
1798  AFW_UTF8_FMT_ARG(err_message));
1799  }
1800 
1801  /* xmlRegexpExec returns: 1 if it matches, 0 if not */
1802  result = xmlRegexpExec(rx, s_z) == 0 ? afw_value_false : afw_value_true;
1803  xmlRegFreeRegexp(rx);
1804 
1805  return result;
1806 }
1807 
1808 
1809 
1810 /*
1811  * Common polymorphic function for repeat
1812  *
1813  * afw_function_execute_repeat
1814  *
1815  * See afw_function_bindings.h for more information.
1816  *
1817  * Repeat a `<dataType>` value a specified number of times.
1818  *
1819  * This function is pure, so it will always return the same result
1820  * given exactly the same parameters and has no side effects.
1821  *
1822  * Supported `<dataType>`:
1823  *
1824  * anyURI, string.
1825  *
1826  * Declaration:
1827  *
1828  * ```
1829  * function repeat <dataType>(
1830  * value: dataType,
1831  * times: integer
1832  * ): dataType;
1833  * ```
1834  *
1835  * Parameters:
1836  *
1837  * value - (``<Type>``) The `<dataType>` value to repeat.
1838  *
1839  * times - (integer) The number of times to repeat the value.
1840  *
1841  * Returns:
1842  *
1843  * (``<Type>``) The repeated `<dataType>` value.
1844  */
1845 const afw_value_t *
1848 {
1849  const afw_value_t *single;
1850  const afw_value_string_t *value;
1851  const afw_value_integer_t *times;
1852  afw_value_string_t *result;
1853  afw_utf8_octet_t *s;
1854  afw_integer_t count;
1855 
1858  value = (const afw_value_string_t *)single;
1860 
1861  if (times->internal <= 0) {
1862  return afw_value_empty_string;
1863  }
1864 
1866  if (times->internal > 1000) {
1867  AFW_THROW_ERROR_Z(general, "Parameter times exceeds 1000", x->xctx);
1868  }
1869 
1870  result = afw_value_allocate_string(x->p, x->xctx);
1871  result->internal.len = (afw_size_t)times->internal * value->internal.len;
1872  result->internal.s = s = afw_pool_malloc(x->p,
1873  result->internal.len, x->xctx);
1874  for (count = times->internal; count > 0; count--) {
1875  memcpy(s, value->internal.s, value->internal.len);
1876  s += value->internal.len;
1877  }
1878 
1879  return (const afw_value_t *)result;
1880 }
1881 
1882 
1883 
1884 /*
1885  * Common polymorphic function for replace
1886  *
1887  * afw_function_execute_replace
1888  *
1889  * See afw_function_bindings.h for more information.
1890  *
1891  * Replace string(s) in a `<dataType>` value.
1892  *
1893  * This function is pure, so it will always return the same result
1894  * given exactly the same parameters and has no side effects.
1895  *
1896  * Supported `<dataType>`:
1897  *
1898  * anyURI, string.
1899  *
1900  * Declaration:
1901  *
1902  * ```
1903  * function replace <dataType>(
1904  * value: dataType,
1905  * match: string,
1906  * replacement: string,
1907  * limit?: integer
1908  * ): dataType;
1909  * ```
1910  *
1911  * Parameters:
1912  *
1913  * value - (``<Type>``) The original `<dataType>` value.
1914  *
1915  * match - (string) The string to replace.
1916  *
1917  * replacement - (string) The replacement string.
1918  *
1919  * limit - (optional integer) This is the maximum times to replace. The
1920  * default is 1. Specify -1 to replace all occurrences.
1921  *
1922  * Returns:
1923  *
1924  * (``<Type>``) A `<dataType>` value with the matched string(s) replaced.
1925  */
1926 const afw_value_t *
1929 {
1930  const afw_value_t *value;
1931  const afw_value_string_t *match;
1932  const afw_value_string_t *replacement;
1933  const afw_value_integer_t *limit_value;
1934  afw_value_string_t *result;
1935  afw_size_t count;
1936  afw_size_t limit;
1937  afw_utf8_t remaining;
1938  afw_utf8_octet_t *s;
1939  afw_size_t len;
1940 
1945 
1946  limit = 1;
1948  {
1950  limit_value, 4, integer);
1951  limit = (limit_value->internal < 0 ||
1952  limit_value->internal > AFW_SIZE_T_MAX)
1953  ? AFW_SIZE_T_MAX
1954  : (afw_size_t)limit_value->internal;
1955  }
1956 
1957  /* If limit is 0, return value. */
1958  if (limit == 0) {
1959  return value;
1960  }
1961 
1962  /* Count number of replacement that will be made. */
1963  afw_memory_copy(&remaining, &(((afw_value_string_t *)value)->internal));
1964  if (remaining.len == 0) {
1965  return afw_value_empty_string;
1966  }
1967  for (count = 0; count < limit && remaining.len > match->internal.len; )
1968  {
1969  for (;
1970  remaining.len >= match->internal.len;
1971  remaining.s++, remaining.len--)
1972  {
1973  if (memcmp(remaining.s, match->internal.s, match->internal.len)
1974  == 0)
1975  {
1976  remaining.s += match->internal.len;
1977  remaining.len -= match->internal.len;
1978  count++;
1979  break;
1980  }
1981  }
1982  }
1983 
1984  /* If no replacements, just return value. */
1985  if (count == 0) {
1986  return value;
1987  }
1988 
1989  /* Make a result string large enough to hold replacement. */
1990  afw_memory_copy(&remaining, &(((afw_value_string_t *)value)->internal));
1991  len = remaining.len - (count * match->internal.len) +
1992  (count * replacement->internal.len);
1993  s = afw_pool_malloc(x->p, len, x->xctx);
1994  result = afw_value_allocate_string(x->p, x->xctx);
1995  result->internal.len = len;
1996  result->internal.s = s;
1997 
1998  /* Do replaces and return result. */
1999  for (; count > 0; count--) {
2000  for (;;) {
2001  if (memcmp(remaining.s, match->internal.s, match->internal.len) == 0)
2002  {
2003  memcpy(s, replacement->internal.s, replacement->internal.len);
2004  s += replacement->internal.len;
2005  remaining.s += match->internal.len;
2006  remaining.len -= match->internal.len;
2007  break;
2008  }
2009  else {
2010  *s++ = *remaining.s++;
2011  remaining.len--;
2012  }
2013  }
2014  }
2015  if (remaining.len > 0) {
2016  memcpy(s, remaining.s, remaining.len);
2017  }
2018  return (const afw_value_t *)result;
2019 }
2020 
2021 
2022 
2023 /*
2024  * Common polymorphic function for set_equals
2025  *
2026  * afw_function_execute_set_equals
2027  *
2028  * See afw_function_bindings.h for more information.
2029  *
2030  * Returns boolean true if `<dataType>` list1 and `<dataType>` list2 are
2031  * subsets of each other and return the boolean result.
2032  *
2033  * This function is pure, so it will always return the same result
2034  * given exactly the same parameters and has no side effects.
2035  *
2036  * Supported `<dataType>`:
2037  *
2038  * anyURI, base64Binary, boolean, date, dateTime, dayTimeDuration, double,
2039  * hexBinary, integer, rfc822Name, string, time, x500Name, yearMonthDuration.
2040  *
2041  * Declaration:
2042  *
2043  * ```
2044  * function set_equals <dataType>(
2045  * list1: list,
2046  * list2: list
2047  * ): boolean;
2048  * ```
2049  *
2050  * Parameters:
2051  *
2052  * list1 - (list ``<Type>``)
2053  *
2054  * list2 - (list ``<Type>``)
2055  *
2056  * Returns:
2057  *
2058  * (boolean)
2059  */
2060 const afw_value_t *
2063 {
2064  const afw_value_list_t *list1;
2065  const afw_value_list_t *list2;
2066  const afw_data_type_t *data_type_1;
2067  const afw_data_type_t *data_type_2;
2068 
2071 
2072  data_type_1 = afw_list_get_data_type(list1->internal, x->xctx);
2073  data_type_2 = afw_list_get_data_type(list2->internal, x->xctx);
2074  if (!data_type_1 || data_type_1 != data_type_2) {
2075  AFW_THROW_ERROR_Z(arg_error,
2076  "list1 and list2 must have a data type that matches", x->xctx);
2077  }
2078 
2079  return (impl_is_subset_list(list1->internal, list2->internal, x->xctx) &&
2080  impl_is_subset_list(list2->internal, list1->internal, x->xctx))
2081  ? afw_value_true
2082  : afw_value_false;
2083 }
2084 
2085 
2086 
2087 /*
2088  * Common polymorphic function for split
2089  *
2090  * afw_function_execute_split
2091  *
2092  * See afw_function_bindings.h for more information.
2093  *
2094  * Split `<dataType>` value into an list of strings using a separator.
2095  *
2096  * This function is pure, so it will always return the same result
2097  * given exactly the same parameters and has no side effects.
2098  *
2099  * Supported `<dataType>`:
2100  *
2101  * anyURI, string.
2102  *
2103  * Declaration:
2104  *
2105  * ```
2106  * function split <dataType>(
2107  * value: dataType,
2108  * separator?: string,
2109  * limit?: integer
2110  * ): list;
2111  * ```
2112  *
2113  * Parameters:
2114  *
2115  * value - (``<Type>``) The `<dataType>` value to split.
2116  *
2117  * separator - (optional string) The separator to use. If this is an empty
2118  * string or separator is not specified, the value is split between
2119  * characters.
2120  *
2121  * limit - (optional integer) This is the maximum number of splits. Any
2122  * remaining part of value is ignored.
2123  *
2124  * Returns:
2125  *
2126  * (list) An list of strings.
2127  */
2128 const afw_value_t *
2131 {
2132  const afw_value_t *value;
2133  const afw_value_string_t *separator_value;
2134  const afw_value_integer_t *limit_value;
2135  const afw_list_t *list;
2136  const afw_value_t *result;
2137  const afw_utf8_t *separator;
2138  afw_integer_t count;
2139  afw_integer_t limit;
2140  afw_utf8_t remaining;
2141  afw_utf8_t split;
2142 
2145 
2146  separator = NULL;
2149  2, string);
2150  separator = &separator_value->internal;
2151  if (separator->len == 0) {
2152  separator = NULL;
2153  }
2154  }
2155 
2156  limit = AFW_INTEGER_MAX;
2159  3, integer);
2160  limit = limit_value->internal;
2161  }
2162 
2164  x->p, x->xctx);
2165  result = afw_value_create_list(list, x->p, x->xctx);
2166  afw_memory_copy(&remaining, &(((afw_value_string_t *)value)->internal));
2167 
2168  if (separator) {
2169  for (count = 0; count < limit && remaining.len > 0; count++) {
2170  for (split.s = remaining.s, split.len = remaining.len;
2171  ;
2172  remaining.s++, remaining.len--)
2173  {
2174  if (remaining.len < separator->len) {
2175  remaining.len = 0;
2176  break;
2177  }
2178  if (memcmp(remaining.s, separator->s, separator->len) == 0) {
2179  split.len = remaining.s - split.s;
2180  remaining.s += separator->len;
2181  remaining.len -= separator->len;
2182  break;
2183  }
2184  }
2186  (const void *)&split, x->xctx);
2187  }
2188  }
2189 
2190  else {
2191  for (count = 0; count < limit && remaining.len > 0; count++) {
2192  split.s = remaining.s;
2193  split.len = 1;
2194  remaining.s++;
2195  remaining.len--;
2197  (const void *)&split, x->xctx);
2198  }
2199  }
2200 
2201  return result;
2202 }
2203 
2204 
2205 
2206 /*
2207  * Common polymorphic function for starts_with
2208  *
2209  * afw_function_execute_starts_with
2210  *
2211  * See afw_function_bindings.h for more information.
2212  *
2213  * Checks whether `<dataType>` value starts with a subString and return the
2214  * boolean result.
2215  *
2216  * This function is pure, so it will always return the same result
2217  * given exactly the same parameters and has no side effects.
2218  *
2219  * Supported `<dataType>`:
2220  *
2221  * anyURI, string.
2222  *
2223  * Declaration:
2224  *
2225  * ```
2226  * function starts_with <dataType>(
2227  * value: dataType,
2228  * subString: string
2229  * ): boolean;
2230  * ```
2231  *
2232  * Parameters:
2233  *
2234  * value - (``<Type>``)
2235  *
2236  * subString - (string)
2237  *
2238  * Returns:
2239  *
2240  * (boolean)
2241  */
2242 const afw_value_t *
2245 {
2246  const afw_value_t *arg1;
2247  const afw_value_t *arg2;
2248  const afw_value_string_t *a1;
2249  const afw_value_string_t *a2;
2250 
2255 
2256  a1 = (const afw_value_string_t *)arg1;
2257  a2 = (const afw_value_string_t *)arg2;
2258 
2259  return
2260  (
2261  a1->internal.len >= a2->internal.len &&
2262  memcmp(a1->internal.s, a2->internal.s, a2->internal.len) == 0
2263  )
2264  ? afw_value_true
2265  : afw_value_false;
2266 }
2267 
2268 
2269 
2270 /*
2271  * Common polymorphic function for subset
2272  *
2273  * afw_function_execute_subset
2274  *
2275  * See afw_function_bindings.h for more information.
2276  *
2277  * Returns boolean true if the unique values in `<dataType>` list1 are all in
2278  * `<dataType>` list2.
2279  *
2280  * This function is pure, so it will always return the same result
2281  * given exactly the same parameters and has no side effects.
2282  *
2283  * Supported `<dataType>`:
2284  *
2285  * anyURI, base64Binary, boolean, date, dateTime, dayTimeDuration, double,
2286  * hexBinary, integer, rfc822Name, string, time, x500Name, yearMonthDuration.
2287  *
2288  * Declaration:
2289  *
2290  * ```
2291  * function subset <dataType>(
2292  * list1: list,
2293  * list2: list
2294  * ): boolean;
2295  * ```
2296  *
2297  * Parameters:
2298  *
2299  * list1 - (list ``<Type>``) The first list.
2300  *
2301  * list2 - (list ``<Type>``) The second list.
2302  *
2303  * Returns:
2304  *
2305  * (boolean)
2306  */
2307 const afw_value_t *
2310 {
2311  const afw_value_list_t *list1;
2312  const afw_value_list_t *list2;
2313  const afw_data_type_t *data_type_1;
2314  const afw_data_type_t *data_type_2;
2315 
2318 
2319  data_type_1 = afw_list_get_data_type(list1->internal, x->xctx);
2320  data_type_2 = afw_list_get_data_type(list2->internal, x->xctx);
2321  if (!data_type_1 || data_type_1 != data_type_2) {
2322  AFW_THROW_ERROR_Z(arg_error,
2323  "list1 and list2 must have a data type that matches", x->xctx);
2324  }
2325 
2326  return impl_is_subset_list(list1->internal, list2->internal, x->xctx)
2327  ? afw_value_true
2328  : afw_value_false;
2329 }
2330 
2331 
2332 
2333 /*
2334  * Common polymorphic function for substring
2335  *
2336  * afw_function_execute_substring
2337  *
2338  * See afw_function_bindings.h for more information.
2339  *
2340  * Returns the `<dataType>` substring of value beginning at zero-based position
2341  * integer startIndex and ending at the position before integer endIndex.
2342  * Specify -1 or omitting endIndex to return up to end of `<dataType>`.
2343  *
2344  * This function is pure, so it will always return the same result
2345  * given exactly the same parameters and has no side effects.
2346  *
2347  * Supported `<dataType>`:
2348  *
2349  * anyURI, string.
2350  *
2351  * Declaration:
2352  *
2353  * ```
2354  * function substring <dataType>(
2355  * string: dataType,
2356  * startIndex: integer,
2357  * endIndex?: integer
2358  * ): dataType;
2359  * ```
2360  *
2361  * Parameters:
2362  *
2363  * string - (``<Type>``)
2364  *
2365  * startIndex - (integer)
2366  *
2367  * endIndex - (optional integer)
2368  *
2369  * Returns:
2370  *
2371  * (``<Type>``)
2372  *
2373  * Errors thrown:
2374  *
2375  * arg_error - startIndex or endIndex is out of range
2376  */
2377 const afw_value_t *
2380 {
2381  const afw_value_t *string;
2382  const afw_value_integer_t *startIndex;
2383  const afw_value_integer_t *endIndex;
2384  const afw_utf8_t *s;
2385  afw_size_t offset;
2386  afw_size_t pos;
2387  afw_size_t start;
2388  afw_size_t end;
2389  afw_utf8_t substring;
2390 
2391  /* string -> s */
2394  s = AFW_VALUE_INTERNAL(string);
2395 
2396  /* startIndex -> start */
2398  integer);
2399  if (startIndex->internal < 0) {
2400  AFW_THROW_ERROR_Z(arg_error, "startIndex is out of bounds", x->xctx);
2401  }
2402  start = afw_safe_cast_integer_to_size(startIndex->internal, x->xctx);
2403 
2404  /* endIndex -> end */
2405  end = -1;
2408  integer);
2409  if (endIndex->internal < -1 ||
2410  (endIndex->internal != -1 &&
2411  startIndex->internal >= endIndex->internal))
2412  {
2413  AFW_THROW_ERROR_Z(arg_error, "endIndex is out of bounds", x->xctx);
2414  }
2415  end = afw_safe_cast_integer_to_size(endIndex->internal, x->xctx);
2416  }
2417 
2418  /* Set substring.s */
2419  memset(&substring, 0, sizeof(afw_utf8_t));
2420  for (offset = 0, pos = 0; pos < start; pos++)
2421  {
2422  if (afw_utf8_next_code_point(s->s, &offset, s->len, x->xctx) < 0) {
2423  AFW_THROW_ERROR_Z(arg_error,
2424  "startIndex is out of bounds", x->xctx);
2425  }
2426  }
2427  substring.s = s->s + offset;
2428 
2429  /* Set substring.len */
2430  if (end == -1) {
2431  substring.len = s->s + s->len - substring.s;
2432  }
2433  else {
2434  for (; pos < end; pos++)
2435  {
2436  if (afw_utf8_next_code_point(s->s, &offset, s->len, x->xctx) < 0) {
2437  AFW_THROW_ERROR_Z(arg_error,
2438  "startIndex and/or endIndex is out of bounds", x->xctx);
2439  }
2440  }
2441  substring.len = s->s + offset - substring.s;
2442  }
2443 
2444  /* Return substring. */
2445  return afw_value_create_string(&substring, x->p, x->xctx);
2446 }
2447 
2448 
2449 
2450 /*
2451  * Common polymorphic function for union
2452  *
2453  * afw_function_execute_union
2454  *
2455  * See afw_function_bindings.h for more information.
2456  *
2457  * Returns a list of `<dataType>` contains all of the unique values in two or
2458  * more list of `<dataType>` values.
2459  *
2460  * This function is pure, so it will always return the same result
2461  * given exactly the same parameters and has no side effects.
2462  *
2463  * Supported `<dataType>`:
2464  *
2465  * anyURI, base64Binary, boolean, date, dateTime, dayTimeDuration, double,
2466  * hexBinary, integer, rfc822Name, string, time, x500Name, yearMonthDuration.
2467  *
2468  * Declaration:
2469  *
2470  * ```
2471  * function union <dataType>(
2472  * lists_1: list,
2473  * lists_2: list,
2474  * ...lists_rest: (list of list)
2475  * ): list;
2476  * ```
2477  *
2478  * Parameters:
2479  *
2480  * lists - (2 or more list ``<Type>``) Two or more lists.
2481  *
2482  * Returns:
2483  *
2484  * (list ``<Type>``)
2485  */
2486 const afw_value_t *
2489 {
2490  const afw_value_list_t *list1;
2491  const afw_value_list_t *listn;
2492  const afw_data_type_t *data_type;
2493  const afw_list_t *list;
2494  afw_size_t i;
2495 
2497 
2498  data_type = afw_list_get_data_type(list1->internal, x->xctx);
2499  if (!data_type)
2500  {
2501  AFW_THROW_ERROR_Z(general,
2502  "all lists must have the same data type",
2503  x->xctx);
2504  }
2505 
2506  list = afw_list_of_create(data_type, x->p, x->xctx);
2507  impl_add_nondups_to_list(data_type, list1->internal, list, x->xctx);
2508  for (i = 2; i <= x->argc; i++) {
2510  if (afw_list_get_data_type(listn->internal, x->xctx) != data_type) {
2511  AFW_THROW_ERROR_Z(general,
2512  "all lists must have the same data type",
2513  x->xctx);
2514  }
2515  impl_add_nondups_to_list(data_type, listn->internal, list, x->xctx);
2516  }
2517 
2518  return afw_value_create_list(list, x->p, x->xctx);
2519 }
2520 
2521 
2522 
2523 /*
2524  * Common polymorphic function for last_index_of
2525  *
2526  * afw_function_execute_last_index_of
2527  *
2528  * See afw_function_bindings.h for more information.
2529  *
2530  * Returns the zero-based index into `<dataType>` value of the last occurrence
2531  * of a subString. If subString is not found, -1 is returned.
2532  *
2533  * This function is pure, so it will always return the same result
2534  * given exactly the same parameters and has no side effects.
2535  *
2536  * Supported `<dataType>`:
2537  *
2538  * anyURI, string.
2539  *
2540  * Declaration:
2541  *
2542  * ```
2543  * function last_index_of <dataType>(
2544  * value: dataType,
2545  * subString: string,
2546  * startIndex?: integer
2547  * ): integer;
2548  * ```
2549  *
2550  * Parameters:
2551  *
2552  * value - (``<Type>``) The `<dataType>` value to search.
2553  *
2554  * subString - (string) Substring to search for.
2555  *
2556  * startIndex - (optional integer) Optional start index for search if
2557  * different than start of string.
2558  *
2559  * Returns:
2560  *
2561  * (integer) Zero-based index of subString or -1 if not found.
2562  */
2563 const afw_value_t *
2566 {
2567  const afw_value_t *arg1;
2568  const afw_value_string_t *value;
2569  const afw_value_string_t *subString;
2570  const afw_value_integer_t *startIndex;
2571  afw_size_t index;
2572  afw_integer_t result;
2573  afw_size_t offset;
2574 
2577  value = (const afw_value_string_t *)arg1;
2579  2, string);
2580  index = 0;
2583  3, integer);
2584  index = (afw_size_t)startIndex->internal;
2585  }
2586 
2587  result = -1;
2588 
2589  for (offset = 0; offset < index; ) {
2590  if (afw_utf8_next_code_point(value->internal.s, &offset,
2591  value->internal.len, x->xctx) < 0)
2592  {
2593  goto return_result;
2594  }
2595  }
2596 
2597  for (;;) {
2598 
2599  if (offset + subString->internal.len > value->internal.len) {
2600  break;
2601  }
2602 
2603  if (memcmp(value->internal.s + offset,
2604  subString->internal.s, subString->internal.len) == 0)
2605  {
2606  result = index;
2607  }
2608 
2609  index++;
2610 
2611  if (afw_utf8_next_code_point(value->internal.s, &offset,
2612  value->internal.len, x->xctx) < 0)
2613  {
2614  break;
2615  }
2616  }
2617 
2618 return_result:
2619  return afw_value_create_integer(result, x->p, x->xctx);
2620 }
2621 
2622 
2623 
2624 /*
2625  * Common polymorphic function for regexp_index_of
2626  *
2627  * afw_function_execute_regexp_index_of
2628  *
2629  * See afw_function_bindings.h for more information.
2630  *
2631  * Search `<dataType>` value for a regular expression and return index. If not
2632  * found, -1 is returned.
2633  *
2634  * This function is pure, so it will always return the same result
2635  * given exactly the same parameters and has no side effects.
2636  *
2637  * Supported `<dataType>`:
2638  *
2639  * anyURI, string.
2640  *
2641  * Declaration:
2642  *
2643  * ```
2644  * function regexp_index_of <dataType>(
2645  * value: dataType,
2646  * regexp: string
2647  * ): integer;
2648  * ```
2649  *
2650  * Parameters:
2651  *
2652  * value - (``<Type>``) The `<dataType>` value to search.
2653  *
2654  * regexp - (string) A regular expression to use for search.
2655  *
2656  * Returns:
2657  *
2658  * (integer) Zero-based index of subString or -1 if not found.
2659  */
2660 const afw_value_t *
2663 {
2665  AFW_THROW_ERROR_Z(general, "Not implemented", x->xctx);
2666 }
2667 
2668 
2669 
2670 /*
2671  * Common polymorphic function for regexp_replace
2672  *
2673  * afw_function_execute_regexp_replace
2674  *
2675  * See afw_function_bindings.h for more information.
2676  *
2677  * Replace matched values for a regular expression in a `<dataType>` value.
2678  *
2679  * This function is pure, so it will always return the same result
2680  * given exactly the same parameters and has no side effects.
2681  *
2682  * Supported `<dataType>`:
2683  *
2684  * anyURI, string.
2685  *
2686  * Declaration:
2687  *
2688  * ```
2689  * function regexp_replace <dataType>(
2690  * value: dataType,
2691  * regexp: string,
2692  * replacement: string,
2693  * limit?: integer
2694  * ): dataType;
2695  * ```
2696  *
2697  * Parameters:
2698  *
2699  * value - (``<Type>``) The original `<dataType>` value.
2700  *
2701  * regexp - (string) A regular expression to use for search.
2702  *
2703  * replacement - (string) The replacement string.
2704  *
2705  * limit - (optional integer) This is the maximum times to replace. The
2706  * default is 1. Specify -1 to replace all occurrences.
2707  *
2708  * Returns:
2709  *
2710  * (``<Type>``) A `<dataType>` value with the matched string(s) replaced.
2711  */
2712 const afw_value_t *
2715 {
2717  AFW_THROW_ERROR_Z(general, "Not implemented", x->xctx);
2718 }
2719 
2720 
2721 
2722 /*
2723  * Common polymorphic function for url_encode
2724  *
2725  * afw_function_execute_url_encode
2726  *
2727  * See afw_function_bindings.h for more information.
2728  *
2729  * URL encode a value or bag of values.
2730  *
2731  * This function is pure, so it will always return the same result
2732  * given exactly the same parameters and has no side effects.
2733  *
2734  * Supported `<dataType>`:
2735  *
2736  * string, anyURI.
2737  *
2738  * Declaration:
2739  *
2740  * ```
2741  * function url_encode <dataType>(
2742  * unencoded: dataType
2743  * ): string;
2744  * ```
2745  *
2746  * Parameters:
2747  *
2748  * unencoded - (``<Type>``) URL encode a single value. See the url_encode
2749  * method for the data type of more details.
2750  *
2751  * Returns:
2752  *
2753  * (string) URI encoded string.
2754  */
2755 const afw_value_t *
2758 {
2759  const afw_value_anyURI_t *unencoded;
2760  const afw_utf8_t *s;
2761 
2763 
2764  s = afw_uri_encode(&unencoded->internal,
2765  AFW_URI_OCTET_ENCODE_URI, x->p, x->xctx);
2766 
2767  /* Return String value. */
2768  return afw_value_create_string(s, x->p, x->xctx);
2769 }
2770 
2771 
2772 
2773 /*
2774  * Common polymorphic function for encode_as_base64Binary
2775  *
2776  * afw_function_execute_encode_as_base64Binary
2777  *
2778  * See afw_function_bindings.h for more information.
2779  *
2780  * Encode a value as a base64Binary. The effect is to create a base64Binary
2781  * value with an internal value of the value passed.
2782  *
2783  * This function is pure, so it will always return the same result
2784  * given exactly the same parameters and has no side effects.
2785  *
2786  * Supported `<dataType>`:
2787  *
2788  * string.
2789  *
2790  * Declaration:
2791  *
2792  * ```
2793  * function encode_as_base64Binary <dataType>(
2794  * value: dataType
2795  * ): base64Binary;
2796  * ```
2797  *
2798  * Parameters:
2799  *
2800  * value - (``<Type>``) The `<dataType>` value to encode.
2801  *
2802  * Returns:
2803  *
2804  * (base64Binary) A base64Binary value.
2805  */
2806 const afw_value_t *
2809 {
2810  afw_value_base64Binary_t *result;
2811  const afw_value_string_t *value;
2812 
2813  /* Only string supported at the moment. */
2815 
2816  result = afw_value_allocate_base64Binary(x->p, x->xctx);
2817  result->internal.ptr = (const afw_octet_t *)value->internal.s;
2818  result->internal.size = value->internal.len;
2819 
2820  return (const afw_value_t *)result;
2821 }
2822 
2823 
2824 
2825 /*
2826  * Common polymorphic function for encode_as_hexBinary
2827  *
2828  * afw_function_execute_encode_as_hexBinary
2829  *
2830  * See afw_function_bindings.h for more information.
2831  *
2832  * Encode a value as a hexBinary. The effect is to create a hexBinary value
2833  * with an internal value of the value passed.
2834  *
2835  * This function is pure, so it will always return the same result
2836  * given exactly the same parameters and has no side effects.
2837  *
2838  * Supported `<dataType>`:
2839  *
2840  * string.
2841  *
2842  * Declaration:
2843  *
2844  * ```
2845  * function encode_as_hexBinary <dataType>(
2846  * value: dataType
2847  * ): hexBinary;
2848  * ```
2849  *
2850  * Parameters:
2851  *
2852  * value - (``<Type>``) The `<dataType>` value to encode.
2853  *
2854  * Returns:
2855  *
2856  * (hexBinary) A hexBinary value.
2857  */
2858 const afw_value_t *
2861 {
2862  afw_value_hexBinary_t *result;
2863  const afw_value_string_t *value;
2864 
2865  /* Only string supported at the moment. */
2867 
2868  result = afw_value_allocate_hexBinary(x->p, x->xctx);
2869  result->internal.ptr = (const afw_octet_t *)value->internal.s;
2870  result->internal.size = value->internal.len;
2871 
2872  return (const afw_value_t *)result;
2873 }
2874 
2875 
2876 
2877 /*
2878  * Common polymorphic function for is
2879  *
2880  * afw_function_execute_is
2881  *
2882  * See afw_function_bindings.h for more information.
2883  *
2884  * Checks whether value is dataType `<dataType>` and return the boolean result.
2885  *
2886  * This function is pure, so it will always return the same result
2887  * given exactly the same parameters and has no side effects.
2888  *
2889  * Supported `<dataType>`:
2890  *
2891  * anyURI, base64Binary, boolean, date, dateTime, dayTimeDuration, dnsName,
2892  * double, expression, function, hexBinary, hybrid, ia5String, integer,
2893  * ipAddress, list, null, object, objectId, objectPath, password, rfc822Name,
2894  * script, string, template, time, x500Name, xpathExpression,
2895  * yearMonthDuration, unevaluated.
2896  *
2897  * Declaration:
2898  *
2899  * ```
2900  * function is <dataType>(
2901  * value: any
2902  * ): boolean;
2903  * ```
2904  *
2905  * Parameters:
2906  *
2907  * value - (any dataType) Value to check.
2908  *
2909  * Returns:
2910  *
2911  * (boolean)
2912  */
2913 const afw_value_t *
2916 {
2917  const afw_value_t *arg;
2918  const afw_data_type_t *data_type;
2919 
2921 
2922  if (!arg) {
2923  return afw_value_false;
2924  }
2925 
2926  data_type = afw_value_get_data_type(arg, x->xctx);
2927  return (x->data_type == data_type)
2928  ? afw_value_true
2929  : afw_value_false;
2930 }
const afw_value_t * afw_function_execute_compile(afw_function_execute_t *x)
Adaptive Framework Core Internal.
afw_value_allocate_base64Binary(const afw_pool_t *p, afw_xctx_t *xctx)
Allocate function for unmanaged data type base64Binary value.
#define afw_value_is_double(A_VALUE)
Macro to determine if value is evaluated double.
afw_value_allocate_hexBinary(const afw_pool_t *p, afw_xctx_t *xctx)
Allocate function for unmanaged data type hexBinary value.
afw_value_create_integer(afw_integer_t internal, const afw_pool_t *p, afw_xctx_t *xctx)
Create function for unmanaged data type integer 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.
#define afw_value_is_null(A_VALUE)
Macro to determine if value is evaluated null.
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_value_allocate_string(const afw_pool_t *p, afw_xctx_t *xctx)
Allocate function for unmanaged data type string value.
afw_data_type_string
Data type struct for string.
#define AFW_UTF8_FMT_ARG(A_STRING)
Convenience Macro for use with AFW_UTF8_FMT to specify arg.
Definition: afw_common.h:605
#define AFW_UTF8_Z_LEN
String is NUL (0) terminate.
Definition: afw_common.h:266
#define AFW_SIZE_T_MAX
afw_size_t max.
Definition: afw_common.h:346
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
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
unsigned char afw_octet_t
8 bits (unsigned).
Definition: afw_common.h:211
#define AFW_INTEGER_MAX
largest afw_integer_t
Definition: afw_common.h:281
apr_int64_t afw_integer_t
typedef for big signed int.
Definition: afw_common.h:321
#define afw_data_type_compare_internal(instance, internal1, internal2, xctx)
Call method compare_internal of interface afw_data_type.
#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_FUNCTION_EVALUATE_DATA_TYPE_PARAMETER(A_RESULT, A_N, A_TYPE)
Evaluate an arg for a particular data type.
Definition: afw_function.h:261
afw_function_evaluate_required_parameter(afw_function_execute_t *x, afw_size_t parameter_number, const afw_data_type_t *data_type)
Evaluate an required parameter and convert if necessary.
Definition: afw_function.c:213
#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_ASSERT_VALUE_IS_UTF8(A_VALUE)
Assert that a value is at data type with cType of afw_utf8_t.
Definition: afw_function.h:223
#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_split(afw_function_execute_t *x)
Function implementation function afw_function_execute_split.
const afw_value_t * afw_function_execute_starts_with(afw_function_execute_t *x)
Function implementation function afw_function_execute_starts_with.
const afw_value_t * afw_function_execute_nex(afw_function_execute_t *x)
Function implementation function afw_function_execute_nex.
const afw_value_t * afw_function_execute_substring(afw_function_execute_t *x)
Function implementation function afw_function_execute_substring.
const afw_value_t * afw_function_execute_regexp_index_of(afw_function_execute_t *x)
Function implementation function afw_function_execute_regexp_index_of.
const afw_value_t * afw_function_execute_ge(afw_function_execute_t *x)
Function implementation function afw_function_execute_ge.
const afw_value_t * afw_function_execute_is_in(afw_function_execute_t *x)
Function implementation function afw_function_execute_is_in.
const afw_value_t * afw_function_execute_bag(afw_function_execute_t *x)
Function implementation function afw_function_execute_bag.
const afw_value_t * afw_function_execute_includes(afw_function_execute_t *x)
Function implementation function afw_function_execute_includes.
const afw_value_t * afw_function_execute_max(afw_function_execute_t *x)
Function implementation function afw_function_execute_max.
const afw_value_t * afw_function_execute_index_of(afw_function_execute_t *x)
Function implementation function afw_function_execute_index_of.
const afw_value_t * afw_function_execute_eq(afw_function_execute_t *x)
Function implementation function afw_function_execute_eq.
const afw_value_t * afw_function_execute_min(afw_function_execute_t *x)
Function implementation function afw_function_execute_min.
const afw_value_t * afw_function_execute_ends_with(afw_function_execute_t *x)
Function implementation function afw_function_execute_ends_with.
const afw_value_t * afw_function_execute_is(afw_function_execute_t *x)
Function implementation function afw_function_execute_is.
const afw_value_t * afw_function_execute_subset(afw_function_execute_t *x)
Function implementation function afw_function_execute_subset.
const afw_value_t * afw_function_execute_intersection(afw_function_execute_t *x)
Function implementation function afw_function_execute_intersection.
const afw_value_t * afw_function_execute_regexp_match(afw_function_execute_t *x)
Function implementation function afw_function_execute_regexp_match.
const afw_value_t * afw_function_execute_replace(afw_function_execute_t *x)
Function implementation function afw_function_execute_replace.
const afw_value_t * afw_function_execute_clone(afw_function_execute_t *x)
Function implementation function afw_function_execute_clone.
const afw_value_t * afw_function_execute_eqx(afw_function_execute_t *x)
Function implementation function afw_function_execute_eqx.
const afw_value_t * afw_function_execute_regexp_replace(afw_function_execute_t *x)
Function implementation function afw_function_execute_regexp_replace.
const afw_value_t * afw_function_execute_last_index_of(afw_function_execute_t *x)
Function implementation function afw_function_execute_last_index_of.
const afw_value_t * afw_function_execute_length(afw_function_execute_t *x)
Function implementation function afw_function_execute_length.
const afw_value_t * afw_function_execute_at_least_one_member_of(afw_function_execute_t *x)
Function implementation function AFW_FUNCTION_EXECUTE_STANDARD_POLYMORPHIC_FUNCTION_HANDLING.
const afw_value_t * afw_function_execute_le(afw_function_execute_t *x)
Function implementation function afw_function_execute_le.
const afw_value_t * afw_function_execute_one_and_only(afw_function_execute_t *x)
Function implementation function afw_function_execute_one_and_only.
const afw_value_t * afw_function_execute_encode_as_hexBinary(afw_function_execute_t *x)
Function implementation function afw_function_execute_encode_as_hexBinary.
const afw_value_t * afw_function_execute_union(afw_function_execute_t *x)
Function implementation function afw_function_execute_union.
const afw_value_t * afw_function_execute_encode_as_base64Binary(afw_function_execute_t *x)
Function implementation function afw_function_execute_encode_as_base64Binary.
const afw_value_t * afw_function_execute_set_equals(afw_function_execute_t *x)
Function implementation function afw_function_execute_set_equals.
const afw_value_t * afw_function_execute_bag_size(afw_function_execute_t *x)
Function implementation function afw_function_execute_bag_size.
const afw_value_t * afw_function_execute_ne(afw_function_execute_t *x)
Function implementation function afw_function_execute_ne.
const afw_value_t * afw_function_execute_gt(afw_function_execute_t *x)
Function implementation function afw_function_execute_gt.
const afw_value_t * afw_function_execute_lt(afw_function_execute_t *x)
Function implementation function afw_function_execute_lt.
const afw_value_t * afw_function_execute_repeat(afw_function_execute_t *x)
Function implementation function afw_function_execute_repeat.
const afw_value_t * afw_function_execute_url_encode(afw_function_execute_t *x)
Function implementation function afw_function_execute_url_encode.
#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_data_type(instance, xctx)
Call method get_data_type of interface afw_list.
#define afw_list_get_count(instance, xctx)
Call method get_count of interface afw_list.
afw_list_add_internal(const afw_list_t *instance, const afw_data_type_t *data_type, const void *internal, afw_xctx_t *xctx)
Call method add of interface afw_list_setter.
Definition: afw_list.c:78
const afw_list_t * afw_list_create_with_options(int options, const afw_data_type_t *data_type, const afw_pool_t *p, afw_xctx_t *xctx)
Create an list in memory with options.
#define afw_list_of_create(data_type, p, xctx)
Create an list of a specific data type in memory.
Definition: afw_list.h:64
#define afw_memory_copy(to, from)
Copy to preallocated memory of same type.
Definition: afw_memory.h:39
afw_boolean_t afw_number_is_NaN(double d)
Determine if double is not a number.
Definition: afw_number.h:84
#define afw_pool_malloc(instance, size, xctx)
Call method malloc of interface afw_pool.
afw_integer_t afw_safe_cast_size_to_integer(afw_size_t size, afw_xctx_t *xctx)
Safely cast afw_size_t to afw_integer_t.
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
#define AFW_URI_OCTET_ENCODE_URI
encode except A-Z a-z 0-9 ; , / ? : @ & = + $ - _ . ! ~ * ' ( ) #
Definition: afw_uri.h:48
afw_uri_encode(const afw_utf8_t *string, afw_uri_octet_type_t mask, const afw_pool_t *p, afw_xctx_t *xctx)
URI encode a string.
Definition: afw_uri.c:814
#define afw_utf8_create_copy(s, len, p, xctx)
Make a utf-8 sting from chars in pool specified.
Definition: afw_utf8.h:369
const afw_utf8_z_t * afw_utf8_to_utf8_z(const afw_utf8_t *string, const afw_pool_t *p, afw_xctx_t *xctx)
Convert utf8 to utf8_z in specified pool.
Definition: afw_utf8.h:529
afw_utf8_next_code_point(const afw_utf8_octet_t *s, afw_size_t *offset, afw_size_t len, afw_xctx_t *xctx)
Get next codepoint in utf-8.
Definition: afw_utf8.c:31
#define afw_value_get_data_type(instance, xctx)
Call method get_data_type of interface afw_value.
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.
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_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_false
Adaptive value false.
Definition: afw_value.h:354
const afw_value_t * afw_value_evaluated_create(const void *value, const afw_data_type_t *data_type, const afw_pool_t *p, afw_xctx_t *xctx)
Create function for an evaluated data type value.
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
#define AFW_VALUE_INTERNAL(_VALUE_)
Macro to get const void * of the internal of a value.
Definition: afw_value.h:856
afw_value_true
Adaptive value true.
Definition: afw_value.h:348
Interface afw_data_type public struct.
Function execute parameter.
Definition: afw_function.h:53
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_data_type_t * data_type
This is the <dataType> for data type functions or NULL.
Definition: afw_function.h:74
afw_size_t argc
This is the argv count not counting argv[0].
Definition: afw_function.h:89
Interface afw_list public struct.
NFC normalized UTF-8 string.
Definition: afw_common.h:545
struct for data type anyURI values.
struct for data type base64Binary values.
struct for data type double values.
struct for data type hexBinary values.
struct for data type integer values.
struct for data type list values.
Interface afw_value public struct.
struct for data type string values.
Interface afw_xctx public struct.