diff --git a/README.md b/README.md
index debc311..370297c 100644
--- a/README.md
+++ b/README.md
@@ -1 +1,2 @@
-### SIMPLE SHELL PROJECT
\ No newline at end of file
+
+#### SIMPLE SHELL PROJECTS
diff --git a/_atoi.c b/_atoi.c
new file mode 100644
index 0000000..b42c14d
--- /dev/null
+++ b/_atoi.c
@@ -0,0 +1,30 @@
+#include "shell.h"
+
+/**
+ * _atoi - function that convert
+ * string into integer
+ *
+ * @str: to be converted
+ * Return: converted integer
+ */
+int _atoi(const char *str)
+{
+ int number;
+ int sign;
+
+ sign = 1;
+ number = 0;
+ if (*str == '-')
+ {
+ sign = -1;
+ str++;
+ }
+ if (*str == '+')
+ str++;
+ while (*str)
+ {
+ number = number * 10 + (*str - 48);
+ str++;
+ }
+ return (number * sign);
+}
diff --git a/_cd.c b/_cd.c
new file mode 100644
index 0000000..6586b9c
--- /dev/null
+++ b/_cd.c
@@ -0,0 +1,79 @@
+#include "shell.h"
+
+/**
+ * _cd_helper - function helper of cd
+ * that takes key and look it up
+ * in enviroments variable and change
+ * directory to it
+ *
+ * @key: envs keys
+ * Return: 0 success otherwise error
+ */
+int _cd_helper(const char *key)
+{
+ char *s, buffer[200];
+
+ getcwd(buffer, 200);
+ s = _enviroment_management(GET_VALUE, key, NULL);
+ if (chdir(s) == -1)
+ {
+ free(s);
+ return (errno);
+ }
+ _enviroment_management(SET_ENTRY, "OLDPWD", buffer);
+ free(s);
+ return (0);
+}
+
+/**
+ * _cd_helper2 - function that takes
+ * path as parameter and change
+ * directory to it
+ *
+ * @path: path to change directory to it
+ * Return: 0 on success ortherwise error
+ */
+int _cd_helper2(const char *path)
+{
+ char buffer[200];
+
+ getcwd(buffer, 200);
+ if (chdir(path) == -1)
+ {
+ perror(_global_states(GET_SHELL_NAME, NULL));
+ return (errno);
+ }
+ _enviroment_management(SET_ENTRY, "OLDPWD", buffer);
+ return (0);
+}
+
+/**
+ * _cd - builtin function cd
+ * is a function that allows as
+ * to navigate through out different
+ * folders (directories) in our operating
+ * system
+ *
+ * @command: struct the stores information
+ * about passed commands
+ * Return: (0) success otherwise errors
+ */
+int _cd(command_t *command)
+{
+ int len;
+
+ len = _str2dlen(command->arguments + 1);
+
+ if (len >= 1)
+ {
+ if (_strcmp("-", command->arguments[1]))
+ return (_cd_helper("OLDPWD"));
+ else if (_strcmp("~", command->arguments[1]))
+ return (_cd_helper("HOME"));
+ else
+ return (_cd_helper2(command->arguments[1]));
+ }
+ else if (!len)
+ return (_cd_helper("HOME"));
+ return (0);
+}
diff --git a/_clear_entry.c b/_clear_entry.c
index 888de5c..dc01ace 100644
--- a/_clear_entry.c
+++ b/_clear_entry.c
@@ -7,9 +7,9 @@
*
* Return: nothing
*/
-void _clear_entry(void *data)
+void _clear_entry(void *data)
{
- entry_t *entry;
+ entry_t *entry;
entry = data;
free(entry->key);
diff --git a/_clear_map.c b/_clear_map.c
index d7967b1..5fbd583 100644
--- a/_clear_map.c
+++ b/_clear_map.c
@@ -6,7 +6,7 @@
*@map: map to be freed
* Return: nothing
*/
-void _clear_map(map_t *map)
+void _clear_map(map_t *map)
{
int iterator;
diff --git a/_command_functions.c b/_command_functions.c
new file mode 100644
index 0000000..c5b2c5f
--- /dev/null
+++ b/_command_functions.c
@@ -0,0 +1,99 @@
+#include "shell.h"
+
+/**
+ * _free_command - function that frees command
+ *
+ * @data: data to be freed
+ * Return: Nothing
+ */
+void _free_command(void *data)
+{
+ command_t *cmd;
+
+ cmd = data;
+ _free_split(&cmd->arguments);
+ free(data);
+}
+
+/**
+ * _lookup_for_command - function that search
+ * for given command on the builtins
+ * as well as in the path
+ *
+ * @command: to lookup for
+ * @type: the type of the command
+ * Return: proper path or command if it's builtin
+ */
+char *_lookup_for_command(char *command, command_type_t *type)
+{
+ if (_builtin_management(GET_BUILTIN, command, NULL))
+ {
+ *type = BUILTINS;
+ return (_strdup(command));
+ }
+ return (_get_command_from_path(command));
+}
+/**
+ * _init_command - function that initialize our
+ * command
+ *
+ * @tokens: 2d array holds all command arguments
+ * and it contain command name in the first argument
+ * Return: allocated command
+ */
+command_t *_init_command(char **tokens)
+{
+ command_t *command;
+ struct stat st;
+ char *scommand;
+
+ command = malloc(sizeof(command_t));
+ if (!command)
+ return (NULL);
+ command->type = NOT_FOUND;
+ scommand = _lookup_for_command(tokens[0], &command->type);
+ free(tokens[0]);
+ tokens[0] = scommand;
+ if (command->type == NOT_FOUND &&
+ !stat(tokens[0], &st))
+ command->type = EXTERNAL;
+ command->arguments = tokens;
+ command->name = tokens[0];
+ return (command);
+}
+/**
+ * _handle_command - function that takes line
+ * and turn into an easy command to work with
+ *
+ * @line: to be parsed
+ * Return: well strucered method
+ */
+command_t *_handle_command(const char *line)
+{
+ char *trimmed_line, *command_name;
+ char **tokens[2];
+ int iterator;
+
+ trimmed_line = _trim_white_space(line);
+ tokens[0] = _split(trimmed_line, " ");
+ free(trimmed_line);
+ if (!tokens[0])
+ return (NULL);
+ iterator = 0;
+ while (tokens[0][iterator])
+ {
+ if (tokens[0][iterator][0] == '$')
+ {
+ command_name = _evaluate_enviroment_variable(tokens[0][iterator] + 1);
+ free(tokens[0][iterator]);
+ if (command_name)
+ tokens[0][iterator] = command_name;
+ else
+ tokens[0][iterator] = _strdup("");
+ }
+ iterator++;
+ }
+ tokens[1] = _trim_2darray(tokens[0]);
+ _free_split(&tokens[0]);
+ return (_init_command(tokens[1]));
+}
diff --git a/_copy.c b/_copy.c
index cf33654..13a17a6 100644
--- a/_copy.c
+++ b/_copy.c
@@ -1,13 +1,13 @@
#include "shell.h"
/**
- * copy_to_line - function that copy data into dest
+ * _copy - function that copy data into dest
*
* @dest: buffer in which the data will be copied
* @src: buffer source of the characters
* @size: length of data that will be copied into line
* Return: dest
*/
-char *_copy(char *dest, char *src, size_t size)
+char *_copy(char *dest, const char *src, size_t size)
{
size_t iter;
diff --git a/_delete_entry.c b/_delete_entry.c
new file mode 100644
index 0000000..06d86c3
--- /dev/null
+++ b/_delete_entry.c
@@ -0,0 +1,43 @@
+#include "shell.h"
+
+/**
+ * _delete_entry - function that removes
+ * entry from hashmap by given key index
+ *
+ * @map: map to delete entry from
+ * @key: string key of the entry
+ * Return: (0) success, (1) error
+ */
+int _delete_entry(map_t *map, const char *key)
+{
+ list_t *list, *tmp;
+ int backet_index;
+ entry_t *entry;
+
+ backet_index = _get_hash_code(key);
+ list = map->backets[backet_index];
+ if (!list)
+ return (0);
+ entry = list->data;
+ if (_strcmp(entry->key, key))
+ {
+ map->backets[backet_index] = list->next;
+ _clear_entry(list->data);
+ free(list);
+ return (0);
+ }
+ while (list->next)
+ {
+ entry = list->next->data;
+ if (_strcmp(entry->key, key))
+ {
+ tmp = list->next;
+ list->next = list->next->next;
+ _clear_entry(tmp->data);
+ free(tmp);
+ break;
+ }
+ list = list->next;
+ }
+ return (0);
+}
diff --git a/_env.c b/_env.c
new file mode 100644
index 0000000..98dce42
--- /dev/null
+++ b/_env.c
@@ -0,0 +1,27 @@
+#include "shell.h"
+
+/**
+ * _env - builtin function that print whatever
+ * inside our enviroment variables
+ *
+ * @command: command_t contains informations
+ * about the user command
+ * Return: 0 success, 1 error
+ */
+int _env(command_t *command)
+{
+ char **envs, **iterator;
+
+ (void)command;
+
+ iterator = envs = _enviroment_management(CONVERT_INTO_2D, NULL, NULL);
+ if (!iterator)
+ return (1);
+ while (*iterator)
+ {
+ _fprint(1, "%s\n", *iterator);
+ iterator++;
+ }
+ _free_split(&envs);
+ return (0);
+}
diff --git a/_evaluate_enviroment_variable.c b/_evaluate_enviroment_variable.c
new file mode 100644
index 0000000..df2ba6d
--- /dev/null
+++ b/_evaluate_enviroment_variable.c
@@ -0,0 +1,26 @@
+#include "shell.h"
+
+/**
+ * _evaluate_enviroment_variable - function
+ * that takes key and return it's respective
+ * value
+ *
+ * @env_key: key to retrieve it's value from enviroment
+ * variables
+ * Return: corresponding value to given key
+ */
+char *_evaluate_enviroment_variable(char *env_key)
+{
+ char *value;
+ int number;
+
+ if (_strcmp(env_key, "?"))
+ {
+ number = _status_management(GET_STATUS, 0);
+ return (_itoa(number));
+ }
+ if (_strcmp(env_key, "$"))
+ return (_itoa(getpid()));
+ value = _enviroment_management(GET_VALUE, env_key, NULL);
+ return (value);
+}
diff --git a/_exclude_comment.c b/_exclude_comment.c
new file mode 100644
index 0000000..2719d66
--- /dev/null
+++ b/_exclude_comment.c
@@ -0,0 +1,16 @@
+#include "shell.h"
+
+/**
+ * _exclude_comment - remove comment from
+ * line
+ *
+ * @line: full line that user entered
+ * Return: new_line without comment
+ */
+char *_exclude_comment(const char *line)
+{
+ int comment_position;
+
+ comment_position = _get_comment_position(line);
+ return (_strslice(line, 0, comment_position));
+}
diff --git a/_execute.c b/_execute.c
new file mode 100644
index 0000000..2c9a83c
--- /dev/null
+++ b/_execute.c
@@ -0,0 +1,30 @@
+#include "shell.h"
+
+/**
+ * _excute - function that excute commands
+ * that's not part of builtins
+ *
+ * @command: command to be executed
+ * Return: Nothing(void)
+ */
+void _excute(command_t *command)
+{
+ int pid, status;
+ char **envs;
+
+ pid = fork();
+ if (!pid)
+ {
+ envs = _enviroment_management(CONVERT_INTO_2D, NULL, NULL);
+ execve(command->name, command->arguments, envs);
+ _free_command(command);
+ _free_split(&envs);
+ perror(_global_states(GET_SHELL_NAME, NULL));
+ exit(errno);
+ }
+ else
+ {
+ waitpid(pid, &status, 0);
+ _status_management(UPDATE_STATUS, WEXITSTATUS(status));
+ }
+}
diff --git a/_exit.c b/_exit.c
new file mode 100644
index 0000000..efd70e5
--- /dev/null
+++ b/_exit.c
@@ -0,0 +1,40 @@
+#include "shell.h"
+
+/**
+ * __exit - function that exit
+ * from the program
+ *
+ * @command: struct that holds data
+ * about command
+ * Return: 0 success, otherwise error
+ */
+int __exit(command_t *command)
+{
+ char **iterator;
+ int len;
+
+ iterator = command->arguments + 1;
+ len = _str2dlen(iterator);
+ if (len > 0 && !_isdigit(*iterator))
+ {
+ _fprint(2, "%s: %d: exit: Illegal number: %s\n",
+ _global_states(GET_SHELL_NAME, NULL),
+ *((int *)_global_states(GET_LINE_NUMBER, NULL)),
+ command->arguments[1]);
+ return (2);
+ }
+ else
+ {
+ _enviroment_management(CLEAR_ENV, NULL, NULL);
+ free(_global_states(GET_LINE, NULL));
+ if (!len)
+ {
+ _free_command(command);
+ exit(0);
+ }
+ len = _atoi(command->arguments[1]);
+ _free_command(command);
+ exit(len);
+ }
+ return (0);
+}
diff --git a/_fprint.c b/_fprint.c
new file mode 100644
index 0000000..410c648
--- /dev/null
+++ b/_fprint.c
@@ -0,0 +1,110 @@
+#include "shell.h"
+
+/**
+ * _fput_number_helper - function helps to
+ * print number
+ *
+ * @fd: file descriptor of the file that
+ * the given number will be printed in
+ * @number: number to be printed
+ * Return: number of printed digits
+ */
+int _fput_number_helper(int fd, int number)
+{
+ int ret;
+ char c;
+
+ if (number == 0)
+ return (0);
+ ret = _fput_number_helper(fd, number / 10);
+ c = number % 10 + 48;
+ write(fd, &c, 1);
+ return (1 + ret);
+}
+
+/**
+ * _fput_number - function that print
+ * given number into given file
+ *
+ * @fd: file descriptor
+ * @number: to be printed
+ * Return: the length of the printed
+ * characters
+ */
+int _fput_number(int fd, int number)
+{
+ int printed;
+
+ printed = 0;
+ if (!number)
+ {
+ write(fd, "0", 1);
+ return (1);
+ }
+ if (number < 0)
+ {
+ write(fd, "-", 1);
+ printed = 1;
+ number *= -1;
+ }
+ return (printed + _fput_number_helper(fd, number));
+}
+
+/**
+ * _fputs - function that prints string
+ * into given file descriptor
+ *
+ * @fd: file descriptor
+ * @s: string to be printed
+ * Return: number of character printed
+ */
+int _fputs(int fd, const char *s)
+{
+ return (write(fd, s, _strlen(s)));
+}
+
+/**
+ * _fprint - function that allows to
+ * to print number and string using
+ * format specifiers
+ *
+ *
+ * @fd: file descriptor
+ * @format: format to be printed to given fd
+ * and change place holder to specific values
+ * Return: number of printed characters
+ */
+int _fprint(int fd, const char *format, ...)
+{
+ va_list ap;
+ int index, printed;
+ int is_percent;
+
+ va_start(ap, format);
+ is_percent = 0;
+ index = 0;
+ printed = 0;
+ while (format[index])
+ {
+ if (format[index] == '%')
+ is_percent = 1;
+ else
+ {
+ if (is_percent)
+ {
+ if (format[index] == 'd')
+ printed += _fput_number(fd, va_arg(ap, int));
+ else if (format[index] == 's')
+ printed += _fputs(fd, va_arg(ap, char *));
+ else
+ printed += write(fd, &format[index - 1], 2);
+ }
+ else
+ printed += write(fd, format + index, 1);
+ is_percent = 0;
+ }
+ index++;
+ }
+ va_end(ap);
+ return (printed);
+}
diff --git a/_free_list.c b/_free_list.c
index 2437c39..e0c3181 100644
--- a/_free_list.c
+++ b/_free_list.c
@@ -9,7 +9,7 @@
void free_list(list_t *list, void (*free_content)(void *data))
{
list_t *current = list;
- list_t *next;
+ list_t *next;
while (current != NULL)
{
diff --git a/_get_command_from_path.c b/_get_command_from_path.c
new file mode 100644
index 0000000..ab88ad0
--- /dev/null
+++ b/_get_command_from_path.c
@@ -0,0 +1,38 @@
+#include "shell.h"
+
+/**
+ * _get_command_from_path - function that takes command
+ * and return it's corresponding path
+ *
+ * @command: command to lookup for it's path
+ * Return: path where command located
+ */
+char *_get_command_from_path(char *command)
+{
+ char *proper_command, *path,
+ **path_2d, **iterator;
+ struct stat st;
+
+ if (!stat(command, &st))
+ return (_strdup(command));
+ path = _enviroment_management(GET_VALUE, "PATH", NULL);
+ if (!path)
+ return (_strdup(command));
+ iterator = path_2d = _split(path, ":");
+ free(path);
+ while (*iterator)
+ {
+ path = _strcat(*iterator, "/");
+ proper_command = _strcat(path, command);
+ free(path);
+ if (!stat(proper_command, &st))
+ {
+ _free_split(&path_2d);
+ return (proper_command);
+ }
+ free(proper_command);
+ iterator++;
+ }
+ _free_split(&path_2d);
+ return (_strdup(command));
+}
diff --git a/_get_hash_code.c b/_get_hash_code.c
index 3a8b3e4..3d3be84 100644
--- a/_get_hash_code.c
+++ b/_get_hash_code.c
@@ -1,12 +1,12 @@
#include "shell.h"
/**
- * _get_hash_code - calculates the hash code for a given key.
- *
- * @key: key to be hash
- *
- * Return: return an integer signify hashed code of the given key
- */
+ * _get_hash_code - calculates the hash code for a given key.
+ *
+ * @key: key to be hash
+ *
+ * Return: return an integer signify hashed code of the given key
+ */
int _get_hash_code(const char *key)
{
int hash = 0;
diff --git a/_isdigit.c b/_isdigit.c
new file mode 100644
index 0000000..9f1bb7f
--- /dev/null
+++ b/_isdigit.c
@@ -0,0 +1,24 @@
+#include "shell.h"
+
+/**
+ * _isdigit - function that takes a
+ * string and check wether it's digit or
+ * not
+ *
+ * @s: string to check against
+ * Return: 1 signify digits, 0 else
+ */
+int _isdigit(const char *s)
+{
+ if (!s)
+ return (0);
+ if (*s == '-' || *s == '+')
+ s++;
+ while (*s)
+ {
+ if (*s < '0' || *s > '9')
+ return (0);
+ s++;
+ }
+ return (1);
+}
diff --git a/_itoa.c b/_itoa.c
new file mode 100644
index 0000000..71ffcfe
--- /dev/null
+++ b/_itoa.c
@@ -0,0 +1,63 @@
+#include "shell.h"
+
+/**
+ * _count_number_length - function that
+ * calculate the length of the given number
+ *
+ * @number: to calculate it's length
+ * Return: length
+ */
+int _count_number_length(int number)
+{
+ int len;
+
+ len = 0;
+ if (number == 0)
+ return (1);
+ if (number < 0)
+ {
+ len++;
+ number *= -1;
+ }
+ while (number)
+ {
+ len++;
+ number /= 10;
+ }
+ return (len);
+}
+
+/**
+ * _itoa - function convert number int
+ * string
+ *
+ * @number: to be converted
+ * Return: converted string
+ */
+char *_itoa(int number)
+{
+ int len;
+ char *str_number;
+
+ len = _count_number_length(number);
+ str_number = malloc(sizeof(char) * (len + 1));
+ if (!str_number)
+ return (NULL);
+ str_number[len] = 0;
+ if (!number)
+ {
+ str_number[0] = '0';
+ return (str_number);
+ }
+ if (number < 0)
+ {
+ str_number[0] = '-';
+ number *= -1;
+ }
+ while (number)
+ {
+ str_number[--len] = number % 10 + 48;
+ number /= 10;
+ }
+ return (str_number);
+}
diff --git a/_listlen.c b/_listlen.c
new file mode 100644
index 0000000..42848aa
--- /dev/null
+++ b/_listlen.c
@@ -0,0 +1,21 @@
+#include "shell.h"
+
+/**
+ * _listlen - function that calculate the
+ * length of the given linkedlist
+ *
+ * @list: to calculate it's length
+ * Return: length of list
+ */
+size_t _listlen(const list_t *list)
+{
+ size_t len;
+
+ len = 0;
+ while (list)
+ {
+ list = list->next;
+ len++;
+ }
+ return (len);
+}
diff --git a/_main.c b/_main.c
new file mode 100644
index 0000000..5119eb3
--- /dev/null
+++ b/_main.c
@@ -0,0 +1,44 @@
+#include "shell.h"
+
+/**
+ * main - entry level function
+ *
+ * @ac: number of passed arguments
+ * @av: arguments
+ * @env: enviroment variables
+ * Return: 0 sucess, otherwise error
+ */
+int main(int ac, char *av[], char **env)
+{
+ char *line, *no_comment_line;
+
+ (void)ac;
+ signal(SIGINT, _handle_sigint);
+ _enviroment_management(INIT_ENV, NULL, NULL);
+ _feed_enviroment_variable(env);
+ _builtin_management(SET_BUILTIN, "exit", __exit);
+ _builtin_management(SET_BUILTIN, "env", _env);
+ _builtin_management(SET_BUILTIN, "setenv", _setenv);
+ _builtin_management(SET_BUILTIN, "unsetenv", _unsetenv);
+ _builtin_management(SET_BUILTIN, "cd", _cd);
+ _global_states(SET_SHELL_NAME, av[0]);
+ while (1)
+ {
+ _prompt();
+ _getline(&line);
+ if (!line)
+ {
+ free(line);
+ break;
+ }
+ no_comment_line = _exclude_comment(line);
+ free(line);
+ line = no_comment_line;
+ _global_states(SET_LINE, line);
+ _global_states(INCREMENT_LINE_NUMBER, NULL);
+ _semicolon_handler(line);
+ free(line);
+ }
+ _enviroment_management(CLEAR_ENV, NULL, NULL);
+ return (0);
+}
diff --git a/_parsing_error_handler.c b/_parsing_error_handler.c
index 8aa5be1..fcbec06 100644
--- a/_parsing_error_handler.c
+++ b/_parsing_error_handler.c
@@ -12,10 +12,12 @@ int _check_invalid_characters_occurance(char *line)
size_t index, iter, iter2;
char *invalid_characters[] = {
";;",
- "|||"};
+ "|||",
+ ">>>",
+ "<<"};
index = 0;
- while (index < 2)
+ while (index < 4)
{
iter = 0;
iter2 = 0;
@@ -52,7 +54,8 @@ int _parsing_error_handler(char *line)
return (0);
len = _strlen(line);
if (line[0] == ';' || line[0] == '|' ||
- line[len - 1] == ';' || line[len - 1] == '|')
+ line[len - 1] == '|' ||
+ line[len - 1] == '>' || line[len - 1] == '<')
return (2);
len = 0;
while (line[len])
diff --git a/_prompt.c b/_prompt.c
new file mode 100644
index 0000000..c769cb9
--- /dev/null
+++ b/_prompt.c
@@ -0,0 +1,16 @@
+#include "shell.h"
+
+/**
+ * _prompt - function that asks
+ * a user to enter a command
+ *
+ * Return: Nothing (void)
+ */
+void _prompt(void)
+{
+ if (isatty(STDIN_FILENO))
+ {
+ _fprint(1, "%s> ",
+ _global_states(GET_SHELL_NAME, NULL));
+ }
+}
diff --git a/_semicolon_handler.c b/_semicolon_handler.c
new file mode 100644
index 0000000..c71ab3b
--- /dev/null
+++ b/_semicolon_handler.c
@@ -0,0 +1,48 @@
+#include "shell.h"
+
+/**
+ * _semicolon_handler - function that splits given
+ * line bu semicolon and pass the result to be
+ * handled by other functions
+ *
+ * @line: command line to be parsed and executed
+ * Return: 1 on success or 0 signifying error
+ */
+int _semicolon_handler(const char *line)
+{
+ char **semi_commands, **iterator;
+ command_t *command;
+ int argument_length;
+
+ iterator = semi_commands = _split(line, ";");
+ if (!iterator)
+ return (1);
+ while (*iterator)
+ {
+ command = _handle_command(*iterator);
+ if (command->type == NOT_FOUND)
+ {
+ _fprint(2, "%s: %d: %s: not found\n",
+ (char *)_global_states(GET_SHELL_NAME, NULL),
+ *((int *)_global_states(GET_LINE_NUMBER, NULL)),
+ command->name);
+ _status_management(UPDATE_STATUS, 127);
+ }
+ else if (command->type == EXTERNAL)
+ _excute(command);
+ else
+ {
+ _status_management(UPDATE_STATUS,
+ _builtin_management(
+ GET_BUILTIN,
+ command->name, NULL)(command));
+ }
+ argument_length = _str2dlen(command->arguments);
+ _enviroment_management(SET_ENTRY, "_",
+ command->arguments[argument_length - 1]);
+ _free_command(command);
+ iterator++;
+ }
+ _free_split(&semi_commands);
+ return (0);
+}
diff --git a/_set_value.c b/_set_value.c
index ef7e20b..acc90c1 100644
--- a/_set_value.c
+++ b/_set_value.c
@@ -9,11 +9,11 @@
*@value: string implies to value of the entry
*Return: 0 on error, 1 success
*/
-int _set_value(map_t *map, const char *key, const char *value)
+int _set_value(map_t *map, const char *key, const char *value)
{
- int backet_index;
+ int backet_index;
list_t *iterator;
- entry_t *entry;
+ entry_t *entry;
backet_index = _get_hash_code(key);
iterator = map->backets[backet_index];
diff --git a/_setenv.c b/_setenv.c
new file mode 100644
index 0000000..9c70777
--- /dev/null
+++ b/_setenv.c
@@ -0,0 +1,28 @@
+#include "shell.h"
+
+/**
+ * _setenv - builtins that helps
+ * add new entries to our envs
+ * or update entries from it
+ *
+ * @command: struct that stores information
+ * about current running command
+ * Return: (0) success otherwise error
+ */
+int _setenv(command_t *command)
+{
+ int len;
+
+ len = _str2dlen(command->arguments + 1);
+ if (len != 2)
+ {
+ _fprint(2, "%s: Invalid number of arguments\n",
+ _global_states(GET_SHELL_NAME, NULL));
+ return (1);
+ }
+ _enviroment_management(
+ SET_ENTRY,
+ command->arguments[1],
+ command->arguments[2]);
+ return (0);
+}
diff --git a/_signals_handler.c b/_signals_handler.c
new file mode 100644
index 0000000..e8d65e8
--- /dev/null
+++ b/_signals_handler.c
@@ -0,0 +1,20 @@
+#include "shell.h"
+
+/**
+ * _handle_sigint - function that
+ * will be called when control-c(SIGINT)
+ * triggred
+ *
+ * @sig: Integer signifying the signal number
+ * Return: void
+ */
+void _handle_sigint(int sig)
+{
+ (void)sig;
+ fflush(stdin);
+ if (isatty(STDIN_FILENO))
+ {
+ _fprint(1, "\n%s> ",
+ _global_states(GET_SHELL_NAME, NULL));
+ }
+}
diff --git a/_split.c b/_split.c
index 461aaaa..9c64079 100644
--- a/_split.c
+++ b/_split.c
@@ -1,5 +1,4 @@
#include "shell.h"
-#include
/**
* check_diameter - functions that look up for next diameter
@@ -9,7 +8,7 @@
* Return: 0 if the str doesn't contain diameter, 1 when diameter found
* 2 when diameter found in but followed by last character of the diameter
*/
-int check_diameter(char *str, char *diameter)
+int check_diameter(const char *str, const char *diameter)
{
size_t iter;
@@ -31,13 +30,15 @@ int check_diameter(char *str, char *diameter)
* @diameter: buffer to look up for
* Return: number of backets
*/
-size_t backet_count(char *line, char *diameter)
+size_t backet_count(const char *line, const char *diameter)
{
size_t counter, index, before, is_diameter;
counter = 0;
index = 0;
before = 0;
+ if (!*line)
+ return (0);
while (line[index])
{
is_diameter = check_diameter(line + index, diameter);
@@ -73,7 +74,7 @@ size_t backet_count(char *line, char *diameter)
* @diameter: buffer to look up for
* Return: position of the next occurance of the diameter
*/
-size_t get_next_diameter(char *line, char *diameter)
+size_t get_next_diameter(const char *line, const char *diameter)
{
size_t index, before, is_diameter;
@@ -102,6 +103,7 @@ size_t get_next_diameter(char *line, char *diameter)
}
return (index);
}
+
/**
* free_backets - function that frees backets
* in case of error
@@ -132,7 +134,7 @@ void free_backets(char **backets, size_t current_position)
* Return: 2d array that ends with NULL
* or NULL in case of error
*/
-char **_split(char *line, char *diameter)
+char **_split(const char *line, const char *diameter)
{
char **backets;
size_t backet_length, current_line_position, backet_index;
diff --git a/_state_managements.c b/_state_managements.c
new file mode 100644
index 0000000..385fbaa
--- /dev/null
+++ b/_state_managements.c
@@ -0,0 +1,122 @@
+#include "shell.h"
+
+/**
+ * _status_management - status state management is function that
+ * allows to access and apply actions to our status globaly
+ * from any function
+ *
+ * @action: action that will be applied to our state
+ * @new_status: used when updating status
+ * Return: current status
+ */
+
+int _status_management(status_actions_t action, int new_status)
+{
+ static int status;
+
+ if (action == UPDATE_STATUS)
+ status = new_status;
+ return (status);
+}
+
+/**
+ * _enviroment_management - function that allows to access
+ * our global variables anywhere in our program
+ * and provides us with bunch of action to be applied to our
+ * map
+ *
+ * @action: action that will be applied to our env
+ * @key: string used when adding new entry or when
+ * retrieving data
+ * @value: string used when adding new entry
+ * Return: different types based on the given action
+ */
+void *_enviroment_management(enviroment_action_t action,
+ const char *key, const char *value)
+{
+ static map_t *map;
+
+ if (action == INIT_ENV)
+ map = _init_map();
+ else if (action == SET_ENTRY)
+ _set_value(map, key, value);
+ else if (action == GET_VALUE)
+ return (_strdup(_get_value(map, key)));
+ else if (action == GET_KEYS)
+ return (_get_keys(map));
+ else if (action == CONVERT_INTO_2D)
+ return (_convert_env_into_2d_array());
+ else if (action == CLEAR_ENV)
+ _clear_map(map);
+ else if (action == DELETE_ENTRY)
+ _delete_entry(map, key);
+ return (NULL);
+}
+
+/**
+ * _builtin_management - function that manages
+ * builtins inside our application
+ *
+ * @action: action that will be applied to our
+ * builtins state managements
+ * @name: name of the builtin
+ * @function: builtin function that will be
+ * executed later
+ * Return: (void *) function that associated to
+ * builtin or NULL
+ */
+builtins_t _builtin_management(builtin_actions_t action, char *name,
+ int (*function)(command_t *command))
+{
+ static builtin_t builtins[10];
+ static int size;
+ int iter;
+
+ if (action == GET_BUILTIN)
+ {
+ iter = 0;
+ while (iter < size)
+ {
+ if (_strcmp(builtins[iter].name, name))
+ return (builtins[iter].function);
+ iter++;
+ }
+ }
+ if (action == SET_BUILTIN)
+ {
+ _copy(builtins[size].name, name, _strlen(name));
+ builtins[size].function = function;
+ size++;
+ }
+ return (NULL);
+}
+
+/**
+ * _global_states - state management that holds
+ * some variables that will be used in different
+ * places of the applications
+ *
+ * @action: actions that will be applied to
+ * the globals state managements
+ * @s: string to update string
+ * Return: (void *)
+ */
+void *_global_states(globals_action_t action, char *s)
+{
+ static char *line, *shell_name;
+ static int line_number;
+
+ if (action == SET_LINE)
+ line = s;
+ if (action == SET_SHELL_NAME)
+ shell_name = s;
+ if (action == GET_LINE)
+ return (line);
+ if (action == GET_SHELL_NAME)
+ return (shell_name);
+ if (action == GET_LINE_NUMBER)
+ return (&line_number);
+ if (action == INCREMENT_LINE_NUMBER)
+ line_number++;
+ return (NULL);
+}
diff --git a/_str2dlen.c b/_str2dlen.c
new file mode 100644
index 0000000..c6280c8
--- /dev/null
+++ b/_str2dlen.c
@@ -0,0 +1,18 @@
+#include "shell.h"
+
+/**
+ * _str2dlen - function that counts
+ * the length of 2d array
+ *
+ * @arr2d: to count it's length
+ * Return: length of given array
+ */
+int _str2dlen(char **arr2d)
+{
+ int len;
+
+ len = 0;
+ while (arr2d[len])
+ len++;
+ return (len);
+}
diff --git a/_strcat.c b/_strcat.c
new file mode 100644
index 0000000..4b85d25
--- /dev/null
+++ b/_strcat.c
@@ -0,0 +1,35 @@
+#include "shell.h"
+
+/**
+ * _strcat - function that takes 2 string and
+ * combines them
+ *
+ * @str1: first string
+ * @str2: second string
+ * Return: the combination of first and second string
+ * NULL on error case
+ */
+char *_strcat(const char *str1, const char *str2)
+{
+ size_t len1, len2, iter;
+ char *newstr;
+
+ len1 = _strlen(str1);
+ len2 = _strlen(str2);
+ newstr = malloc(sizeof(char) * (len1 + len2 + 1));
+ if (!newstr)
+ return (NULL);
+ iter = 0;
+ while (iter < len1)
+ {
+ newstr[iter] = str1[iter];
+ iter++;
+ }
+ while (iter - len1 < len2)
+ {
+ newstr[iter] = str2[iter - len1];
+ iter++;
+ }
+ newstr[iter] = 0;
+ return (newstr);
+}
diff --git a/_strcmp.c b/_strcmp.c
new file mode 100644
index 0000000..687ccea
--- /dev/null
+++ b/_strcmp.c
@@ -0,0 +1,24 @@
+#include "shell.h"
+
+/**
+ * _strcmp - function checks wether given strings
+ * are identical or not
+ *
+ * @str1: first string to check against
+ * @str2: second string to check against
+ *
+ * Return: 1 success case, 0 error case
+ */
+int _strcmp(const char *str1, const char *str2)
+{
+ if (!str1 || !str2)
+ return (0);
+ while (*str1 && *str2 && *str1 == *str2)
+ {
+ str1++;
+ str2++;
+ }
+ if (!*str1 && !*str2)
+ return (1);
+ return (0);
+}
diff --git a/_strlen.c b/_strlen.c
index 8a7d995..23b7e8c 100644
--- a/_strlen.c
+++ b/_strlen.c
@@ -5,12 +5,12 @@
* @s: string (characters)
* Return: number of characters
*/
-size_t _strlen(char *s)
+size_t _strlen(const char *s)
{
size_t len;
len = 0;
- while (s[len])
+ while (s && s[len])
len++;
return (len);
}
diff --git a/_strslice.c b/_strslice.c
new file mode 100644
index 0000000..4f439ed
--- /dev/null
+++ b/_strslice.c
@@ -0,0 +1,31 @@
+#include "shell.h"
+
+/**
+ * _strslice - function that take string
+ * and return specified part of it
+ *
+ * @line: to be sliced
+ * @start: start position index zero based
+ * @end: end position index zero based(excluded)
+ * Return: part of the string
+ */
+char *_strslice(const char *line, int start, int end)
+{
+ char *slice;
+ int len, iter;
+
+ if (start < 0)
+ start = 0;
+ len = _strlen(line);
+ if (len < end || end < 0)
+ end = len;
+ slice = malloc(sizeof(char) * (end - start + 1));
+ iter = 0;
+ while (start + iter < end)
+ {
+ slice[iter] = line[start + iter];
+ iter++;
+ }
+ slice[iter] = 0;
+ return (slice);
+}
diff --git a/_trim_2darray.c b/_trim_2darray.c
new file mode 100644
index 0000000..22c7470
--- /dev/null
+++ b/_trim_2darray.c
@@ -0,0 +1,53 @@
+#include "shell.h"
+
+/**
+ * _count_non_empty_string - function that counts
+ * number of non empty string inside of 2d array
+ *
+ * @arr: 2d array to lookup for number of non empty
+ * string
+ * Return: number of non empty strings
+ */
+int _count_non_empty_string(char **arr)
+{
+ int len;
+
+ len = 0;
+ while (*arr)
+ {
+ len += (**arr != '\0');
+ arr++;
+ }
+ return (len);
+}
+
+/**
+ * _trim_2darray - function takes an array
+ * and return new one with no empty string
+ *
+ * @arr: 2d array to remove non empty strings
+ * from it
+ * Return: 2d array without empty strings
+ */
+char **_trim_2darray(char **arr)
+{
+ int len;
+ char **new_arr;
+
+ len = _count_non_empty_string(arr);
+ new_arr = malloc(sizeof(char *) * (len + 1));
+ if (!new_arr)
+ return (NULL);
+ new_arr[len] = NULL;
+ len = 0;
+ while (*arr)
+ {
+ if (**arr)
+ {
+ new_arr[len] = _strdup(*arr);
+ len++;
+ }
+ arr++;
+ }
+ return (new_arr);
+}
diff --git a/_trim_white_space.c b/_trim_white_space.c
index b181848..3d329d8 100644
--- a/_trim_white_space.c
+++ b/_trim_white_space.c
@@ -7,7 +7,7 @@
* @end: the end of the line
* Return: length
*/
-size_t _get_length_without_space_dup(char *line, size_t end)
+size_t _get_length_without_space_dup(const char *line, size_t end)
{
size_t start, len;
int is_space;
@@ -40,7 +40,7 @@ size_t _get_length_without_space_dup(char *line, size_t end)
* @end: the end of the string exculding last spaces
* Return: new string
*/
-char *_get_newline_without_space_dup(char *line, size_t end)
+char *_get_newline_without_space_dup(const char *line, size_t end)
{
size_t start, index;
int is_space;
@@ -50,10 +50,10 @@ char *_get_newline_without_space_dup(char *line, size_t end)
is_space = 0;
index = 0;
newline = malloc(sizeof(char) *
- (_get_length_without_space_dup(line, end) + 1));
+ (_get_length_without_space_dup(line, end + 1) + 1));
if (!newline)
return (NULL);
- while (start < end)
+ while (start <= end)
{
if (line[start] == ' ' && !is_space)
{
@@ -80,13 +80,11 @@ char *_get_newline_without_space_dup(char *line, size_t end)
* @line: to check against
* Return: newline without space duplicates
*/
-char *_trim_white_space(char *line)
+char *_trim_white_space(const char *line)
{
- size_t left, right, new_length;
- int is_space;
+ size_t left, right;
left = 0;
- is_space = 0;
right = _strlen(line) - 1;
while (line[left] == ' ')
left++;
diff --git a/_unsetenv.c b/_unsetenv.c
new file mode 100644
index 0000000..61ab44a
--- /dev/null
+++ b/_unsetenv.c
@@ -0,0 +1,24 @@
+#include "shell.h"
+
+/**
+ * _unsetenv - function unset one entry from enviroment
+ * variable
+ *
+ * @command: command that contains information about
+ * entry that will be delete such as key of the entry
+ * Return: status code
+ */
+int _unsetenv(command_t *command)
+{
+ int len;
+
+ len = _str2dlen(command->arguments);
+ if (len != 2)
+ {
+ _fprint(2, "%s: Invalid number of arguments\n",
+ _global_states(GET_SHELL_NAME, NULL));
+ return (1);
+ }
+ _enviroment_management(DELETE_ENTRY, command->arguments[1], NULL);
+ return (0);
+}
diff --git a/_utils_functions.c b/_utils_functions.c
new file mode 100644
index 0000000..c16bc19
--- /dev/null
+++ b/_utils_functions.c
@@ -0,0 +1,61 @@
+#include "shell.h"
+
+/**
+ * _convert_env_into_2d_array - function that turns
+ * env into array 2d
+ *
+ * Return: array 2d or NULL signifying error
+ */
+char **_convert_env_into_2d_array(void)
+{
+ list_t *keys, *iterator;
+ size_t len_iter;
+ char **array;
+ char *tmp[2];
+
+ iterator = keys = _enviroment_management(GET_KEYS, NULL, NULL);
+ len_iter = _listlen(keys);
+ array = malloc(sizeof(char *) * (len_iter + 1));
+ if (!array)
+ {
+ free_list(keys, free);
+ return (NULL);
+ }
+ array[len_iter] = NULL;
+ len_iter = 0;
+ while (iterator)
+ {
+ tmp[0] = _strcat(iterator->data, "=");
+ tmp[1] = _enviroment_management(GET_VALUE,
+ iterator->data,
+ NULL);
+ array[len_iter] = _strcat(tmp[0], tmp[1]);
+ free(tmp[0]);
+ free(tmp[1]);
+ iterator = iterator->next;
+ len_iter++;
+ }
+ free_list(keys, free);
+ return (array);
+}
+
+/**
+ * _feed_enviroment_variable - function take whatever
+ * is inside given 2d enviroment and split by space
+ * and add it to the global env
+ *
+ * @new_env: enviroment as 2d array
+ * Return: void;
+ */
+void _feed_enviroment_variable(char **new_env)
+{
+ char **entry;
+
+ while (*new_env)
+ {
+ entry = _split(*new_env, "=");
+ _enviroment_management(SET_ENTRY, entry[0], entry[1]);
+ _free_split(&entry);
+ new_env++;
+ }
+}
diff --git a/shell.h b/shell.h
index 333bdc6..dd650bd 100644
--- a/shell.h
+++ b/shell.h
@@ -3,8 +3,14 @@
#include
#include
+#include
+#include
#include
-
+#include
+#include
+#include
+#include
+#include
#define BUFFER_SIZE 1024
#define BACKET_SIZE 64
@@ -21,6 +27,18 @@ typedef struct entry_s
char *value;
} entry_t;
+/**
+ * enum status_actions_e - actions that will be applied to
+ * status state management
+ *
+ * @UPDATE_STATUS: action to update status code
+ * @GET_STATUS: action to retrieve status code
+ */
+typedef enum status_actions_e
+{
+ UPDATE_STATUS,
+ GET_STATUS
+} status_actions_t;
/**
* struct list_s - node of linkedlist
@@ -34,6 +52,60 @@ typedef struct list_s
struct list_s *next;
} list_t;
+/**
+ * enum command_type_e - types of command
+ *
+ * @BUILTINS: MEANS THAT COMMAND IS BUILTIN
+ * @EXTERNAL: MEANS IT's AN EXTERNAL COMMAND
+ * @NOT_FOUND: MEANS THAT COMMANS IS NOT FOUND
+ */
+typedef enum command_type_e
+{
+ BUILTINS,
+ EXTERNAL,
+ NOT_FOUND
+} command_type_t;
+/**
+ * struct command_s - struct that holds informations
+ * about command
+ *
+ * @name: name of the command
+ * @arguments: command arguments
+ * @type: type of the command
+ */
+typedef struct command_s
+{
+ char *name;
+ char **arguments;
+ command_type_t type;
+} command_t;
+/**
+ * struct builtin_s - builtin struct
+ * that will contain name of builtins
+ * and it respective function to be
+ * executed
+ *
+ * @name: builtin name
+ * @function: builtin function
+ *
+ */
+typedef struct builtin_s
+{
+ char name[30];
+ int (*function)(command_t *command);
+} builtin_t;
+
+/**
+ * enum builtin_actions_e - builtin actions
+ *
+ * @GET_BUILTIN: action to get builtin function
+ * @SET_BUILTIN: action to add new_buitin function
+ */
+typedef enum builtin_actions_e
+{
+ GET_BUILTIN,
+ SET_BUILTIN
+} builtin_actions_t;
/**
* struct map_s - defines a structure for a hash table
*
@@ -42,27 +114,118 @@ typedef struct list_s
*/
typedef struct map_s
{
- list_t *backets[BACKET_SIZE];
-} map_t;
+ list_t *backets[BACKET_SIZE];
+} map_t;
+
+/**
+ * enum enviroment_action_e - actions that will be applied to
+ * global enviroment
+ *
+ * @INIT_ENV: TO INITIALIZE ENVIROMENT VARIABLE
+ * @SET_ENTRY: TO ADD NEW ENTRY TO ENVIROMENT VARIABLE
+ * @GET_VALUE: TO RETRIEVE VALUE FROM ENVIROMENT VARIABLE
+ * @GET_KEYS: TO GET ALL KEY THAT STORED INSIDE ENV VARIABLE
+ * @CONVERT_INTO_2D: RETURNS 2D ARRAY CONTAINING ALL ENVIRONEMENT
+ * VARIBALES (env)
+ * @CLEAR_ENV: TO FREE AND CLEAR EVERYTHING INSIDE OF OUR
+ * @DELETE_ENTRY: USED TO DELETE ENTRY FROM ENVIROMENT VARIABLE
+ * ENV
+ */
+typedef enum enviroment_action_e
+{
+ INIT_ENV,
+ SET_ENTRY,
+ GET_VALUE,
+ GET_KEYS,
+ DELETE_ENTRY,
+ CONVERT_INTO_2D,
+ CLEAR_ENV
+} enviroment_action_t;
+
+/**
+ * enum globals_action_e - actions to be applied to
+ * some global states or variables
+ *
+ * @GET_LINE: action that allows to
+ * get line
+ * @GET_LINE_NUMBER: action that allows to get
+ * current line number
+ * @GET_SHELL_NAME: action that allows us to
+ * get shell name
+ * @SET_LINE: action that allow us to the line
+ * @SET_SHELL_NAME: action allow us to set
+ * shell name
+ * @INCREMENT_LINE_NUMBER: action to increment
+ * line number by one
+ */
+typedef enum globals_action_e
+{
+ GET_LINE,
+ GET_LINE_NUMBER,
+ GET_SHELL_NAME,
+ SET_LINE,
+ SET_SHELL_NAME,
+ INCREMENT_LINE_NUMBER
+} globals_action_t;
+
+typedef int (*builtins_t)(command_t *);
-char *_copy(char *dest, char *src, size_t size);
+char *_copy(char *dest, const char *src, size_t size);
void *_realloc(void *old_buffer, size_t old_size, size_t new_size);
ssize_t _getline(char **line);
-char *_trim_white_space(char *line);
+char *_trim_white_space(const char *line);
int _parsing_error_handler(char *line);
-size_t _strlen(char *s);
+size_t _strlen(const char *s);
void _free_split(char ***backets);
-char **_split(char *line, char *diameter);
+char **_split(const char *line, const char *diameter);
list_t *add_to_list(list_t **lst, void *data);
void *pop_from_list(list_t **list);
+size_t _listlen(const list_t *list);
void free_list(list_t *list, void (*free_content)(void *data));
-char *_strdup(const char *str);
+int _strcmp(const char *str1, const char *str2);
+char *_strdup(const char *str);
int _get_hash_code(const char *key);
map_t *_init_map(void);
-int _set_value(map_t *map, const char *key, const char *value);
-char *_get_value(const map_t *map, const char *key);
-void _clear_entry(void *data);
-void _clear_map(map_t *map);
-list_t *_get_keys(const map_t *map);
+int _set_value(map_t *map, const char *key, const char *value);
+char *_get_value(const map_t *map, const char *key);
+void _clear_entry(void *data);
+void _clear_map(map_t *map);
+list_t *_get_keys(const map_t *map);
+int _delete_entry(map_t *map, const char *key);
+command_t *_init_command(char **tokens);
+void _free_command(void *data);
+command_t *_handle_command(const char *line);
+int _semicolon_handler(const char *line);
+list_t *_pipe_handler(const char *line);
+int _handle_pipe_execution(list_t *pipes, int previous_stdin);
+int _status_management(status_actions_t action, int new_status);
+void _handle_sigint(int sig);
+void *_enviroment_management(enviroment_action_t action,
+ const char *key, const char *value);
+int _status_management(status_actions_t action, int new_status);
+char **_convert_env_into_2d_array(void);
+void _feed_enviroment_variable(char **new_env);
+char *_get_command_from_path(char *command);
+char *_strslice(const char *line, int start, int end);
+char *_strcat(const char *str1, const char *str2);
+char *_itoa(int number);
+char *_evaluate_enviroment_variable(char *env_key);
+char **_trim_2darray(char **arr);
+int _env(command_t *command);
+int _isdigit(const char *s);
+int _str2dlen(char **arr2d);
+int _atoi(const char *str);
+int __exit(command_t *command);
+builtins_t _builtin_management(builtin_actions_t action, char *name,
+ int (*function)(command_t *command));
+void _excute(command_t *command);
+int _setenv(command_t *command);
+int _unsetenv(command_t *command);
+int _fprint(int fd, const char *format, ...);
+void *_global_states(globals_action_t action, char *s);
+int _cd(command_t *command);
+void _handle_sigint(int sig);
+void _prompt(void);
int _get_comment_position(const char *line);
+char *_exclude_comment(const char *line);
#endif
diff --git a/tests/_fprint_test.c b/tests/_fprint_test.c
new file mode 100644
index 0000000..626d163
--- /dev/null
+++ b/tests/_fprint_test.c
@@ -0,0 +1,11 @@
+#include "../shell.h"
+
+int main(void)
+{
+ _fprint(1, "hello world\n");
+ _fprint(1, "Hello %s\n", "Mohamed");
+ _fprint(1, "Hello I'm %s and I'm %d\n", "Med", 25);
+ _fprint(1, "negative %d\n", -330);
+ _fprint(1, "zero %d\n", 0);
+ return (0);
+}
diff --git a/tests/_split_test.c b/tests/_split_test.c
index 3483852..adee109 100644
--- a/tests/_split_test.c
+++ b/tests/_split_test.c
@@ -3,7 +3,7 @@
int main(void)
{
- char **s = _split("hello||world|again|and&&again&&", "&&");
+ char **s = _split("echo hello world > file | ls -la ns; echo hello world | hi mmm", "|");
char **v = s;
while (*v)
{
diff --git a/tests/_stat.c b/tests/_stat.c
new file mode 100644
index 0000000..b09ed9b
--- /dev/null
+++ b/tests/_stat.c
@@ -0,0 +1,44 @@
+#include
+#include
+#include
+#include
+#include
+
+char *_combine_path(const char *s1, const char *s2)
+{
+ size_t len1, len2;
+ size_t iterator;
+ char *new_string;
+
+ len1 = strlen(s1);
+ len2 = strlen(s2);
+ new_string = malloc(sizeof(char) * (len1 + len2 + 2));
+ if (!new_string)
+ return (NULL);
+ iterator = 0;
+ while (iterator < len1)
+ {
+ new_string[iterator] = s1[iterator];
+ iterator++;
+ }
+ new_string[iterator] = '/';
+ iterator++;
+ while (iterator - len1 - 1 < len2)
+ {
+ new_string[iterator] = s2[iterator - len1 - 1];
+ iterator++;
+ }
+ new_string[iterator] = 0;
+ return (new_string);
+}
+
+int main(void)
+{
+ struct stat s;
+
+ char *str = _combine_path("/bin", "ls");
+ printf("%s\n", str);
+ free(str);
+ // printf("is command exist %d\n", stat("/bin/s", &s));
+ return (0);
+}
diff --git a/tests/_test_list.c b/tests/_test_list.c
new file mode 100644
index 0000000..f16a69e
--- /dev/null
+++ b/tests/_test_list.c
@@ -0,0 +1,38 @@
+#include "../shell.h"
+#include
+
+void free_int(void *data)
+{
+ free(data);
+}
+
+int main()
+{
+ list_t *my_list = NULL;
+
+ int *num1 = (int *)malloc(sizeof(int));
+ *num1 = 10;
+ add_to_list(&my_list, num1);
+
+ int *num2 = (int *)malloc(sizeof(int));
+ *num2 = 20;
+ add_to_list(&my_list, num2);
+
+ int *num3 = (int *)malloc(sizeof(int));
+ *num3 = 30;
+ add_to_list(&my_list, num3);
+
+ int *num4 = malloc(sizeof(int));
+ *num4 = 40;
+ add_to_list(&my_list, num4);
+ printf("List elements:\n");
+ while (my_list != NULL)
+ {
+ int *num = (int *)pop_from_list(&my_list);
+ printf("%d\n", *num);
+ free(num);
+ }
+
+ free_list(my_list, free_int);
+ return 0;
+}
diff --git a/tests/_test_signals.c b/tests/_test_signals.c
new file mode 100644
index 0000000..b7c4db2
--- /dev/null
+++ b/tests/_test_signals.c
@@ -0,0 +1,18 @@
+#include
+#include
+
+void _handle_signal(int sig)
+{
+ (void)sig;
+
+ write(1, "CTRL-C\n", 7);
+}
+
+int main(void)
+{
+ signal(SIGINT, _handle_signal);
+ while (1)
+ {
+ sleep(1);
+ }
+}
diff --git a/tests/fc b/tests/fc
new file mode 100644
index 0000000..e69de29
diff --git a/tests/file b/tests/file
index fb2d91c..82b86fa 100644
--- a/tests/file
+++ b/tests/file
@@ -1,21 +1,2 @@
-Lorem ipsum dolor sit amet consectetur adipisicing elit. Maxime mollitia,
-molestiae quas vel sint commodi repudiandae consequuntur voluptatum laborum
-numquam blanditiis harum quisquam eius sed odit fugiat iusto fuga praesentium
-optio, eaque rerum! Provident similique accusantium nemo autem. Veritatis
-obcaecati tenetur iure eius earum ut molestias architecto voluptate aliquam
-nihil, eveniet aliquid culpa officia aut! Impedit sit sunt quaerat, odit,
-tenetur error, harum nesciunt ipsum debitis quas aliquid. Reprehenderit,
-quia. Quo neque error repudiandae fuga? Ipsa laudantium molestias eos
-sapiente officiis modi at sunt excepturi expedita sint? Sed quibusdam
-recusandae alias error harum maxime adipisci amet laborum. Perspiciatis
-minima nesciunt dolorem! Officiis iure rerum voluptates a cumque velit
-quibusdam sed amet tempora. Sit laborum ab, eius fugit doloribus tenetur
-fugiat, temporibus enim commodi iusto libero magni deleniti quod quam
-consequuntur! Commodi minima excepturi repudiandae velit hic maxime
-doloremque. Quaerat provident commodi consectetur veniam similique ad
-earum omnis ipsum saepe, voluptas, hic voluptates pariatur est explicabo
-fugiat, dolorum eligendi quam cupiditate excepturi mollitia maiores labore
-suscipit quas? Nulla, placeat. Voluptatem quaerat non architecto ab laudantium
-modi minima sunt esse temporibus sint culpa, recusandae aliquam numquam
-totam ratione voluptas quod exercitationem fuga. Possimus quis earum veniam
-quasi aliquam eligendi, placeat qui corporis!
+/bin/ls -la | /bin/cat
+/bin/echo hello wolrd
\ No newline at end of file
diff --git a/tests/getline_test.c b/tests/getline_test.c
index d51cc96..bbaa822 100644
--- a/tests/getline_test.c
+++ b/tests/getline_test.c
@@ -12,7 +12,7 @@ int main(void)
ret = _getline(&line);
if (!line)
break;
- printf("%s\n", line);
+ printf("-> %s\n", line);
free(line);
}
return (0);