42sh/src/utils/args/args.c

156 lines
4.2 KiB
C
Raw Normal View History

2026-01-24 16:02:37 +00:00
#define _POSIX_C_SOURCE 200809L
2026-01-12 18:42:02 +00:00
#include "./args.h"
#include <stdbool.h>
#include <stdio.h>
2026-01-24 16:02:37 +00:00
#include <stdlib.h>
2026-01-12 18:42:02 +00:00
#include <string.h>
2026-01-24 16:02:37 +00:00
#include "../lists/lists.h"
2026-01-23 17:05:56 +00:00
#include "../string_utils/string_utils.h"
#include "../vars/vars.h"
2026-01-24 16:02:37 +00:00
static void strlen_acc(void *acc, void *data)
{
size_t *len = (size_t *)acc;
char *str = (char *)data;
*len += strlen(str);
}
static char *concat_list_str(struct list *list)
{
char *res = NULL;
size_t total_len = list_length(list) + 1; // + spaces + null terminator
list_fold(list, &total_len, strlen_acc);
res = malloc(total_len);
if (res != NULL)
{
res[0] = 0;
for (struct list *it = list; it != NULL; it = it->next)
{
strcat(res, (char *)it->data);
if (it->next != NULL)
strcat(res, " ");
}
res[total_len - 1] = 0;
}
return res;
}
static void args_in_var(struct hash_map *vars, struct list *args_list)
{
int arg_index = 1;
char index_str[11];
for (struct list *it = args_list; it != NULL; it = it->next)
{
int_to_str(arg_index++, index_str);
set_var_copy(vars, index_str, (char *)it->data);
}
char *concated_args = concat_list_str(args_list);
set_var_copy(vars, "*", concated_args);
char *key = strdup("@");
set_var(vars, key, concated_args, NULL);
// key and concated_args consumed by hash_map
int_to_str(arg_index - 1, index_str);
set_var_copy(vars, "#", index_str);
}
2026-01-23 17:05:56 +00:00
int args_handler(int argc, char **argv, struct args_options *options,
struct hash_map *vars)
2026-01-12 18:42:02 +00:00
{
options->type = INPUT_UNDEFINED;
options->input_source = NULL;
// options->pretty_print = false;
2026-01-12 18:42:02 +00:00
options->verbose = false;
2026-01-24 16:02:37 +00:00
struct list *args_list = NULL;
2026-01-23 17:05:56 +00:00
set_var_copy(vars, "0", argv[0]);
2026-01-12 18:42:02 +00:00
for (int i = 1; i < argc; i++)
{
/* if (strcmp(argv[i], "--pretty-print") == 0)
2026-01-12 18:42:02 +00:00
{
options->pretty_print = true;
} */
if (strcmp(argv[i], "--verbose") == 0)
2026-01-12 18:42:02 +00:00
{
options->verbose = true;
}
else if (strcmp(argv[i], "-c") == 0)
2026-01-12 18:42:02 +00:00
{
if (options->type != INPUT_UNDEFINED)
{
fprintf(stderr, "Multiple input sources specified: %s\n",
argv[i + 1]);
return 1;
}
else if (i + 1 >= argc)
{
fprintf(stderr, "No command provided after -c\n");
return 1;
}
2026-01-12 18:42:02 +00:00
options->type = INPUT_CMD;
options->input_source = argv[i + 1];
i++;
}
else if (argv[i][0] == '-')
{
fprintf(stderr, "Unknown option: %s\n", argv[i]);
return 1;
2026-01-12 18:42:02 +00:00
}
2026-01-23 17:05:56 +00:00
else if (options->type == INPUT_UNDEFINED)
2026-01-12 18:42:02 +00:00
{
options->type = INPUT_FILE;
options->input_source = argv[i];
}
2026-01-23 17:05:56 +00:00
else
{
// All remaining arguments are treated as additional arguments
2026-01-24 16:02:37 +00:00
args_list = list_append(args_list, argv[i]);
2026-01-23 17:05:56 +00:00
continue;
}
2026-01-12 18:42:02 +00:00
}
2026-01-24 16:02:37 +00:00
args_in_var(vars, args_list);
2026-01-29 20:35:56 +00:00
list_destroy(&args_list);
2026-01-24 14:51:27 +00:00
2026-01-12 18:42:02 +00:00
if (options->type == INPUT_UNDEFINED)
options->type = INPUT_STDIN;
return 0;
}
void args_print(struct args_options *options)
{
printf("Input type: %s\n",
options->type == INPUT_CMD ? "COMMAND"
: options->type == INPUT_FILE ? "FILE"
: options->type == INPUT_STDIN ? "STDIN"
: "UNDEFINED");
printf("Input source: %s\n",
options->input_source ? options->input_source : "NULL");
// printf("Pretty print: %s\n", options->pretty_print ? "true" : "false");
2026-01-12 18:42:02 +00:00
printf("Verbose: %s\n", options->verbose ? "true" : "false");
}
void print_usage(FILE *std, const char *program_name)
{
fprintf(std, "Usage: %s [OPTIONS] [SCRIPT] [ARGUMENTS...]\n", program_name);
fprintf(std, "Options:\n");
fprintf(std, " -c [SCRIPT] Execute the given command string.\n");
// fprintf(std, " --pretty-print Enable pretty printing of
// outputs.\n");
fprintf(std, " --verbose Enable verbose mode.\n");
fprintf(std,
"If no SCRIPT is provided, input is read from standard input.\n");
}