MCPcopy Create free account
hub / github.com/DeusData/codebase-memory-mcp / cbm_project_name_from_path

Function cbm_project_name_from_path

src/pipeline/fqn.c:416–517  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

414}
415
416char *cbm_project_name_from_path(const char *abs_path) {
417 if (!abs_path || !abs_path[0]) {
418 return strdup("root");
419 }
420 if (path_is_root_syntax(abs_path)) {
421 return strdup("root");
422 }
423
424 char real[CBM_SZ_4K];
425 const char *name_path = abs_path;
426 /* Wide-path canonicalization — the ANSI _access/_fullpath pair corrupted
427 * CJK paths on CJK-locale Windows (#973). */
428 if (cbm_canonical_path(abs_path, real, sizeof(real))) {
429 cbm_normalize_path_sep(real);
430 name_path = real;
431 }
432
433 /* Work on mutable copy */
434 char *path = strdup(name_path);
435 if (!path) {
436 return NULL;
437 }
438 size_t len = strlen(path);
439
440 /* Normalize path separators */
441 cbm_normalize_path_sep(path);
442
443 /* Map every character that is unsafe for portable project DB names. We
444 * keep derived names in [A-Za-z0-9._-], so anything else — path
445 * separators, ':', spaces, '@', '+', … — must be normalized here.
446 * Otherwise a repo like
447 * "/home/u/my project" yields the name "home-u-my project": indexing
448 * creates the DB and it shows in list_projects, but resolve_store rejects
449 * the space and reports project-not-found (#349).
450 *
451 * Non-ASCII bytes (UTF-8 of CJK and other scripts, all >= 0x80) are NOT
452 * dropped to '-' — that silently erased whole path segments and produced
453 * unrecognizable / colliding names (#571). Instead each non-ASCII byte is
454 * transliterated to its two lowercase hex digits, which use only [0-9a-f]
455 * and therefore stay validator-safe while preserving the segment. */
456 static const char hex_digits[] = "0123456789abcdef";
457 char *mapped = malloc(len * 2 + 1); /* worst case: every byte → 2 hex chars */
458 if (!mapped) {
459 free(path);
460 return strdup("root");
461 }
462 size_t mlen = 0;
463 for (size_t i = 0; i < len; i++) {
464 unsigned char c = (unsigned char)path[i];
465 bool safe = (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9') ||
466 c == '.' || c == '_' || c == '-';
467 if (safe) {
468 mapped[mlen++] = (char)c;
469 } else if (c >= 0x80) {
470 mapped[mlen++] = hex_digits[(c >> 4) & 0xF];
471 mapped[mlen++] = hex_digits[c & 0xF];
472 } else {
473 mapped[mlen++] = '-';

Callers 15

normalize_project_argFunction · 0.85
handle_cross_repo_modeFunction · 0.85
handle_index_repositoryFunction · 0.85
detect_sessionFunction · 0.85
cbm_pipeline_newFunction · 0.85
gpf_open_indexedFunction · 0.85
ri_index_captureFunction · 0.85

Calls 4

path_is_root_syntaxFunction · 0.85
cbm_canonical_pathFunction · 0.85
cbm_normalize_path_sepFunction · 0.85
fqn_bound_name_lenFunction · 0.85

Tested by 15

gpf_open_indexedFunction · 0.68
ri_index_captureFunction · 0.68
gpg_open_indexedFunction · 0.68
es_lang_open_indexedFunction · 0.68
gpe_open_indexedFunction · 0.68
gpa_open_indexedFunction · 0.68
et_index_filesFunction · 0.68
idxpar_recovery_checkFunction · 0.68
lrp_open_indexedFunction · 0.68