| 13791 | #endif |
| 13792 | |
| 13793 | char *cbm_cli_build_args_json(const char *tool_name, int argc, char **argv, char **err_out) { |
| 13794 | if (err_out) { |
| 13795 | *err_out = NULL; |
| 13796 | } |
| 13797 | |
| 13798 | /* The tool's input_schema (may be NULL for an unknown tool — then every |
| 13799 | * value is treated as a string). Static lifetime; do not free. */ |
| 13800 | const char *schema_str = cbm_mcp_tool_input_schema(tool_name); |
| 13801 | yyjson_doc *schema_doc = NULL; |
| 13802 | yyjson_val *props = NULL; |
| 13803 | if (schema_str) { |
| 13804 | schema_doc = yyjson_read(schema_str, strlen(schema_str), 0); |
| 13805 | if (schema_doc) { |
| 13806 | props = yyjson_obj_get(yyjson_doc_get_root(schema_doc), "properties"); |
| 13807 | } |
| 13808 | } |
| 13809 | |
| 13810 | yyjson_mut_doc *out = yyjson_mut_doc_new(NULL); |
| 13811 | if (!out) { |
| 13812 | if (schema_doc) { |
| 13813 | yyjson_doc_free(schema_doc); |
| 13814 | } |
| 13815 | return NULL; |
| 13816 | } |
| 13817 | yyjson_mut_val *obj = yyjson_mut_obj(out); |
| 13818 | yyjson_mut_doc_set_root(out, obj); |
| 13819 | |
| 13820 | bool ok = true; |
| 13821 | for (int i = 0; i < argc && ok; i++) { |
| 13822 | const char *arg = argv[i]; |
| 13823 | if (strcmp(arg, "--") == 0) { |
| 13824 | break; /* end of flag parsing */ |
| 13825 | } |
| 13826 | if (strncmp(arg, "--", CLI_PAIR_LEN) != 0) { |
| 13827 | if (err_out) { |
| 13828 | *err_out = cli_heap_msgf("unexpected argument '%s' (expected --flag value)", arg); |
| 13829 | } |
| 13830 | ok = false; |
| 13831 | break; |
| 13832 | } |
| 13833 | |
| 13834 | const char *body = arg + CLI_PAIR_LEN; /* skip leading "--" */ |
| 13835 | const char *eq = strchr(body, '='); |
| 13836 | char key[CLI_BUF_256]; |
| 13837 | const char *value = NULL; |
| 13838 | bool have_value = false; |
| 13839 | |
| 13840 | if (eq) { |
| 13841 | /* --key=value : split on the FIRST '='; value may contain '='/spaces. */ |
| 13842 | size_t klen = (size_t)(eq - body); |
| 13843 | if (klen >= sizeof(key)) { |
| 13844 | klen = sizeof(key) - CLI_SKIP_ONE; |
| 13845 | } |
| 13846 | memcpy(key, body, klen); |
| 13847 | key[klen] = '\0'; |
| 13848 | value = eq + CLI_SKIP_ONE; |
| 13849 | have_value = true; |
| 13850 | } else { |
no test coverage detected