Skip to content

Commit

Permalink
add some more examples to cli also some correction on cli functions
Browse files Browse the repository at this point in the history
  • Loading branch information
KaisenAmin committed Feb 5, 2024
1 parent 9670d0c commit 8afe9c2
Show file tree
Hide file tree
Showing 4 changed files with 431 additions and 171 deletions.
349 changes: 347 additions & 2 deletions cli/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -565,11 +565,356 @@ int main(int argc, char *argv[]) {
else {
fmt_printf("Unknown command or option. Use '--help' for usage information.\n");
}
} else {
}
else {
fmt_printf("No command provided. Use '--help' for usage information.\n");
}

cli_parser_deallocate(parser);
return 0;
}
```
```
## Example 12 : register gree with cli parser
**python compile.py r --version**
**python compile.py r greet amin**
```c
#include "cli/cli.h"
#include "fmt/fmt.h"
// Command Handlers
void greetCommandHandler(const CliCommand *command, int argc, char *argv[], void *userData) {
(void)userData;
(void)command;
fmt_printf("Hello, %s!\n", argc > 1 ? argv[1] : "World");
}
void versionCommandHandler(const CliCommand *command, int argc, char *argv[], void *userData) {
(void)userData;
(void)command;
(void)argc;
(void)argv;
fmt_printf("Version 1.0.0\n");
}
int main(int argc, char *argv[]) {
CliParser *parser = cli_parser_create("ExampleApp");
if (!parser) {
fmt_fprintf(stderr, "Failed to create CLI parser\n");
return 1;
}
CliCommand greetCommand = {
.name = "greet",
.handler = greetCommandHandler,
.description = "Greets a user",
.userData = NULL
};
CliCommand versionCommand = {
.name = "--version",
.handler = versionCommandHandler,
.description = "Shows version",
.userData = NULL
};
if (!cli_register_command(parser, &greetCommand)) {
fmt_fprintf(stderr, "Failed to register 'greet' command\n");
}
if (!cli_register_command(parser, &versionCommand)) {
fmt_fprintf(stderr, "Failed to register '--version' command\n");
}
cli_parse_args(parser, argc, argv);
cli_parser_deallocate(parser);
return 0;
}
```

## Example 13 : interactive mode

**python compile.py r calculate 10 20**
**python compile.py r --interactive**

```c
#include "cli/cli.h"
#include "fmt/fmt.h"
#include <stdlib.h>

// Command Handler
void calculateCommandHandler(const CliCommand *command, int argc, char *argv[], void *userData) {
(void)userData;
(void)command;
if (argc != 3) {
fmt_printf("Usage: calculate <number1> <number2>\n");
return;
}

int num1 = atoi(argv[1]);
int num2 = atoi(argv[2]);
fmt_printf("Sum: %d\n", num1 + num2);
}

// Option Handler for --interactive mode
void interactiveOptionHandler(const CliOption *option, const char *value, void *userData) {
(void)option;
(void)value;
CliParser *parser = (CliParser *)userData;

fmt_printf("Entering interactive mode. Type 'exit' to quit.\n");
cli_enter_interactive_mode(parser, "> ");
}

int main(int argc, char *argv[]) {
CliParser *parser = cli_parser_create("InteractiveApp");
if (!parser) {
fmt_fprintf(stderr, "Failed to create CLI parser\n");
return 1;
}

CliCommand calculateCommand = {
.name = "calculate",
.handler = calculateCommandHandler,
.description = "Performs a simple addition",
.userData = NULL
};

CliOption interactiveOption = {
.longOpt = "--interactive",
.optionType = CLI_NO_ARG,
.handler = interactiveOptionHandler,
.description = "Enters interactive mode",
.userData = (void *)parser
};

if (!cli_register_command(parser, &calculateCommand)) {
fmt_fprintf(stderr, "Failed to register 'calculate' command\n");
}

if (!cli_register_option(parser, &interactiveOption)) {
fmt_fprintf(stderr, "Failed to register '--interactive' option\n");
}

cli_parse_args(parser, argc, argv);

cli_parser_deallocate(parser);
return 0;
}
```
## Example 14 : Using Option Groups and Pipelining
**This example demonstrates how to use option groups and enable pipelining for advanced command-line parsing scenarios**
`this will enable verbose mode in your program`
**python compile.py r --versbose**
`this will proccess command data`
**python compile.py r process one two**
```c
#include "cli/cli.h"
#include "fmt/fmt.h"
#include <stdlib.h>
// Option handler for setting verbose mode
void verboseOptionHandler(const CliOption *option, const char *value, void *userData) {
(void)option;
(void)value;
bool *verboseMode = (bool *)userData;
*verboseMode = true;
fmt_printf("Verbose mode enabled\n");
}
// Command handler for a 'process' command
void processCommandHandler(const CliCommand *command, int argc, char *argv[], void *userData) {
(void)command;
(void)userData;
fmt_printf("Processing with %d arguments\n", argc);
for (int i = 0; i < argc; ++i) {
fmt_printf("Arg %d: %s\n", i + 1, argv[i]);
}
}
int main(int argc, char *argv[]) {
bool verboseMode = false;
CliParser *parser = cli_parser_create("PipelineApp");
CliOption verboseOption = {
.longOpt = "--verbose",
.shortOpt = 'v',
.optionType = CLI_NO_ARG,
.handler = verboseOptionHandler,
.description = "Enable verbose output",
.userData = &verboseMode
};
CliCommand processCommand = {
.name = "process",
.handler = processCommandHandler,
.description = "Process data",
.userData = NULL
};
cli_register_option(parser, &verboseOption);
cli_register_command(parser, &processCommand);
// Enable pipelining to allow command outputs to be used as inputs for other commands
cli_enable_pipelining(parser, true);
cli_parse_args(parser, argc, argv);
cli_parser_deallocate(parser);
return 0;
}
```

## Example 15: Interactive Mode and Command Aliases

`entering an interactive mode and using command aliases to provide alternative names for commands`
**python compile.py r**
```c
#include "cli/cli.h"
#include "fmt/fmt.h"
#include <stdlib.h>

// Command handler for exiting the application
void exitCommandHandler(const CliCommand *command, int argc, char *argv[], void *userData) {
(void)command;
(void)argc;
(void)argv;
(void)userData;
fmt_printf("Exiting application.\n");
exit(0);
}

// Interactive mode prompt
void enterInteractiveMode(CliParser *parser) {
fmt_printf("Interactive mode. Type 'exit' or 'quit' to exit.\n");
cli_enter_interactive_mode(parser, ">");
}

int main() {
CliParser *parser = cli_parser_create("InteractiveCLI");

CliCommand exitCommand = {
.name = "exit",
.handler = exitCommandHandler,
.description = "Exit the application",
.userData = NULL
};

cli_register_command(parser, &exitCommand);

// Register an alias for the 'exit' command
cli_register_command_alias(parser, "exit", "quit");

// Enter interactive mode immediately for demonstration purposes
enterInteractiveMode(parser);

cli_parser_deallocate(parser);
return 0;
}
```
## Example 16 : running server with different mode
`start server with port`
**python .\compile.py r start --port 8080**
`enabling verbose mode`
**python .\compile.py r start -v**
**python .\compile.py r start --port 8080 --verbose**
`Specifiyin a log file`
**python .\compile.py r start --port 8080 --log-file "server.log"**
`Combining Multiple Options`
**python .\compile.py r start --verbose --port 8080 --log-file "server.log"**
```c
#include "cli/cli.h"
#include "fmt/fmt.h"
#include <stdlib.h>
#include <string.h>
int globalPort = 0; // Global variable to store the port
bool verboseMode = false; // Global variable to store the verbose flag
// Custom validator for the port option
bool validatePort(const char *value, void *userData) {
(void)userData;
long port = strtol(value, NULL, 10);
if (port <= 0 || port > 65535) {
fmt_printf("Port must be between 1 and 65535\n");
return false;
}
return true;
}
// Handler for the --port option
void portOptionHandler(const CliOption *option, const char *value, void *userData) {
(void)userData;
(void)option;
long port = strtol(value, NULL, 10);
globalPort = (int)port;
fmt_printf("Port set to %d\n", globalPort);
}
// Handler for the --verbose option
void verboseOptionHandler(const CliOption *option, const char *value, void *userData) {
(void)userData;
(void)option;
(void)value;
verboseMode = true;
fmt_printf("Verbose mode enabled\n");
}
// Handler for the --log-file option
void logFileOptionHandler(const CliOption *option, const char *value, void *userData) {
(void)userData;
(void)option;
if (value == NULL || strlen(value) == 0) {
fmt_printf("Log file name must be provided\n");
exit(EXIT_FAILURE);
}
fmt_printf("Logging to file: %s\n", value);
}
// Handler for the server start command
void startServerCommandHandler(const CliCommand *command, int argc, char *argv[], void *userData) {
(void)command;
(void)userData;
(void)argc;
(void)argv;
fmt_printf("Server started on port %d...\n", globalPort);
if (verboseMode) {
fmt_printf("Verbose mode is ON\n");
}
}
int main(int argc, char *argv[]) {
CliParser *parser = cli_parser_create("ServerApp");
// Register the start server command
CliCommand startServerCommand = {
.name = "start",
.handler = startServerCommandHandler,
.description = "Starts the server",
};
CliOption serverOptions[] = {
{.longOpt = "--port", .shortOpt = 'p', .optionType = CLI_REQUIRED_ARG, .handler = portOptionHandler, .validator = validatePort, .description = "Set server port"},
{.longOpt = "--verbose", .shortOpt = 'v', .optionType = CLI_NO_ARG, .handler = verboseOptionHandler, .description = "Enable verbose output"},
{.longOpt = "--log-file", .shortOpt = 'l', .optionType = CLI_REQUIRED_ARG, .handler = logFileOptionHandler, .description = "Specify log file"},
};
cli_register_command(parser, &startServerCommand);
cli_add_option_group(parser, "Server Options", serverOptions, sizeof(serverOptions) / sizeof(CliOption));
cli_parse_args(parser, argc, argv);
cli_parser_deallocate(parser);
return 0;
}
```
Loading

0 comments on commit 8afe9c2

Please sign in to comment.