feat(args): $0, $1, ... in vars
This commit is contained in:
parent
82f35cfa08
commit
7bcf48f63e
4 changed files with 82 additions and 29 deletions
15
src/main.c
15
src/main.c
|
|
@ -20,9 +20,16 @@
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
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)
|
// Create the options struct (with argument handler)
|
||||||
struct args_options options;
|
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)
|
if (return_code != 0)
|
||||||
{
|
{
|
||||||
print_usage(stderr, argv[0]);
|
print_usage(stderr, argv[0]);
|
||||||
|
|
@ -31,12 +38,6 @@ int main(int argc, char **argv)
|
||||||
// args_print(&options);
|
// args_print(&options);
|
||||||
|
|
||||||
// Initialize variables hash map
|
// 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
|
// Create the IO-Backend context struct
|
||||||
struct iob_context *io_context = malloc(sizeof(struct iob_context));
|
struct iob_context *io_context = malloc(sizeof(struct iob_context));
|
||||||
|
|
|
||||||
|
|
@ -4,13 +4,22 @@
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
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->type = INPUT_UNDEFINED;
|
||||||
options->input_source = NULL;
|
options->input_source = NULL;
|
||||||
options->pretty_print = false;
|
options->pretty_print = false;
|
||||||
options->verbose = 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++)
|
for (int i = 1; i < argc; i++)
|
||||||
{
|
{
|
||||||
if (strcmp(argv[i], "--pretty-print") == 0)
|
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]);
|
fprintf(stderr, "Unknown option: %s\n", argv[i]);
|
||||||
return 1;
|
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->type = INPUT_FILE;
|
||||||
options->input_source = argv[i];
|
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)
|
if (options->type == INPUT_UNDEFINED)
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,8 @@
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include "../hash_map/hash_map.h"
|
||||||
|
|
||||||
enum input_type
|
enum input_type
|
||||||
{
|
{
|
||||||
INPUT_UNDEFINED,
|
INPUT_UNDEFINED,
|
||||||
|
|
@ -30,9 +32,11 @@ struct args_options
|
||||||
* @param argc The argument count.
|
* @param argc The argument count.
|
||||||
* @param argv The argument vector.
|
* @param argv The argument vector.
|
||||||
* @param options Pointer to args_options structure to be populated.
|
* @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.
|
* @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.
|
/** Prints the parsed arguments for debugging purposes.
|
||||||
* @param options Pointer to args_options structure containing parsed options.
|
* @param options Pointer to args_options structure containing parsed options.
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,9 @@
|
||||||
#include <criterion/new/assert.h>
|
#include <criterion/new/assert.h>
|
||||||
#include <criterion/redirect.h>
|
#include <criterion/redirect.h>
|
||||||
|
|
||||||
|
#include "../../../src/utils/hash_map/hash_map.h"
|
||||||
|
#include "../../../src/utils/vars/vars.h"
|
||||||
|
|
||||||
TestSuite(utils_args);
|
TestSuite(utils_args);
|
||||||
|
|
||||||
Test(utils_args, basic_command)
|
Test(utils_args, basic_command)
|
||||||
|
|
@ -12,13 +15,15 @@ Test(utils_args, basic_command)
|
||||||
struct args_options options;
|
struct args_options options;
|
||||||
char *input[] = { "program", "-c", "echo Hello, World!" };
|
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(r == 0);
|
||||||
cr_expect(options.pretty_print == false);
|
cr_expect(options.pretty_print == false);
|
||||||
cr_expect(options.verbose == false);
|
cr_expect(options.verbose == false);
|
||||||
cr_expect(options.type == INPUT_CMD);
|
cr_expect(options.type == INPUT_CMD);
|
||||||
cr_expect(eq(options.input_source, "echo Hello, World!"));
|
cr_expect(eq(options.input_source, "echo Hello, World!"));
|
||||||
|
hash_map_free(&vars);
|
||||||
}
|
}
|
||||||
|
|
||||||
Test(utils_args, basic_command_with_flags)
|
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!",
|
char *input[] = { "program", "--pretty-print", "-c", "echo Hello, World!",
|
||||||
"--verbose" };
|
"--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(r == 0);
|
||||||
cr_expect(options.pretty_print == true);
|
cr_expect(options.pretty_print == true);
|
||||||
cr_expect(options.verbose == true);
|
cr_expect(options.verbose == true);
|
||||||
cr_expect(options.type == INPUT_CMD);
|
cr_expect(options.type == INPUT_CMD);
|
||||||
cr_expect(eq(options.input_source, "echo Hello, World!"));
|
cr_expect(eq(options.input_source, "echo Hello, World!"));
|
||||||
|
hash_map_free(&vars);
|
||||||
}
|
}
|
||||||
|
|
||||||
Test(utils_args, basic_file_input)
|
Test(utils_args, basic_file_input)
|
||||||
|
|
@ -43,13 +50,15 @@ Test(utils_args, basic_file_input)
|
||||||
struct args_options options;
|
struct args_options options;
|
||||||
char *input[] = { "program", "input.txt" };
|
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(r == 0);
|
||||||
cr_expect(options.pretty_print == false);
|
cr_expect(options.pretty_print == false);
|
||||||
cr_expect(options.verbose == false);
|
cr_expect(options.verbose == false);
|
||||||
cr_expect(options.type == INPUT_FILE);
|
cr_expect(options.type == INPUT_FILE);
|
||||||
cr_expect(eq(options.input_source, "input.txt"));
|
cr_expect(eq(options.input_source, "input.txt"));
|
||||||
|
hash_map_free(&vars);
|
||||||
}
|
}
|
||||||
|
|
||||||
Test(utils_args, basic_file_input_with_flags)
|
Test(utils_args, basic_file_input_with_flags)
|
||||||
|
|
@ -58,13 +67,15 @@ Test(utils_args, basic_file_input_with_flags)
|
||||||
struct args_options options;
|
struct args_options options;
|
||||||
char *input[] = { "program", "--verbose", "input.txt", "--pretty-print" };
|
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(r == 0);
|
||||||
cr_expect(options.pretty_print == true);
|
cr_expect(options.pretty_print == true);
|
||||||
cr_expect(options.verbose == true);
|
cr_expect(options.verbose == true);
|
||||||
cr_expect(options.type == INPUT_FILE);
|
cr_expect(options.type == INPUT_FILE);
|
||||||
cr_expect(eq(options.input_source, "input.txt"));
|
cr_expect(eq(options.input_source, "input.txt"));
|
||||||
|
hash_map_free(&vars);
|
||||||
}
|
}
|
||||||
|
|
||||||
Test(utils_args, basic_stdin_input)
|
Test(utils_args, basic_stdin_input)
|
||||||
|
|
@ -73,13 +84,15 @@ Test(utils_args, basic_stdin_input)
|
||||||
struct args_options options;
|
struct args_options options;
|
||||||
char *input[] = { "program" };
|
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(r == 0);
|
||||||
cr_expect(options.pretty_print == false);
|
cr_expect(options.pretty_print == false);
|
||||||
cr_expect(options.verbose == false);
|
cr_expect(options.verbose == false);
|
||||||
cr_expect(options.type == INPUT_STDIN);
|
cr_expect(options.type == INPUT_STDIN);
|
||||||
cr_expect(options.input_source == NULL);
|
cr_expect(options.input_source == NULL);
|
||||||
|
hash_map_free(&vars);
|
||||||
}
|
}
|
||||||
|
|
||||||
Test(utils_args, pretty_print_and_verbose_flags)
|
Test(utils_args, pretty_print_and_verbose_flags)
|
||||||
|
|
@ -88,13 +101,15 @@ Test(utils_args, pretty_print_and_verbose_flags)
|
||||||
struct args_options options;
|
struct args_options options;
|
||||||
char *input[] = { "program", "--pretty-print", "--verbose" };
|
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(r == 0);
|
||||||
cr_expect(options.pretty_print == true);
|
cr_expect(options.pretty_print == true);
|
||||||
cr_expect(options.verbose == true);
|
cr_expect(options.verbose == true);
|
||||||
cr_expect(options.type == INPUT_STDIN);
|
cr_expect(options.type == INPUT_STDIN);
|
||||||
cr_expect(options.input_source == NULL);
|
cr_expect(options.input_source == NULL);
|
||||||
|
hash_map_free(&vars);
|
||||||
}
|
}
|
||||||
|
|
||||||
Test(utils_args, missing_command_after_c, .init = cr_redirect_stderr)
|
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;
|
struct args_options options;
|
||||||
char *input[] = { "program", "-c" };
|
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_expect(r != 0);
|
||||||
cr_assert_stderr_eq_str("No command provided after -c\n");
|
cr_assert_stderr_eq_str("No command provided after -c\n");
|
||||||
|
hash_map_free(&vars);
|
||||||
}
|
}
|
||||||
|
|
||||||
Test(utils_args, unknown_option, .init = cr_redirect_stderr)
|
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;
|
struct args_options options;
|
||||||
char *input[] = { "program", "--unknown" };
|
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_expect(r != 0);
|
||||||
cr_assert_stderr_eq_str("Unknown option: --unknown\n");
|
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;
|
int argc = 4;
|
||||||
struct args_options options;
|
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_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);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue