diff --git a/src/main.c b/src/main.c index a03cfa9..1c802d7 100644 --- a/src/main.c +++ b/src/main.c @@ -20,9 +20,16 @@ int main(int argc, char **argv) { + struct hash_map *vars = vars_init(); + if (vars == NULL) + { + fprintf(stderr, "Error: Failed to initialize variables hash map\n"); + return ERR_MALLOC; + } + // Create the options struct (with argument handler) struct args_options options; - int return_code = args_handler(argc, argv, &options); + int return_code = args_handler(argc, argv, &options, vars); if (return_code != 0) { print_usage(stderr, argv[0]); @@ -31,12 +38,6 @@ int main(int argc, char **argv) // args_print(&options); // Initialize variables hash map - struct hash_map *vars = vars_init(); - if (vars == NULL) - { - fprintf(stderr, "Error: Failed to initialize variables hash map\n"); - return ERR_MALLOC; - } // Create the IO-Backend context struct struct iob_context *io_context = malloc(sizeof(struct iob_context)); diff --git a/src/utils/args/args.c b/src/utils/args/args.c index a2dabd8..e6995fa 100644 --- a/src/utils/args/args.c +++ b/src/utils/args/args.c @@ -4,13 +4,22 @@ #include #include -int args_handler(int argc, char **argv, struct args_options *options) +#include "../string_utils/string_utils.h" +#include "../vars/vars.h" + +int args_handler(int argc, char **argv, struct args_options *options, + struct hash_map *vars) { options->type = INPUT_UNDEFINED; options->input_source = NULL; options->pretty_print = false; options->verbose = false; + int arg_index = 1; + char index_str[11]; + + set_var_copy(vars, "0", argv[0]); + for (int i = 1; i < argc; i++) { if (strcmp(argv[i], "--pretty-print") == 0) @@ -44,18 +53,18 @@ int args_handler(int argc, char **argv, struct args_options *options) fprintf(stderr, "Unknown option: %s\n", argv[i]); return 1; } - else + else if (options->type == INPUT_UNDEFINED) { - if (options->type != INPUT_UNDEFINED) - { - fprintf(stderr, "Multiple input sources specified: %s\n", - argv[i]); - return 1; - } - options->type = INPUT_FILE; options->input_source = argv[i]; } + else + { + // All remaining arguments are treated as additional arguments + int_to_str(arg_index++, index_str); + set_var_copy(vars, index_str, argv[i]); + continue; + } } if (options->type == INPUT_UNDEFINED) diff --git a/src/utils/args/args.h b/src/utils/args/args.h index d19859b..6eac20c 100644 --- a/src/utils/args/args.h +++ b/src/utils/args/args.h @@ -4,6 +4,8 @@ #include #include +#include "../hash_map/hash_map.h" + enum input_type { INPUT_UNDEFINED, @@ -30,9 +32,11 @@ struct args_options * @param argc The argument count. * @param argv The argument vector. * @param options Pointer to args_options structure to be populated. + * @param vars Pointer to the variables hash map. * @return 0 on success, non-zero on failure. */ -int args_handler(int argc, char **argv, struct args_options *options); +int args_handler(int argc, char **argv, struct args_options *options, + struct hash_map *vars); /** Prints the parsed arguments for debugging purposes. * @param options Pointer to args_options structure containing parsed options. diff --git a/tests/unit/utils/args.c b/tests/unit/utils/args.c index 04dfe26..672f6e9 100644 --- a/tests/unit/utils/args.c +++ b/tests/unit/utils/args.c @@ -4,6 +4,9 @@ #include #include +#include "../../../src/utils/hash_map/hash_map.h" +#include "../../../src/utils/vars/vars.h" + TestSuite(utils_args); Test(utils_args, basic_command) @@ -12,13 +15,15 @@ Test(utils_args, basic_command) struct args_options options; char *input[] = { "program", "-c", "echo Hello, World!" }; - int r = args_handler(argc, input, &options); + struct hash_map *vars = vars_init(); + int r = args_handler(argc, input, &options, vars); cr_expect(r == 0); cr_expect(options.pretty_print == false); cr_expect(options.verbose == false); cr_expect(options.type == INPUT_CMD); cr_expect(eq(options.input_source, "echo Hello, World!")); + hash_map_free(&vars); } Test(utils_args, basic_command_with_flags) @@ -28,13 +33,15 @@ Test(utils_args, basic_command_with_flags) char *input[] = { "program", "--pretty-print", "-c", "echo Hello, World!", "--verbose" }; - int r = args_handler(argc, input, &options); + struct hash_map *vars = vars_init(); + int r = args_handler(argc, input, &options, vars); cr_expect(r == 0); cr_expect(options.pretty_print == true); cr_expect(options.verbose == true); cr_expect(options.type == INPUT_CMD); cr_expect(eq(options.input_source, "echo Hello, World!")); + hash_map_free(&vars); } Test(utils_args, basic_file_input) @@ -43,13 +50,15 @@ Test(utils_args, basic_file_input) struct args_options options; char *input[] = { "program", "input.txt" }; - int r = args_handler(argc, input, &options); + struct hash_map *vars = vars_init(); + int r = args_handler(argc, input, &options, vars); cr_expect(r == 0); cr_expect(options.pretty_print == false); cr_expect(options.verbose == false); cr_expect(options.type == INPUT_FILE); cr_expect(eq(options.input_source, "input.txt")); + hash_map_free(&vars); } Test(utils_args, basic_file_input_with_flags) @@ -58,13 +67,15 @@ Test(utils_args, basic_file_input_with_flags) struct args_options options; char *input[] = { "program", "--verbose", "input.txt", "--pretty-print" }; - int r = args_handler(argc, input, &options); + struct hash_map *vars = vars_init(); + int r = args_handler(argc, input, &options, vars); cr_expect(r == 0); cr_expect(options.pretty_print == true); cr_expect(options.verbose == true); cr_expect(options.type == INPUT_FILE); cr_expect(eq(options.input_source, "input.txt")); + hash_map_free(&vars); } Test(utils_args, basic_stdin_input) @@ -73,13 +84,15 @@ Test(utils_args, basic_stdin_input) struct args_options options; char *input[] = { "program" }; - int r = args_handler(argc, input, &options); + struct hash_map *vars = vars_init(); + int r = args_handler(argc, input, &options, vars); cr_expect(r == 0); cr_expect(options.pretty_print == false); cr_expect(options.verbose == false); cr_expect(options.type == INPUT_STDIN); cr_expect(options.input_source == NULL); + hash_map_free(&vars); } Test(utils_args, pretty_print_and_verbose_flags) @@ -88,13 +101,15 @@ Test(utils_args, pretty_print_and_verbose_flags) struct args_options options; char *input[] = { "program", "--pretty-print", "--verbose" }; - int r = args_handler(argc, input, &options); + struct hash_map *vars = vars_init(); + int r = args_handler(argc, input, &options, vars); cr_expect(r == 0); cr_expect(options.pretty_print == true); cr_expect(options.verbose == true); cr_expect(options.type == INPUT_STDIN); cr_expect(options.input_source == NULL); + hash_map_free(&vars); } Test(utils_args, missing_command_after_c, .init = cr_redirect_stderr) @@ -103,10 +118,12 @@ Test(utils_args, missing_command_after_c, .init = cr_redirect_stderr) struct args_options options; char *input[] = { "program", "-c" }; - int r = args_handler(argc, input, &options); + struct hash_map *vars = vars_init(); + int r = args_handler(argc, input, &options, vars); cr_expect(r != 0); cr_assert_stderr_eq_str("No command provided after -c\n"); + hash_map_free(&vars); } Test(utils_args, unknown_option, .init = cr_redirect_stderr) @@ -115,20 +132,42 @@ Test(utils_args, unknown_option, .init = cr_redirect_stderr) struct args_options options; char *input[] = { "program", "--unknown" }; - int r = args_handler(argc, input, &options); + struct hash_map *vars = vars_init(); + int r = args_handler(argc, input, &options, vars); cr_expect(r != 0); cr_assert_stderr_eq_str("Unknown option: --unknown\n"); + hash_map_free(&vars); } -Test(utils_args, conflicting_input_types, .init = cr_redirect_stderr) +Test(utils_args, multiple_command, .init = cr_redirect_stderr) { int argc = 4; struct args_options options; - char *input[] = { "program", "-c", "echo Hello", "input.txt" }; + char *input[] = { "program", "exec.sh", "-c", "echo World" }; - int r = args_handler(argc, input, &options); + struct hash_map *vars = vars_init(); + int r = args_handler(argc, input, &options, vars); cr_expect(r != 0); - cr_assert_stderr_eq_str("Multiple input sources specified: input.txt\n"); + cr_assert_stderr_eq_str("Multiple input sources specified: echo World\n"); + hash_map_free(&vars); +} + +Test(utils_args, command_with_additional_arguments) +{ + int argc = 5; + struct args_options options; + char *input[] = { "program", "-c", "echo Hello", "arg1", "arg2" }; + + struct hash_map *vars = vars_init(); + int r = args_handler(argc, input, &options, vars); + + cr_expect(r == 0); + cr_expect(options.type == INPUT_CMD); + cr_expect(eq(options.input_source, "echo Hello")); + cr_expect_str_eq(get_var(vars, "0"), "program"); + cr_expect_str_eq(get_var(vars, "1"), "arg1"); + cr_expect_str_eq(get_var(vars, "2"), "arg2"); + hash_map_free(&vars); }