lib

morphux C utility library
Log | Files | Refs | Submodules | README | LICENSE | git clone https://git.ne02ptzero.me/git/lib

commit ebef6979c0d338b7afa0124ff6029eb227dee005
parent 110220ffcba120cceed09bed8d80a966fb3228ca
Author: Ne02ptzero <louis@ne02ptzero.me>
Date:   Sat, 21 Jan 2017 16:39:52 +0100

Add(More margs tests)

Diffstat:
Minc/m_args.h | 4++--
Msrc/m_args.c | 28+++++++++++++++-------------
Mtests/Makefile | 2+-
Mtests/test.h | 27+++++++++++++++++++++++++++
Mtests/test_args.c | 211+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----
5 files changed, 247 insertions(+), 25 deletions(-)

diff --git a/inc/m_args.h b/inc/m_args.h @@ -56,7 +56,7 @@ typedef struct s_args { u32_t read_opt(const int ac, char **av, const margs_t *args); -void opt_help(const margs_t *args); -void p_version(void); +void opt_help(const margs_t *args, u8_t ret); +void p_version(u8_t ret); #endif /* M_ARGS_H */ diff --git a/src/m_args.c b/src/m_args.c @@ -64,9 +64,9 @@ u32_t read_opt(const int ac, char **av, const margs_t *args) { /* Builtins options */ if (av[i][1] == 'h') - opt_help(args); + opt_help(args, 0); else if (av[i][1] == 'v') - p_version(); + p_version(0); /* Search the option in the args array */ for (u32_t z = 1; av[i][z] != '\0'; z++) { @@ -76,7 +76,7 @@ u32_t read_opt(const int ac, char **av, const margs_t *args) { /* Can't find the option */ if (args[it].opt == 0) { m_error("Unknow option -%s\n", &(av[i][z])); - opt_help(args); + opt_help(args, 1); } else { if (args[it].take_arg) { if (i + 1 < (u32_t)ac) { @@ -85,7 +85,7 @@ u32_t read_opt(const int ac, char **av, const margs_t *args) { } else { m_error("Option -%c must take an argument\n", args[it].opt); - opt_help(args); + opt_help(args, 1); } } else { args[it].callback(NULL); @@ -105,9 +105,9 @@ u32_t read_opt(const int ac, char **av, const margs_t *args) { /* Builtins options */ if (strcmp(&(av[i][2]), "help") == 0) - opt_help(args); + opt_help(args, 0); else if (strcmp(&(av[i][2]), "version") == 0) - p_version(); + p_version(0); /* Look for an argument */ for (k = 2; av[i][k] != '\0' && av[i][k] != '='; k++) @@ -128,11 +128,11 @@ u32_t read_opt(const int ac, char **av, const margs_t *args) { /* Can't find the option */ if (args[it].opt == 0) { m_error("Unknown option %s\n", av[i]); - opt_help(args); + opt_help(args, 1); } else { if (args[it].take_arg && !got_arg) { m_error("Option %s must take an argument", args[it].s_opt); - opt_help(args); + opt_help(args, 1); } if (got_arg) @@ -147,10 +147,11 @@ u32_t read_opt(const int ac, char **av, const margs_t *args) { } /*! - * \brief Print helps with a list of argument + * \brief Print helps with a list of argument, and exit * \param args List of arguments to print + * \param ret Return code of the exit */ -void opt_help(const margs_t *args) { +void opt_help(const margs_t *args, u8_t ret) { m_info("Help:\n"); for (u32_t i = 0; args[i].opt != 0; i++) { m_info("\t-%c | --%s : %s\n", args[i].opt, args[i].s_opt, args[i].desc); @@ -159,15 +160,16 @@ void opt_help(const margs_t *args) { m_info("If an argument requires a value, you can set it two ways:\n"); m_info("\t-o value\n"); m_info("\t--option=value\n"); - _exit(1); + _exit(ret); } /*! * \brief Print the program name, the version and the maintainer, then exit + * \param ret Return code of the exit */ -void p_version(void) { +void p_version(u8_t ret) { m_info("Program: %s\n", get_program_name()); m_info("Version: %s\n", get_version()); m_info("%s\n", get_maintainer()); - _exit(1); + _exit(ret); } diff --git a/tests/Makefile b/tests/Makefile @@ -1,6 +1,6 @@ NAME = test CC = gcc -CFLAGS = -Wall -Wextra -g -O3 -I../inc -lmorphux +CFLAGS = -Wall -Wextra -Wno-unused-result -g -O3 -I../inc -lmorphux SRCS = $(wildcard *.c) OBJS = $(SRCS:%.c=%.o) diff --git a/tests/test.h b/tests/test.h @@ -6,8 +6,29 @@ # include <sys/types.h> # include <sys/wait.h> +# define DUP_ALL_OUTPUTS(name) dup2(name[1], 1); dup2(name[1], 2); close(name[1]); +# define WAIT_AND_CLOSE(pid, status, fd) pid = waitpid(pid, &status, 0); close(fd[1]); +# define OPT_STR_SIZE 150 +# define OPT_DEF(val) { \ + {'q', "--qwerty", "qwerty", val, &callback_q}, \ + {'w', "--wertyu", "wertyu", val, &callback_w}, \ + {'e', "--ertyui", "rtyuio", val, &callback_e}, \ + {'r', "--rtyuio", "tyuiop", val, &callback_r}, \ + {'t', "--tyuiop", "tyuiop", val, &callback_t}, \ + {'y', "--yuiop[", "yuiop[", val, &callback_y}, \ + ARGS_EOL \ +} + void register_infos_tests(void); void register_args_tests(void); +void callback_q(const char *s); +void callback_w(const char *s); +void callback_e(const char *s); +void callback_r(const char *s); +void callback_t(const char *s); +void callback_y(const char *s); +void reset_args(void); + struct margs_tests { bool opt_q; @@ -16,6 +37,12 @@ struct margs_tests { bool opt_r; bool opt_t; bool opt_y; + char str_q[OPT_STR_SIZE]; + char str_w[OPT_STR_SIZE]; + char str_e[OPT_STR_SIZE]; + char str_r[OPT_STR_SIZE]; + char str_t[OPT_STR_SIZE]; + char str_y[OPT_STR_SIZE]; }; #endif /* TEST_H */ diff --git a/tests/test_args.c b/tests/test_args.c @@ -57,9 +57,8 @@ TEST(args_empty_2) { TEST(args_unhandled_1) { - fflush(stdout); margs_t opt[] = { - {'z', "--zoiberg", "No idea.", false, NULL}, + {'z', "zoiberg", "No idea.", false, NULL}, ARGS_EOL }; char *av[] = {"./tests", "oui", "--allow"}; @@ -67,22 +66,203 @@ TEST(args_unhandled_1) { int st, fd[2]; pipe(fd); - + fflush(stdout); if ((pid = fork()) == 0) { - dup2(fd[1], 1); - dup2(fd[1], 2); - close(fd[1]); - + DUP_ALL_OUTPUTS(fd); TEST_ASSERT(read_opt(sizeof(av), av, opt) == 0, "Not handling properly unknown arguments"); } else { - pid = waitpid(pid, &st, 0); - close(fd[1]); + WAIT_AND_CLOSE(pid, st, fd); TEST_ASSERT((WEXITSTATUS(st) == 1), "Wrong return"); } return TEST_SUCCESS; } +TEST(args_unhandled_2) { + margs_t opt[] = { + {'z', "zoiberg", "No idea.", false, NULL}, + ARGS_EOL + }; + char *av[] = {"./test", "---wrong-option"}; + int st, fd[2]; + pid_t pid; + + pipe(fd); + if ((pid = fork()) == 0) { + DUP_ALL_OUTPUTS(fd); + TEST_ASSERT(read_opt(sizeof(av), av, opt) == 0, "Not handling triple '-' arguments"); + _exit(0); + } else { + WAIT_AND_CLOSE(pid, st, fd); + TEST_ASSERT((WEXITSTATUS(st) == 0), "Wrong return"); + } + return TEST_SUCCESS; +} + +TEST(args_unhandled_3) { + margs_t opt[] = { + {'z', "zoiberg", "No idea.", false, NULL}, + ARGS_EOL + }; + char *av[] = {"./test", "-", "<-", "Single dash"}; + int st, fd[2]; + pid_t pid; + + pipe(fd); + if ((pid = fork()) == 0) { + DUP_ALL_OUTPUTS(fd); + TEST_ASSERT(read_opt(sizeof(av), av, opt) == 0, "Not handling alone '-' in arguments"); + _exit(0); + } else { + WAIT_AND_CLOSE(pid, st, fd); + TEST_ASSERT((WEXITSTATUS(st) == 0), "Wrong return"); + } + return TEST_SUCCESS; +} + +TEST(args_help_1) { + margs_t opt[] = { + {'z', "zoiberg", "No idea.", false, NULL}, + ARGS_EOL + }; + char *av[] = {"./test", "-h"}; + int st, fd[2]; + pid_t pid; + + pipe(fd); + if ((pid = fork()) == 0) { + DUP_ALL_OUTPUTS(fd); + TEST_ASSERT(read_opt(sizeof(av), av, opt) == 0, "Not handling -h arguments"); + _exit(5); + } else { + WAIT_AND_CLOSE(pid, st, fd); + TEST_ASSERT((WEXITSTATUS(st) == 0), "Wrong return"); + } + return TEST_SUCCESS; +} + +TEST(args_help_2) { + margs_t opt[] = { + {'z', "zoiberg", "No idea.", false, NULL}, + ARGS_EOL + }; + char *av[] = {"./test", "--help"}; + int st, fd[2]; + pid_t pid; + + pipe(fd); + if ((pid = fork()) == 0) { + DUP_ALL_OUTPUTS(fd); + TEST_ASSERT(read_opt(sizeof(av), av, opt) == 0, "Not handling --help arguments"); + _exit(5); + } else { + WAIT_AND_CLOSE(pid, st, fd); + TEST_ASSERT((WEXITSTATUS(st) == 0), "Wrong return"); + } + return TEST_SUCCESS; +} + +TEST(args_version_1) { + margs_t opt[] = { + {'z', "zoiberg", "No idea.", false, NULL}, + ARGS_EOL + }; + char *av[] = {"./test", "-v"}; + int st, fd[2]; + pid_t pid; + + pipe(fd); + if ((pid = fork()) == 0) { + DUP_ALL_OUTPUTS(fd); + TEST_ASSERT(read_opt(sizeof(av), av, opt) == 0, "Not handling --version arguments"); + _exit(5); + } else { + WAIT_AND_CLOSE(pid, st, fd); + TEST_ASSERT((WEXITSTATUS(st) == 0), "Wrong return"); + } + return TEST_SUCCESS; +} + +TEST(args_version_2) { + margs_t opt[] = { + {'z', "zoiberg", "No idea.", false, NULL}, + ARGS_EOL + }; + char *av[] = {"./test", "--version"}; + int st, fd[2]; + pid_t pid; + + pipe(fd); + if ((pid = fork()) == 0) { + DUP_ALL_OUTPUTS(fd); + TEST_ASSERT(read_opt(sizeof(av), av, opt) == 0, "Not handling -v arguments"); + _exit(5); + } else { + WAIT_AND_CLOSE(pid, st, fd); + TEST_ASSERT((WEXITSTATUS(st) == 0), "Wrong return"); + } + return TEST_SUCCESS; +} + +TEST(args_base_1) { + margs_t opt[] = OPT_DEF(false); + char *av[] = {"./test", "-q"}; + + reset_args(); + TEST_ASSERT((read_opt(sizeof(av) / sizeof(av[0]), av, opt) == 1), "Wrong return"); + TEST_ASSERT(args.opt_q == true, "Argument not read"); + TEST_ASSERT(args.opt_w != true, "Argument not read"); + return TEST_SUCCESS; +} + + +void callback_q(const char *s) { + args.opt_q = true; + if (s == NULL) + strcpy(args.str_q, ""); + else + strcpy(args.str_q, s); +} + +void callback_w(const char *s) { + args.opt_w = true; + if (s == NULL) + strcpy(args.str_w, ""); + else + strcpy(args.str_w, s); +} + +void callback_e(const char *s) { + args.opt_e = true; + if (s == NULL) + strcpy(args.str_e, ""); + else + strcpy(args.str_e, s); +} + +void callback_r(const char *s) { + args.opt_r = true; + if (s == NULL) + strcpy(args.str_r, ""); + else + strcpy(args.str_r, s); +} + +void callback_t(const char *s) { + args.opt_t = true; + if (s == NULL) + strcpy(args.str_t, ""); + else + strcpy(args.str_t, s); +} + +void callback_y(const char *s) { + args.opt_y = true; + if (s == NULL) + strcpy(args.str_y, ""); + else + strcpy(args.str_y, s); +} void reset_args(void) { args.opt_q = false; @@ -91,6 +271,12 @@ void reset_args(void) { args.opt_r = false; args.opt_t = false; args.opt_y = false; + strcpy(args.str_q, ""); + strcpy(args.str_w, ""); + strcpy(args.str_e, ""); + strcpy(args.str_r, ""); + strcpy(args.str_t, ""); + strcpy(args.str_y, ""); } void register_args_tests(void) { @@ -103,4 +289,11 @@ void register_args_tests(void) { reg_test("m_args", args_empty_1); reg_test("m_args", args_empty_2); reg_test("m_args", args_unhandled_1); + reg_test("m_args", args_unhandled_2); + reg_test("m_args", args_unhandled_3); + reg_test("m_args", args_help_1); + reg_test("m_args", args_help_2); + reg_test("m_args", args_version_2); + reg_test("m_args", args_version_2); + reg_test("m_args", args_base_1); }