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