| 2905 | /* ── String function application ──────────────────────────────── */ |
| 2906 | |
| 2907 | static const char *apply_string_func(const char *func, const char *val, char *buf, size_t buf_sz) { |
| 2908 | if (!func || !val) { |
| 2909 | return val ? val : ""; |
| 2910 | } |
| 2911 | if (strcmp(func, "toLower") == 0) { |
| 2912 | size_t i = 0; |
| 2913 | for (; i < buf_sz - SKIP_ONE && val[i]; i++) { |
| 2914 | buf[i] = (char)tolower((unsigned char)val[i]); |
| 2915 | } |
| 2916 | buf[i] = '\0'; |
| 2917 | return buf; |
| 2918 | } |
| 2919 | if (strcmp(func, "toUpper") == 0) { |
| 2920 | size_t i = 0; |
| 2921 | for (; i < buf_sz - SKIP_ONE && val[i]; i++) { |
| 2922 | buf[i] = (char)toupper((unsigned char)val[i]); |
| 2923 | } |
| 2924 | buf[i] = '\0'; |
| 2925 | return buf; |
| 2926 | } |
| 2927 | if (strcmp(func, "toString") == 0) { |
| 2928 | return val; /* already strings */ |
| 2929 | } |
| 2930 | if (strcmp(func, "toInteger") == 0) { |
| 2931 | char *end = NULL; |
| 2932 | long long v = strtoll(val, &end, CBM_DECIMAL_BASE); |
| 2933 | if (end == val) { |
| 2934 | /* Not an integer literal — accept a float string and truncate. */ |
| 2935 | char *fend = NULL; |
| 2936 | double d = strtod(val, &fend); |
| 2937 | if (fend == val) { |
| 2938 | return ""; /* non-numeric → null */ |
| 2939 | } |
| 2940 | v = (long long)d; |
| 2941 | } |
| 2942 | snprintf(buf, buf_sz, "%lld", v); |
| 2943 | return buf; |
| 2944 | } |
| 2945 | if (strcmp(func, "toFloat") == 0) { |
| 2946 | char *end = NULL; |
| 2947 | double d = strtod(val, &end); |
| 2948 | if (end == val) { |
| 2949 | return ""; /* non-numeric → null */ |
| 2950 | } |
| 2951 | snprintf(buf, buf_sz, "%g", d); |
| 2952 | return buf; |
| 2953 | } |
| 2954 | if (strcmp(func, "toBoolean") == 0) { |
| 2955 | if (cyp_ci_eq(val, "true")) { |
| 2956 | return "true"; |
| 2957 | } |
| 2958 | if (cyp_ci_eq(val, "false")) { |
| 2959 | return "false"; |
| 2960 | } |
| 2961 | return ""; /* not a boolean → null */ |
| 2962 | } |
| 2963 | if (strcmp(func, "size") == 0 || strcmp(func, "length") == 0) { |
| 2964 | snprintf(buf, buf_sz, "%zu", strlen(val)); |
no test coverage detected