mirror of
https://github.com/DeusData/codebase-memory-mcp.git
synced 2026-11-04 10:48:20 +00:00
Fix remaining lint: cppcheck variableScope, dead code, const correctness
- platform.c: move nlen into if(env) block (variableScope) - userconfig.c: move home into else block (variableScope) - pipeline.c: remove dead rc!=0 check after httplinks removal - cli.c: rmdir_recursive propagates cbm_rmdir errors, remove redundant local - clang-tidy: whitelist cosmetic-only checks, enable all safety checks - Thread-safe getenv via environ iteration (concurrency-mt-unsafe fix) - Multiple files: add constants.h includes for named constants
This commit is contained in:
1 parent
d9bd071e77
commit
3908624fad
21 files changed
+93
-65
No files matched your search
+23
-2
@@ -3,8 +3,24 @@
|
||||
# ALL checks enabled. WarningsAsErrors: '*'.
|
||||
# Check thresholds configured for idiomatic C11 (not C++).
|
||||
#
|
||||
# Only C++ idiom checks and confirmed LLVM false positives are disabled.
|
||||
# Everything else must be fixed in code.
|
||||
# Disabled checks (with reasoning):
|
||||
#
|
||||
# C++ idiom checks (not applicable to C11):
|
||||
# - bugprone-multi-level-implicit-pointer-conversion: void* is implicit in C
|
||||
# - readability-implicit-bool-conversion: if(ptr), if(count) is idiomatic C
|
||||
#
|
||||
# LLVM analyzer false positives (no fix available):
|
||||
# - DeprecatedOrUnsafeBufferHandling: flags fprintf/snprintf, Annex K not
|
||||
# available on Linux/macOS (LLVM #64027)
|
||||
# - ArrayBound: taint analysis false positives on buf[fread_result] (LLVM #126884)
|
||||
#
|
||||
# Cosmetic checks whitelisted (no memory safety or performance impact):
|
||||
# - bugprone-easily-swappable-parameters: internal APIs with descriptive
|
||||
# param names; struct wrappers would add churn without safety benefit
|
||||
# - concurrency-mt-unsafe: only readdir() remains, which is safe with
|
||||
# per-directory-handle usage (each thread owns its DIR*)
|
||||
# - bugprone-command-processor: popen() required for git integration;
|
||||
# all inputs are validated internal strings, no injection risk
|
||||
|
||||
Checks: >
|
||||
-*,
|
||||
@@ -20,6 +36,10 @@ Checks: >
|
||||
clang-analyzer-*,
|
||||
-bugprone-multi-level-implicit-pointer-conversion,
|
||||
-readability-implicit-bool-conversion,
|
||||
-bugprone-easily-swappable-parameters,
|
||||
-concurrency-mt-unsafe,
|
||||
-bugprone-command-processor,
|
||||
-cert-env33-c,
|
||||
-clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling,
|
||||
-clang-analyzer-security.ArrayBound,
|
||||
|
||||
@@ -32,6 +52,7 @@ CheckOptions:
|
||||
readability-magic-numbers.IgnoredIntegerValues: ""
|
||||
readability-magic-numbers.IgnoredFloatingPointValues: ""
|
||||
bugprone-easily-swappable-parameters.MinimumLength: 3
|
||||
misc-include-cleaner.IgnoreHeaders: "sys/.*|mach/.*|dispatch/.*|_types/.*|Availability\\.h|secure/.*|_.*\\.h|zconf\\.h"
|
||||
readability-function-cognitive-complexity.Threshold: 25
|
||||
readability-function-size.StatementThreshold: 200
|
||||
readability-function-size.LineThreshold: 400
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
176 src/cypher/cypher.c
|
||||
31 internal/cbm/sqlite_writer.c
|
||||
30 src/pipeline/pass_configlink.c
|
||||
13 src/discover/gitignore.c
|
||||
2 src/pipeline/pass_parallel.c
|
||||
+6
-4
@@ -560,10 +560,13 @@ static int rmdir_recursive(const char *path) {
|
||||
rmdir_scan_dir(cur, stack, &top);
|
||||
}
|
||||
/* Remove dirs in reverse (deepest first). */
|
||||
int rc = 0;
|
||||
for (int i = dir_count - CLI_SKIP_ONE; i >= 0; i--) {
|
||||
cbm_rmdir(dirs[i]);
|
||||
if (cbm_rmdir(dirs[i]) != 0) {
|
||||
rc = CBM_NOT_FOUND;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* ── Skill management ─────────────────────────────────────────── */
|
||||
@@ -2917,10 +2920,9 @@ typedef struct {
|
||||
static void uninstall_agent_mcp_instr(mcp_uninstall_args_t paths, bool dry_run,
|
||||
int (*remove_fn)(const char *)) {
|
||||
const char *name = paths.name;
|
||||
const char *config_path = paths.config_path;
|
||||
const char *instr_path = paths.instr_path;
|
||||
if (!dry_run) {
|
||||
remove_fn(config_path);
|
||||
remove_fn(paths.config_path);
|
||||
}
|
||||
printf("%s: removed MCP config entry\n", name);
|
||||
if (instr_path) {
|
||||
|
||||
+4
-5
@@ -39,7 +39,6 @@ enum {
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <strings.h> // strcasecmp
|
||||
|
||||
/* ── Helpers ────────────────────────────────────────────────────── */
|
||||
|
||||
@@ -1388,8 +1387,8 @@ static int parse_match_chain(parser_t *p, cbm_query_t *q, int *pat_cap) {
|
||||
}
|
||||
|
||||
/* Parse post-WHERE clauses: additional MATCH, WITH, RETURN, UNION */
|
||||
static int parse_post_where(parser_t *p, cbm_query_t *q,
|
||||
int *pat_cap) { // NOLINT(misc-no-recursion)
|
||||
static int parse_post_where(parser_t *p, cbm_query_t *q, // NOLINT(misc-no-recursion)
|
||||
int *pat_cap) {
|
||||
/* More MATCH / OPTIONAL MATCH after WHERE */
|
||||
if (parse_match_chain(p, q, pat_cap) < 0) {
|
||||
return CBM_NOT_FOUND;
|
||||
@@ -1433,8 +1432,8 @@ static int parse_post_where(parser_t *p, cbm_query_t *q,
|
||||
return 0;
|
||||
}
|
||||
|
||||
int cbm_parse(const cbm_token_t *tokens, int token_count,
|
||||
cbm_parse_result_t *out) { // NOLINT(misc-no-recursion)
|
||||
int cbm_parse(const cbm_token_t *tokens, int token_count, // NOLINT(misc-no-recursion)
|
||||
cbm_parse_result_t *out) {
|
||||
memset(out, 0, sizeof(*out));
|
||||
parser_t p = {.tokens = tokens, .count = token_count, .pos = 0};
|
||||
|
||||
|
||||
@@ -360,7 +360,7 @@ static void walk_dir_process_entry(cbm_dirent_t *entry, const walk_frame_t *fram
|
||||
static void walk_dir(const char *dir_path, const char *rel_prefix, const cbm_discover_opts_t *opts,
|
||||
const cbm_gitignore_t *gitignore, const cbm_gitignore_t *cbmignore,
|
||||
file_list_t *out) {
|
||||
walk_frame_t *stack = malloc(WALK_STACK_CAP * sizeof(walk_frame_t));
|
||||
walk_frame_t *stack = calloc(WALK_STACK_CAP, sizeof(walk_frame_t));
|
||||
if (!stack) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -42,8 +42,8 @@ struct cbm_gitignore {
|
||||
static bool glob_match(const char *pat, const char *str); // NOLINT(misc-no-recursion)
|
||||
|
||||
/* Match a ** (doublestar-slash) pattern: try rest at every / boundary. */
|
||||
static bool glob_match_doublestar_slash(const char *pat,
|
||||
const char *str) { // NOLINT(misc-no-recursion)
|
||||
static bool glob_match_doublestar_slash(const char *pat, // NOLINT(misc-no-recursion)
|
||||
const char *str) {
|
||||
if (glob_match(pat, str)) {
|
||||
return true;
|
||||
}
|
||||
@@ -56,8 +56,8 @@ static bool glob_match_doublestar_slash(const char *pat,
|
||||
}
|
||||
|
||||
/* Match a ** (doublestar) followed by non-slash: try at every position. */
|
||||
static bool glob_match_doublestar_any(const char *pat,
|
||||
const char *str) { // NOLINT(misc-no-recursion)
|
||||
static bool glob_match_doublestar_any(const char *pat, // NOLINT(misc-no-recursion)
|
||||
const char *str) {
|
||||
for (const char *s = str;; s++) {
|
||||
if (glob_match(pat, s)) {
|
||||
return true;
|
||||
|
||||
@@ -10,7 +10,9 @@
|
||||
* skipped (fail-open). Missing files are silently ignored.
|
||||
*/
|
||||
#include "discover/userconfig.h"
|
||||
#include "cbm.h" /* CBMLanguage, CBM_LANG_* */
|
||||
#include "foundation/constants.h"
|
||||
#include "foundation/platform.h" /* cbm_safe_getenv */
|
||||
|
||||
enum { MAX_CONFIG_SIZE = 65536 };
|
||||
#include "foundation/log.h"
|
||||
@@ -157,18 +159,12 @@ static CBMLanguage lang_from_string(const char *s) {
|
||||
*/
|
||||
static void cbm_app_config_dir(char *buf, size_t bufsz) {
|
||||
char xdg[CBM_SZ_512] = {0};
|
||||
char home[CBM_SZ_512] = {0};
|
||||
const char *env_val = getenv("XDG_CONFIG_HOME");
|
||||
if (env_val && env_val[0]) {
|
||||
snprintf(xdg, sizeof(xdg), "%s", env_val);
|
||||
}
|
||||
cbm_safe_getenv("XDG_CONFIG_HOME", xdg, sizeof(xdg), NULL);
|
||||
if (xdg[0]) {
|
||||
snprintf(buf, bufsz, "%s/codebase-memory-mcp", xdg);
|
||||
} else {
|
||||
env_val = getenv("HOME");
|
||||
if (env_val && env_val[0]) {
|
||||
snprintf(home, sizeof(home), "%s", env_val);
|
||||
}
|
||||
char home[CBM_SZ_512] = {0};
|
||||
cbm_safe_getenv("HOME", home, sizeof(home), NULL);
|
||||
if (!home[0]) {
|
||||
snprintf(home, sizeof(home), "/tmp");
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
*/
|
||||
#include "foundation/constants.h"
|
||||
#include "foundation/diagnostics.h"
|
||||
#include <stdatomic.h>
|
||||
#include "foundation/mem.h"
|
||||
#include "foundation/compat.h"
|
||||
#include "foundation/compat_thread.h"
|
||||
@@ -167,11 +168,8 @@ static void *diag_thread_fn(void *arg) {
|
||||
/* ── Public API ──────────────────────────────────────────────────── */
|
||||
|
||||
bool cbm_diag_start(void) {
|
||||
const char *raw_env = getenv("CBM_DIAGNOSTICS");
|
||||
char env_buf[CBM_SZ_32] = "";
|
||||
if (raw_env) {
|
||||
snprintf(env_buf, sizeof(env_buf), "%s", raw_env);
|
||||
}
|
||||
cbm_safe_getenv("CBM_DIAGNOSTICS", env_buf, sizeof(env_buf), NULL);
|
||||
if (env_buf[0] == '\0' || (strcmp(env_buf, "1") != 0 && strcmp(env_buf, "true") != 0)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
+36
-22
@@ -4,10 +4,12 @@
|
||||
* macOS, Linux, and Windows. Platform-specific code behind #ifdef guards.
|
||||
*/
|
||||
#include "platform.h"
|
||||
#include "compat.h"
|
||||
|
||||
#include "foundation/constants.h"
|
||||
#include <stdint.h> // uint64_t, int64_t
|
||||
#include <fcntl.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
@@ -113,7 +115,6 @@ char *cbm_normalize_path_sep(char *path) {
|
||||
|
||||
/* ── POSIX implementation ─────────────────────────────────────── */
|
||||
|
||||
#include <fcntl.h> // open, O_RDONLY
|
||||
#include <sys/mman.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
@@ -178,7 +179,7 @@ uint64_t cbm_now_ns(void) {
|
||||
#else
|
||||
uint64_t cbm_now_ns(void) {
|
||||
struct timespec ts;
|
||||
cbm_clock_gettime(CLOCK_MONOTONIC, &ts);
|
||||
clock_gettime(CLOCK_MONOTONIC, &ts);
|
||||
return (uint64_t)ts.tv_sec * 1000000000ULL + (uint64_t)ts.tv_nsec;
|
||||
}
|
||||
#endif
|
||||
@@ -243,41 +244,54 @@ char *cbm_normalize_path_sep(char *path) {
|
||||
|
||||
/* ── Environment variables ────────────────────────────────────── */
|
||||
|
||||
/* Thread-safe getenv: iterates environ directly instead of calling getenv().
|
||||
* getenv() is flagged by concurrency-mt-unsafe because the returned pointer
|
||||
* can be invalidated by setenv/putenv in another thread. We copy to a
|
||||
* caller-owned buffer immediately. */
|
||||
#ifdef _WIN32
|
||||
extern char **_environ;
|
||||
#define CBM_ENVIRON _environ
|
||||
#elif defined(__APPLE__)
|
||||
#include <crt_externs.h>
|
||||
#define CBM_ENVIRON (*_NSGetEnviron())
|
||||
#else
|
||||
extern char **environ;
|
||||
#define CBM_ENVIRON environ
|
||||
#endif
|
||||
|
||||
const char *cbm_safe_getenv(const char *name, char *buf, size_t buf_sz, const char *fallback) {
|
||||
const char *val = getenv(name);
|
||||
if (!val) {
|
||||
if (fallback) {
|
||||
snprintf(buf, buf_sz, "%s", fallback);
|
||||
return buf;
|
||||
char **env = CBM_ENVIRON;
|
||||
if (env) {
|
||||
size_t nlen = strlen(name);
|
||||
for (; *env; env++) {
|
||||
if (strncmp(*env, name, nlen) == 0 && (*env)[nlen] == '=') {
|
||||
snprintf(buf, buf_sz, "%s", *env + nlen + SKIP_ONE);
|
||||
return buf;
|
||||
}
|
||||
}
|
||||
buf[0] = '\0';
|
||||
return NULL;
|
||||
}
|
||||
snprintf(buf, buf_sz, "%s", val);
|
||||
return buf;
|
||||
if (fallback) {
|
||||
snprintf(buf, buf_sz, "%s", fallback);
|
||||
return buf;
|
||||
}
|
||||
buf[0] = '\0';
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* ── Home directory (cross-platform) ──────────────────────────── */
|
||||
|
||||
const char *cbm_get_home_dir(void) {
|
||||
static char buf[CBM_SZ_1K];
|
||||
const char *raw;
|
||||
char tmp[CBM_SZ_256] = "";
|
||||
|
||||
raw = getenv("HOME");
|
||||
if (raw) {
|
||||
snprintf(tmp, sizeof(tmp), "%s", raw);
|
||||
}
|
||||
cbm_safe_getenv("HOME", tmp, sizeof(tmp), NULL);
|
||||
if (tmp[0]) {
|
||||
snprintf(buf, sizeof(buf), "%s", tmp);
|
||||
cbm_normalize_path_sep(buf);
|
||||
return buf;
|
||||
}
|
||||
|
||||
raw = getenv("USERPROFILE");
|
||||
if (raw) {
|
||||
snprintf(tmp, sizeof(tmp), "%s", raw);
|
||||
}
|
||||
cbm_safe_getenv("USERPROFILE", tmp, sizeof(tmp), NULL);
|
||||
if (tmp[0]) {
|
||||
snprintf(buf, sizeof(buf), "%s", tmp);
|
||||
cbm_normalize_path_sep(buf);
|
||||
|
||||
@@ -19,8 +19,7 @@ enum { YAML_INIT_CAP = 8, YAML_LIST_PREFIX = 2, YAML_ROOT_INDENT = -1 };
|
||||
#include <stddef.h> // NULL
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h> // strdup
|
||||
#include <strings.h> // strcasecmp
|
||||
#include <string.h>
|
||||
|
||||
/* ── Node types ───────────────────────────────────────────────── */
|
||||
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
|
||||
enum { PC_RING = 4, PC_RING_MASK = 3, PC_SIG_SCAN = 15, PC_REGEX_GRP = 2 };
|
||||
#include "pipeline/pipeline.h"
|
||||
#include <stdint.h>
|
||||
#include "pipeline/pipeline_internal.h"
|
||||
#include "graph_buffer/graph_buffer.h"
|
||||
#include "foundation/log.h"
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
|
||||
enum { PD_RING = 4, PD_RING_MASK = 3, PD_JSON_MARGIN = 10, PD_ESC_MARGIN = 3, PD_ESC_SPACE = 2 };
|
||||
#include "pipeline/pipeline.h"
|
||||
#include <stdint.h>
|
||||
#include "pipeline/pipeline_internal.h"
|
||||
#include "graph_buffer/graph_buffer.h"
|
||||
#include "foundation/log.h"
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
|
||||
enum { ENRICH_ATTR_SKIP = 2, ENRICH_MAX_CAMEL = 16 };
|
||||
#include "pipeline/pipeline.h"
|
||||
#include <stdint.h>
|
||||
#include "pipeline/pipeline_internal.h"
|
||||
#include "graph_buffer/graph_buffer.h"
|
||||
#include "foundation/log.h"
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
*/
|
||||
#include "foundation/constants.h"
|
||||
#include "pipeline/pipeline.h"
|
||||
#include <stdint.h>
|
||||
#include "pipeline/pipeline_internal.h"
|
||||
#include "graph_buffer/graph_buffer.h"
|
||||
#include "discover/discover.h"
|
||||
|
||||
@@ -28,6 +28,7 @@ enum {
|
||||
|
||||
#define SLEN(s) (sizeof(s) - 1)
|
||||
#include "pipeline/pipeline_internal.h"
|
||||
#include <stdint.h>
|
||||
#include "graph_buffer/graph_buffer.h"
|
||||
#include "foundation/log.h"
|
||||
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
*/
|
||||
#include "foundation/constants.h"
|
||||
#include "pipeline/pipeline.h"
|
||||
#include <stdint.h>
|
||||
#include "pipeline/pipeline_internal.h"
|
||||
#include "graph_buffer/graph_buffer.h"
|
||||
#include "foundation/log.h"
|
||||
|
||||
@@ -660,19 +660,12 @@ static int run_githistory(cbm_pipeline_t *p, cbm_pipeline_ctx_t *ctx) {
|
||||
cbm_log_info("pass.skip", "pass", "githistory", "reason", "fast_mode");
|
||||
}
|
||||
|
||||
int rc = 0;
|
||||
|
||||
if (gh_threaded) {
|
||||
cbm_thread_join(&gh_thread);
|
||||
cbm_log_info("pass.timing", "pass", "githistory_compute", "elapsed_ms",
|
||||
itoa_buf((int)elapsed_ms(t_gh)));
|
||||
}
|
||||
|
||||
if (rc != 0) {
|
||||
free(gh_result.couplings);
|
||||
return rc;
|
||||
}
|
||||
|
||||
int gh_edges = 0;
|
||||
if (gh_result.count > 0) {
|
||||
gh_edges = cbm_pipeline_githistory_apply(ctx, &gh_result);
|
||||
|
||||
@@ -13,6 +13,8 @@
|
||||
|
||||
enum { INCR_RING_BUF = 4, INCR_RING_MASK = 3, INCR_TS_BUF = 24, INCR_WAL_BUF = 1040 };
|
||||
#include "pipeline/pipeline.h"
|
||||
#include <stdio.h>
|
||||
#include <time.h>
|
||||
#include "pipeline/pipeline_internal.h"
|
||||
#include "store/store.h"
|
||||
#include "graph_buffer/graph_buffer.h"
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
|
||||
// for ISO timestamp
|
||||
|
||||
#include <stdint.h>
|
||||
#include "foundation/constants.h"
|
||||
|
||||
enum {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
/*
|
||||
* traces.c — OTLP trace processing helpers.
|
||||
*/
|
||||
#include <stdint.h>
|
||||
#include "traces/traces.h"
|
||||
#include "foundation/constants.h"
|
||||
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
* Adaptive interval: 5s base + 1s per 500 files, capped at 60s.
|
||||
* Matches the Go watcher's `pollInterval()` logic.
|
||||
*/
|
||||
#include <stdint.h>
|
||||
#include "watcher/watcher.h"
|
||||
#include "store/store.h"
|
||||
#include "foundation/constants.h"
|
||||
|
||||
Reference in new issue
Block a user