| 250 | } |
| 251 | |
| 252 | void cbm_cargo_parse(CBMArena* arena, const char* src, int src_len, |
| 253 | CBMCargoManifest* out) { |
| 254 | if (!arena || !src || !out) return; |
| 255 | memset(out, 0, sizeof(*out)); |
| 256 | if (src_len <= 0) src_len = (int)strlen(src); |
| 257 | |
| 258 | int from = 0; |
| 259 | /* Default: pre-header content treated as [package]. */ |
| 260 | const char* section = "package"; |
| 261 | |
| 262 | while (from < src_len) { |
| 263 | from = skip_ws_and_comment(src, src_len, from); |
| 264 | if (from >= src_len) break; |
| 265 | if (src[from] == '[') { |
| 266 | const char* hdr = NULL; |
| 267 | from = parse_section(arena, src, src_len, from, &hdr); |
| 268 | section = hdr ? hdr : ""; |
| 269 | continue; |
| 270 | } |
| 271 | if (!section) { |
| 272 | from = skip_value(src, src_len, from); |
| 273 | continue; |
| 274 | } |
| 275 | if (strcmp(section, "package") == 0) { |
| 276 | from = parse_package_kv(arena, src, src_len, from, out); |
| 277 | } else if (strcmp(section, "workspace") == 0) { |
| 278 | from = parse_workspace_kv(arena, src, src_len, from, out); |
| 279 | } else if (strcmp(section, "dependencies") == 0 || |
| 280 | strcmp(section, "dev-dependencies") == 0 || |
| 281 | strcmp(section, "build-dependencies") == 0 || |
| 282 | strcmp(section, "workspace.dependencies") == 0) { |
| 283 | from = parse_dep_entry(arena, src, src_len, from, out); |
| 284 | } else { |
| 285 | /* Section we don't care about — skip the line. */ |
| 286 | while (from < src_len && src[from] != '\n' && src[from] != '[') { |
| 287 | from++; |
| 288 | } |
| 289 | } |
| 290 | } |
| 291 | } |
| 292 | |
| 293 | bool cbm_cargo_is_known_dep(const CBMCargoManifest* m, const char* head) { |
| 294 | if (!m || !head) return false; |
no test coverage detected