mirror of
https://github.com/zoriya/ash.git
synced 2026-06-08 04:30:47 +00:00
Merging master into parser
This commit is contained in:
@@ -50,7 +50,8 @@ SRC = src/shell.c \
|
|||||||
src/key_bindings/move_commands.c \
|
src/key_bindings/move_commands.c \
|
||||||
src/my_ncurses/my_ncurses.c \
|
src/my_ncurses/my_ncurses.c \
|
||||||
src/my_ncurses/string_utils.c \
|
src/my_ncurses/string_utils.c \
|
||||||
src/my_ncurses/pause_utils.c
|
src/my_ncurses/pause_utils.c \
|
||||||
|
src/key_bindings/autocompletion.c
|
||||||
|
|
||||||
OBJ = $(SRC:%.c=%.o)
|
OBJ = $(SRC:%.c=%.o)
|
||||||
OBJ += src/main.o
|
OBJ += src/main.o
|
||||||
|
|||||||
+2
-1
@@ -29,12 +29,13 @@ int builtin_history(char **args, env_t *env);
|
|||||||
int builtin_alias(char **args, env_t *env);
|
int builtin_alias(char **args, env_t *env);
|
||||||
int builtin_unalias(char **args, env_t *env);
|
int builtin_unalias(char **args, env_t *env);
|
||||||
int builtin_echo(char **args, env_t *env);
|
int builtin_echo(char **args, env_t *env);
|
||||||
//utility
|
//which / where
|
||||||
bool find_path_in_builtins(char *cmd);
|
bool find_path_in_builtins(char *cmd);
|
||||||
char **get_envpath(env_t *env);
|
char **get_envpath(env_t *env);
|
||||||
char *check_executable(char *cmd, char *folder);
|
char *check_executable(char *cmd, char *folder);
|
||||||
char **get_paths_from_envpath(char *cmd, char **envpath);
|
char **get_paths_from_envpath(char *cmd, char **envpath);
|
||||||
char **get_envpath(env_t *env);
|
char **get_envpath(env_t *env);
|
||||||
|
void fill_path_arr(char *cmd, char **envpath, char **res);
|
||||||
//history
|
//history
|
||||||
int add_to_history(char *cmd, env_t *env);
|
int add_to_history(char *cmd, env_t *env);
|
||||||
int show_history(env_t *env);
|
int show_history(env_t *env);
|
||||||
|
|||||||
@@ -41,3 +41,5 @@ int end_of_line_command(int key, buffer_t *buffer, env_t *env);
|
|||||||
|
|
||||||
int up_history_command(int key, buffer_t *buffer, env_t *env);
|
int up_history_command(int key, buffer_t *buffer, env_t *env);
|
||||||
int down_history_command(int key, buffer_t *buffer, env_t *env);
|
int down_history_command(int key, buffer_t *buffer, env_t *env);
|
||||||
|
|
||||||
|
int complete_command(int key, buffer_t *buffer, env_t *env);
|
||||||
+3
-1
@@ -28,4 +28,6 @@ int ncount_char(const char *str, int end, char c);
|
|||||||
int get_max_eof(char *ignoreeof);
|
int get_max_eof(char *ignoreeof);
|
||||||
int skip_eof(buffer_t *buffer, env_t *env);
|
int skip_eof(buffer_t *buffer, env_t *env);
|
||||||
int count_trailing_spaces(char *cmd);
|
int count_trailing_spaces(char *cmd);
|
||||||
char **remove_leading_entries(char **cmds);
|
char **remove_leading_entries(char **cmds);
|
||||||
|
|
||||||
|
#define MAX(x, y) ((x) < (y) ? (y) : (x))
|
||||||
|
|||||||
+88
@@ -0,0 +1,88 @@
|
|||||||
|
/*
|
||||||
|
** EPITECH PROJECT, 2020
|
||||||
|
** alias.c
|
||||||
|
** File description:
|
||||||
|
** alias
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "shell.h"
|
||||||
|
#include "builtin.h"
|
||||||
|
#include "utility.h"
|
||||||
|
#include <unistd.h>
|
||||||
|
#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; i == 0; 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, 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);
|
||||||
|
}
|
||||||
+17
-17
@@ -15,9 +15,18 @@
|
|||||||
#include "utility.h"
|
#include "utility.h"
|
||||||
#include "shell.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)
|
char *check_executable(char *cmd, char *folder)
|
||||||
{
|
{
|
||||||
struct stat st_buff;
|
struct stat st_buff = {};
|
||||||
char *path = catpath(folder, cmd);
|
char *path = catpath(folder, cmd);
|
||||||
char *res = path;
|
char *res = path;
|
||||||
|
|
||||||
@@ -58,23 +67,14 @@ void fill_path_arr(char *cmd, char **envpath, char **res)
|
|||||||
res[counter] = NULL;
|
res[counter] = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
char **get_paths_from_envpath(char *cmd, char **envpath)
|
void print_path_no_stop(char *cmd, char **envpath, env_t *env)
|
||||||
{
|
|
||||||
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)
|
|
||||||
{
|
{
|
||||||
|
char *dup_cmd = strdup(cmd);
|
||||||
char **paths = NULL;
|
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);
|
find_path_in_builtins(cmd);
|
||||||
if (!envpath)
|
if (!envpath)
|
||||||
return;
|
return;
|
||||||
@@ -101,7 +101,7 @@ int builtin_where(char **argv, env_t *env)
|
|||||||
if (strchr(argv[i], '/'))
|
if (strchr(argv[i], '/'))
|
||||||
printf("where: / in command makes no sense\n");
|
printf("where: / in command makes no sense\n");
|
||||||
else
|
else
|
||||||
print_path_no_stop(argv[i], envpath);
|
print_path_no_stop(argv[i], envpath, env);
|
||||||
}
|
}
|
||||||
free(envpath);
|
free(envpath);
|
||||||
return (0);
|
return (0);
|
||||||
|
|||||||
@@ -12,6 +12,28 @@
|
|||||||
#include "utility.h"
|
#include "utility.h"
|
||||||
#include "builtin.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)
|
bool find_path_in_builtins(char *cmd)
|
||||||
{
|
{
|
||||||
extern const builtin builtins[];
|
extern const builtin builtins[];
|
||||||
@@ -24,11 +46,17 @@ bool find_path_in_builtins(char *cmd)
|
|||||||
return (false);
|
return (false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void print_path(char *cmd, char **envpath)
|
void print_path(char *cmd, char **envpath, env_t *env)
|
||||||
{
|
{
|
||||||
char **res = NULL;
|
char **res = NULL;
|
||||||
|
char *dup_cmd = strdup(cmd);
|
||||||
int len = 0;
|
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))
|
if (find_path_in_builtins(cmd))
|
||||||
return;
|
return;
|
||||||
res = get_paths_from_envpath(cmd, envpath);
|
res = get_paths_from_envpath(cmd, envpath);
|
||||||
@@ -52,7 +80,7 @@ int builtin_which(char **argv, env_t *env)
|
|||||||
}
|
}
|
||||||
envpath = get_envpath(env);
|
envpath = get_envpath(env);
|
||||||
for (int i = 1; argv[i]; i++)
|
for (int i = 1; argv[i]; i++)
|
||||||
print_path(argv[i], envpath);
|
print_path(argv[i], envpath, env);
|
||||||
free(envpath);
|
free(envpath);
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
-44
@@ -1,44 +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[0]);
|
|
||||||
return (NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
char **globbing(char **argv)
|
|
||||||
{
|
|
||||||
static glob_t results;
|
|
||||||
int flags = GLOB_DOOFFS | GLOB_NOMAGIC | GLOB_NOCHECK;
|
|
||||||
int ret = 0;
|
|
||||||
|
|
||||||
if (!argv)
|
|
||||||
return (NULL);
|
|
||||||
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,105 @@
|
|||||||
|
/*
|
||||||
|
** EPITECH PROJECT, 2020
|
||||||
|
** ash
|
||||||
|
** File description:
|
||||||
|
** autocompletion
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define _GNU_SOURCE
|
||||||
|
#include "shell.h"
|
||||||
|
#include "utility.h"
|
||||||
|
#include <glob.h>
|
||||||
|
#include <malloc.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
char *get_start_of_current_arg(buffer_t *buffer)
|
||||||
|
{
|
||||||
|
char *p;
|
||||||
|
|
||||||
|
if (!buffer->buffer)
|
||||||
|
return (NULL);
|
||||||
|
p = memrchr(buffer->buffer, ' ', buffer->pos);
|
||||||
|
if (!p)
|
||||||
|
return (NULL);
|
||||||
|
return (p + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void print_results(my_window *window, unsigned count, char **results)
|
||||||
|
{
|
||||||
|
unsigned size = 0;
|
||||||
|
int per_line;
|
||||||
|
int prefix_length = 0;
|
||||||
|
char *p = memrchr(results[0], '/', strlen(results[0]) - 1);
|
||||||
|
|
||||||
|
if (p)
|
||||||
|
prefix_length = p - results[0] + 1;
|
||||||
|
putchar('\n');
|
||||||
|
my_clrtobot();
|
||||||
|
for (unsigned i = 0; i < count; i++)
|
||||||
|
size = MAX(size, strlen(results[i]) - prefix_length);
|
||||||
|
size++;
|
||||||
|
per_line = window->w / size;
|
||||||
|
for (unsigned i = 0; i < count; i += per_line) {
|
||||||
|
for (int j = 0; j < per_line && i + j < count; j++)
|
||||||
|
printf("%-*s", size, results[i + j] + prefix_length);
|
||||||
|
putchar('\n');
|
||||||
|
}
|
||||||
|
window->y -= MAX(0, (window->y + ((int)count / per_line) + 3 - window->h));
|
||||||
|
}
|
||||||
|
|
||||||
|
void buffer_replace(buffer_t *buffer, char *to_replace, int start, int end)
|
||||||
|
{
|
||||||
|
int len = strlen(to_replace);
|
||||||
|
int total = len + (buffer->buffer ? strlen(buffer->buffer) : 0);
|
||||||
|
|
||||||
|
if (buffer->size < total) {
|
||||||
|
buffer->buffer = realloc(buffer->buffer, total + 50);
|
||||||
|
buffer->size = total + 50;
|
||||||
|
}
|
||||||
|
if (!buffer->buffer)
|
||||||
|
return;
|
||||||
|
for (int i = strlen(buffer->buffer); i >= end; i--)
|
||||||
|
buffer->buffer[i + len - 1] = buffer->buffer[i];
|
||||||
|
memcpy(buffer->buffer + start, to_replace, len);
|
||||||
|
buffer->buffer[total - (end - start)] = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
void complete_current(buffer_t *buffer, char *cmd)
|
||||||
|
{
|
||||||
|
char *start = get_start_of_current_arg(buffer);
|
||||||
|
char *end;
|
||||||
|
|
||||||
|
if (!start)
|
||||||
|
return;
|
||||||
|
end = strchr(start, ' ');
|
||||||
|
if (!end)
|
||||||
|
end = buffer->buffer + strlen(buffer->buffer);
|
||||||
|
buffer_replace(buffer, cmd, start - buffer->buffer, end - buffer->buffer);
|
||||||
|
buffer->pos = start - buffer->buffer + strlen(cmd);
|
||||||
|
}
|
||||||
|
|
||||||
|
int complete_command(int key, buffer_t *buffer, env_t *env)
|
||||||
|
{
|
||||||
|
char *str;
|
||||||
|
char *p = get_start_of_current_arg(buffer);
|
||||||
|
glob_t result;
|
||||||
|
|
||||||
|
if (!buffer->buffer || !p)
|
||||||
|
return (0);
|
||||||
|
str = malloc(buffer->pos - (p - buffer->buffer) + 2);
|
||||||
|
if (!str)
|
||||||
|
return (0);
|
||||||
|
strncpy(str, p, buffer->pos - (p - buffer->buffer));
|
||||||
|
str[buffer->pos - (p - buffer->buffer)] = '\0';
|
||||||
|
strcat(str, "*");
|
||||||
|
if (!glob(str, GLOB_MARK | GLOB_BRACE, NULL, &result)) {
|
||||||
|
if (result.gl_pathc == 1)
|
||||||
|
complete_current(buffer, result.gl_pathv[0]);
|
||||||
|
else
|
||||||
|
print_results(env->window, result.gl_pathc, result.gl_pathv);
|
||||||
|
}
|
||||||
|
globfree(&result);
|
||||||
|
free(str);
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
@@ -20,6 +20,8 @@ const key_function_t key_functions[] = {
|
|||||||
{"forward-char", &forward_char_command},
|
{"forward-char", &forward_char_command},
|
||||||
{"beginning-of-line", &beginning_of_line_command},
|
{"beginning-of-line", &beginning_of_line_command},
|
||||||
{"end-of-line", &end_of_line_command},
|
{"end-of-line", &end_of_line_command},
|
||||||
|
{"up-history", &up_history_command},
|
||||||
|
{"down-history", &down_history_command},
|
||||||
{NULL, NULL}
|
{NULL, NULL}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -35,5 +37,6 @@ const binding_t emacs_bindings[] = {
|
|||||||
{KEY_END, &end_of_line_command},
|
{KEY_END, &end_of_line_command},
|
||||||
{KEY_UP, &up_history_command},
|
{KEY_UP, &up_history_command},
|
||||||
{KEY_DOWN, &down_history_command},
|
{KEY_DOWN, &down_history_command},
|
||||||
|
{'\t', &complete_command},
|
||||||
{0, NULL}
|
{0, NULL}
|
||||||
};
|
};
|
||||||
@@ -19,6 +19,7 @@ void on_resize(int sig, siginfo_t *info, void *context)
|
|||||||
{
|
{
|
||||||
my_getmaxyx(&stdwin->h, &stdwin->w);
|
my_getmaxyx(&stdwin->h, &stdwin->w);
|
||||||
my_getcuryx(&stdwin->y, &stdwin->x);
|
my_getcuryx(&stdwin->y, &stdwin->x);
|
||||||
|
my_clrtobot();
|
||||||
}
|
}
|
||||||
|
|
||||||
my_window *my_initwin(void)
|
my_window *my_initwin(void)
|
||||||
|
|||||||
+2
-1
@@ -23,6 +23,7 @@ int process_key(int key, buffer_t *buffer, env_t *env)
|
|||||||
{
|
{
|
||||||
if (key <= 0)
|
if (key <= 0)
|
||||||
return (0);
|
return (0);
|
||||||
|
my_clrtobot();
|
||||||
for (int i = 0; env->bindings[i].func; i++)
|
for (int i = 0; env->bindings[i].func; i++)
|
||||||
if (key == env->bindings[i].key)
|
if (key == env->bindings[i].key)
|
||||||
return (env->bindings[i].func(key, buffer, env));
|
return (env->bindings[i].func(key, buffer, env));
|
||||||
@@ -57,7 +58,7 @@ void shell_refresh(buffer_t *buffer, env_t *env)
|
|||||||
|
|
||||||
if (buffer->buffer)
|
if (buffer->buffer)
|
||||||
my_mvaddstr(env->window, y, buffer->startx, buffer->buffer);
|
my_mvaddstr(env->window, y, buffer->startx, buffer->buffer);
|
||||||
my_clrtobot();
|
my_clrtoeol();
|
||||||
my_move(env->window, newy, buf_getx(buffer, env));
|
my_move(env->window, newy, buf_getx(buffer, env));
|
||||||
my_refresh();
|
my_refresh();
|
||||||
oldbuffer_pos = buffer->pos;
|
oldbuffer_pos = buffer->pos;
|
||||||
|
|||||||
@@ -28,7 +28,6 @@ char **get_envpath(env_t *env)
|
|||||||
if (pathstr) {
|
if (pathstr) {
|
||||||
path_cpy = strdup(pathstr);
|
path_cpy = strdup(pathstr);
|
||||||
envpath = to_array(path_cpy);
|
envpath = to_array(path_cpy);
|
||||||
free(path_cpy);
|
|
||||||
}
|
}
|
||||||
return (envpath);
|
return (envpath);
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user