| 955 | }; |
| 956 | |
| 957 | idx_t ShellState::PrintHelp(const char *pattern) { |
| 958 | bool print_extended = false; |
| 959 | string glob_pattern; |
| 960 | if (pattern) { |
| 961 | // if a pattern is provided we always print extended info |
| 962 | print_extended = true; |
| 963 | if (StringUtil::Equals(pattern, "-a") || StringUtil::Equals(pattern, "-all") || |
| 964 | StringUtil::Equals(pattern, "--all")) { |
| 965 | // --all matches all commands |
| 966 | glob_pattern = string(); |
| 967 | } else { |
| 968 | glob_pattern = StringUtil::Format("%s*", pattern); |
| 969 | } |
| 970 | } |
| 971 | |
| 972 | constexpr idx_t MIN_SPACING = 4; |
| 973 | constexpr idx_t SPACING_PER_LAYER = 2; |
| 974 | vector<PrintCommandInfo> print_info_list; |
| 975 | // gather a list of all print statements |
| 976 | for (idx_t i = 0; metadata_commands[i].command; i++) { |
| 977 | auto &command = metadata_commands[i]; |
| 978 | if (!ShouldPrintCommand(command, glob_pattern)) { |
| 979 | continue; |
| 980 | } |
| 981 | PrintCommandInfo print_info; |
| 982 | print_info.command_name = StringUtil::Format(".%s", command.command); |
| 983 | print_info.first_part += StringUtil::Format(" %s", command.usage); |
| 984 | print_info.second_part = command.description; |
| 985 | print_info.first_part_highlight = HighlightElementType::STRING_CONSTANT; |
| 986 | print_info_list.push_back(std::move(print_info)); |
| 987 | |
| 988 | if (print_extended) { |
| 989 | // process extended info |
| 990 | PrintCommandInfo current_command; |
| 991 | bool first_part = true; |
| 992 | bool after_newline = true; |
| 993 | for (auto c = command.extra_description; *c; c++) { |
| 994 | if (*c == '\n') { |
| 995 | // newline - flush the current command and reset |
| 996 | print_info_list.push_back(std::move(current_command)); |
| 997 | current_command = PrintCommandInfo(); |
| 998 | first_part = true; |
| 999 | after_newline = true; |
| 1000 | } else if (*c == '\t') { |
| 1001 | // tab |
| 1002 | if (after_newline) { |
| 1003 | // tab right after newline - add spaces |
| 1004 | current_command.first_part += string(SPACING_PER_LAYER, ' '); |
| 1005 | } else { |
| 1006 | // tab not right after newline move to second part |
| 1007 | if (!first_part) { |
| 1008 | throw duckdb::InternalException( |
| 1009 | "Failed to parse extra description for command \"%s\" - only one tab (switch from " |
| 1010 | "first -> second part) was expected", |
| 1011 | command.command); |
| 1012 | } |
| 1013 | first_part = false; |
| 1014 | } |
no test coverage detected