Refactor help-related code into redis-cli.c

This commit is contained in:
Pieter Noordhuis 2010-11-28 21:37:19 +01:00
parent 50d0e82d54
commit a2a69d5803
4 changed files with 482 additions and 583 deletions

File diff suppressed because it is too large Load Diff

View File

@ -84,6 +84,65 @@ static long long mstime(void) {
return mst;
}
/*------------------------------------------------------------------------------
* Help functions
*--------------------------------------------------------------------------- */
/* Output command help to stdout. */
static void outputCommandHelp(struct commandHelp *help) {
printf("\n \x1b[1m%s\x1b[0m \x1b[90m%s\x1b[0m\n", help->name, help->params);
printf(" \x1b[33msummary:\x1b[0m %s\n", help->summary);
printf(" \x1b[33msince:\x1b[0m %s\n", help->since);
printf(" \x1b[33mgroup:\x1b[0m %s\n", commandGroups[help->group]);
}
/* Return command group type by name string. */
static int commandGroupIndex(const char *name) {
int i, len = sizeof(commandGroups)/sizeof(char*);
for (i = 0; i < len; i++)
if (strcasecmp(name, commandGroups[i]) == 0)
return i;
return -1;
}
/* Output group names. */
static void outputGroupHelp() {
int i, len = sizeof(commandGroups)/sizeof(char*);
for (i = 0; i < len; i++)
printf(" \x1b[90m-\x1b[0m %s\n", commandGroups[i]);
}
/* Output all command help, filtering by group or command name. */
static void outputHelp(int argc, char **argv) {
int i, len = sizeof(commandHelp) / sizeof(struct commandHelp);
int group;
struct commandHelp *help;
if (argc && strcasecmp("groups", argv[0]) == 0) {
outputGroupHelp();
return;
}
group = argc ? commandGroupIndex(argv[0]) : -1;
for (i = 0; i < len; i++) {
help = &commandHelp[i];
if (group == -1) {
if (argc) {
if (strcasecmp(help->name, argv[0]) == 0) {
outputCommandHelp(help);
}
} else {
outputCommandHelp(help);
}
} else {
if (group == help->group) {
outputCommandHelp(help);
}
}
}
puts("");
}
/*------------------------------------------------------------------------------
* Networking / parsing
*--------------------------------------------------------------------------- */
@ -260,7 +319,7 @@ static int cliSendCommand(int argc, char **argv, int repeat) {
config.raw_output = !strcasecmp(command,"info");
if (!strcasecmp(command,"help")) {
output_help(--argc, ++argv);
outputHelp(--argc, ++argv);
return REDIS_OK;
}
if (!strcasecmp(command,"shutdown")) config.shutdown = 1;

View File

@ -1,5 +1,24 @@
#!/usr/bin/env ruby
GROUPS = [
"generic",
"string",
"list",
"set",
"sorted_set",
"hash",
"pubsub",
"transactions",
"connection",
"server"
].freeze
GROUPS_BY_NAME = Hash[*
GROUPS.each_with_index.map do |n,i|
[n,i]
end.flatten
].freeze
def argument arg
name = arg["name"].is_a?(Array) ? arg["name"].join(" ") : arg["name"]
name = arg["enum"].join "|" if "enum" == arg["type"]
@ -39,21 +58,54 @@ def commands
end
end
def generate_groups
GROUPS.map do |n|
"\"#{n}\""
end.join(",\n ");
end
def generate_commands
commands.to_a.sort do |x,y|
x[0] <=> y[0]
end.map do |key, command|
<<-SPEC
group = GROUPS_BY_NAME[command["group"]]
if group.nil?
STDERR.puts "Please update groups array in #{__FILE__}"
raise "Unknown group #{command["group"]}"
end
ret = <<-SPEC
{ "#{key}",
"#{arguments(command)}",
"#{command["summary"]}",
COMMAND_GROUP_#{command["group"].upcase},
#{group},
"#{command["since"]}" }
SPEC
end.join(", ")
ret.strip
end.join(",\n ")
end
# Write to stdout
tmpl = File.read "./utils/help.h"
puts "\n// Auto-generated, do not edit.\n" + tmpl.sub("__COMMANDS__", generate_commands)
puts <<-HELP_H
/* Automatically generated by #{__FILE__}, do not edit. */
#ifndef __REDIS_HELP_H
#define __REDIS_HELP_H
static char *commandGroups[] = {
#{generate_groups}
};
struct commandHelp {
char *name;
char *params;
char *summary;
int group;
char *since;
} commandHelp[] = {
#{generate_commands}
};
#endif
HELP_H

View File

@ -1,119 +0,0 @@
#include <stdio.h>
#include <string.h>
/*
* List command groups.
*/
#define GROUPS \
G(UNKNOWN, "unknown") \
G(SET, "set") \
G(LIST, "list") \
G(HASH, "hash") \
G(GENERIC, "generic") \
G(PUBSUB, "pubsub") \
G(STRING, "string") \
G(SERVER, "server") \
G(CONNECTION, "connection") \
G(TRANSACTIONS, "transactions") \
G(SORTED_SET, "sorted_set")
/*
* Command group types.
*/
typedef enum {
#define G(GROUP, _) COMMAND_GROUP_##GROUP,
GROUPS
#undef G
COMMAND_GROUP_LENGTH
} command_group_type_t;
/*
* Command group type names.
*/
static char *command_group_type_names[] = {
#define G(_, STR) STR,
GROUPS
#undef G
};
/*
* Command help struct.
*/
struct command_help {
char *name;
char *params;
char *summary;
command_group_type_t group;
char *since;
} command_help[] = {
__COMMANDS__
};
/*
* Output command help to stdout.
*/
static void
output_command_help(struct command_help *help) {
printf("\n \x1b[1m%s\x1b[0m \x1b[90m%s\x1b[0m\n", help->name, help->params);
printf(" \x1b[33msummary:\x1b[0m %s\n", help->summary);
printf(" \x1b[33msince:\x1b[0m %s\n", help->since);
printf(" \x1b[33mgroup:\x1b[0m %s\n", command_group_type_names[help->group]);
}
/*
* Return command group type by name string.
*/
static command_group_type_t
command_group_type_by_name(const char *name) {
for (int i = 0; i < COMMAND_GROUP_LENGTH; ++i) {
const char *group = command_group_type_names[i];
if (0 == strcasecmp(name, group)) return i;
}
return 0;
}
/*
* Output group names.
*/
static void
output_group_help() {
for (int i = 0; i < COMMAND_GROUP_LENGTH; ++i) {
if (COMMAND_GROUP_UNKNOWN == i) continue;
const char *group = command_group_type_names[i];
printf(" \x1b[90m-\x1b[0m %s\n", group);
}
}
/*
* Output all command help, filtering by group or command name.
*/
static void
output_help(int argc, const char **argv) {
int len = sizeof(command_help) / sizeof(struct command_help);
if (argc && 0 == strcasecmp("groups", argv[0])) {
output_group_help();
return;
}
command_group_type_t group = argc
? command_group_type_by_name(argv[0])
: COMMAND_GROUP_UNKNOWN;
for (int i = 0; i < len; ++i) {
struct command_help help = command_help[i];
if (argc && !group && 0 != strcasecmp(help.name, argv[0])) continue;
if (group && group != help.group) continue;
output_command_help(&help);
}
puts("");
}