One more command processing functions refactor, made command structure local
This commit is contained in:
parent
05a074795f
commit
0addae9633
@ -11,6 +11,7 @@ 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
|
* Files and commands from `/usr/bin` autocompletion on `Tab` keypress
|
||||||
* History of commands and navigation or search through it with `up/down` keys
|
* 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
|
* Username, ip address and current path in prompt before each command input
|
||||||
|
* Invert return status of command with `!`, separated with space, specified before it
|
||||||
|
|
||||||
# Builtin commands
|
# Builtin commands
|
||||||
* `cd`: changes current working directory to the one specified by user. If no arguments provided, shows error.
|
* `cd`: changes current working directory to the one specified by user. If no arguments provided, shows error.
|
||||||
|
@ -41,24 +41,24 @@ struct history
|
|||||||
struct hist_sub sub;
|
struct hist_sub sub;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct command
|
struct status
|
||||||
{
|
{
|
||||||
char *line;
|
|
||||||
char **args;
|
|
||||||
bool pipes;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct status {
|
|
||||||
int s;
|
int s;
|
||||||
bool invert;
|
bool invert;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef struct commands
|
||||||
|
{
|
||||||
|
char **args;
|
||||||
|
struct status stat;
|
||||||
|
struct commands *next;
|
||||||
|
} * cmds_p;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
struct history hist;
|
struct history hist;
|
||||||
char **envs;
|
char **envs;
|
||||||
struct command com;
|
int last_status;
|
||||||
struct status status;
|
|
||||||
} t_;
|
} t_;
|
||||||
|
|
||||||
//Globals defenition
|
//Globals defenition
|
||||||
@ -66,10 +66,10 @@ extern t_ term;
|
|||||||
extern char *builtin[];
|
extern char *builtin[];
|
||||||
|
|
||||||
// Functions prototypes
|
// Functions prototypes
|
||||||
int process_line(char *line, char ***args);
|
int process_line(char *line, cmds_p *coms);
|
||||||
int launch(char **args);
|
int launch(char **args);
|
||||||
void process_command();
|
void process_command();
|
||||||
int execute(char **args);
|
int execute(cmds_p command);
|
||||||
|
|
||||||
void sig_handler();
|
void sig_handler();
|
||||||
|
|
||||||
|
@ -18,9 +18,10 @@
|
|||||||
void append_to_pos(char **str, int pos, char ch);
|
void append_to_pos(char **str, int pos, char ch);
|
||||||
void remove_on_pos(char **str, int pos);
|
void remove_on_pos(char **str, int pos);
|
||||||
int sep_string(char *line, char ***toks, char *sep);
|
int sep_string(char *line, char ***toks, char *sep);
|
||||||
char *trim_string(char **str);
|
char *trim_string(char **str, bool leave_trailing_space);
|
||||||
void free_str_arr(char **arr);
|
void free_str_arr(char **arr);
|
||||||
char **slice_array(char **arr, int beg, int end, bool asc);
|
char **slice_array(char **arr, int beg, int end, bool asc);
|
||||||
int get_null_term_arr_size(char **arr);
|
int get_null_term_arr_size(char **arr);
|
||||||
|
int append_to_str_arr(char ***arr, int *sz, char *str);
|
||||||
|
|
||||||
#endif
|
#endif
|
@ -268,7 +268,7 @@ void tab_key(int *pos, int *n, char **line)
|
|||||||
(*line)[*pos] = '\0';
|
(*line)[*pos] = '\0';
|
||||||
*line = realloc(*line, strlen(*line) + 1);
|
*line = realloc(*line, strlen(*line) + 1);
|
||||||
|
|
||||||
*line = trim_string(line);
|
*line = trim_string(line, true);
|
||||||
*pos = strlen(*line);
|
*pos = strlen(*line);
|
||||||
*n = *pos;
|
*n = *pos;
|
||||||
|
|
||||||
|
@ -48,10 +48,7 @@ t_ init_term()
|
|||||||
term.hist.sub.pos = -1;
|
term.hist.sub.pos = -1;
|
||||||
term.hist.sub.content = (char **)malloc(sizeof(char *) * 0);
|
term.hist.sub.content = (char **)malloc(sizeof(char *) * 0);
|
||||||
|
|
||||||
term.status.s = 0;
|
term.last_status = 0;
|
||||||
term.status.invert = 0;
|
|
||||||
|
|
||||||
term.com.line = NULL;
|
|
||||||
|
|
||||||
signal(SIGINT, SIG_IGN);
|
signal(SIGINT, SIG_IGN);
|
||||||
|
|
||||||
|
101
src/shell.c
101
src/shell.c
@ -19,45 +19,26 @@ int (*builtin_func[])(char **) = {
|
|||||||
*/
|
*/
|
||||||
void process_command()
|
void process_command()
|
||||||
{
|
{
|
||||||
char **args = NULL;
|
cmds_p coms = NULL;
|
||||||
|
|
||||||
char *prompt = compose_prompt();
|
char *prompt = compose_prompt();
|
||||||
print_str(prompt, strlen(prompt));
|
print_str(prompt, strlen(prompt));
|
||||||
|
|
||||||
char *line = read_line();
|
char *line = read_line();
|
||||||
|
line = trim_string(&line, false);
|
||||||
|
|
||||||
line = trim_string(&line);
|
process_line(line, &coms);
|
||||||
if (line[strlen(line) - 1] == ' ')
|
|
||||||
remove_on_pos(&line, strlen(line));
|
|
||||||
|
|
||||||
term.com.line = line;
|
cmds_p curr = coms;
|
||||||
|
int status = 0;
|
||||||
process_line(line, &args);
|
while (curr != NULL)
|
||||||
|
|
||||||
if (args[0] != NULL)
|
|
||||||
if (strcmp(args[0], "!") == 0)
|
|
||||||
{
|
|
||||||
term.status.invert = true;
|
|
||||||
args = slice_array(args, 1, -1, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
int status = execute(args);
|
|
||||||
|
|
||||||
if (term.status.invert)
|
|
||||||
{
|
{
|
||||||
if (status == 0)
|
status = execute(curr);
|
||||||
term.status.s = 1;
|
curr = curr->next;
|
||||||
else
|
|
||||||
term.status.s = 0;
|
|
||||||
|
|
||||||
term.status.invert = false;
|
|
||||||
}
|
}
|
||||||
else
|
|
||||||
term.status.s = status;
|
|
||||||
|
|
||||||
free(line);
|
free(line);
|
||||||
free(prompt);
|
free(prompt);
|
||||||
free_str_arr(args);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -66,60 +47,50 @@ void process_command()
|
|||||||
* @param line
|
* @param line
|
||||||
* @param args
|
* @param args
|
||||||
*/
|
*/
|
||||||
int process_line(char *line, char ***args)
|
int process_line(char *line, cmds_p *coms)
|
||||||
{
|
{
|
||||||
int buff_size = ARG_SIZE, pos = 0;
|
|
||||||
*args = malloc(buff_size * sizeof(char *));
|
|
||||||
|
|
||||||
for (int i = 0; i < buff_size; i++)
|
|
||||||
{
|
|
||||||
(*args)[i] = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
char *tmp = strdup(line), *free_tmp = tmp;
|
char *tmp = strdup(line), *free_tmp = tmp;
|
||||||
|
int 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;
|
||||||
|
|
||||||
for (int i = 0; i < strlen(line); i++)
|
for (int i = 0; i < strlen(line); i++)
|
||||||
{
|
{
|
||||||
if (line[i] == ' ')
|
if (line[i] == ' ')
|
||||||
{
|
{
|
||||||
tmp[i] = '\0';
|
tmp[i] = '\0';
|
||||||
(*args)[pos] = strdup(tmp);
|
|
||||||
tmp += strlen((*args)[pos]) + 1;
|
append_to_str_arr(&((*coms)->args), &args_am, tmp);
|
||||||
pos++;
|
|
||||||
|
tmp += strlen((*coms)->args[args_am - 1]) + 1;
|
||||||
}
|
}
|
||||||
else if (line[i] == '#')
|
else if (line[i] == '#')
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pos > buff_size)
|
|
||||||
{
|
|
||||||
buff_size += ARG_SIZE;
|
|
||||||
*args = realloc(*args, buff_size * sizeof(char *));
|
|
||||||
if (*args == NULL)
|
|
||||||
{
|
|
||||||
fprintf(stderr, "myshell: memory allocation error");
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tmp[0] != '\0' && tmp[0] != '#')
|
if (tmp[0] != '\0' && tmp[0] != '#')
|
||||||
{
|
{
|
||||||
(*args)[pos] = strdup(tmp);
|
append_to_str_arr(&((*coms)->args), &args_am, tmp);
|
||||||
pos++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((*args)[0] == NULL && line[0] != '#' && line[0] != '\0')
|
if ((*coms)->args[0] != NULL)
|
||||||
{
|
{
|
||||||
(*args)[0] = strdup(line);
|
if (strcmp((*coms)->args[0], "!") == 0)
|
||||||
pos++;
|
{
|
||||||
|
(*coms)->stat.invert = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
free(free_tmp);
|
free(free_tmp);
|
||||||
|
|
||||||
(*args)[pos] = NULL;
|
(*coms)->args[args_am] = NULL;
|
||||||
return pos;
|
return args_am;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -128,16 +99,16 @@ int process_line(char *line, char ***args)
|
|||||||
* @param args
|
* @param args
|
||||||
* @return int
|
* @return int
|
||||||
*/
|
*/
|
||||||
int execute(char **args)
|
int execute(cmds_p command)
|
||||||
{
|
{
|
||||||
if (args[0] == NULL)
|
if (command->args[0] == NULL)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
for (int i = 0; i < BUILTIN_NUM; i++)
|
for (int i = 0; i < BUILTIN_NUM; i++)
|
||||||
if (strcmp(args[0], builtin[i]) == 0)
|
if (strcmp(command->args[0], builtin[i]) == 0)
|
||||||
return (*builtin_func[i])(args);
|
return (*builtin_func[i])(command->args);
|
||||||
|
|
||||||
return launch(args);
|
return launch(command->args);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -283,10 +254,10 @@ char *compose_prompt()
|
|||||||
free(full_path);
|
free(full_path);
|
||||||
|
|
||||||
// Previous status
|
// Previous status
|
||||||
if (term.status.s != 0)
|
if (term.last_status != 0)
|
||||||
{
|
{
|
||||||
char *status = malloc(snprintf(NULL, 0, " \033[91m%d\033[39m", term.status.s));
|
char *status = malloc(snprintf(NULL, 0, " \033[91m%d\033[39m", term.last_status));
|
||||||
sprintf(status, " \033[91m%d\033[39m", term.status.s);
|
sprintf(status, " \033[91m%d\033[39m", term.last_status);
|
||||||
prompt = realloc(prompt, strlen(prompt) + strlen(status) + 1);
|
prompt = realloc(prompt, strlen(prompt) + strlen(status) + 1);
|
||||||
prompt = strcat(prompt, status);
|
prompt = strcat(prompt, status);
|
||||||
free(status);
|
free(status);
|
||||||
|
23
src/utils.c
23
src/utils.c
@ -77,7 +77,7 @@ int sep_string(char *line, char ***toks, char *sep)
|
|||||||
* @param str
|
* @param str
|
||||||
* @return char*
|
* @return char*
|
||||||
*/
|
*/
|
||||||
char *trim_string(char **str)
|
char *trim_string(char **str, bool leave_trailing_space)
|
||||||
{
|
{
|
||||||
while ((*str)[0] == ' ')
|
while ((*str)[0] == ' ')
|
||||||
remove_on_pos(str, 1);
|
remove_on_pos(str, 1);
|
||||||
@ -89,6 +89,10 @@ char *trim_string(char **str)
|
|||||||
i--;
|
i--;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!leave_trailing_space)
|
||||||
|
if ((*str)[strlen(*str) - 1] == ' ' && (*str)[strlen(*str) - 2] == ' ')
|
||||||
|
remove_on_pos(str, strlen(*str) - 1);
|
||||||
|
|
||||||
return *str;
|
return *str;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -147,3 +151,20 @@ int get_null_term_arr_size(char **arr)
|
|||||||
|
|
||||||
return k;
|
return k;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int append_to_str_arr(char ***arr, int *sz, char *str)
|
||||||
|
{
|
||||||
|
(*sz)++;
|
||||||
|
|
||||||
|
char **tmp = realloc(*arr, sizeof(char *) * *sz);
|
||||||
|
if (tmp == NULL)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Couldn't reallocate memory\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
*arr = tmp;
|
||||||
|
|
||||||
|
(*arr)[*sz - 1] = strdup(str);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user