Skip to content
Open
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
5 changes: 5 additions & 0 deletions src/cypher/cypher.c
Original file line number Diff line number Diff line change
Expand Up @@ -2163,8 +2163,13 @@ static const char *node_string_field(const cbm_node_t *n, const char *prop) {
} fields[] = {
{"name", offsetof(cbm_node_t, name)},
{"qualified_name", offsetof(cbm_node_t, qualified_name)},
/* Aliases: field-eval agents reach for the short names, and a miss
* used to return a silent empty column costing a round-trip. */
{"qn", offsetof(cbm_node_t, qualified_name)},
{"label", offsetof(cbm_node_t, label)},
{"file_path", offsetof(cbm_node_t, file_path)},
{"file", offsetof(cbm_node_t, file_path)},
{"path", offsetof(cbm_node_t, file_path)},
};
for (size_t i = 0; i < sizeof(fields) / sizeof(fields[0]); i++) {
if (strcmp(prop, fields[i].key) == 0) {
Expand Down
58 changes: 31 additions & 27 deletions src/mcp/compact_out.c
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/* compact_out.c — TOON emission helpers. See compact_out.h for the contract. */
/* compact_out.c — tree-format emission helpers. See compact_out.h for the contract. */
#include "mcp/compact_out.h"

#include <ctype.h>
Expand Down Expand Up @@ -72,7 +72,7 @@ void cbm_sb_free(cbm_sb_t *sb) {
cbm_sb_init(sb);
}

/* ── TOON quoting ───────────────────────────────────────────────── */
/* ── Tree quoting ───────────────────────────────────────────────── */

/* True when `s` parses as an integer or real literal (sign, digits, one dot). */
static bool looks_numeric(const char *s) {
Expand All @@ -99,17 +99,17 @@ static bool looks_numeric(const char *s) {

static bool needs_quotes(const char *s) {
if (!s || !*s) {
return true; /* empty cell must be visible as "" */
}
if (isspace((unsigned char)s[0]) || isspace((unsigned char)s[strlen(s) - 1])) {
return true;
return false; /* empty cells emit as the "-" placeholder, not quotes */
}
for (const char *p = s; *p; p++) {
if (*p == ',' || *p == '"' || *p == '\n' || *p == '\r') {
/* Space-delimited rows: any internal whitespace or quote forces
* quoting so column positions stay parseable. */
if (isspace((unsigned char)*p) || *p == '"' || *p == '\r') {
return true;
}
}
if (strcmp(s, "true") == 0 || strcmp(s, "false") == 0 || strcmp(s, "null") == 0) {
if (strcmp(s, "true") == 0 || strcmp(s, "false") == 0 || strcmp(s, "null") == 0 ||
strcmp(s, "-") == 0) {
return true;
}
return looks_numeric(s);
Expand Down Expand Up @@ -140,6 +140,10 @@ static void append_quoted(cbm_sb_t *sb, const char *s) {
}

static void append_value(cbm_sb_t *sb, const char *s) {
if (!s || !*s) {
cbm_sb_append_n(sb, "-", 1); /* stable column positions for empties */
return;
}
if (needs_quotes(s)) {
append_quoted(sb, s);
} else {
Expand All @@ -149,14 +153,14 @@ static void append_value(cbm_sb_t *sb, const char *s) {

/* ── Scalars ────────────────────────────────────────────────────── */

void cbm_toon_scalar_str(cbm_sb_t *sb, const char *key, const char *val) {
void cbm_tree_scalar_str(cbm_sb_t *sb, const char *key, const char *val) {
cbm_sb_append(sb, key);
cbm_sb_append_n(sb, ": ", 2);
append_value(sb, val);
cbm_sb_append_n(sb, "\n", 1);
}

void cbm_toon_scalar_int(cbm_sb_t *sb, const char *key, long long v) {
void cbm_tree_scalar_int(cbm_sb_t *sb, const char *key, long long v) {
char num[32];
snprintf(num, sizeof(num), "%lld", v);
cbm_sb_append(sb, key);
Expand All @@ -165,7 +169,7 @@ void cbm_toon_scalar_int(cbm_sb_t *sb, const char *key, long long v) {
cbm_sb_append_n(sb, "\n", 1);
}

void cbm_toon_scalar_bool(cbm_sb_t *sb, const char *key, bool v) {
void cbm_tree_scalar_bool(cbm_sb_t *sb, const char *key, bool v) {
cbm_sb_append(sb, key);
cbm_sb_append_n(sb, ": ", 2);
cbm_sb_append(sb, v ? "true" : "false");
Expand All @@ -174,57 +178,57 @@ void cbm_toon_scalar_bool(cbm_sb_t *sb, const char *key, bool v) {

/* ── Tables ─────────────────────────────────────────────────────── */

void cbm_toon_table_header(cbm_sb_t *sb, const char *key, int n, const char *const *cols,
/* Tree-syntax table header: `key: N (cols: a b c)` — count first (agents
* read scale before rows), column names once, rows indented beneath. */
void cbm_tree_table_header(cbm_sb_t *sb, const char *key, int n, const char *const *cols,
int ncols) {
char num[32];
snprintf(num, sizeof(num), "[%d]{", n);
snprintf(num, sizeof(num), ": %d (cols:", n);
cbm_sb_append(sb, key);
cbm_sb_append(sb, num);
for (int i = 0; i < ncols; i++) {
if (i > 0) {
cbm_sb_append_n(sb, ",", 1);
}
cbm_sb_append_n(sb, " ", 1);
cbm_sb_append(sb, cols[i]);
}
cbm_sb_append_n(sb, "}:\n", 3);
cbm_sb_append_n(sb, ")\n", 2);
}

void cbm_toon_row_begin(cbm_sb_t *sb) {
void cbm_tree_row_begin(cbm_sb_t *sb) {
cbm_sb_append_n(sb, " ", 2);
}

void cbm_toon_cell_str(cbm_sb_t *sb, const char *val, bool first) {
void cbm_tree_cell_str(cbm_sb_t *sb, const char *val, bool first) {
if (!first) {
cbm_sb_append_n(sb, ",", 1);
cbm_sb_append_n(sb, " ", 1);
}
append_value(sb, val ? val : "");
}

void cbm_toon_cell_int(cbm_sb_t *sb, long long v, bool first) {
void cbm_tree_cell_int(cbm_sb_t *sb, long long v, bool first) {
char num[32];
snprintf(num, sizeof(num), "%lld", v);
if (!first) {
cbm_sb_append_n(sb, ",", 1);
cbm_sb_append_n(sb, " ", 1);
}
cbm_sb_append(sb, num);
}

void cbm_toon_cell_real(cbm_sb_t *sb, double v, bool first) {
void cbm_tree_cell_real(cbm_sb_t *sb, double v, bool first) {
char num[48];
snprintf(num, sizeof(num), "%.4g", v);
if (!first) {
cbm_sb_append_n(sb, ",", 1);
cbm_sb_append_n(sb, " ", 1);
}
cbm_sb_append(sb, num);
}

void cbm_toon_cell_bool(cbm_sb_t *sb, bool v, bool first) {
void cbm_tree_cell_bool(cbm_sb_t *sb, bool v, bool first) {
if (!first) {
cbm_sb_append_n(sb, ",", 1);
cbm_sb_append_n(sb, " ", 1);
}
cbm_sb_append(sb, v ? "true" : "false");
}

void cbm_toon_row_end(cbm_sb_t *sb) {
void cbm_tree_row_end(cbm_sb_t *sb) {
cbm_sb_append_n(sb, "\n", 1);
}
20 changes: 10 additions & 10 deletions src/mcp/compact_out.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,21 +34,21 @@ char *cbm_sb_finish(cbm_sb_t *sb);
void cbm_sb_free(cbm_sb_t *sb);

/* `key: value` scalar lines (top-level, no indent). */
void cbm_toon_scalar_str(cbm_sb_t *sb, const char *key, const char *val);
void cbm_toon_scalar_int(cbm_sb_t *sb, const char *key, long long v);
void cbm_toon_scalar_bool(cbm_sb_t *sb, const char *key, bool v);
void cbm_tree_scalar_str(cbm_sb_t *sb, const char *key, const char *val);
void cbm_tree_scalar_int(cbm_sb_t *sb, const char *key, long long v);
void cbm_tree_scalar_bool(cbm_sb_t *sb, const char *key, bool v);

/* `key[n]{col1,col2,...}:` table header; rows follow at 2-space indent. */
void cbm_toon_table_header(cbm_sb_t *sb, const char *key, int n, const char *const *cols,
void cbm_tree_table_header(cbm_sb_t *sb, const char *key, int n, const char *const *cols,
int ncols);

/* Row cells: call row_begin, then cell_* per column (first=true for the
* first cell), then row_end. Empty/NULL strings emit as empty cells. */
void cbm_toon_row_begin(cbm_sb_t *sb);
void cbm_toon_cell_str(cbm_sb_t *sb, const char *val, bool first);
void cbm_toon_cell_int(cbm_sb_t *sb, long long v, bool first);
void cbm_toon_cell_real(cbm_sb_t *sb, double v, bool first);
void cbm_toon_cell_bool(cbm_sb_t *sb, bool v, bool first);
void cbm_toon_row_end(cbm_sb_t *sb);
void cbm_tree_row_begin(cbm_sb_t *sb);
void cbm_tree_cell_str(cbm_sb_t *sb, const char *val, bool first);
void cbm_tree_cell_int(cbm_sb_t *sb, long long v, bool first);
void cbm_tree_cell_real(cbm_sb_t *sb, double v, bool first);
void cbm_tree_cell_bool(cbm_sb_t *sb, bool v, bool first);
void cbm_tree_row_end(cbm_sb_t *sb);

#endif /* CBM_MCP_COMPACT_OUT_H */
Loading
Loading