Added semicolon separated sequences execution

This commit is contained in:
Dmitriy Shishkov 2020-07-15 13:35:29 +05:00
parent d578d08410
commit 9fe0b6a293
6 changed files with 113 additions and 42 deletions

View File

@ -11,7 +11,8 @@ Work is still in porgress, buf when you will see a "finished" topic assigned to
* Files and commands from `/usr/bin` autocompletion on `Tab` keypress
* History of commands and navigation or search through it with `up/down` keys
* Username, ip address and current path in prompt before each command input
* Invert return status of command with `!`, separated with space, specified before it
* Show previous command return status in prompt and invert it with `!`, separated with space, specified before it
* Running multiple commands separated by `;`
# Builtin commands
* `cd`: changes current working directory to the one specified by user. If no arguments provided, shows error.
@ -23,4 +24,5 @@ Work is still in porgress, buf when you will see a "finished" topic assigned to
* Replace linux `echo` command with builtin one with support of environmental variables
* Environmental variables
* `Ctrl+Z` running programm with `fd`
* ~~Getting commands path from system `PATH` environment variable~~
* ~~Getting commands path from system `PATH` environment variable~~
* Running multiple commands separated by `&&` and `||` with appropriate logic

View File

@ -47,12 +47,21 @@ struct status
bool invert;
};
typedef enum
{
NO_SEP,
SEMICOLON_SEP,
AND_SEP,
OR_SEP
} cmd_sep;
typedef struct commands
{
char **args;
struct status stat;
struct commands *next;
} * cmds_p;
cmd_sep sep_next;
} cmds_p;
typedef struct
{
@ -66,10 +75,10 @@ extern t_ term;
extern char *builtin[];
// Functions prototypes
int process_line(char *line, cmds_p *coms);
int process_line(char *line, cmds_p **coms);
int launch(char **args);
void process_command();
int execute(cmds_p command);
int execute(cmds_p *command);
void sig_handler();
@ -79,6 +88,8 @@ int sh_exec(char **args);
char *compose_prompt();
cmds_p *new_cmd();
#define BUILTIN_NUM sizeof(builtin) / sizeof(char *)
#endif

View File

@ -18,7 +18,7 @@
void append_to_pos(char **str, int pos, char ch);
void remove_on_pos(char **str, int pos);
int sep_string(char *line, char ***toks, char *sep);
char *trim_string(char **str, bool leave_trailing_space);
char *trim_string(char *str, bool leave_trailing_space);
void free_str_arr(char **arr);
char **slice_array(char **arr, int beg, int end, bool asc);
int get_null_term_arr_size(char **arr);

View File

@ -268,7 +268,10 @@ void tab_key(int *pos, int *n, char **line)
(*line)[*pos] = '\0';
*line = realloc(*line, strlen(*line) + 1);
*line = trim_string(line, true);
char *tmp = trim_string(*line, true);
free(*line);
*line = tmp;
*pos = strlen(*line);
*n = *pos;

View File

@ -19,17 +19,20 @@ int (*builtin_func[])(char **) = {
*/
void process_command()
{
cmds_p coms = NULL;
cmds_p *coms = NULL;
char *prompt = compose_prompt();
print_str(prompt, strlen(prompt));
char *line = read_line();
line = trim_string(&line, false);
char *tmp = trim_string(line, false);
free(line);
line = tmp;
process_line(line, &coms);
cmds_p curr = coms;
cmds_p *curr = coms;
int status = 0;
while (curr != NULL)
{
@ -57,18 +60,14 @@ void process_command()
* @param line
* @param args
*/
int process_line(char *line, cmds_p *coms)
int process_line(char *line, cmds_p **coms)
{
char *tmp = strdup(line), *free_tmp = tmp;
int args_am = 0;
int line_size = strlen(line), args_am = 0;
*coms = malloc(sizeof(cmds_p));
(*coms)->args = malloc(sizeof(char *) * args_am);
(*coms)->stat.s = 0;
(*coms)->stat.invert = false;
(*coms)->next = NULL;
*coms = new_cmd();
int line_size = strlen(line);
cmds_p *curr_cmd = *coms;
for (int i = 0; i < line_size; i++)
{
@ -81,9 +80,9 @@ int process_line(char *line, cmds_p *coms)
{
free_tmp[j] = '\0';
append_to_str_arr(&((*coms)->args), &args_am, tmp);
append_to_str_arr(&(curr_cmd->args), &args_am, trim_string(tmp, false));
tmp += strlen((*coms)->args[args_am - 1]) + 1;
tmp += strlen(curr_cmd->args[args_am - 1]) + 1;
break;
}
@ -101,15 +100,60 @@ int process_line(char *line, cmds_p *coms)
i--;
continue;
}
i += j;
i += j - i;
}
else if (line[i] == ';' || (line[i] == '&' && line[i + 1] == '&') || (line[i] == '|' && line[i + 1] == '|'))
{
free_tmp[i] = '\0';
if (line[i - 1] != ' ')
{
append_to_str_arr(&(curr_cmd->args), &args_am, trim_string(tmp, false));
tmp += strlen(curr_cmd->args[args_am - 1]) + 1;
}
else {
tmp++;
}
if (tmp[0] == ' ')
{
tmp++;
i++;
}
curr_cmd->args = realloc(curr_cmd->args, sizeof(char *) * (args_am + 1));
curr_cmd->args[args_am] = NULL;
switch (line[i])
{
case ';':
curr_cmd->sep_next = SEMICOLON_SEP;
break;
case '&':
curr_cmd->sep_next = AND_SEP;
i++;
tmp++;
break;
case '|':
curr_cmd->sep_next = OR_SEP;
i++;
tmp++;
break;
}
cmds_p *next = new_cmd();
curr_cmd->next = next;
curr_cmd = curr_cmd->next;
args_am = 0;
}
else if (line[i] == ' ')
{
free_tmp[i] = '\0';
append_to_str_arr(&((*coms)->args), &args_am, tmp);
append_to_str_arr(&(curr_cmd->args), &args_am, trim_string(tmp, false));
tmp += strlen((*coms)->args[args_am - 1]) + 1;
tmp += strlen(curr_cmd->args[args_am - 1]) + 1;
}
else if (line[i] == '#')
{
@ -119,20 +163,21 @@ int process_line(char *line, cmds_p *coms)
if (tmp[0] != '\0' && tmp[0] != '#')
{
append_to_str_arr(&((*coms)->args), &args_am, tmp);
append_to_str_arr(&(curr_cmd->args), &args_am, trim_string(tmp, false));
}
if ((*coms)->args[0] != NULL)
if (curr_cmd->args[0] != NULL)
{
if (strcmp((*coms)->args[0], "!") == 0)
if (strcmp(curr_cmd->args[0], "!") == 0)
{
(*coms)->stat.invert = true;
curr_cmd->stat.invert = true;
}
}
free(free_tmp);
(*coms)->args[args_am] = NULL;
curr_cmd->args = realloc(curr_cmd->args, sizeof(char *) * (args_am + 1));
curr_cmd->args[args_am] = NULL;
return args_am;
}
@ -142,7 +187,7 @@ int process_line(char *line, cmds_p *coms)
* @param args
* @return int
*/
int execute(cmds_p command)
int execute(cmds_p *command)
{
if (command->args[0] == NULL)
return 1;
@ -178,7 +223,7 @@ int launch(char **args)
}
else if (pid < 0)
{
perror("myshell");
perror("myshell1");
}
else
do
@ -201,7 +246,7 @@ int sh_cd(char **args)
if (args[1] == NULL)
chdir(getenv("HOME"));
else if (chdir(args[1]) < 0)
perror("myshell");
perror("myshell2");
return 0;
}
@ -233,7 +278,7 @@ int sh_exec(char **args)
if (execvp(args[0], args) < 0)
{
perror("myshell");
perror("myshell3");
}
exit(EXIT_FAILURE);
@ -321,4 +366,13 @@ char *compose_prompt()
prompt = strcat(prompt, "\n% ");
return prompt;
}
cmds_p *new_cmd()
{
cmds_p *new = malloc(sizeof(cmds_p));
new->args = calloc(0, sizeof(char *));
new->stat.s = 0;
new->stat.invert = false;
new->next = NULL;
}

View File

@ -77,23 +77,24 @@ int sep_string(char *line, char ***toks, char *sep)
* @param str
* @return char*
*/
char *trim_string(char **str, bool leave_trailing_space)
char *trim_string(char *str, bool leave_trailing_space)
{
while ((*str)[0] == ' ')
remove_on_pos(str, 1);
char *tmp = strdup(str);
while (tmp[0] == ' ')
remove_on_pos(&tmp, 1);
for (int i = 1; i < strlen(*str); i++)
if ((*str)[i] == ' ' && (*str)[i - 1] == ' ')
for (int i = 1; i < strlen(tmp); i++)
if (tmp[i] == ' ' && tmp[i - 1] == ' ')
{
remove_on_pos(str, i);
remove_on_pos(&tmp, i);
i--;
}
if (!leave_trailing_space)
if ((*str)[strlen(*str) - 1] == ' ' && (*str)[strlen(*str) - 2] == ' ')
remove_on_pos(str, strlen(*str) - 1);
if (tmp[strlen(tmp) - 1] == ' ' && tmp[strlen(tmp) - 2] == ' ')
remove_on_pos(&tmp, strlen(tmp) - 1);
return *str;
return tmp;
}
/**
@ -149,7 +150,7 @@ int get_null_term_arr_size(char **arr)
for (int i = 0; arr[i] != NULL; i++)
k++;
return k;
return ++k;
}
int append_to_str_arr(char ***arr, int *sz, char *str)