mirror of
https://github.com/zoriya/ash.git
synced 2026-06-05 03:19:43 +00:00
Merge branch 'master' of github.com:AnonymusRaccoon/ash into bindkey
This commit is contained in:
@@ -7,9 +7,8 @@
|
||||
|
||||
SRC = src/shell.c \
|
||||
src/prompt.c \
|
||||
src/alias.c \
|
||||
src/execute.c \
|
||||
src/glob.c \
|
||||
src/alias.c \
|
||||
src/redirections/redirection_manager.c \
|
||||
src/redirections/redirections.c \
|
||||
src/redirections/redirections_functions.c \
|
||||
@@ -39,6 +38,11 @@ SRC = src/shell.c \
|
||||
src/utility/fusion.c \
|
||||
src/utility/split_commands.c \
|
||||
src/utility/get_return.c \
|
||||
src/parser/parser.c \
|
||||
src/parser/quotes.c \
|
||||
src/parser/double_quotes.c \
|
||||
src/parser/parser_utilities.c \
|
||||
src/parser/parser_vars_utilities.c \
|
||||
src/utility/eof.c \
|
||||
src/key_bindings/basic_typing_functions.c \
|
||||
src/key_bindings/default_bindings.c \
|
||||
@@ -57,7 +61,7 @@ TESTS = tests/tenv.c \
|
||||
tests/targc.c \
|
||||
tests/texecute.c \
|
||||
tests/tcd.c \
|
||||
tests/tsource.c \
|
||||
tests/tsource.c \
|
||||
tests/techo.c
|
||||
|
||||
COVERAGE = -lcriterion --coverage
|
||||
@@ -80,7 +84,7 @@ $(NAME): $(OBJ)
|
||||
$(CC) -o $(NAME) $(OBJ) $(LDFLAGS)
|
||||
|
||||
tests_run: clean
|
||||
$(CC) -o $(UT) $(TESTS) $(SRC) $(COVERAGE) $(CFLAGS) $(LDFLAGS)
|
||||
$(CC) -o $(UT) $(TESTS) $(SRC) $(COVERAGE) -g $(CFLAGS) $(LDFLAGS)
|
||||
$(UT)
|
||||
|
||||
func: all
|
||||
|
||||
+2
-1
@@ -30,12 +30,13 @@ int builtin_alias(char **args, env_t *env);
|
||||
int builtin_unalias(char **args, env_t *env);
|
||||
int builtin_bindkey(char **argv, env_t *env);
|
||||
int builtin_echo(char **args, env_t *env);
|
||||
//utility
|
||||
//which / where
|
||||
bool find_path_in_builtins(char *cmd);
|
||||
char **get_envpath(env_t *env);
|
||||
char *check_executable(char *cmd, char *folder);
|
||||
char **get_paths_from_envpath(char *cmd, char **envpath);
|
||||
char **get_envpath(env_t *env);
|
||||
void fill_path_arr(char *cmd, char **envpath, char **res);
|
||||
//history
|
||||
int add_to_history(char *cmd, env_t *env);
|
||||
int show_history(env_t *env);
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
** EPITECH PROJECT, 2020
|
||||
** PSU_minishell2_2019
|
||||
** File description:
|
||||
** redirections
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "shell.h"
|
||||
#include <wordexp.h>
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
|
||||
typedef struct parser_map {
|
||||
char key;
|
||||
int (*parser)(char *, char **, env_t *);
|
||||
} parser_map;
|
||||
|
||||
char **parse_input(char *cmd, env_t *env, wordexp_t *parser);
|
||||
void free_array(char **array);
|
||||
|
||||
int parse_quotes(char *ptr, char **data, env_t *env);
|
||||
int parse_double_quotes(char *ptr, char **data, env_t *env);
|
||||
|
||||
char *strcat_realloc(char *dest, char *src);
|
||||
char *add_to_buffer(char *buffer, char *ptr, int nb, env_t *env);
|
||||
char *get_var_value(char *var, env_t *env);
|
||||
|
||||
void insert_substring(char *dest, char *src, int position);
|
||||
|
||||
char *process_vars(char *cmd, env_t *env);
|
||||
void rm_n_char(char *ptr, int n);
|
||||
|
||||
void remove_inhibitors_symbols_n_limit(char *str, int nb);
|
||||
@@ -19,7 +19,6 @@ typedef enum redirection_type {
|
||||
PTY = 1 << 4
|
||||
} redirection_type;
|
||||
|
||||
|
||||
typedef struct redirection_map {
|
||||
char *key;
|
||||
int (*get_fd)(redirection *);
|
||||
|
||||
+1
-2
@@ -54,7 +54,7 @@ typedef struct env_s
|
||||
|
||||
void start_shell(env_t *env);
|
||||
void free_env(env_t *env);
|
||||
int prompt_run(char *cmd, redirection *inout[2], env_t *env);
|
||||
int prompt_run(char *cmd, redirection *inout[2], env_t *env, redirection *red);
|
||||
void prompt_prepare(buffer_t *buffer, env_t *env);
|
||||
|
||||
int eval_raw_cmd(char *cmd, env_t *env);
|
||||
@@ -81,7 +81,6 @@ char **globbing(char **argv);
|
||||
|
||||
char *get_alias(char *cmd, alias_t *alias);
|
||||
char *add_separator(char *cmd, int *return_values, int index);
|
||||
char *replace_alias(char *cmd, alias_t *alias);
|
||||
char *get_alias_command(char *cmd, alias_t *alias);
|
||||
|
||||
|
||||
|
||||
+4
-3
@@ -17,16 +17,17 @@ bool is_alpha(char c);
|
||||
bool is_num(char c);
|
||||
bool envvar_is_valid(const char *str);
|
||||
int count_str(char *str, char *delim);
|
||||
char **split_str(char *str, char delim);
|
||||
char **split_str(char *str, char **delims);
|
||||
char *same_var(char *str, const char *to_find);
|
||||
void destroy_str_arr(char **arr);
|
||||
char *fusion(char *command, char **args);
|
||||
char **split_commands(char *cmd);
|
||||
int *get_return_separator(char *cmd);
|
||||
int split_is_invalid(char **cmds, int *return_values, int i);
|
||||
int count_char(const char *str, char c);
|
||||
int ncount_char(const char *str, int end, char c);
|
||||
int get_max_eof(char *ignoreeof);
|
||||
int skip_eof(buffer_t *buffer, env_t *env);
|
||||
int count_trailing_spaces(char *cmd);
|
||||
char **remove_leading_entries(char **cmds);
|
||||
|
||||
#define MAX(x, y) ((x) < (y) ? (y) : (x))
|
||||
#define MAX(x, y) ((x) < (y) ? (y) : (x))
|
||||
|
||||
+2
-63
@@ -12,77 +12,16 @@
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
char *get_alias(char *cmd, alias_t *alias)
|
||||
{
|
||||
char **array = split_commands(cmd);
|
||||
int *return_values = get_return_separator(cmd);
|
||||
char *final_command = NULL;
|
||||
|
||||
if (!array)
|
||||
return (cmd);
|
||||
for (int i = 0; array[i]; i++) {
|
||||
if (strlen(array[i]) && (strncmp("alias ", array[i], 6)
|
||||
&& strncmp("unalias ", array[i], 8)))
|
||||
array[i] = replace_alias(array[i], alias);
|
||||
array[i] = add_separator(array[i], return_values, i);
|
||||
if (!array[i])
|
||||
return (NULL);
|
||||
}
|
||||
final_command = fusion(array[0], array);
|
||||
return (final_command);
|
||||
}
|
||||
|
||||
char *replace_alias(char *cmd, alias_t *alias)
|
||||
{
|
||||
char **arg_array = split_str(cmd, ' ');
|
||||
char *final_str = NULL;
|
||||
|
||||
if (!arg_array)
|
||||
return (NULL);
|
||||
for (int i = 0; arg_array[i]; i++) {
|
||||
arg_array[i] = get_alias_command(arg_array[i], alias);
|
||||
if (!arg_array[i])
|
||||
return (NULL);
|
||||
}
|
||||
final_str = fusion(arg_array[0], arg_array);
|
||||
return (final_str);
|
||||
}
|
||||
|
||||
char *get_alias_command(char *cmd, alias_t *alias)
|
||||
{
|
||||
alias_t *tmp = NULL;
|
||||
|
||||
tmp = alias;
|
||||
for (; tmp; tmp = tmp->next) {
|
||||
if (!strcmp(cmd, alias->alias)) {
|
||||
cmd = strdup(alias->command);
|
||||
if (!strcmp(cmd, tmp->alias)) {
|
||||
cmd = strdup(tmp->command);
|
||||
tmp = alias;
|
||||
}
|
||||
}
|
||||
return (cmd);
|
||||
}
|
||||
|
||||
char *add_separator(char *cmd, int *return_values, int index)
|
||||
{
|
||||
int pos = 0;
|
||||
char *new_cmd = NULL;
|
||||
|
||||
if (!cmd)
|
||||
return (NULL);
|
||||
new_cmd = calloc(strlen(cmd) + 3, sizeof(char));
|
||||
if (!new_cmd)
|
||||
return (NULL);
|
||||
for (int i = 0; cmd[i]; i++)
|
||||
new_cmd[i] = cmd[pos++];
|
||||
if (return_values[index + 1] != -2) {
|
||||
new_cmd[pos] = ';';
|
||||
if (return_values[index + 1] == 1) {
|
||||
new_cmd[pos++] = '|';
|
||||
new_cmd[pos++] = '|';
|
||||
} else if (return_values[index + 1] == 0) {
|
||||
new_cmd[pos++] = '&';
|
||||
new_cmd[pos++] = '&';
|
||||
}
|
||||
}
|
||||
return (new_cmd);
|
||||
}
|
||||
@@ -33,8 +33,10 @@ int add_alias(alias_t **list, char *alias, char **command)
|
||||
elem = malloc(sizeof(alias_t));
|
||||
if (!elem)
|
||||
return (-1);
|
||||
*elem = (alias_t){alias, concatenate(command), NULL};
|
||||
if (!elem->command)
|
||||
elem->alias = strdup(alias);
|
||||
elem->command = concatenate(command);
|
||||
elem->next = NULL;
|
||||
if (!elem->command || !elem->alias)
|
||||
return (-1);
|
||||
if (*list == NULL) {
|
||||
*list = elem;
|
||||
@@ -75,7 +77,7 @@ char *concatenate(char **command)
|
||||
int pos = 0;
|
||||
|
||||
if (!command[1])
|
||||
return (command[0]);
|
||||
return (strdup(command[0]));
|
||||
for (int i = 0; command[i]; i++)
|
||||
total_len += strlen(command[i]) + 1;
|
||||
concatened = calloc(total_len + 1, sizeof(char));
|
||||
@@ -93,8 +95,6 @@ char *concatenate(char **command)
|
||||
|
||||
void print_aliases(alias_t *list)
|
||||
{
|
||||
for (alias_t *tmp = list; tmp; tmp = tmp->next) {
|
||||
for (alias_t *tmp = list; tmp; tmp = tmp->next)
|
||||
printf("%s\t%s\n", tmp->alias, tmp->command);
|
||||
fflush(stdout);
|
||||
}
|
||||
}
|
||||
@@ -18,7 +18,6 @@ int builtin_env(char **argv, env_t *env)
|
||||
write(1, "\n", 1);
|
||||
}
|
||||
env->vars = my_setenv(env->vars, "?", "0");
|
||||
free(argv);
|
||||
return (0);
|
||||
}
|
||||
|
||||
@@ -39,7 +38,6 @@ int builtin_setenv(char **argv, env_t *env)
|
||||
}
|
||||
env->env = my_setenv(env->env, argv[1], argv[2]);
|
||||
env->vars = my_setenv(env->vars, "?", "0");
|
||||
free(argv);
|
||||
return (0);
|
||||
}
|
||||
|
||||
@@ -48,13 +46,11 @@ int builtin_unsetenv(char **argv, env_t *env)
|
||||
if (!argv[1]) {
|
||||
write(2, "unsetenv: Too few arguments.\n", 29);
|
||||
env->vars = my_setenv(env->vars, "?", "1");
|
||||
free(argv);
|
||||
return (0);
|
||||
}
|
||||
for (int i = 1; argv[i]; i++)
|
||||
if (!strchr(argv[i], '='))
|
||||
env->env = my_unsetenv(env->env, argv[i]);
|
||||
env->vars = my_setenv(env->vars, "?", "0");
|
||||
free(argv);
|
||||
return (0);
|
||||
}
|
||||
@@ -37,8 +37,10 @@ int add_to_history(char *cmd, env_t *env)
|
||||
char *command = cmd;
|
||||
|
||||
for (; *command && (*command == ' ' || *command == '\t'); command++);
|
||||
if (!strlen(command))
|
||||
if (!strlen(command)) {
|
||||
free(log);
|
||||
return (0);
|
||||
}
|
||||
if (!log)
|
||||
return (-1);
|
||||
for (tmp = env->history; tmp && tmp->next; tmp = tmp->next);
|
||||
|
||||
@@ -46,7 +46,6 @@ int builtin_cd(char **argv, env_t *env)
|
||||
|
||||
if (get_argc(argv) > 2) {
|
||||
write(2, "cd: Too many arguments.\n", 25);
|
||||
free(argv);
|
||||
env->vars = my_setenv(env->vars, "?", "1");
|
||||
return (0);
|
||||
}
|
||||
@@ -61,7 +60,6 @@ int builtin_cd(char **argv, env_t *env)
|
||||
} else
|
||||
env->env = my_setenv(env->env, "OLDPWD", old);
|
||||
free(old);
|
||||
free(argv);
|
||||
return (0);
|
||||
}
|
||||
|
||||
@@ -69,6 +67,5 @@ int builtin_exit(char **argv, env_t *env)
|
||||
{
|
||||
if (argv[1])
|
||||
env->vars = my_setenv(env->vars, "?", "1");
|
||||
free(argv);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@ char **get_arr_from_fd(int fd, char *filepath, char *str)
|
||||
str = malloc(st_buff.st_size + 1);
|
||||
if (str) {
|
||||
read(fd, str, st_buff.st_size);
|
||||
arr = split_str(str, '\n');
|
||||
arr = split_str(str, (char *[]){"\n", NULL});
|
||||
}
|
||||
return (arr);
|
||||
}
|
||||
|
||||
+17
-17
@@ -15,9 +15,18 @@
|
||||
#include "utility.h"
|
||||
#include "shell.h"
|
||||
|
||||
void print_alias_where(char *cmd, char *aliased)
|
||||
{
|
||||
if (aliased[0] == '(') {
|
||||
aliased = &aliased[1];
|
||||
aliased[strlen(aliased) - 1] = 0;
|
||||
}
|
||||
printf("%s is aliased to %s\n", cmd, aliased);
|
||||
}
|
||||
|
||||
char *check_executable(char *cmd, char *folder)
|
||||
{
|
||||
struct stat st_buff;
|
||||
struct stat st_buff = {};
|
||||
char *path = catpath(folder, cmd);
|
||||
char *res = path;
|
||||
|
||||
@@ -58,23 +67,14 @@ void fill_path_arr(char *cmd, char **envpath, char **res)
|
||||
res[counter] = NULL;
|
||||
}
|
||||
|
||||
char **get_paths_from_envpath(char *cmd, char **envpath)
|
||||
{
|
||||
int len = 0;
|
||||
char **res = NULL;
|
||||
|
||||
for (; envpath[len]; len++);
|
||||
res = malloc(sizeof(char *) * (len + 2));
|
||||
if (!res)
|
||||
return (NULL);
|
||||
fill_path_arr(cmd, envpath, res);
|
||||
return (res);
|
||||
}
|
||||
|
||||
void print_path_no_stop(char *cmd, char **envpath)
|
||||
void print_path_no_stop(char *cmd, char **envpath, env_t *env)
|
||||
{
|
||||
char *dup_cmd = strdup(cmd);
|
||||
char **paths = NULL;
|
||||
//check_alias_no_stop
|
||||
char *aliased = get_alias_command(cmd, env->alias);
|
||||
|
||||
if (strcmp(aliased, dup_cmd))
|
||||
print_alias_where(dup_cmd, aliased);
|
||||
find_path_in_builtins(cmd);
|
||||
if (!envpath)
|
||||
return;
|
||||
@@ -101,7 +101,7 @@ int builtin_where(char **argv, env_t *env)
|
||||
if (strchr(argv[i], '/'))
|
||||
printf("where: / in command makes no sense\n");
|
||||
else
|
||||
print_path_no_stop(argv[i], envpath);
|
||||
print_path_no_stop(argv[i], envpath, env);
|
||||
}
|
||||
free(envpath);
|
||||
return (0);
|
||||
|
||||
@@ -12,6 +12,28 @@
|
||||
#include "utility.h"
|
||||
#include "builtin.h"
|
||||
|
||||
char **get_paths_from_envpath(char *cmd, char **envpath)
|
||||
{
|
||||
int len = 0;
|
||||
char **res = NULL;
|
||||
|
||||
for (; envpath[len]; len++);
|
||||
res = malloc(sizeof(char *) * (len + 2));
|
||||
if (!res)
|
||||
return (NULL);
|
||||
fill_path_arr(cmd, envpath, res);
|
||||
return (res);
|
||||
}
|
||||
|
||||
void print_alias_which(char *cmd, char *aliased)
|
||||
{
|
||||
if (aliased[0] == '(') {
|
||||
aliased = &aliased[1];
|
||||
aliased[strlen(aliased) - 1] = 0;
|
||||
}
|
||||
printf("%s:\taliased to %s\n", cmd, aliased);
|
||||
}
|
||||
|
||||
bool find_path_in_builtins(char *cmd)
|
||||
{
|
||||
extern const builtin builtins[];
|
||||
@@ -24,11 +46,17 @@ bool find_path_in_builtins(char *cmd)
|
||||
return (false);
|
||||
}
|
||||
|
||||
void print_path(char *cmd, char **envpath)
|
||||
void print_path(char *cmd, char **envpath, env_t *env)
|
||||
{
|
||||
char **res = NULL;
|
||||
char *dup_cmd = strdup(cmd);
|
||||
int len = 0;
|
||||
//check_alias
|
||||
char *aliased = get_alias_command(cmd, env->alias);
|
||||
|
||||
if (strcmp(aliased, dup_cmd)) {
|
||||
print_alias_which(dup_cmd, aliased);
|
||||
return;
|
||||
}
|
||||
if (find_path_in_builtins(cmd))
|
||||
return;
|
||||
res = get_paths_from_envpath(cmd, envpath);
|
||||
@@ -52,7 +80,7 @@ int builtin_which(char **argv, env_t *env)
|
||||
}
|
||||
envpath = get_envpath(env);
|
||||
for (int i = 1; argv[i]; i++)
|
||||
print_path(argv[i], envpath);
|
||||
print_path(argv[i], envpath, env);
|
||||
free(envpath);
|
||||
return (0);
|
||||
}
|
||||
-42
@@ -1,42 +0,0 @@
|
||||
/*
|
||||
** EPITECH PROJECT, 2020
|
||||
** ash
|
||||
** File description:
|
||||
** glob
|
||||
*/
|
||||
|
||||
#include <glob.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include "shell.h"
|
||||
|
||||
char **glob_error(char **argv, int err)
|
||||
{
|
||||
if (err == GLOB_ABORTED)
|
||||
fprintf(stderr, "%s: %s\n", argv[0], "Aborted.");
|
||||
if (err == GLOB_NOMATCH)
|
||||
fprintf(stderr, "%s: %s\n", argv[0], "No match.");
|
||||
if (err == GLOB_NOSPACE)
|
||||
fprintf(stderr, "%s: %s\n", argv[0], "No space.");
|
||||
free(argv);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
char **globbing(char **argv)
|
||||
{
|
||||
static glob_t results;
|
||||
int flags = GLOB_DOOFFS | GLOB_NOMAGIC | GLOB_TILDE;
|
||||
int ret = 0;
|
||||
|
||||
for (int i = 0; argv[i] && ret == 0; i++) {
|
||||
flags |= (i > 0 ? GLOB_APPEND : 0);
|
||||
ret = glob(argv[i], flags, NULL, &results);
|
||||
}
|
||||
if (ret != 0) {
|
||||
globfree(&results);
|
||||
return (glob_error(argv, ret));
|
||||
}
|
||||
free(argv);
|
||||
return (&results.gl_pathv[0]);
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
** EPITECH PROJECT, 2020
|
||||
** PSU_minishell2_2019
|
||||
** File description:
|
||||
** redirections
|
||||
*/
|
||||
|
||||
#include "parser.h"
|
||||
#include <stdio.h>
|
||||
|
||||
int parse_double_quotes(char *ptr, char **data, env_t *env)
|
||||
{
|
||||
int length = 0;
|
||||
char *ptr_end = strchr(&ptr[1], '"');
|
||||
char *cmd;
|
||||
|
||||
if (!ptr_end) {
|
||||
dprintf(2, "Unmatched '\"'.\n");
|
||||
return (-1);
|
||||
}
|
||||
length = (ptr_end - ptr) / sizeof(char);
|
||||
cmd = strndup(&ptr[1], length);
|
||||
if (!cmd)
|
||||
return (-1);
|
||||
cmd[length - 1] = '\0';
|
||||
*data = process_vars(cmd, env);
|
||||
return (length);
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
** EPITECH PROJECT, 2020
|
||||
** PSU_minishell2_2019
|
||||
** File description:
|
||||
** redirections
|
||||
*/
|
||||
|
||||
#define _XOPEN_SOURCE
|
||||
|
||||
#include "parser.h"
|
||||
#include "shell.h"
|
||||
#include "redirections.h"
|
||||
#include "utility.h"
|
||||
#include "builtin.h"
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <malloc.h>
|
||||
|
||||
char *strdup(const char *);
|
||||
|
||||
int count_trailing_spaces(char *cmd)
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
for (i = 0; cmd[i]; i++)
|
||||
if (cmd[i] != ' ' && cmd[i] != '\t')
|
||||
break;
|
||||
return (i);
|
||||
}
|
||||
|
||||
char **remove_leading_entries(char **cmds)
|
||||
{
|
||||
if (!cmds)
|
||||
return (NULL);
|
||||
for (int i = 0; cmds[i]; i++)
|
||||
if (cmds[i][count_trailing_spaces(cmds[i])])
|
||||
return (cmds + i);
|
||||
return (cmds);
|
||||
}
|
||||
|
||||
char *process_aliases(char *cmd, env_t *env)
|
||||
{
|
||||
int bin_len;
|
||||
|
||||
for (bin_len = 0; cmd[bin_len]; bin_len++) {
|
||||
if (cmd[bin_len] == ' ' || cmd[bin_len] == '\t')
|
||||
break;
|
||||
}
|
||||
for (alias_t *al = env->alias; al; al = al->next) {
|
||||
if (!strncmp(al->alias, cmd, bin_len)) {
|
||||
cmd = realloc(cmd, strlen(cmd) + strlen(al->command) + 1 - bin_len);
|
||||
if (!cmd)
|
||||
return (NULL);
|
||||
rm_n_char(cmd, bin_len);
|
||||
insert_substring(cmd, al->command, 1);
|
||||
}
|
||||
}
|
||||
return (cmd);
|
||||
}
|
||||
|
||||
char **parse_input(char *cmd, env_t *env, wordexp_t *parser)
|
||||
{
|
||||
if (!(cmd = strdup(cmd + count_trailing_spaces(cmd))))
|
||||
return (NULL);
|
||||
if (!(cmd = process_vars(cmd, env)))
|
||||
return (NULL);
|
||||
cmd = process_aliases(cmd, env);
|
||||
if (wordexp(cmd, parser, WRDE_SHOWERR)) {
|
||||
perror(SHELL_NAME);
|
||||
return (NULL);
|
||||
}
|
||||
free(cmd);
|
||||
return (parser->we_wordv);
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
/*
|
||||
** EPITECH PROJECT, 2020
|
||||
** PSU_minishell2_2019
|
||||
** File description:
|
||||
** parser_utilities
|
||||
*/
|
||||
|
||||
#include <malloc.h>
|
||||
#include <glob.h>
|
||||
#include "shell.h"
|
||||
#include "parser.h"
|
||||
|
||||
char **glob_error(char **argv, int err);
|
||||
|
||||
char *strcat_realloc(char *dest, char *src)
|
||||
{
|
||||
if (dest) {
|
||||
dest = realloc(dest, sizeof(char) * (strlen(dest) + strlen(src) + 1));
|
||||
if (!dest)
|
||||
return (NULL);
|
||||
} else {
|
||||
dest = malloc(sizeof(char) * (strlen(src) + 1));
|
||||
if (!dest)
|
||||
return (NULL);
|
||||
dest[0] = '\0';
|
||||
}
|
||||
strcat(dest, src);
|
||||
return (dest);
|
||||
}
|
||||
|
||||
char *add_to_buffer(char *buffer, char *ptr, int nb, env_t *env)
|
||||
{
|
||||
char *new;
|
||||
|
||||
if (nb <= 0)
|
||||
return (buffer);
|
||||
new = strndup(ptr, nb + 1);
|
||||
if (!new)
|
||||
return (NULL);
|
||||
new[nb] = '\0';
|
||||
if (env) {
|
||||
remove_inhibitors_symbols_n_limit(new, nb);
|
||||
new = process_vars(new, env);
|
||||
}
|
||||
buffer = strcat_realloc(buffer, new);
|
||||
free(new);
|
||||
return (buffer);
|
||||
}
|
||||
|
||||
void remove_inhibitors_symbols_n_limit(char *str, int nb)
|
||||
{
|
||||
for (int i = 0; str[i] && i < nb; i++) {
|
||||
if (str[i] == '\\') {
|
||||
for (int j = i; str[j]; j++) {
|
||||
str[j] = str[j + 1];
|
||||
}
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
char *substring(char *string, int position, int length)
|
||||
{
|
||||
char *pointer = malloc(length + 1);
|
||||
int i;
|
||||
|
||||
if (pointer == NULL)
|
||||
return (NULL);
|
||||
for (i = 0; i < length; i++)
|
||||
*(pointer + i) = *((string + position - 1) + i);
|
||||
*(pointer + i) = '\0';
|
||||
return (pointer);
|
||||
}
|
||||
|
||||
void insert_substring(char *dest, char *src, int position)
|
||||
{
|
||||
char *f;
|
||||
char *e;
|
||||
int length;
|
||||
|
||||
length = strlen(dest);
|
||||
f = substring(dest, 1, position - 1);
|
||||
e = substring(dest, position, length - position + 1);
|
||||
strcpy(dest, "");
|
||||
strcat(dest, f);
|
||||
free(f);
|
||||
strcat(dest, src);
|
||||
strcat(dest, e);
|
||||
free(e);
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
/*
|
||||
** EPITECH PROJECT, 2020
|
||||
** PSU_minishell2_2019
|
||||
** File description:
|
||||
** redirections
|
||||
*/
|
||||
|
||||
#include "parser.h"
|
||||
#include <stdio.h>
|
||||
#include <malloc.h>
|
||||
|
||||
char *get_var_value(char *var, env_t *env)
|
||||
{
|
||||
char *value;
|
||||
|
||||
if (!var)
|
||||
return (NULL);
|
||||
value = my_getenv(env->env, var);
|
||||
if (value)
|
||||
return (value);
|
||||
value = my_getenv(env->vars, var);
|
||||
if (value)
|
||||
return (value);
|
||||
printf("%s: Undefined variable.\n", var);
|
||||
env->vars = my_setenv(env->vars, "?", "1");
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
int get_var_name(char *ptr, char **name)
|
||||
{
|
||||
int length = 0;
|
||||
|
||||
for (int i = 1; ptr[i] && ptr[i] != ' ' && ptr[i] != '$'; i++) {
|
||||
length++;
|
||||
}
|
||||
*name = strndup(&ptr[1], length);
|
||||
return (length + 1);
|
||||
}
|
||||
|
||||
void rm_n_char(char *ptr, int n)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; ptr[i + n]; i++) {
|
||||
ptr[i] = ptr[i + n];
|
||||
}
|
||||
ptr[i] = '\0';
|
||||
}
|
||||
|
||||
char *process_vars(char *cmd, env_t *env)
|
||||
{
|
||||
char *name = NULL;
|
||||
char *value;
|
||||
int new_index;
|
||||
int length = strlen(cmd);
|
||||
|
||||
for (int i = 0; i < length; i++, length = strlen(cmd)) {
|
||||
if (cmd[i] != '$')
|
||||
continue;
|
||||
new_index = get_var_name(&cmd[i], &name);
|
||||
value = get_var_value(name, env);
|
||||
if (!value)
|
||||
return (NULL);
|
||||
cmd = realloc(cmd, sizeof(char) * (strlen(value) + length + 2));
|
||||
if (!cmd)
|
||||
return (NULL);
|
||||
rm_n_char(&cmd[i], strlen(name) + 1);
|
||||
insert_substring(cmd, value, i + 1);
|
||||
i += new_index;
|
||||
free(name);
|
||||
}
|
||||
return (cmd);
|
||||
}
|
||||
|
||||
void free_array(char **array)
|
||||
{
|
||||
for (int i = 0; array[i]; i++) {
|
||||
free(array[i]);
|
||||
}
|
||||
free(array);
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
** EPITECH PROJECT, 2020
|
||||
** PSU_minishell2_2019
|
||||
** File description:
|
||||
** redirections
|
||||
*/
|
||||
|
||||
#include "parser.h"
|
||||
#include <stdio.h>
|
||||
|
||||
int parse_quotes(char *ptr, char **data, env_t *env)
|
||||
{
|
||||
int length = 0;
|
||||
char *ptr_end = strchr(&ptr[1], '\'');
|
||||
(void)env;
|
||||
|
||||
if (!ptr_end) {
|
||||
dprintf(2, "Unmatched '''.\n");
|
||||
return (-1);
|
||||
}
|
||||
length = (ptr_end - ptr) / sizeof(char);
|
||||
*data = strndup(&ptr[1], length);
|
||||
if (!(*data))
|
||||
return (-1);
|
||||
(*data)[length - 1] = '\0';
|
||||
return (length);
|
||||
}
|
||||
+15
-14
@@ -10,6 +10,7 @@
|
||||
#include "shell.h"
|
||||
#include "builtin.h"
|
||||
#include "redirections.h"
|
||||
#include "parser.h"
|
||||
#include "utility.h"
|
||||
#include <unistd.h>
|
||||
#include <malloc.h>
|
||||
@@ -32,27 +33,27 @@ const builtin builtins[] = {
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
||||
int prompt_run(char *cmd, redirection *inout[2], env_t *env)
|
||||
int prompt_run(char *cmd, redirection *inout[2], env_t *env, redirection *cmds)
|
||||
{
|
||||
char **argv = get_argv(cmd);
|
||||
wordexp_t parser;
|
||||
char **argv = parse_input(cmd, env, &parser);
|
||||
int ret = -2;
|
||||
|
||||
if (!argv) {
|
||||
perror(SHELL_NAME);
|
||||
return (-1);
|
||||
}
|
||||
if (!argv[0])
|
||||
return (0);
|
||||
argv = globbing(argv);
|
||||
if (!argv)
|
||||
return (0);
|
||||
if (**argv == '!' && argv[0][1] && argv[0][1] != ' ')
|
||||
return (run_builtin(&builtins[5], argv, inout, env));
|
||||
ret = run_builtin(&builtins[5], argv, inout, env);
|
||||
for (int i = 0; builtins[i].name; i++)
|
||||
if (!strcmp(argv[0], builtins[i].name))
|
||||
return (run_builtin(&builtins[i], argv, inout, env));
|
||||
run_cmd(argv, inout, env);
|
||||
free(argv);
|
||||
return (0);
|
||||
ret = run_builtin(&builtins[i], argv, inout, env);
|
||||
if (ret == -2) {
|
||||
run_cmd(argv, inout, env);
|
||||
ret = 0;
|
||||
}
|
||||
wordfree(&parser);
|
||||
if (cmds)
|
||||
free(cmds);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
void prompt_prepare(buffer_t *buffer, env_t *env)
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#include <sys/types.h>
|
||||
#include <sys/wait.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include "utility.h"
|
||||
#include "builtin.h"
|
||||
|
||||
@@ -66,31 +67,32 @@ int run_with_redirections(char *cmd, env_t *env, redirection *input)
|
||||
inout[0] = input;
|
||||
inout[1] = NULL;
|
||||
if (!cmds || !cmds[0].type)
|
||||
return (prompt_run(cmd, inout, env));
|
||||
return (prompt_run(cmd, inout, env, cmds));
|
||||
for (int i = 0; cmds[i].type; i++) {
|
||||
if (cmds[i].type->type & INPUT)
|
||||
inout[0] = &cmds[i];
|
||||
else
|
||||
inout[1] = &cmds[i];
|
||||
if (cmds[i].type->type & PIPE)
|
||||
return (prompt_run(cmd, inout, env));
|
||||
return (prompt_run(cmd, inout, env, cmds));
|
||||
}
|
||||
return (prompt_run(cmd, inout, env));
|
||||
return (prompt_run(cmd, inout, env, cmds));
|
||||
}
|
||||
|
||||
int command_format_is_invalid(char **cmds, env_t *env, int *return_values)
|
||||
bool command_format_is_invalid(char **cmds, env_t *env, int *return_values)
|
||||
{
|
||||
for (int i = 0; cmds[i]; i++) {
|
||||
if (redirections_are_invalid(cmds[i])) {
|
||||
env->env = my_setenv(env->vars, "?", "1");
|
||||
return (1);
|
||||
} else if (split_is_invalid(cmds, return_values, i)) {
|
||||
write(2, "Invalid null command.\n", 22);
|
||||
if (!cmds[i] || !cmds[i][count_trailing_spaces(cmds[i])]
|
||||
|| split_is_invalid(cmds, return_values, i)) {
|
||||
dprintf(2, "Invalid null command.\n");
|
||||
env->vars = my_setenv(env->vars, "?", "1");
|
||||
return (1);
|
||||
return (true);
|
||||
} else if (redirections_are_invalid(cmds[i])) {
|
||||
env->env = my_setenv(env->vars, "?", "1");
|
||||
return (true);
|
||||
}
|
||||
}
|
||||
return (0);
|
||||
return (false);
|
||||
}
|
||||
|
||||
int eval_raw_cmd(char *cmd, env_t *env)
|
||||
@@ -99,11 +101,9 @@ int eval_raw_cmd(char *cmd, env_t *env)
|
||||
char **cmds = NULL;
|
||||
int ret = 0;
|
||||
|
||||
cmd = get_alias(cmd, env->alias);
|
||||
if (!cmd)
|
||||
return (0);
|
||||
return_values = get_return_separator(cmd);
|
||||
cmds = split_commands(cmd);
|
||||
cmds = split_str(cmd, (char *[]){";", "||", "&&", NULL});
|
||||
cmds = remove_leading_entries(cmds);
|
||||
if (!cmds)
|
||||
return (-1);
|
||||
if (command_format_is_invalid(cmds, env, return_values))
|
||||
|
||||
@@ -28,7 +28,6 @@ char **get_envpath(env_t *env)
|
||||
if (pathstr) {
|
||||
path_cpy = strdup(pathstr);
|
||||
envpath = to_array(path_cpy);
|
||||
free(path_cpy);
|
||||
}
|
||||
return (envpath);
|
||||
}
|
||||
+2
-2
@@ -16,10 +16,10 @@ int get_max_eof(char *ignoreeof)
|
||||
bool correct = true;
|
||||
|
||||
for (int i = 0; ignoreeof[i] && correct; i++)
|
||||
if(!is_num(ignoreeof[i]))
|
||||
if (!is_num(ignoreeof[i]))
|
||||
correct = false;
|
||||
if (correct && strcmp(ignoreeof, "0") && strcmp(ignoreeof, ""))
|
||||
return(strtol(ignoreeof, NULL, 10));
|
||||
return (strtol(ignoreeof, NULL, 10));
|
||||
return (26);
|
||||
}
|
||||
|
||||
|
||||
+38
-39
@@ -1,36 +1,20 @@
|
||||
/*
|
||||
** EPITECH PROJECT, 2020
|
||||
** PSU_minishell2_2019
|
||||
** Utility
|
||||
** File description:
|
||||
** split_str
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <malloc.h>
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
|
||||
int ncount_char(const char *str, int end, char c)
|
||||
static char *get_delimiter(char *str, char **delims)
|
||||
{
|
||||
int count = 0;
|
||||
|
||||
if (str == NULL)
|
||||
return (0);
|
||||
while (*str && end-- > 0)
|
||||
if (*(str++) == c)
|
||||
count++;
|
||||
return (count);
|
||||
}
|
||||
|
||||
int count_char(const char *str, char c)
|
||||
{
|
||||
int count = 0;
|
||||
|
||||
if (str == NULL)
|
||||
return (0);
|
||||
while (*str)
|
||||
if (*(str++) == c)
|
||||
count++;
|
||||
return (count);
|
||||
for (int i = 0; delims[i]; i++)
|
||||
if (!strncmp(str, delims[i], strlen(delims[i])))
|
||||
return (delims[i]);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
int count_str(char *str, char *delim)
|
||||
@@ -44,27 +28,42 @@ int count_str(char *str, char *delim)
|
||||
return (count);
|
||||
}
|
||||
|
||||
char **split_str(char *str, char delim)
|
||||
static int get_splitted_count(char *str, char **delims)
|
||||
{
|
||||
char **splited = malloc(sizeof(char *) * (count_char(str, delim) + 2));
|
||||
int i;
|
||||
int j = 0;
|
||||
int count = 1;
|
||||
char *delim;
|
||||
|
||||
for (int i = 0; str[i]; i++) {
|
||||
delim = get_delimiter(str + i, delims);
|
||||
if (delim) {
|
||||
count++;
|
||||
i += strlen(delim);
|
||||
}
|
||||
}
|
||||
return (count);
|
||||
}
|
||||
|
||||
char **split_str(char *str, char **delims)
|
||||
{
|
||||
char **arr = malloc(sizeof(char *) * (get_splitted_count(str, delims) + 1));
|
||||
int index = 0;
|
||||
int i;
|
||||
char *delim;
|
||||
|
||||
if (!arr)
|
||||
return (NULL);
|
||||
for (i = 0; str[i]; i++) {
|
||||
if (str[i] != delim)
|
||||
if (!(delim = get_delimiter(str + i, delims)))
|
||||
continue;
|
||||
str[i] = '\0';
|
||||
if (i > 0) {
|
||||
splited[j] = str;
|
||||
j++;
|
||||
}
|
||||
str += i + 1;
|
||||
arr[index] = str;
|
||||
str += i + strlen(delim);
|
||||
if (i > 0)
|
||||
index++;
|
||||
i = -1;
|
||||
}
|
||||
if (i > 0) {
|
||||
splited[j] = str;
|
||||
j++;
|
||||
}
|
||||
splited[j] = NULL;
|
||||
return (splited);
|
||||
// if (i > 0)
|
||||
arr[index++] = str;
|
||||
arr[index] = NULL;
|
||||
return (arr);
|
||||
}
|
||||
+1
-9
@@ -332,7 +332,7 @@ NAME="933"
|
||||
SETUP=""
|
||||
CLEAN=""
|
||||
TESTS=
|
||||
echo ' || ls'
|
||||
echo ' && ls'
|
||||
[933-END]
|
||||
|
||||
[934]
|
||||
@@ -343,14 +343,6 @@ TESTS=
|
||||
echo ' || '
|
||||
[934-END]
|
||||
|
||||
[935]
|
||||
NAME="935"
|
||||
SETUP=""
|
||||
CLEAN=""
|
||||
TESTS=
|
||||
echo ' && '
|
||||
[935-END]
|
||||
|
||||
[936]
|
||||
NAME="936"
|
||||
SETUP=""
|
||||
|
||||
+2
-2
@@ -15,7 +15,7 @@
|
||||
|
||||
Test(get_special_arg_at, at_arg)
|
||||
{
|
||||
char **argv = split_str(strdup("source file a b c"), ' ');
|
||||
char **argv = split_str(strdup("source file a b c"), (char *[]) {" ", NULL});
|
||||
int argv_len = 5;
|
||||
char *res = NULL;
|
||||
|
||||
@@ -26,7 +26,7 @@ Test(get_special_arg_at, at_arg)
|
||||
|
||||
Test(get_special_arg_star, at_arg)
|
||||
{
|
||||
char **argv = split_str(strdup("source file a b c"), ' ');
|
||||
char **argv = split_str(strdup("source file a b c"), (char *[]) {" ", NULL});
|
||||
int argv_len = 5;
|
||||
char *res = NULL;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user