mirror of
https://github.com/Savapitech/42sh.git
synced 2026-03-18 21:50:35 +01:00
[ADD] history parsing command
This commit is contained in:
103
src/builtin_history.c
Normal file
103
src/builtin_history.c
Normal file
@@ -0,0 +1,103 @@
|
||||
/*
|
||||
** EPITECH PROJECT, 2025
|
||||
** history_42sh
|
||||
** File description:
|
||||
** builtin_history
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "history.h"
|
||||
|
||||
/*
|
||||
**Il faut deux \0 parce que dans le gettokeniser
|
||||
** y un truc qui regarde
|
||||
**après le premier \0
|
||||
*/
|
||||
|
||||
/*
|
||||
**cat in str prend un
|
||||
** his_variable_t en
|
||||
** parametre pour
|
||||
** connaitre la coord
|
||||
** d' ou commencer a concaténer
|
||||
** mais aussi le nombre de charactère a retiré
|
||||
** il vas free le buffer
|
||||
*/
|
||||
|
||||
static
|
||||
char *cat_in_str()
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
char *his_last_command(char *line, his_variable_t *his_variable, his_command_t *his_command)
|
||||
{
|
||||
char *new_line = malloc(sizeof(char) * 10);
|
||||
|
||||
if (new_line == NULL)
|
||||
return NULL;
|
||||
new_line[0] = 'l';
|
||||
new_line[1] = 's';
|
||||
new_line[2] = '\0';
|
||||
new_line[3] = '\0';
|
||||
free(line);
|
||||
return new_line;
|
||||
}
|
||||
|
||||
char *his_last_same_command(char *line, his_variable_t *his_variable, his_command_t *his_command)
|
||||
{
|
||||
char *new_line = malloc(sizeof(char) * 10);
|
||||
|
||||
if (new_line == NULL)
|
||||
return NULL;
|
||||
new_line[0] = 'l';
|
||||
new_line[1] = 's';
|
||||
new_line[2] = '\0';
|
||||
new_line[3] = '\0';
|
||||
free(line);
|
||||
return new_line;
|
||||
}
|
||||
|
||||
char *his_id_command(char *line, his_variable_t *his_variable, his_command_t *his_command)
|
||||
{
|
||||
char *new_line = malloc(sizeof(char) * 10);
|
||||
|
||||
if (new_line == NULL)
|
||||
return NULL;
|
||||
new_line[0] = 'l';
|
||||
new_line[1] = 's';
|
||||
new_line[2] = '\0';
|
||||
new_line[3] = '\0';
|
||||
free(line);
|
||||
return new_line;
|
||||
}
|
||||
|
||||
char *his_last_word(char *line, his_variable_t *his_variable, his_command_t *his_command)
|
||||
{
|
||||
char *new_line = malloc(sizeof(char) * 10);
|
||||
|
||||
if (new_line == NULL)
|
||||
return NULL;
|
||||
new_line[0] = 'l';
|
||||
new_line[1] = 's';
|
||||
new_line[2] = '\0';
|
||||
new_line[3] = '\0';
|
||||
free(line);
|
||||
return new_line;
|
||||
}
|
||||
|
||||
char *his_last_arg(char *line, his_variable_t *his_variable, his_command_t *his_command)
|
||||
{
|
||||
char *new_line = malloc(sizeof(char) * 10);
|
||||
|
||||
if (new_line == NULL)
|
||||
return NULL;
|
||||
new_line[0] = 'l';
|
||||
new_line[1] = 's';
|
||||
new_line[2] = '\0';
|
||||
new_line[3] = '\0';
|
||||
free(line);
|
||||
return new_line;
|
||||
}
|
||||
43
src/history.h
Normal file
43
src/history.h
Normal file
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
** EPITECH PROJECT, 2025
|
||||
** __
|
||||
** File description:
|
||||
** _
|
||||
*/
|
||||
|
||||
#ifndef HISTORY_H
|
||||
#define HISTORY_H
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#define CHAR_HIST '!'
|
||||
#define TWO_CHAR_CMD 3
|
||||
|
||||
typedef struct history_variable_s {
|
||||
int coord_variable;
|
||||
int size_variable;
|
||||
int type;
|
||||
} his_variable_t;
|
||||
|
||||
typedef struct history_command_s {
|
||||
int id;
|
||||
char time[5];// []h[]
|
||||
char *command;
|
||||
char *arg;
|
||||
int sz;
|
||||
} his_command_t;
|
||||
|
||||
typedef struct parsing_history_s {
|
||||
char *name;
|
||||
char *(*funct)(char *, his_variable_t *, his_command_t *);
|
||||
} parsing_history_t;
|
||||
|
||||
char *parse_history(char *line, size_t *buffer);
|
||||
char *his_last_command(char *line, his_variable_t *his_variable, his_command_t *his_command);
|
||||
char *his_last_same_command(char *line, his_variable_t *his_variable, his_command_t *his_command);
|
||||
char *his_id_command(char *line, his_variable_t *his_variable, his_command_t *his_command);
|
||||
char *his_last_word(char *line, his_variable_t *his_variable, his_command_t *his_command);
|
||||
char *his_last_arg(char *line, his_variable_t *his_variable, his_command_t *his_command);
|
||||
#endif /* HISTORY_H */
|
||||
|
||||
|
||||
98
src/parse_history.c
Normal file
98
src/parse_history.c
Normal file
@@ -0,0 +1,98 @@
|
||||
/*
|
||||
** EPITECH PROJECT, 2025
|
||||
** history_42sh
|
||||
** File description:
|
||||
** his for history
|
||||
*/
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "common.h"
|
||||
#include "env.h"
|
||||
#include "exec.h"
|
||||
#include "u_mem.h"
|
||||
#include "u_str.h"
|
||||
#include "history.h"
|
||||
|
||||
const parsing_history_t tab_fnct[] = {
|
||||
{"!!", &his_last_command},//last command
|
||||
{"!$", &his_last_word},//last word command
|
||||
{"!*", &his_last_arg},//last argument commmand
|
||||
{"![command]", &his_last_same_command},//derniere commande + arg sur la derniere meme command dans l historique dans le cas ou il n y a qu un charactère il prend le dernier qui commence par la meme chaine
|
||||
{"![number]", &his_id_command},//id command
|
||||
{NULL, NULL},
|
||||
};
|
||||
|
||||
static
|
||||
int cmd_history_is_in(char *line)
|
||||
{
|
||||
for (int i = 0; line[i] != 0; i++)
|
||||
if (line[i] == CHAR_HIST &&
|
||||
(line[i + 1] != ' ' && line[i + 1] != '\t'))
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static
|
||||
int is_two_char_cmd(char *line, int coord_x)
|
||||
{
|
||||
if (line[coord_x] != CHAR_HIST)
|
||||
return -1;
|
||||
coord_x++;
|
||||
switch (line[coord_x]){
|
||||
case '!':
|
||||
return 0;
|
||||
case '$':
|
||||
return 1;
|
||||
case '*':
|
||||
return 2;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
static
|
||||
int which_his_cmd(his_variable_t *his_variable, char *line)
|
||||
{
|
||||
for (int i = 0; line[i] != '\0' ; i++){
|
||||
his_variable->type = is_two_char_cmd(line, i);
|
||||
if (his_variable->type != -1){
|
||||
his_variable->coord_variable = i;
|
||||
his_variable->size_variable = 2;
|
||||
printf("command find; %s\n", tab_fnct[his_variable->type].name);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static
|
||||
char *replace_history(char *line)
|
||||
{
|
||||
his_variable_t his_variable = {0, 0, -1};
|
||||
|
||||
which_his_cmd(&his_variable, line);
|
||||
while(his_variable.type != -1){
|
||||
line = tab_fnct[his_variable.type].funct(line, &his_variable, NULL);
|
||||
if (line == NULL)
|
||||
return NULL;
|
||||
which_his_cmd(&his_variable, line);
|
||||
}
|
||||
return line;
|
||||
}
|
||||
|
||||
char *parse_history(char *line, size_t *buffer_len)//Faire passer une structure avec l historique
|
||||
{
|
||||
if (cmd_history_is_in(line) == 0){
|
||||
line = replace_history(line);
|
||||
if (line == NULL)
|
||||
return NULL;
|
||||
*buffer_len = u_strlen(line) + 1;
|
||||
printf("FIND ! |%s| in line\n-------------\n", line);
|
||||
return line;
|
||||
}
|
||||
printf("PARSING HIS; %s try to find : %c\n", line, CHAR_HIST);
|
||||
return line;
|
||||
}
|
||||
@@ -17,6 +17,7 @@
|
||||
#include "env.h"
|
||||
#include "shell.h"
|
||||
#include "u_str.h"
|
||||
#include "history.h"
|
||||
|
||||
__attribute__((unused))
|
||||
static
|
||||
@@ -55,20 +56,21 @@ int shell_loop(env_t *env, int is_a_tty, history_t *history)
|
||||
while (true) {
|
||||
if (is_a_tty)
|
||||
WRITE_CONST(STDOUT_FILENO, SHELL_PROMPT);
|
||||
if (getline(&buffer, &buffer_sz, stdin) == -1)
|
||||
if (getline(&buffer, &buffer_sz, stdin) == -1)//passer la ligne 59 a 63 dans une fonction
|
||||
break;
|
||||
buffer_len = u_strlen(buffer);
|
||||
buffer = parse_history(buffer, &buffer_len);
|
||||
if (buffer_len < 2 || !u_str_is_alnum(buffer)) {
|
||||
check_basic_error(buffer);
|
||||
continue;
|
||||
}
|
||||
/*SAVE COMMAND pour evité le cas !4 !3*/
|
||||
buffer[buffer_len - 1] = '\0';
|
||||
U_DEBUG("Buffer [%lu] [%s]\n", buffer_len, buffer);
|
||||
visitor(buffer, env, history);
|
||||
}
|
||||
return (free(buffer), history->last_exit_code);
|
||||
}
|
||||
|
||||
int shell(char **env_ptr)
|
||||
{
|
||||
env_t env = parse_env(env_ptr);
|
||||
|
||||
Reference in New Issue
Block a user