命令行解析

To increase extensibility, we can use a more flexible approach by creating a command table and defining functions for each command. This way, we can easily add new commands in the future without modifying the core parsing logic. Let’s rewrite the code to demonstrate this:

#include 
#include 
#include 
#include 

// Define a struct to represent the command-line options and arguments
typedef struct {
    char *command;
    char *option;
    char *args[3];
} CommandLineArgs;

// Function prototypes for command handlers
static error_t read_handler(CommandLineArgs *arguments);
static error_t write_handler(CommandLineArgs *arguments);
static error_t show_handler(CommandLineArgs *arguments);

// Define a struct for each command
typedef struct {
    const char *name;
    const char *description;
    error_t (*handler)(CommandLineArgs *arguments);
} Command;

// Command table with all available commands
static const Command commands[] = {
    { "read", "Read command", read_handler },
    { "write", "Write command", write_handler },
    { "show", "Show command", show_handler },
    { NULL, NULL, NULL } // End of table marker
};

// Parse command-line arguments using argp
static error_t parse_opt(int key, char *arg, struct argp_state *state) {
    CommandLineArgs *arguments = state->input;

    switch (key) {
        case 'c':
            arguments->command = arg;
            break;
        case 'o':
            arguments->option = arg;
            break;
        case ARGP_KEY_ARG:
            for (int i = 0; i < 3; i++) {
                if (!arguments->args[i]) {
                    arguments->args[i] = arg;
                    break;
                }
            }
            break;
        case ARGP_KEY_END:
            if (!arguments->command) {
                argp_error(state, "Error: No command provided.");
            }
            break;
        default:
            return ARGP_ERR_UNKNOWN;
    }
    return 0;
}

// Find the appropriate command handler and execute it
static error_t run_command(CommandLineArgs *arguments) {
    const Command *cmd = commands;
    while (cmd->name) {
        if (strcmp(arguments->command, cmd->name) == 0) {
            return cmd->handler(arguments);
        }
        cmd++;
    }
    argp_failure(NULL, 1, 0, "Error: Unknown command.");
    return EINVAL; // Should never reach here
}

// Command handlers
static error_t read_handler(CommandLineArgs *arguments) {
    // Implement read command logic here
    printf("Read command executed.\n");
    printf("Option: %s\n", arguments->option);
    printf("Arg1: %s\n", arguments->args[0]);
    printf("Arg2: %s\n", arguments->args[1]);
    return 0;
}

static error_t write_handler(CommandLineArgs *arguments) {
    // Implement write command logic here
    printf("Write command executed.\n");
    printf("Option: %s\n", arguments->option);
    printf("Arg1: %s\n", arguments->args[0]);
    printf("Arg2: %s\n", arguments->args[1]);
    printf("Arg3: %s\n", arguments->args[2]);
    return 0;
}

static error_t show_handler(CommandLineArgs *arguments) {
    // Implement show command logic here
    printf("Show command executed.\n");
    return 0;
}

// Define the argp parser
static struct argp argp_parser = {
    .options = {
        { "command", 'c', "COMMAND", 0, "The command to execute (read, write, show)" },
        { "option", 'o', "OPTION", 0, "Option for the command (e.g., -addr)" },
        { 0 },
    },
    .parser = parse_opt,
    .args_doc = NULL,
    .doc = "A command-line argument parsing example using argp.",
};

int main(int argc, char *argv[]) {
    CommandLineArgs arguments = {0};

    // Parse command-line arguments using argp
    argp_parse(&argp_parser, argc, argv, 0, 0, &arguments);

    // Execute the command
    run_command(&arguments);

    return 0;
}

In this version of the code, we’ve added a Command struct to define each command with its name, description, and a function pointer to its handler. We then created an array commands to store all available commands.

The parse_opt function now handles the command arguments dynamically by storing them in an array args. We’ve also added the run_command function, which looks up the appropriate command handler based on the provided command name and executes it.

By using this approach, you can easily add new commands by defining new command handlers and adding them to the commands array. This increases the extensibility of the command-line parsing tool.

你可能感兴趣的:(命令行解析)