| 2638 | /* ── String function application ──────────────────────────────── */ |
| 2639 | |
| 2640 | static const char *apply_string_func(const char *func, const char *val, char *buf, size_t buf_sz) { |
| 2641 | if (!func || !val) { |
| 2642 | return val ? val : ""; |
| 2643 | } |
| 2644 | if (strcmp(func, "toLower") == 0) { |
| 2645 | size_t i = 0; |
| 2646 | for (; i < buf_sz - SKIP_ONE && val[i]; i++) { |
| 2647 | buf[i] = (char)tolower((unsigned char)val[i]); |
| 2648 | } |
| 2649 | buf[i] = '\0'; |
| 2650 | return buf; |
| 2651 | } |
| 2652 | if (strcmp(func, "toUpper") == 0) { |
| 2653 | size_t i = 0; |
| 2654 | for (; i < buf_sz - SKIP_ONE && val[i]; i++) { |
| 2655 | buf[i] = (char)toupper((unsigned char)val[i]); |
| 2656 | } |
| 2657 | buf[i] = '\0'; |
| 2658 | return buf; |
| 2659 | } |
| 2660 | if (strcmp(func, "toString") == 0) { |
| 2661 | return val; /* already strings */ |
| 2662 | } |
| 2663 | if (strcmp(func, "toInteger") == 0) { |
| 2664 | char *end = NULL; |
| 2665 | long long v = strtoll(val, &end, CBM_DECIMAL_BASE); |
| 2666 | if (end == val) { |
| 2667 | /* Not an integer literal — accept a float string and truncate. */ |
| 2668 | char *fend = NULL; |
| 2669 | double d = strtod(val, &fend); |
| 2670 | if (fend == val) { |
| 2671 | return ""; /* non-numeric → null */ |
| 2672 | } |
| 2673 | v = (long long)d; |
| 2674 | } |
| 2675 | snprintf(buf, buf_sz, "%lld", v); |
| 2676 | return buf; |
| 2677 | } |
| 2678 | if (strcmp(func, "toFloat") == 0) { |
| 2679 | char *end = NULL; |
| 2680 | double d = strtod(val, &end); |
| 2681 | if (end == val) { |
| 2682 | return ""; /* non-numeric → null */ |
| 2683 | } |
| 2684 | snprintf(buf, buf_sz, "%g", d); |
| 2685 | return buf; |
| 2686 | } |
| 2687 | if (strcmp(func, "toBoolean") == 0) { |
| 2688 | if (cyp_ci_eq(val, "true")) { |
| 2689 | return "true"; |
| 2690 | } |
| 2691 | if (cyp_ci_eq(val, "false")) { |
| 2692 | return "false"; |
| 2693 | } |
| 2694 | return ""; /* not a boolean → null */ |
| 2695 | } |
| 2696 | if (strcmp(func, "size") == 0 || strcmp(func, "length") == 0) { |
| 2697 | snprintf(buf, buf_sz, "%zu", strlen(val)); |
no test coverage detected