Return a string field from a node by property name. NULL-safe. */
| 2217 | |
| 2218 | /* Return a string field from a node by property name. NULL-safe. */ |
| 2219 | static const char *node_string_field(const cbm_node_t *n, const char *prop) { |
| 2220 | static const struct { |
| 2221 | const char *key; |
| 2222 | size_t offset; |
| 2223 | } fields[] = { |
| 2224 | {"name", offsetof(cbm_node_t, name)}, |
| 2225 | {"qualified_name", offsetof(cbm_node_t, qualified_name)}, |
| 2226 | /* Aliases: field-eval agents reach for the short names, and a miss |
| 2227 | * used to return a silent empty column costing a round-trip. */ |
| 2228 | {"qn", offsetof(cbm_node_t, qualified_name)}, |
| 2229 | {"label", offsetof(cbm_node_t, label)}, |
| 2230 | {"file_path", offsetof(cbm_node_t, file_path)}, |
| 2231 | {"file", offsetof(cbm_node_t, file_path)}, |
| 2232 | {"path", offsetof(cbm_node_t, file_path)}, |
| 2233 | }; |
| 2234 | for (size_t i = 0; i < sizeof(fields) / sizeof(fields[0]); i++) { |
| 2235 | if (strcmp(prop, fields[i].key) == 0) { |
| 2236 | const char *val = *(const char **)((const char *)n + fields[i].offset); |
| 2237 | return val ? val : ""; |
| 2238 | } |
| 2239 | } |
| 2240 | return NULL; |
| 2241 | } |
| 2242 | |
| 2243 | /* Get node property by name. |
| 2244 | * store may be NULL; only needed for virtual degree properties. */ |