| 407 | } |
| 408 | |
| 409 | static void parse_pyproject_toml(const char *source, int source_len, const char *rel_path, |
| 410 | cbm_pkg_entries_t *entries) { |
| 411 | const char *section = find_line_value(source, source_len, "[project]"); |
| 412 | if (!section) { |
| 413 | return; |
| 414 | } |
| 415 | char *name = toml_extract_name(section, source + source_len); |
| 416 | if (!name) { |
| 417 | return; |
| 418 | } |
| 419 | py_normalize_name(name); |
| 420 | |
| 421 | /* Register src/<name>/__init__ as primary entry */ |
| 422 | char suffix[PKGMAP_PATH_BUF]; |
| 423 | snprintf(suffix, sizeof(suffix), "src/%s/__init__", name); |
| 424 | char *entry = build_entry_path(rel_path, suffix); |
| 425 | char *name_copy = strdup(name); |
| 426 | pkg_entries_push(entries, name, entry); |
| 427 | |
| 428 | /* Also register <name>/__init__ as alternative (no src/ prefix) */ |
| 429 | snprintf(suffix, sizeof(suffix), "%s/__init__", name_copy); |
| 430 | char *alt_entry = build_entry_path(rel_path, suffix); |
| 431 | if (name_copy && alt_entry) { |
| 432 | pkg_entries_push(entries, name_copy, alt_entry); |
| 433 | } else { |
| 434 | free(name_copy); |
| 435 | free(alt_entry); |
| 436 | } |
| 437 | } |
| 438 | |
| 439 | /* Extract PSR-4 autoload entries from composer.json root. */ |
| 440 | static void extract_psr4(yyjson_val *root, const char *dir, cbm_pkg_entries_t *entries) { |
no test coverage detected