Parse a comma-separated list at the outermost generic level of `text`. * `text` is the substring INSIDE the angle brackets, e.g. for * "Map >" the caller would pass "String, List ". * * Returns a NULL-terminated array of arena-allocated substrings; sets * *out_count to the number of args. */
| 3012 | * Returns a NULL-terminated array of arena-allocated substrings; sets |
| 3013 | * *out_count to the number of args. */ |
| 3014 | static const char **split_generic_args(CBMArena *a, const char *inside, int *out_count) { |
| 3015 | *out_count = 0; |
| 3016 | if (!inside || !inside[0]) |
| 3017 | return NULL; |
| 3018 | const char *args[16]; |
| 3019 | int count = 0; |
| 3020 | int depth = 0; |
| 3021 | const char *seg_start = inside; |
| 3022 | for (const char *p = inside; *p; p++) { |
| 3023 | if (*p == '<') |
| 3024 | depth++; |
| 3025 | else if (*p == '>') |
| 3026 | depth--; |
| 3027 | else if (*p == ',' && depth == 0) { |
| 3028 | /* trim leading whitespace from seg_start */ |
| 3029 | while (seg_start < p && (*seg_start == ' ' || *seg_start == '\t')) |
| 3030 | seg_start++; |
| 3031 | const char *seg_end = p; |
| 3032 | while (seg_end > seg_start && (seg_end[-1] == ' ' || seg_end[-1] == '\t')) |
| 3033 | seg_end--; |
| 3034 | if (count < 16 && seg_end > seg_start) { |
| 3035 | args[count++] = cbm_arena_strndup(a, seg_start, (size_t)(seg_end - seg_start)); |
| 3036 | } |
| 3037 | seg_start = p + 1; |
| 3038 | } |
| 3039 | } |
| 3040 | /* last segment */ |
| 3041 | while (*seg_start == ' ' || *seg_start == '\t') |
| 3042 | seg_start++; |
| 3043 | const char *seg_end = inside + strlen(inside); |
| 3044 | while (seg_end > seg_start && (seg_end[-1] == ' ' || seg_end[-1] == '\t')) |
| 3045 | seg_end--; |
| 3046 | if (count < 16 && seg_end > seg_start) { |
| 3047 | args[count++] = cbm_arena_strndup(a, seg_start, (size_t)(seg_end - seg_start)); |
| 3048 | } |
| 3049 | if (count == 0) |
| 3050 | return NULL; |
| 3051 | const char **result = (const char **)cbm_arena_alloc(a, (size_t)(count + 1) * sizeof(*result)); |
| 3052 | for (int i = 0; i < count; i++) |
| 3053 | result[i] = args[i]; |
| 3054 | result[count] = NULL; |
| 3055 | *out_count = count; |
| 3056 | return result; |
| 3057 | } |
| 3058 | |
| 3059 | /* Parse a type-text into a CBMType, with full inner-class qualification. |
| 3060 | * `parent_class` is the QN of the enclosing class (NULL at file scope), used |
no test coverage detected