usage.c (2208B)
1 #include "usage.h" 2 3 #include <stdio.h> 4 #include <stdlib.h> 5 6 #include "cofyc/argparse.h" 7 #include "cli/command.h" 8 9 static int opt_version = 0; 10 11 static const char *const usages[] = { 12 "supercop [global options] <command> [command options]", 13 "supercop list-commands", 14 NULL, 15 }; 16 17 static struct argparse_option options[] = { 18 OPT_GROUP("Global options:"), 19 OPT_BOOLEAN('h', "help", NULL, "Show this help message and exit", argparse_help_cb, 0, OPT_NONEG), 20 OPT_BOOLEAN('V', "version", &opt_version, "Show version information and exit", NULL, 0, OPT_NONEG), 21 OPT_END(), 22 }; 23 24 // argparse prints the epilog at the end of its usage output, which is the only 25 // way to get our command listing into the built-in --help handler 26 static char *build_epilog(void) { 27 char *buffer = NULL; 28 size_t size = 0; 29 FILE *out = open_memstream(&buffer, &size); 30 if (!out) { 31 return NULL; 32 } 33 34 struct cmd_struct *cmd = commands; 35 36 // The %-17s aligns our descriptions with the ones argparse prints 37 fprintf(out, "\nCommands:\n"); 38 while (cmd) { 39 fprintf(out, " %-17s %s\n", cmd->display ? cmd->display : cmd->name[0], 40 cmd->description ? cmd->description : ""); 41 cmd = cmd->next; 42 } 43 44 fclose(out); 45 46 // argparse adds a newline of its own 47 if (size && buffer[size - 1] == '\n') { 48 buffer[size - 1] = '\0'; 49 } 50 51 return buffer; 52 } 53 54 int supercop_global_options(int argc, const char **argv, int *show_version) { 55 struct argparse argparse; 56 char *epilog = build_epilog(); 57 58 opt_version = 0; 59 argparse_init(&argparse, options, usages, ARGPARSE_STOP_AT_NON_OPTION); 60 argparse_describe(&argparse, "\nMinimalistic program to generate ed25519 keys and verify/sign messages", epilog); 61 argc = argparse_parse(&argparse, argc, argv); 62 free(epilog); 63 64 if (show_version) { 65 *show_version = opt_version; 66 } 67 68 return argc; 69 } 70 71 void supercop_print_global_usage(void) { 72 struct argparse argparse; 73 char *epilog = build_epilog(); 74 75 argparse_init(&argparse, options, usages, ARGPARSE_STOP_AT_NON_OPTION); 76 argparse_describe(&argparse, "\nMinimalistic program to generate ed25519 keys and verify/sign messages", epilog); 77 argparse_usage(&argparse); 78 free(epilog); 79 }