Skip to content

Commit

Permalink
Merge branch 'Dev' of git.epitech.eu:/florent.poinsard@epitech.eu/PSU…
Browse files Browse the repository at this point in the history
…_42sh_2017 into Dev
  • Loading branch information
frouioui committed May 25, 2018
2 parents b7f2fc7 + 2fd24f8 commit f01f628
Show file tree
Hide file tree
Showing 26 changed files with 786 additions and 16 deletions.
14 changes: 14 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,13 @@ SRCS = $(PATH_SRC)/check_args.c \
$(PATH_SRC)/shell_loop/execution/display_error_instruction.c \
$(PATH_SRC)/shell_loop/execution/redirect_stdin_double.c \
$(PATH_SRC)/shell_loop/execution/condition_instruction.c \
$(PATH_SRC)/scripting/check_script.c \
$(PATH_SRC)/scripting/fill_condition_script.c \
$(PATH_SRC)/scripting/get_valid_line_script.c \
$(PATH_SRC)/scripting/init_condition_script.c \
$(PATH_SRC)/scripting/keywords_script.c \
$(PATH_SRC)/scripting/open_script.c \
$(PATH_SRC)/scripting/run_script.c \

SRC_MAIN = $(PATH_SRC)/main.c

Expand Down Expand Up @@ -156,6 +163,13 @@ SRCS_TEST = $(PATH_TEST)/shell/check_args_test.c \
$(PATH_TEST)/execution/env_built_test.c \
$(PATH_TEST)/execution/roll_back_path_test.c \
$(PATH_TEST)/execution/alias_built_test.c \
$(PATH_TEST)/scripting/script_name_test.c \
$(PATH_TEST)/scripting/script_access_test.c \
$(PATH_TEST)/scripting/script_shebang_test.c \
$(PATH_TEST)/scripting/script_fill_cond_test.c \
$(PATH_TEST)/scripting/script_if_keyword_test.c \
$(PATH_TEST)/scripting/script_no_keyword_test.c \
$(PATH_TEST)/scripting/script_other_keyword_test.c \

## ---- FLAGS ---- ##

Expand Down
57 changes: 57 additions & 0 deletions include/script.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
/*
** EPITECH PROJECT, 2018
** PSU_42sh_2017
** File description:
** Include file of the scripting functions
*/

#ifndef SCRIPTING_H
#define SCRIPTING_H

#include <stdbool.h>
#include <stdlib.h>
#include <stdio.h>
#include "shell.h"

#define SH_CHAR(c) (c == '.' || c == 's' || c == 'h')
#define NB_COND (6)

/* -- Structures definition --- */
typedef enum keyword_e {
EMPTY,
IF,
ELSE,
ELSIF,
WHILE,
FOREACH,
WHICH,
WHERE
} keyword_t;

typedef struct cond_script_s {
keyword_t key;
char *condition;
char *command;
bool end;
} cond_t;

/* --- Check script file --- */
bool check_script(char *);
bool check_script_access(char *);
bool check_script_name(char *);
bool check_script_shebang(char *);

/* --- Script running --- */
char *get_valid_line(FILE *, shell_t *);
char *run_script(shell_t *, FILE *);
FILE *open_script(char *, shell_t *);
bool fill_cond(cond_t *, char *, char **);
int search_keyword(cond_t *, char *);

/* --- Initialization --- */
cond_t *init_conditional_line(void);

/* -- Resources destruction --- */
void free_cond_line(cond_t *);

#endif /* !CRIPTING_H */
8 changes: 6 additions & 2 deletions include/shell.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,20 +66,24 @@ typedef struct shell_s {
terminal_t terminal;
bool bonus;
bool prompt;
bool script;
} shell_t;

char **copy_environement(char **);
shell_t *initialisation_shell(int, char **, char **);
char **copy_environement(char **);
backup_t *initialisation_backup(char **);
void free_array_string(char **);
void display_bonus_prompt(int, char *, char *, char *);
void update_backup(shell_t *);
bool init_terminal(shell_t *);
bool is_bonus(int, char **);
int display_prompt(shell_t *);
int check_args(int);
int check_args(int, char **);
int destroy_shell(shell_t *);
int find_option_env(char **, char *);
int find_separator_env(char *);
unsigned int shell_loop(shell_t *);
unsigned int shell_loop(shell_t *, FILE *);
unsigned int redirect_loop(shell_t *, char *, char *);
char **init_local(void);

Expand Down
7 changes: 6 additions & 1 deletion src/check_args.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,17 @@

#include "shell.h"
#include "mylib.h"
#include "script.h"

int check_args(int argc)
int check_args(int argc, char **argv)
{
if (argc != 1 && argc != 2) {
my_putstr("You must give 0 arguments to the program.\n");
return (FAILURE);
}
if (argc == 2 && !check_script(argv[1])) {
my_putstr("The given argument must be a valid script\n");
return (FAILURE);
}
return (SUCCESS);
}
1 change: 1 addition & 0 deletions src/initialisation_shell/initialisation_shell.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ shell_t *initialisation_shell(int argc, char **argv, char **env)
if (shell->env == NULL)
return (NULL);
shell->bonus = true;
shell->script = false;
shell->command_line = NULL;
shell->code = 0;
shell->prompt = true;
Expand Down
7 changes: 5 additions & 2 deletions src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,20 @@

#include <stdlib.h>
#include "shell.h"
#include "script.h"

int main(int argc, char **argv, char **env)
{
shell_t *shell = NULL;
FILE *fd = NULL;

if (check_args(argc) == FAILURE)
if (check_args(argc, argv) == FAILURE)
return (FAILURE);
shell = initialisation_shell(argc, argv, env);
if (shell == NULL)
return (FAILURE);
if (shell_loop(shell) == FAILURE)
fd = open_script(argv[1], shell);
if (shell_loop(shell, fd) == FAILURE)
return (FAILURE);
return (destroy_shell(shell));
}
77 changes: 77 additions & 0 deletions src/scripting/check_script.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
/*
** EPITECH PROJECT, 2018
** PSU_42sh_2017
** File description:
** Check script file
*/

#include "script.h"
#include <unistd.h>
#include <string.h>

bool check_script_shebang(char *path)
{
FILE *fd = fopen(path, "r");
size_t n = 0;
char *buf = NULL;
bool status = false;

if (!fd)
return (false);
if (getline(&buf, &n, fd) == -1)
status = false;
else if (buf && !strncmp(buf, "#!", 2))
status = true;
if (buf)
free(buf);
fclose(fd);
return (status);
}

bool check_script_name(char *path)
{
char *tmp = malloc(sizeof(*tmp) * (strlen(path) + 1));
int j = 0;

if (!tmp)
return (false);
for (int i = strlen(path) - 1; SH_CHAR(path[i]) && j < 3; i -= 1) {
tmp[j] = path[i];
j += 1;
}
tmp[j] = '\0';
if (!strcmp(tmp, "hs.")) {
free(tmp);
return (true);
}
free(tmp);
return (false);
}

bool check_script_access(char *path)
{
if (access(path, R_OK) == -1) {
write(1, path, strlen(path));
write(1, ": Command not found.\n", 21);
return (false);
}
else if (access(path, X_OK) == -1) {
write(1, path, strlen(path));
write(1, ": Permission denied.\n", 21);
return (false);
}
return (true);
}

bool check_script(char *path)
{
if (!path)
return (false);
if (!check_script_name(path))
return (false);
if (!check_script_access(path))
return (false);
if (!check_script_shebang(path))
return (false);
return (true);
}
96 changes: 96 additions & 0 deletions src/scripting/fill_condition_script.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
/*
** EPITECH PROJECT, 2018
** PSU_42sh_2017
** File description:
** Conditional structure initialization
*/

#include "script.h"

static bool copy_command(cond_t *cond, char *line)
{
int start = 0;

for (int i = 0; line[i] != '\0'; i += 1)
if (line[i] == ')')
start = i;
if (line[start + 1] == '\0') {
if (cond->key == IF || cond->key == ELSIF) {
puts("if: Empty if.");
return (false);
}
else if (cond->key == ELSE)
return (true);
}
cond->command = malloc(sizeof(char) * (strlen(line) - start));
if (!cond->command)
return (false);
for (int i = start + 1, j = 0; line[i] != '\0'; i += 1, j += 1)
cond->command[j] = line[i];
cond->command[strlen(line) - start - 1] = '\0';
return (true);
}

static bool search_then(cond_t *cond, char *line, char **words_array)
{
bool then_exist = false;

for (int i = 0; words_array[i]; i += 1)
if (!strcmp(words_array[i], "then"))
then_exist = true;
if (!then_exist && cond->key != ELSE)
cond->end = true;
if (!then_exist || cond->key == ELSE)
if (copy_command(cond, line) != true)
return (false);
return (true);
}

static bool copy_condition(cond_t *cond, char *line, int start, int end)
{
char **words_array = cut_line(line);

cond->condition = malloc(sizeof(char) * (end - start));
if (!cond->condition || !words_array)
return (false);
for (int i = start + 1, j = 0;i < end; i += 1, j += 1)
cond->condition[j] = line[i];
cond->condition[end - start - 1] = '\0';
if (cond->key != IF && cond->key != ELSIF && cond->key != ELSE)
if (line[end + 1] != '\0') {
my_putstr(words_array[0]);
puts(": Expression Syntax.");
free_array_string(words_array);
return (false);
}
free_array_string(words_array);
return (true);
}

static bool check_condition(cond_t *cond, char *line)
{
int open_bracket = 0;
int close_bracket = 0;

for (int i = 0; line[i] != '\0'; i += 1) {
if (line[i] == '(')
open_bracket = i;
else if (line[i] == ')')
close_bracket = i;
}
if (!open_bracket || !close_bracket)
return (false);
if (copy_condition(cond, line, open_bracket, close_bracket) != true)
return (false);
return (true);
}

bool fill_cond(cond_t *cond, char *line, char **words_array)
{
if (check_condition(cond, line) != true)
return (false);
if (cond->key == IF || cond->key == ELSIF || cond->key == ELSE)
if (search_then(cond, line, words_array) != true)
return (false);
return (true);
}
38 changes: 38 additions & 0 deletions src/scripting/get_valid_line_script.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/*
** EPITECH PROJECT, 2018
** PSU_42sh_2017
** File description:
** Get valid line in the script
*/

#include "script.h"

static char *check_and_rect_line(char *line)
{
if (!line)
return (NULL);
for (int i = 0; line[i] != '\0'; i += 1) {
if (line[i] == '#' || line[i] == '\n')
line[i] = '\0';
}
if (!strncmp(line, "#!", 2) || !strcmp(line, "\n") ||
!strcmp(line, "")) {
free(line);
line = NULL;
}
return (line);
}

char *get_valid_line(FILE *fd, shell_t *shell)
{
char *line = NULL;
size_t n = 0;

while (!(line = check_and_rect_line(line)))
if (getline(&line, &n, fd) == -1) {
shell->script = false;
fclose(fd);
return (NULL);
}
return (line);
}
Loading

0 comments on commit f01f628

Please sign in to comment.