#pragma once #include struct options { char *name; char opt; char *doc; uint8_t arg_nb; uint8_t grp; }; typedef enum { USAGE, HELP, VERSION, VERBOSE, COUNT, SIZE, TIMEOUT, LINGER, INTERVAL } options_nb_t; static struct options options[] = { #define GRP 0 // AKA random useless sh*t {"usage", 'u', "give a short usage message", 0, GRP}, {"help", '?', "give this help list", 0, GRP}, {"version", 'V', "print program version", 0, GRP}, #undef GRP #define GRP 1 // AKA mandatory {"verbose", 'v', "verbose output", 0, GRP}, #undef GRP #define GRP 2 // AKA bonus {"count", 'c', "stop after sending NUMBER packets", 1, GRP}, {"size", 's', "send NUMBER data octets", 1, GRP}, {"timeout", 'w', "stop after N seconds", 1, GRP}, {"linger", 'W', "number of seconds to wait for response", 1, GRP}, {"interval", 'i', "wait NUMBER seconds between sending each packet", 1, GRP} #undef GRP }; #define OPT_NB 10 #define FT_PING_V "0.1" #define OPT_WHILE \ int i = 0; \ while (i < OPT_NB) #define OPT_HANDLE(i) \ if (options[i].arg_nb == 1) { \ if (!(av + 1) || !*(av + 1)) { \ print_parse_err(NEED_ARG, (*av) + 1); \ return EX_USAGE; \ } \ int n = atoi(*(av + 1)); \ if (n == 0) { \ print_parse_err(ERR_ARG, (*av) + 1); \ return EX_USAGE; \ } \ args->arg[i] = n; \ } \ args->opts[i] = true; \ return EXIT_SUCCESS; typedef enum { MISSING_HOST, INVALID_OPT, NEED_ARG, ERR_ARG } error_t; /** * @brief Can be used to print error message when needed * @param err The type of error to print * @param opt The option that cause an error (if applicable) */ void print_parse_err(error_t err, char *opt); /** * @brief Can be used to print the help message */ void print_help(void); /** * @brief Can be used to print the usage help message */ void print_usage(void); /** * @brief Can be used to print the version message */ void print_version(void);