| 849 | } |
| 850 | |
| 851 | int cbm_parse_shell_source(const char *source, cbm_shell_result_t *out) { |
| 852 | if (!source || !out) { |
| 853 | return CBM_NOT_FOUND; |
| 854 | } |
| 855 | memset(out, 0, sizeof(*out)); |
| 856 | |
| 857 | const char *p = source; |
| 858 | char line[CBM_SZ_4K]; |
| 859 | bool shebang_checked = false; |
| 860 | |
| 861 | while (*p) { |
| 862 | const char *eol = strchr(p, '\n'); |
| 863 | size_t line_len = eol ? (size_t)(eol - p) : strlen(p); |
| 864 | if (line_len >= sizeof(line)) { |
| 865 | line_len = sizeof(line) - SKIP_ONE; |
| 866 | } |
| 867 | memcpy(line, p, line_len); |
| 868 | line[line_len] = '\0'; |
| 869 | p = eol ? eol + SKIP_ONE : p + line_len; |
| 870 | |
| 871 | char *trimmed = line; |
| 872 | while (*trimmed == ' ' || *trimmed == '\t') { |
| 873 | trimmed++; |
| 874 | } |
| 875 | rtrim(trimmed); |
| 876 | |
| 877 | if (*trimmed == '\0') { |
| 878 | continue; |
| 879 | } |
| 880 | |
| 881 | if (shell_try_shebang(trimmed, out, &shebang_checked)) { |
| 882 | continue; |
| 883 | } |
| 884 | |
| 885 | if (*trimmed == '#') { |
| 886 | continue; |
| 887 | } |
| 888 | |
| 889 | shell_dispatch_line(trimmed, out); |
| 890 | } |
| 891 | |
| 892 | bool has_content = out->shebang[0] != '\0' || out->env_count > 0 || out->source_count > 0 || |
| 893 | out->docker_cmd_count > 0; |
| 894 | return has_content ? 0 : IS_NOT_FOUND; |
| 895 | } |
| 896 | |
| 897 | /* ── Terraform parser ───────────────────────────────────────────── */ |
| 898 |
no test coverage detected