mirror of
https://github.com/zoriya/ash.git
synced 2026-05-27 08:33:04 +00:00
Merge branch 'master' of github.com:AnonymusRaccoon/ash into parser
This commit is contained in:
+2
-1
@@ -7,4 +7,5 @@
|
||||
unit_tests
|
||||
test_shell/
|
||||
func_tests
|
||||
.vscode
|
||||
.vscode
|
||||
scri.sh
|
||||
@@ -59,7 +59,6 @@ TESTS = tests/tenv.c \
|
||||
tests/targc.c \
|
||||
tests/texecute.c \
|
||||
tests/tcd.c \
|
||||
tests/tsource.c \
|
||||
|
||||
COVERAGE = -lcriterion --coverage
|
||||
|
||||
|
||||
+2
-2
@@ -43,8 +43,8 @@ void remove_duplicate_history(env_t *env);
|
||||
int execute_command_history(history_t *old, history_t *new,
|
||||
char **args, env_t *env);
|
||||
//source
|
||||
char *parse_source_cmd(char *cmd, char **argv, int len_argv);
|
||||
|
||||
void init_source_args(char **argv, int len_argv, env_t *env);
|
||||
void reset_source_args(int len_argv, env_t *env);
|
||||
//alias
|
||||
int add_alias(alias_t **list, char *alias, char **command);
|
||||
char *concatenate(char **command);
|
||||
|
||||
@@ -16,27 +16,41 @@
|
||||
#include "utility.h"
|
||||
#include "shell.h"
|
||||
|
||||
static void start_script(char **argv, env_t *env, int len_argv)
|
||||
char **get_arr_from_fd(int fd, char *filepath, char *str)
|
||||
{
|
||||
char *str = NULL;
|
||||
char **arr = NULL;
|
||||
int fd = open(argv[1], O_RDONLY);
|
||||
bool should_close = false;
|
||||
struct stat st_buff;
|
||||
char **arr = NULL;
|
||||
|
||||
if (fd == -1)
|
||||
return;
|
||||
stat(argv[1], &st_buff);
|
||||
stat(filepath, &st_buff);
|
||||
str = malloc(st_buff.st_size + 1);
|
||||
if (str) {
|
||||
read(fd, str, st_buff.st_size);
|
||||
arr = split_str(str, '\n');
|
||||
if (arr)
|
||||
for (int i = 0; arr[i] && !should_close; i++)
|
||||
should_close = (eval_raw_cmd(parse_source_cmd(arr[i],
|
||||
argv, len_argv), env) < 0);
|
||||
free(str);
|
||||
}
|
||||
return (arr);
|
||||
}
|
||||
|
||||
static void start_script(char **argv, env_t *env, int len_argv)
|
||||
{
|
||||
int fd = open(argv[1], O_RDONLY);
|
||||
bool should_close = false;
|
||||
char **arr = NULL;
|
||||
char *str = NULL;
|
||||
|
||||
if (fd == -1)
|
||||
return;
|
||||
arr = get_arr_from_fd(fd, argv[1], str);
|
||||
init_source_args(argv, len_argv, env);
|
||||
if (arr) {
|
||||
for (int i = 0; arr[i] && !should_close; i++) {
|
||||
if (arr[i][0] == '#')
|
||||
continue;
|
||||
should_close = (eval_raw_cmd(arr[i], env) < 0);
|
||||
}
|
||||
}
|
||||
reset_source_args(len_argv, env);
|
||||
free(arr);
|
||||
free(str);
|
||||
close(fd);
|
||||
}
|
||||
|
||||
@@ -69,9 +83,12 @@ int builtin_source(char **argv, env_t *env)
|
||||
for (; argv[len]; len++);
|
||||
if (len == 1) {
|
||||
printf("%s: Too few arguments.\n", argv[0]);
|
||||
env->vars = my_setenv(env->vars, "?", "1");
|
||||
return (0);
|
||||
}
|
||||
if (file_is_accessible(argv[1]))
|
||||
start_script(argv, env, len);
|
||||
else
|
||||
env->vars = my_setenv(env->vars, "?", "1");
|
||||
return (0);
|
||||
}
|
||||
@@ -5,76 +5,34 @@
|
||||
** second part of the source function
|
||||
*/
|
||||
|
||||
#include "shell.h"
|
||||
#include "utility.h"
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
int count_char_in_str(char *str, char c)
|
||||
void init_source_args(char **argv, int len_argv, env_t *env)
|
||||
{
|
||||
int res = 0;
|
||||
char *str = NULL;
|
||||
|
||||
for (int i = 0; str[i]; i++)
|
||||
if (str[i] == c)
|
||||
res++;
|
||||
return (res);
|
||||
}
|
||||
|
||||
static char *get_str_arg(int arg_index, char **argv)
|
||||
{
|
||||
if (arg_index == 0)
|
||||
return ("42sh");
|
||||
return (argv[arg_index + 1]);
|
||||
}
|
||||
|
||||
static int get_max_args_len(char **argv)
|
||||
{
|
||||
int max_len = 4;
|
||||
int len = 0;
|
||||
|
||||
for (int i = 2; argv[i]; i++) {
|
||||
len = strlen(argv[i]);
|
||||
if (len > max_len)
|
||||
max_len = len;
|
||||
env->vars = my_setenv(env->vars, "#", tostr(len_argv - 2));
|
||||
for (int i = 1; i < len_argv - 1; i++) {
|
||||
str = tostr(i);
|
||||
env->vars = my_setenv(env->vars, str, strdup(argv[i + 1]));
|
||||
free(str);
|
||||
}
|
||||
return (max_len);
|
||||
}
|
||||
|
||||
void fill_parsed_str(char *result, char *cmd, char **argv, int len_argv)
|
||||
void reset_source_args(int len_argv, env_t *env)
|
||||
{
|
||||
int counter = 0;
|
||||
int argv_index = 0;
|
||||
char *str_arg = NULL;
|
||||
char *str = NULL;
|
||||
|
||||
for (int i = 0; cmd[i]; i++) {
|
||||
if (cmd[i] == '$') {
|
||||
if (!cmd[i + 1])
|
||||
break;
|
||||
argv_index = atoi(&cmd[i + 1]);
|
||||
if (argv_index <= len_argv - 2 && isdigit(cmd[i + 1])) {
|
||||
str_arg = get_str_arg(argv_index, argv);
|
||||
for (int j = 0; str_arg[j]; j++)
|
||||
result[counter++] = str_arg[j];
|
||||
}
|
||||
i++;
|
||||
}
|
||||
else
|
||||
result[counter++] = cmd[i];
|
||||
env->vars = my_unsetenv(env->vars, "#");
|
||||
for (int i = 1; i < len_argv - 1; i++) {
|
||||
str = tostr(i);
|
||||
env->vars = my_unsetenv(env->vars, str);
|
||||
free(str);
|
||||
}
|
||||
result[counter] = '\0';
|
||||
}
|
||||
|
||||
char *parse_source_cmd(char *cmd, char **argv, int len_argv)
|
||||
{
|
||||
char *result = NULL;
|
||||
int max_arg_len = get_max_args_len(argv);
|
||||
int max_parsed_str_len = strlen(cmd) +
|
||||
(max_arg_len * count_char_in_str(cmd, '$'));
|
||||
|
||||
result = malloc(sizeof(char) * (max_parsed_str_len + 1));
|
||||
if (!result)
|
||||
return (NULL);
|
||||
fill_parsed_str(result, cmd, argv, len_argv);
|
||||
return (result);
|
||||
}
|
||||
+5
-3
@@ -5,6 +5,7 @@
|
||||
** main
|
||||
*/
|
||||
|
||||
#include "builtin.h"
|
||||
#include "shell.h"
|
||||
#include "key_functions.h"
|
||||
#include <stdlib.h>
|
||||
@@ -38,9 +39,10 @@ int main(int argc, char **argv, char **env)
|
||||
|
||||
if (!envt)
|
||||
return (ERROR);
|
||||
start_shell(envt);
|
||||
(void)argc;
|
||||
(void)argv;
|
||||
if (argc >= 2)
|
||||
builtin_source(argv, envt);
|
||||
else
|
||||
start_shell(envt);
|
||||
ret = get_return(my_getenv(envt->vars, "?"));
|
||||
free_env(envt);
|
||||
return (ret);
|
||||
|
||||
Reference in New Issue
Block a user