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. */
| 2929 | * Returns a NULL-terminated array of arena-allocated substrings; sets |
| 2930 | * *out_count to the number of args. */ |
| 2931 | static const char **split_generic_args(CBMArena *a, const char *inside, int *out_count) { |
| 2932 | *out_count = 0; |
| 2933 | if (!inside || !inside[0]) |
| 2934 | return NULL; |
| 2935 | const char *args[16]; |
| 2936 | int count = 0; |
| 2937 | int depth = 0; |
| 2938 | const char *seg_start = inside; |
| 2939 | for (const char *p = inside; *p; p++) { |
| 2940 | if (*p == '<') |
| 2941 | depth++; |
| 2942 | else if (*p == '>') |
| 2943 | depth--; |
| 2944 | else if (*p == ',' && depth == 0) { |
| 2945 | /* trim leading whitespace from seg_start */ |
| 2946 | while (seg_start < p && (*seg_start == ' ' || *seg_start == '\t')) |
| 2947 | seg_start++; |
| 2948 | const char *seg_end = p; |
| 2949 | while (seg_end > seg_start && (seg_end[-1] == ' ' || seg_end[-1] == '\t')) |
| 2950 | seg_end--; |
| 2951 | if (count < 16 && seg_end > seg_start) { |
| 2952 | args[count++] = cbm_arena_strndup(a, seg_start, (size_t)(seg_end - seg_start)); |
| 2953 | } |
| 2954 | seg_start = p + 1; |
| 2955 | } |
| 2956 | } |
| 2957 | /* last segment */ |
| 2958 | while (*seg_start == ' ' || *seg_start == '\t') |
| 2959 | seg_start++; |
| 2960 | const char *seg_end = inside + strlen(inside); |
| 2961 | while (seg_end > seg_start && (seg_end[-1] == ' ' || seg_end[-1] == '\t')) |
| 2962 | seg_end--; |
| 2963 | if (count < 16 && seg_end > seg_start) { |
| 2964 | args[count++] = cbm_arena_strndup(a, seg_start, (size_t)(seg_end - seg_start)); |
| 2965 | } |
| 2966 | if (count == 0) |
| 2967 | return NULL; |
| 2968 | const char **result = (const char **)cbm_arena_alloc(a, (size_t)(count + 1) * sizeof(*result)); |
| 2969 | for (int i = 0; i < count; i++) |
| 2970 | result[i] = args[i]; |
| 2971 | result[count] = NULL; |
| 2972 | *out_count = count; |
| 2973 | return result; |
| 2974 | } |
| 2975 | |
| 2976 | /* Parse a type-text into a CBMType, with full inner-class qualification. |
| 2977 | * `parent_class` is the QN of the enclosing class (NULL at file scope), used |
no test coverage detected