| 1527 | } |
| 1528 | |
| 1529 | std::string RpcServerImpl::help(const std::string& command_name) const |
| 1530 | { |
| 1531 | std::string help_string; |
| 1532 | if (command_name.empty()) //if no arguments, display list of commands with short description |
| 1533 | { |
| 1534 | for (const MethodMapType::value_type& method_data_pair : _method_map) |
| 1535 | if (method_data_pair.second.name[0] != '_' && method_data_pair.second.name.substr(0, 8) != "bitcoin_") // hide undocumented commands |
| 1536 | help_string += make_short_description(method_data_pair.second, false); |
| 1537 | } |
| 1538 | else |
| 1539 | { //display detailed description of requested command |
| 1540 | auto alias_iter = _alias_map.find(command_name); |
| 1541 | if (alias_iter != _alias_map.end()) |
| 1542 | { |
| 1543 | auto method_iter = _method_map.find(alias_iter->second); |
| 1544 | FC_ASSERT(method_iter != _method_map.end(), "internal error, mismatch between _method_map and _alias_map"); |
| 1545 | const thinkyoung::api::MethodData& method_data = method_iter->second; |
| 1546 | help_string += "Usage:\n"; |
| 1547 | help_string += make_short_description(method_data); |
| 1548 | help_string += method_data.detailed_description; |
| 1549 | if (method_data.aliases.size() > 0) |
| 1550 | help_string += "\naliases: " + boost::join(method_data.aliases, ", "); |
| 1551 | } |
| 1552 | else |
| 1553 | { |
| 1554 | // no exact matches for the command they requested. |
| 1555 | // If they give us a prefix, give them the list of commands that start |
| 1556 | // with that prefix (i.e. "help wallet" will return wallet_open, wallet_close, &c) |
| 1557 | std::set<std::string> matching_commands; |
| 1558 | for (auto method_iter = _method_map.lower_bound(command_name); |
| 1559 | method_iter != _method_map.end() && method_iter->first.compare(0, command_name.size(), command_name) == 0; |
| 1560 | ++method_iter) |
| 1561 | matching_commands.insert(method_iter->first); |
| 1562 | // If they give us an alias (or its prefix), give them the list of real command names, eliminating duplication |
| 1563 | for (auto alias_itr = _alias_map.lower_bound(command_name); |
| 1564 | alias_itr != _alias_map.end() && alias_itr->first.compare(0, command_name.size(), command_name) == 0; |
| 1565 | ++alias_itr) |
| 1566 | matching_commands.insert(alias_itr->second); |
| 1567 | for (auto command : matching_commands) |
| 1568 | { |
| 1569 | auto method_iter = _method_map.find(command); |
| 1570 | FC_ASSERT(method_iter != _method_map.end(), "internal error, mismatch between _method_map and _alias_map"); |
| 1571 | help_string += make_short_description(method_iter->second); |
| 1572 | } |
| 1573 | if (help_string.empty()) |
| 1574 | throw rpc_misc_error_exception(FC_LOG_MESSAGE(error, "No help available for command \"${command}\"", ("command", command_name))); |
| 1575 | } |
| 1576 | } |
| 1577 | |
| 1578 | return boost::algorithm::trim_copy(help_string); |
| 1579 | } |
| 1580 | |
| 1581 | } // detail |
| 1582 | |