Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/discover/discover.c
Original file line number Diff line number Diff line change
Expand Up @@ -245,7 +245,7 @@ static bool expand_git_path(const char *path, char *out, size_t out_sz) {
}

static bool read_core_excludes_file(const char *config_path, char *out, size_t out_sz) {
FILE *f = fopen(config_path, "r");
FILE *f = cbm_fopen(config_path, "r");
if (!f) {
return false;
}
Expand Down
3 changes: 2 additions & 1 deletion src/discover/gitignore.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
* - patterns with / are rooted (anchored to base)
*/
#include "foundation/constants.h"
#include "foundation/compat_fs.h"

enum { GI_INIT_CAP = 16, GI_CHAR_IDX1 = 1, GI_CHAR_IDX2 = 2, GI_SKIP3 = 3 };
#include "discover/discover.h"
Expand Down Expand Up @@ -287,7 +288,7 @@ cbm_gitignore_t *cbm_gitignore_load(const char *path) {
return NULL;
}

FILE *f = fopen(path, "r");
FILE *f = cbm_fopen(path, "r");
if (!f) {
return NULL;
}
Expand Down
3 changes: 2 additions & 1 deletion src/discover/language.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include "cbm.h" // CBMLanguage, CBM_LANG_*

#include "foundation/constants.h"
#include "foundation/compat_fs.h"

enum { LANG_SCAN_PASSES = 2 };
#define SLEN(s) (sizeof(s) - 1)
Expand Down Expand Up @@ -998,7 +999,7 @@ CBMLanguage cbm_disambiguate_m(const char *path) {
return CBM_LANG_MATLAB;
}

FILE *f = fopen(path, "r");
FILE *f = cbm_fopen(path, "r");
if (!f) {
return CBM_LANG_MATLAB;
}
Expand Down
3 changes: 2 additions & 1 deletion src/discover/userconfig.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#include "cbm.h" /* CBMLanguage, CBM_LANG_* */
#include "foundation/constants.h"
#include "foundation/platform.h" /* cbm_safe_getenv */
#include "foundation/compat_fs.h"

enum { MAX_CONFIG_SIZE = 65536 };
#include "foundation/log.h"
Expand Down Expand Up @@ -231,7 +232,7 @@ static int parse_extra_extensions(yyjson_val *root, cbm_userext_t **entries, int
* Returns 0 on success (or absent file), -1 on alloc failure.
*/
static int load_config_file(const char *path, cbm_userext_t **entries, int *count) {
FILE *f = fopen(path, "rb");
FILE *f = cbm_fopen(path, "rb");
if (!f) {
return 0; /* file absent — silently ignore */
}
Expand Down
20 changes: 20 additions & 0 deletions src/foundation/compat_fs.c
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,22 @@ int cbm_pclose(FILE *f) {
return _pclose(f);
}

FILE *cbm_fopen(const char *path, const char *mode) {
wchar_t *wpath = cbm_utf8_to_wide(path);
if (!wpath) {
return NULL;
}
wchar_t *wmode = cbm_utf8_to_wide(mode);
if (!wmode) {
free(wpath);
return NULL;
}
FILE *f = _wfopen(wpath, wmode);
free(wpath);
free(wmode);
return f;
}

bool cbm_mkdir_p(const char *path, int mode) {
(void)mode;
wchar_t *wpath = cbm_utf8_to_wide(path);
Expand Down Expand Up @@ -262,6 +278,10 @@ int cbm_pclose(FILE *f) {
return pclose(f);
}

FILE *cbm_fopen(const char *path, const char *mode) {
return fopen(path, mode);
}

bool cbm_mkdir_p(const char *path, int mode) {
/* Try direct mkdir first */
if (mkdir(path, (mode_t)mode) == 0) {
Expand Down
8 changes: 7 additions & 1 deletion src/foundation/compat_fs.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,10 +50,16 @@ int cbm_unlink(const char *path);
/* Delete an empty directory. Returns 0 on success. */
int cbm_rmdir(const char *path);

/* Open a file by UTF-8 path.
* On Windows, converts to wide-char and calls _wfopen so paths with
* non-ASCII characters (accents, CJK, etc.) are handled correctly.
* On POSIX, delegates to fopen. mode must be an ASCII string. */
FILE *cbm_fopen(const char *path, const char *mode);

/* Execute a command without shell interpretation.
* argv is a NULL-terminated array: {"cmd", "arg1", "arg2", NULL}.
* Returns the process exit code, or -1 on fork/exec failure.
* POSIX: fork() + execvp(). Windows: _spawnvp(). */
* POSIX: fork() + execvp(). Windows: CreateProcess with proper quoting. */
int cbm_exec_no_shell(const char *const *argv);

#endif /* CBM_COMPAT_FS_H */
4 changes: 2 additions & 2 deletions src/mcp/mcp.c
Original file line number Diff line number Diff line change
Expand Up @@ -2782,7 +2782,7 @@ static void free_node_contents(cbm_node_t *n) {
/* ── Helper: read lines [start, end] from a file ─────────────── */

static char *read_file_lines(const char *path, int start, int end) {
FILE *fp = fopen(path, "r");
FILE *fp = cbm_fopen(path, "r");
if (!fp) {
return NULL;
}
Expand Down Expand Up @@ -4639,7 +4639,7 @@ static char *adr_read_legacy_file(const char *root_path) {
}
char adr_path[CBM_SZ_4K];
snprintf(adr_path, sizeof(adr_path), "%s/.codebase-memory/adr.md", root_path);
FILE *fp = fopen(adr_path, "r");
FILE *fp = cbm_fopen(adr_path, "r");
if (!fp) {
return NULL;
}
Expand Down
2 changes: 1 addition & 1 deletion src/pipeline/artifact.c
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ static bool artifact_path(char *buf, size_t bufsz, const char *repo_path, const

/* Read entire file into malloc'd buffer. Sets *out_len. Returns NULL on error. */
static char *read_file_alloc(const char *path, size_t *out_len) {
FILE *fp = fopen(path, "rb");
FILE *fp = cbm_fopen(path, "rb");
if (!fp) {
return NULL;
}
Expand Down
3 changes: 2 additions & 1 deletion src/pipeline/pass_calls.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ enum { PC_RING = 4, PC_RING_MASK = 3, PC_SIG_SCAN = 15, PC_REGEX_GRP = 2 };
#include "graph_buffer/graph_buffer.h"
#include "foundation/log.h"
#include "foundation/compat.h"
#include "foundation/compat_fs.h"
#include "foundation/str_util.h"
#include "cbm.h"
#include "service_patterns.h"
Expand All @@ -43,7 +44,7 @@ static bool pc_module_is_dir(CBMLanguage lang) {

/* Read entire file into heap-allocated buffer. Caller must free(). */
static char *read_file(const char *path, int *out_len) {
FILE *f = fopen(path, "rb");
FILE *f = cbm_fopen(path, "rb");
if (!f) {
return NULL;
}
Expand Down
3 changes: 2 additions & 1 deletion src/pipeline/pass_definitions.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ enum { PD_JSON_FIELD_OVERHEAD = 6 };
#include "graph_buffer/graph_buffer.h"
#include "foundation/log.h"
#include "foundation/compat.h"
#include "foundation/compat_fs.h"
#include "cbm.h"
#include "simhash/minhash.h"
#include "semantic/ast_profile.h"
Expand All @@ -33,7 +34,7 @@ enum { PD_JSON_FIELD_OVERHEAD = 6 };
/* Read entire file into heap-allocated buffer. Returns NULL on error.
* Caller must free(). Sets *out_len to byte count. */
static char *read_file(const char *path, int *out_len) {
FILE *f = fopen(path, "rb");
FILE *f = cbm_fopen(path, "rb");
if (!f) {
return NULL;
}
Expand Down
2 changes: 1 addition & 1 deletion src/pipeline/pass_envscan.c
Original file line number Diff line number Diff line change
Expand Up @@ -316,7 +316,7 @@ static int scan_line(const char *line, file_type_t ft, char *key_out, size_t key
/* Scan a single file for env URL bindings. Returns number of bindings added. */
static int scan_env_file(const char *full_path, const char *rel, file_type_t ft,
cbm_env_binding_t *out, int max_out) {
FILE *f = fopen(full_path, "r");
FILE *f = cbm_fopen(full_path, "r");
if (!f) {
return 0;
}
Expand Down
3 changes: 2 additions & 1 deletion src/pipeline/pass_k8s.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#include "discover/discover.h"
#include "foundation/log.h"
#include "foundation/compat.h"
#include "foundation/compat_fs.h"
#include "cbm.h"

#include <stdlib.h>
Expand All @@ -30,7 +31,7 @@
/* Read entire file into heap-allocated buffer. Returns NULL on error.
* Caller must free(). Sets *out_len to byte count. */
static char *k8s_read_file(const char *path, int *out_len) {
FILE *f = fopen(path, "rb");
FILE *f = cbm_fopen(path, "rb");
if (!f) {
return NULL;
}
Expand Down
3 changes: 2 additions & 1 deletion src/pipeline/pass_lsp_cross.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
#include "foundation/constants.h"
#include "foundation/hash_table.h"
#include "foundation/log.h"
#include "foundation/compat_fs.h"

#include <stdio.h>
#include <stdlib.h>
Expand Down Expand Up @@ -67,7 +68,7 @@ static bool pxc_module_is_dir(CBMLanguage lang) {
* read_file helper in pass_calls.c / pass_parallel.c (kept local so the
* pipeline doesn't grow a public read-file API just for this pass). */
static char *pxc_read_file(const char *path, int *out_len) {
FILE *f = fopen(path, "rb");
FILE *f = cbm_fopen(path, "rb");
if (!f)
return NULL;
(void)fseek(f, 0, SEEK_END);
Expand Down
3 changes: 2 additions & 1 deletion src/pipeline/pass_parallel.c
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ enum { PP_CSHARP_M_PREFIX_LEN = 2 };
#include "helpers.h" /* cbm_kind_in_set_free_cache — per-worker-thread cache teardown */
#include "pipeline/worker_pool.h"
#include "foundation/compat.h"
#include "foundation/compat_fs.h"
#include "foundation/compat_thread.h"
#include "graph_buffer/graph_buffer.h"
#include "service_patterns.h"
Expand Down Expand Up @@ -88,7 +89,7 @@ static uint64_t extract_now_ns(void) {

/* Read file into a malloc'd buffer (= mimalloc in production). */
static char *read_file(const char *path, int *out_len) {
FILE *f = fopen(path, "rb");
FILE *f = cbm_fopen(path, "rb");
if (!f) {
return NULL;
}
Expand Down
2 changes: 1 addition & 1 deletion src/pipeline/pass_pkgmap.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@

/* Read an entire file into a malloc'd buffer. Returns NULL on failure. */
static char *pkgmap_read_file(const char *path, int *out_len) {
FILE *f = fopen(path, "rb");
FILE *f = cbm_fopen(path, "rb");
if (!f) {
return NULL;
}
Expand Down
3 changes: 2 additions & 1 deletion src/pipeline/pass_semantic.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#include "graph_buffer/graph_buffer.h"
#include "foundation/log.h"
#include "foundation/compat.h"
#include "foundation/compat_fs.h"
#include "cbm.h"

#include <stdio.h>
Expand All @@ -34,7 +35,7 @@ static bool ps_module_is_dir(CBMLanguage lang) {
}

static char *read_file(const char *path, int *out_len) {
FILE *f = fopen(path, "rb");
FILE *f = cbm_fopen(path, "rb");
if (!f) {
return NULL;
}
Expand Down
3 changes: 2 additions & 1 deletion src/pipeline/pass_usages.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#include "graph_buffer/graph_buffer.h"
#include "foundation/log.h"
#include "foundation/compat.h"
#include "foundation/compat_fs.h"
#include "cbm.h"

#include <stdio.h>
Expand All @@ -33,7 +34,7 @@ static bool pu_module_is_dir(CBMLanguage lang) {

/* Read file into heap buffer. Caller must free(). */
static char *read_file(const char *path, int *out_len) {
FILE *f = fopen(path, "rb");
FILE *f = cbm_fopen(path, "rb");
if (!f) {
return NULL;
}
Expand Down
4 changes: 2 additions & 2 deletions src/pipeline/path_alias.c
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ static int cmp_scope_by_specificity(const void *a, const void *b) {
* (e.g. "apps/manager", or "" for repo root). Returns NULL if the file is
* missing, malformed, or has neither a usable paths block nor a baseUrl. */
static cbm_path_alias_map_t *load_tsconfig_file(const char *abs_path, const char *dir_prefix) {
FILE *f = fopen(abs_path, "r");
FILE *f = cbm_fopen(abs_path, "r");
if (!f) {
return NULL;
}
Expand Down Expand Up @@ -346,7 +346,7 @@ static void find_alias_files(const char *abs_dir, const char *rel_dir, alias_con
for (int i = 0; i < TS_CONFIG_NAMES_COUNT && *count < max_count; i++) {
char check[CBM_SZ_512];
snprintf(check, sizeof(check), "%s/%s", abs_dir, TS_CONFIG_NAMES[i]);
FILE *f = fopen(check, "r");
FILE *f = cbm_fopen(check, "r");
if (f) {
fclose(f);
snprintf(out[*count].abs, sizeof(out[*count].abs), "%s", check);
Expand Down
Loading