first effort towards subshells and backquotes, lexer done, execution done for subshells

This commit is contained in:
Jack Halford 2017-01-11 18:06:26 +01:00
parent 757976474e
commit ef400aa225
49 changed files with 479 additions and 115 deletions

View file

@ -6,7 +6,7 @@
/* By: jhalford <jack@crans.org> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2016/11/27 20:29:56 by jhalford #+# #+# */
/* Updated: 2017/01/10 10:23:55 by jhalford ### ########.fr */
/* Updated: 2017/01/11 17:59:52 by jhalford ### ########.fr */
/* */
/* ************************************************************************** */
@ -19,16 +19,17 @@
# define PROCESS_BUILTIN (1 << 0)
# define PROCESS_BINARY (1 << 1)
# define PROCESS_SCRIPT (1 << 2)
# define PROCESS_UNKNOWN (1 << 3)
# define PROCESS_PIPESTART (1 << 4)
# define PROCESS_PIPEEND (1 << 5)
# define PROCESS_COMPLETED (1 << 6)
# define PROCESS_SUSPENDED (1 << 7)
# define PROCESS_RUNNING (1 << 8)
# define PROCESS_CONTINUED (1 << 9)
# define PROCESS_SUBSHELL (1 << 3)
# define PROCESS_UNKNOWN (1 << 4)
# define PROCESS_PIPESTART (1 << 5)
# define PROCESS_PIPEEND (1 << 6)
# define PROCESS_COMPLETED (1 << 7)
# define PROCESS_SUSPENDED (1 << 8)
# define PROCESS_RUNNING (1 << 9)
# define PROCESS_CONTINUED (1 << 10)
# define PROCESS_TYPE_MASK (1 << 0 | 1 << 1 | 1 << 2 | 1 << 3)
# define PROCESS_STATE_MASK (1 << 6 | 1 << 7 | 1 << 8 | 1 << 9)
# define PROCESS_TYPE_MASK (1 << 0 | 1 << 1 | 1 << 2 | 1 << 3 | 1 << 4)
# define PROCESS_STATE_MASK (1 << 7 | 1 << 8 | 1 << 9 | 1 << 10)
# define IS_PIPESTART(a) (a & PROCESS_PIPESTART)
# define IS_PIPEEND(a) (a & PROCESS_PIPEEND)
@ -81,7 +82,7 @@ int exec_dgreat(t_btree **ast);
int exec_command(t_btree **ast);
int launch_process(t_process *p);
int process_setexec(t_process *p);
int process_setexec(t_type type, t_process *p);
int process_setgroup(t_process *p);
int process_redirect(t_process *p);
void process_free(void *content, size_t content_size);

View file

@ -6,7 +6,7 @@
/* By: sbenning <sbenning@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2016/12/08 18:02:25 by sbenning #+# #+# */
/* Updated: 2017/01/10 17:59:30 by jhalford ### ########.fr */
/* Updated: 2017/01/11 17:31:09 by jhalford ### ########.fr */
/* */
/* ************************************************************************** */
@ -209,6 +209,6 @@ int rl_cut_function(t_line *line, long int input); /* Cut selected area or cu
int rl_paste_function(t_line *line, long int input); /* Paste copied/cuted area */
int rl_insert_function(t_line *line, long int input); /* Toogle insert-mode/replacement-mode */
int ft_readline(t_line *line);
int ft_readline();
#endif

View file

@ -6,7 +6,7 @@
/* By: jhalford <jack@crans.org> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2016/12/01 12:15:50 by jhalford #+# #+# */
/* Updated: 2017/01/10 16:49:13 by jhalford ### ########.fr */
/* Updated: 2017/01/11 17:08:20 by jhalford ### ########.fr */
/* */
/* ************************************************************************** */
@ -28,13 +28,18 @@ typedef long long t_type;
# define TK_AND_IF (1 << 8)
# define TK_OR_IF (1 << 9)
# define TK_AMP (1 << 10)
# define TK_N_WORD (1 << 11)
# define TK_Q_WORD (1 << 12)
# define TK_DQ_WORD (1 << 13)
# define TK_COMMAND (1 << 14)
# define TK_PAREN_OPEN (1 << 11)
# define TK_PAREN_CLOSE (1 << 12)
# define TK_BQUOTE (1 << 13)
# define TK_N_WORD (1 << 14)
# define TK_Q_WORD (1 << 15)
# define TK_DQ_WORD (1 << 16)
# define TK_COMMAND (1 << 17)
# define TK_SUBSHELL (1 << 18)
# define TK_WORD (TK_N_WORD | TK_Q_WORD | TK_DQ_WORD)
# define TK_REDIR (0x1 | 0x2 | 0x4 | 0x8 | 0x10 | 0x20)
# define TK_WORD (TK_N_WORD | TK_Q_WORD | TK_DQ_WORD)
# define TK_REDIR (0x1 | 0x2 | 0x4 | 0x8 | 0x10 | 0x20)
# define TK_NON_FREEABLE (TK_PAREN_OPEN | TK_PAREN_CLOSE | TK_BQUOTE)
enum e_lexstate
{
@ -51,6 +56,7 @@ enum e_lexstate
DQUOTE,
BACKSLASH,
VAR,
SPECIAL,
};
struct s_token
@ -68,12 +74,16 @@ extern int (*g_lexer[])(t_list **alst, char *str);
t_token *token_init();
int ft_tokenize(t_list **alst, char *str, t_lexstate state);
int ft_post_tokenize(t_list **alst, char *str);
int token_append(t_token *token, char c);
void token_free(void *data, size_t size);
int token_cmp_type(t_token *token, t_type *ref);
void token_print(t_list *lst);
void token_expand_var(t_token *token);
int reduce_parens(t_list **alst, char *str);
int reduce_bquotes(t_list **alst, char *str);
int ft_is_delim(char c);
t_lexstate get_lexer_state(char *str);
@ -90,5 +100,6 @@ int lexer_quote(t_list **alst, char *str);
int lexer_dquote(t_list **alst, char *str);
int lexer_backslash(t_list **alst, char *str);
int lexer_var(t_list **alst, char *str);
int lexer_special(t_list **alst, char *str);
#endif

View file

@ -6,7 +6,7 @@
/* By: jhalford <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2016/11/10 13:07:44 by jhalford #+# #+# */
/* Updated: 2017/01/10 17:59:41 by jhalford ### ########.fr */
/* Updated: 2017/01/11 17:17:16 by jhalford ### ########.fr */
/* */
/* ************************************************************************** */
@ -31,21 +31,27 @@
# include <fcntl.h>
# include <errno.h>
enum e_mode
{
MODE_INPUT,
MODE_EXEC,
};
struct s_comp
{
int a;
};
# define SHELL_OPTS_JOBC (1 << 0)
# define SHELL_OPTS_LC (1 << 1)
# define SHELL_MODE_INPUT (1 << 2)
# define SHELL_MODE_EXEC (1 << 3)
# define SHELL_MODE_MASK (SHELL_MODE_INPUT | SHELL_MODE_EXEC)
# define SHELL_HAS_JOBC(b) (b & SHELL_OPTS_JOBC)
# define SHELL_MSG_NOJOBC "no job-control"
struct s_data
{
char **env;
t_mode mode;
int argc;
char **argv;
t_flag opts;
t_line line;
t_comp comp;
t_exec exec;
@ -54,11 +60,15 @@ struct s_data
extern t_stof g_builtins[];
void shell_init(void);
void shell_get_opts(int ac, char **av);
char *shell_get_avdata();
void shell_init(int ac, char **av);
void shell_exit(void);
int data_init(void);
void data_exit(void);
int shell_single_command(char *command);
void ft_expand_dollar(char **av, char **env);
char *ft_findexec(char *path, char *file);

View file

@ -6,7 +6,7 @@
/* By: jhalford <jack@crans.org> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2016/12/01 12:15:54 by jhalford #+# #+# */
/* Updated: 2016/12/05 12:33:54 by jhalford ### ########.fr */
/* Updated: 2017/01/11 17:06:17 by jhalford ### ########.fr */
/* */
/* ************************************************************************** */
@ -45,6 +45,7 @@ union u_astdata
{
t_redir redir;
char **sstr;
char *str;
};
struct s_astnode
@ -64,5 +65,6 @@ int parse_dgreat(t_btree **ast, t_list **start, t_list **lst);
int parse_lessand(t_btree **ast, t_list **start, t_list **lst);
int parse_greatand(t_btree **ast, t_list **start, t_list **lst);
int parse_word(t_btree **ast, t_list **start, t_list **lst);
int parse_subshell(t_btree **ast, t_list **start, t_list **lst);
#endif

@ -1 +1 @@
Subproject commit af71e8b8de26051cd63fde8ab82c90801bd835d8
Subproject commit 5cfe17901496443664e5b7be7fd87310f854030c

View file

@ -6,14 +6,14 @@
/* By: jhalford <jack@crans.org> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2016/12/03 11:57:53 by jhalford #+# #+# */
/* Updated: 2016/12/15 17:50:04 by jhalford ### ########.fr */
/* Updated: 2017/01/11 14:29:14 by jhalford ### ########.fr */
/* */
/* ************************************************************************** */
#include "builtin.h"
#define CDOPT_L 0x001
#define CDOPT_P 0x002
#define CDOPT_L (1 << 0)
#define CDOPT_P (1 << 2)
#define HAS_CDOPT_P(x) (x & CD_OPT_P)
#define HAS_CDOPT_L(x) (x & CD_OPT_L)
#define CDERR_1 "cd: no such file or directory: %s\n"

View file

@ -6,7 +6,7 @@
/* By: jhalford <jack@crans.org> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2016/12/05 11:50:51 by jhalford #+# #+# */
/* Updated: 2016/12/15 13:28:36 by jhalford ### ########.fr */
/* Updated: 2017/01/11 17:50:03 by jhalford ### ########.fr */
/* */
/* ************************************************************************** */

View file

@ -6,7 +6,7 @@
/* By: jhalford <jack@crans.org> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2016/12/10 16:01:30 by jhalford #+# #+# */
/* Updated: 2016/12/15 13:40:11 by jhalford ### ########.fr */
/* Updated: 2017/01/11 14:41:54 by jhalford ### ########.fr */
/* */
/* ************************************************************************** */
@ -14,9 +14,11 @@
int exec_ampersand(t_btree **ast)
{
data_singleton()->exec.job.attributes |= JOB_BG;
if (SHELL_HAS_JOBC(data_singleton()->opts))
data_singleton()->exec.job.attributes |= JOB_BG;
ft_exec(&(*ast)->left);
data_singleton()->exec.job.attributes &= ~JOB_BG;
if (SHELL_HAS_JOBC(data_singleton()->opts))
data_singleton()->exec.job.attributes &= ~JOB_BG;
ft_exec(&(*ast)->right);
btree_delone(ast, &ast_free);
return (0);

View file

@ -6,7 +6,7 @@
/* By: jhalford <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2016/11/14 17:28:14 by jhalford #+# #+# */
/* Updated: 2017/01/10 13:16:51 by jhalford ### ########.fr */
/* Updated: 2017/01/11 17:51:08 by jhalford ### ########.fr */
/* */
/* ************************************************************************** */
@ -22,7 +22,7 @@ int exec_command(t_btree **ast)
p = &data_singleton()->exec.process;
job = &data_singleton()->exec.job;
p->av = ft_sstrdup(node->data.sstr);
process_setexec(p);
process_setexec(node->type, p);
if (!(launch_process(p)))
{
job_addprocess(p);

View file

@ -6,7 +6,7 @@
/* By: jhalford <jack@crans.org> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2016/11/27 20:30:32 by jhalford #+# #+# */
/* Updated: 2017/01/08 11:03:09 by jhalford ### ########.fr */
/* Updated: 2017/01/11 18:01:05 by jhalford ### ########.fr */
/* */
/* ************************************************************************** */
@ -22,7 +22,7 @@ t_execmap g_execmap[] =
{TK_LESS, &exec_less},
{TK_GREAT, &exec_great},
{TK_DGREAT, &exec_dgreat},
{TK_COMMAND, &exec_command},
{TK_COMMAND | TK_SUBSHELL, &exec_command},
{0, 0},
};
@ -37,7 +37,7 @@ int ft_exec(t_btree **ast)
item = (*ast)->item;
while (g_execmap[i].type)
{
if (item->type == g_execmap[i].type)
if (item->type & g_execmap[i].type)
/* return ((*g_execmap[i].f)(ast)); */
(*g_execmap[i].f)(ast);
i++;

View file

@ -6,7 +6,7 @@
/* By: jhalford <jack@crans.org> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2016/12/13 14:20:45 by jhalford #+# #+# */
/* Updated: 2017/01/10 17:47:21 by jhalford ### ########.fr */
/* Updated: 2017/01/11 18:01:10 by jhalford ### ########.fr */
/* */
/* ************************************************************************** */
@ -28,9 +28,9 @@ int launch_process(t_process *p)
set_exitstatus((*p->execf)(p->path, p->av, data_singleton()->env));
else
{
/* DG("process is to be forked, %i->[]->%i, attr=%b", p->fdin, p->fdout, p->attributes); */
p->attributes &= ~PROCESS_STATE_MASK;
p->attributes |= PROCESS_RUNNING;
DG("process is to be forked, %i->[]->%i, attr=%b", p->fdin, p->fdout, p->attributes);
if (p->attributes & (PROCESS_BINARY | PROCESS_SCRIPT)
&& access(p->path, X_OK) == -1)
{
@ -43,7 +43,7 @@ int launch_process(t_process *p)
process_setgroup(p);
signal(SIGINT, SIG_DFL);
signal(SIGQUIT, SIG_DFL);
signal(SIGTSTP, sigtstp_handler);
signal(SIGTSTP, SIG_DFL);
signal(SIGTTIN, sigttin_handler);
signal(SIGTTOU, sigttou_handler);
signal(SIGCHLD, SIG_DFL);

View file

@ -6,18 +6,22 @@
/* By: jhalford <jack@crans.org> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2016/12/13 17:07:10 by jhalford #+# #+# */
/* Updated: 2017/01/10 13:17:23 by jhalford ### ########.fr */
/* Updated: 2017/01/11 18:01:36 by jhalford ### ########.fr */
/* */
/* ************************************************************************** */
#include "minishell.h"
int process_setexec(t_process *p)
int process_setexec(t_type type, t_process *p)
{
if ((p->execf = is_builtin(p)))
if (type == TK_SUBSHELL)
{
p->attributes |= PROCESS_BUILTIN;
p->execf = &execve;
p->attributes |= PROCESS_SUBSHELL;
p->path = ft_strdup(p->av[0]);
}
else if ((p->execf = is_builtin(p)))
p->attributes |= PROCESS_BUILTIN;
else if (ft_strchr(p->av[0], '/'))
{
p->execf = &execve;

View file

@ -6,7 +6,7 @@
/* By: jhalford <jack@crans.org> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2016/12/13 17:48:10 by jhalford #+# #+# */
/* Updated: 2017/01/09 15:58:32 by jhalford ### ########.fr */
/* Updated: 2017/01/11 14:45:36 by jhalford ### ########.fr */
/* */
/* ************************************************************************** */

View file

@ -6,11 +6,10 @@
/* By: jhalford <jack@crans.org> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2017/01/09 16:54:18 by jhalford #+# #+# */
/* Updated: 2017/01/10 11:11:21 by jhalford ### ########.fr */
/* Updated: 2017/01/11 14:37:23 by jhalford ### ########.fr */
/* */
/* ************************************************************************** */
#include "job_control.h"
int builtin_bg(const char *path, char *const av[], char *const envp[])
@ -24,11 +23,14 @@ int builtin_bg(const char *path, char *const av[], char *const envp[])
(void)path;
(void)envp;
(void)av;
if (!SHELL_HAS_JOBC(data_singleton()->opts))
{
ft_dprintf(2, "{red}bg: %s{eoc}\n", SHELL_MSG_NOJOBC);
return (-1);
}
jobc = &data_singleton()->jobc;
job_getrank(&rank);
id = av[1] ? ft_atoi(av[1]) : rank[0];
if (id == 0 && !av[1])
return (0);
jlist = ft_lst_find(jobc->first_job, &id, job_cmp_id);
if (jlist)
{
@ -36,8 +38,11 @@ int builtin_bg(const char *path, char *const av[], char *const envp[])
mark_job_as_running(job);
job_format(job, rank, JOBS_OPTS_L);
put_job_in_background(job, 1);
return (0);
}
else
else if (av[1])
ft_dprintf(2, "{red}bg: job not found: %i{eoc}\n", id);
return (0);
else
ft_dprintf(2, "{red}bg: no current job{eoc}\n");
return (1);
}

View file

@ -6,7 +6,7 @@
/* By: jhalford <jack@crans.org> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2017/01/08 14:30:07 by jhalford #+# #+# */
/* Updated: 2017/01/10 11:16:03 by jhalford ### ########.fr */
/* Updated: 2017/01/11 14:42:04 by jhalford ### ########.fr */
/* */
/* ************************************************************************** */
@ -23,19 +23,25 @@ int builtin_fg(const char *path, char *const av[], char *const envp[])
(void)path;
(void)envp;
(void)av;
if (!SHELL_HAS_JOBC(data_singleton()->opts))
{
ft_dprintf(2, "{red}fg: %s{eoc}\n", SHELL_MSG_NOJOBC);
return (-1);
}
jobc = &data_singleton()->jobc;
job_getrank(&rank);
id = av[1] ? ft_atoi(av[1]) : rank[0];
if (id == 0 && !av[1])
return (0);
jlist = ft_lst_find(jobc->first_job, &id, job_cmp_id);
if (jlist)
{
job = jlist->content;
mark_job_as_running(job);
put_job_in_foreground(job, 1);
return (0);
}
else
else if (av[1])
ft_dprintf(2, "{red}fg: job not found: [%i]{eoc}\n", id);
return (0);
else
ft_dprintf(2, "{red}fg: no current job{eoc}\n");
return (1);
}

View file

@ -6,7 +6,7 @@
/* By: jhalford <jack@crans.org> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2016/12/15 17:43:01 by jhalford #+# #+# */
/* Updated: 2017/01/10 11:16:16 by jhalford ### ########.fr */
/* Updated: 2017/01/11 14:38:50 by jhalford ### ########.fr */
/* */
/* ************************************************************************** */
@ -24,6 +24,11 @@ int builtin_jobs(const char *path, char *const av[], char *const envp[])
(void)path;
(void)envp;
(void)av;
if (!SHELL_HAS_JOBC(data_singleton()->opts))
{
ft_dprintf(2, "{red}jobs: %s{eoc}\n", SHELL_MSG_NOJOBC);
return (-1);
}
jobc = &data_singleton()->jobc;
jlist = jobc->first_job;
job_getrank(&rank);

View file

@ -6,7 +6,7 @@
/* By: jhalford <jack@crans.org> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2016/12/15 13:01:19 by jhalford #+# #+# */
/* Updated: 2017/01/10 17:05:31 by jhalford ### ########.fr */
/* Updated: 2017/01/11 17:35:15 by jhalford ### ########.fr */
/* */
/* ************************************************************************** */

View file

@ -6,7 +6,7 @@
/* By: jhalford <jack@crans.org> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2016/12/13 13:54:51 by jhalford #+# #+# */
/* Updated: 2017/01/10 12:30:12 by jhalford ### ########.fr */
/* Updated: 2017/01/11 14:40:34 by jhalford ### ########.fr */
/* */
/* ************************************************************************** */

View file

@ -6,7 +6,7 @@
/* By: jhalford <jack@crans.org> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2016/12/13 15:10:20 by jhalford #+# #+# */
/* Updated: 2017/01/10 16:41:15 by jhalford ### ########.fr */
/* Updated: 2017/01/11 17:53:45 by jhalford ### ########.fr */
/* */
/* ************************************************************************** */

View file

@ -6,7 +6,7 @@
/* By: jhalford <jack@crans.org> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2016/12/13 15:06:45 by jhalford #+# #+# */
/* Updated: 2017/01/10 12:30:05 by jhalford ### ########.fr */
/* Updated: 2017/01/11 17:54:33 by jhalford ### ########.fr */
/* */
/* ************************************************************************** */

View file

@ -6,7 +6,7 @@
/* By: jhalford <jack@crans.org> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2016/12/15 11:49:05 by jhalford #+# #+# */
/* Updated: 2017/01/10 17:58:27 by jhalford ### ########.fr */
/* Updated: 2017/01/11 17:55:30 by jhalford ### ########.fr */
/* */
/* ************************************************************************** */
@ -24,8 +24,8 @@ int job_wait(int id)
pid = waitpid(WAIT_ANY, &status, WUNTRACED);
DG("waitpid done");
while (!process_mark_status(pid, status)
&& !job_is_stopped(id)
&& !job_is_completed(id))
&& !job_is_completed(id)
&& !job_is_stopped(id))
{
DG("waitpid now");
pid = waitpid(WAIT_ANY, &status, WUNTRACED);

View file

@ -6,7 +6,7 @@
/* By: jhalford <jack@crans.org> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2017/01/09 13:05:55 by jhalford #+# #+# */
/* Updated: 2017/01/10 12:27:47 by jhalford ### ########.fr */
/* Updated: 2017/01/11 16:49:50 by jhalford ### ########.fr */
/* */
/* ************************************************************************** */

View file

@ -6,7 +6,7 @@
/* By: jhalford <jack@crans.org> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2016/12/12 12:41:11 by jhalford #+# #+# */
/* Updated: 2017/01/10 12:28:22 by jhalford ### ########.fr */
/* Updated: 2017/01/11 17:54:22 by jhalford ### ########.fr */
/* */
/* ************************************************************************** */

View file

@ -6,7 +6,7 @@
/* By: jhalford <jack@crans.org> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2016/12/13 14:58:36 by jhalford #+# #+# */
/* Updated: 2017/01/10 17:47:41 by jhalford ### ########.fr */
/* Updated: 2017/01/11 17:54:29 by jhalford ### ########.fr */
/* */
/* ************************************************************************** */

View file

@ -6,7 +6,7 @@
/* By: jhalford <jack@crans.org> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2016/12/10 15:14:53 by jhalford #+# #+# */
/* Updated: 2017/01/10 18:02:54 by jhalford ### ########.fr */
/* Updated: 2017/01/11 14:51:27 by jhalford ### ########.fr */
/* */
/* ************************************************************************** */

View file

@ -0,0 +1,22 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* ft_post_tokenize.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: jhalford <jack@crans.org> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2017/01/11 16:11:11 by jhalford #+# #+# */
/* Updated: 2017/01/11 17:07:39 by jhalford ### ########.fr */
/* */
/* ************************************************************************** */
#include "lexer.h"
int ft_post_tokenize(t_list **alst, char *str)
{
if (reduce_parens(alst, str))
return (1);
if (reduce_bquotes(alst, str))
return (1);
return (0);
}

View file

@ -6,7 +6,7 @@
/* By: jhalford <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2016/11/10 13:37:11 by jhalford #+# #+# */
/* Updated: 2017/01/10 16:37:30 by jhalford ### ########.fr */
/* Updated: 2017/01/11 16:11:02 by jhalford ### ########.fr */
/* */
/* ************************************************************************** */
@ -27,6 +27,7 @@ int (*g_lexer[])(t_list **alst, char *str) =
&lexer_dquote,
&lexer_backslash,
&lexer_var,
&lexer_special,
};
int ft_is_delim(char c)

View file

@ -6,7 +6,7 @@
/* By: jhalford <jack@crans.org> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2017/01/10 13:45:46 by jhalford #+# #+# */
/* Updated: 2017/01/10 15:18:01 by jhalford ### ########.fr */
/* Updated: 2017/01/11 15:48:13 by jhalford ### ########.fr */
/* */
/* ************************************************************************** */
@ -26,5 +26,7 @@ t_lexstate get_lexer_state(char *str)
return (QUOTE);
else if (*str == '\"')
return (DQUOTE);
else if (*str == '(' || *str == ')' || *str == '`')
return (SPECIAL);
return (0);
}

View file

@ -6,7 +6,7 @@
/* By: jhalford <jack@crans.org> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2016/11/28 18:36:21 by jhalford #+# #+# */
/* Updated: 2017/01/10 14:50:37 by jhalford ### ########.fr */
/* Updated: 2017/01/11 16:10:53 by jhalford ### ########.fr */
/* */
/* ************************************************************************** */
@ -17,7 +17,6 @@ int lexer_default(t_list **alst, char *str)
t_lexstate state;
t_token *token;
state = DEFAULT;
if ((state = get_lexer_state(str)))
return (ft_tokenize(alst, str, state));
if (*str == '>')

View file

@ -6,7 +6,7 @@
/* By: jhalford <jack@crans.org> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2016/12/03 11:58:44 by jhalford #+# #+# */
/* Updated: 2017/01/10 13:49:23 by jhalford ### ########.fr */
/* Updated: 2017/01/11 15:45:53 by jhalford ### ########.fr */
/* */
/* ************************************************************************** */
@ -19,7 +19,7 @@ int lexer_delim(t_list **alst, char *str)
token = (*alst)->content;
while (ft_is_delim(*str))
str++;
if (*token->data)
if (token->type)
return (ft_tokenize(&(*alst)->next, str, DEFAULT));
else
return (ft_tokenize(alst, str, DEFAULT));

View file

@ -0,0 +1,38 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* lexer_special.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: jhalford <jack@crans.org> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2017/01/11 15:35:38 by jhalford #+# #+# */
/* Updated: 2017/01/11 17:36:10 by jhalford ### ########.fr */
/* */
/* ************************************************************************** */
#include "lexer.h"
int lexer_special(t_list **alst, char *str)
{
t_token *token;
t_list **lst;
lst = alst;
if (*alst)
{
token = (*alst)->content;
if (token->type)
lst = &(*alst)->next;
}
token = token_init();
*lst = ft_lstnew(token, sizeof(*token));
token = (*lst)->content;
if (*str == '(')
token->type = TK_PAREN_OPEN;
else if (*str == ')')
token->type = TK_PAREN_CLOSE;
else if (*str == '`')
token->type = TK_BQUOTE;
token->data = str;
return (ft_tokenize(&(*lst)->next, str + 1, DEFAULT));
}

View file

@ -6,7 +6,7 @@
/* By: jhalford <jack@crans.org> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2016/12/03 12:07:11 by jhalford #+# #+# */
/* Updated: 2017/01/10 15:09:27 by jhalford ### ########.fr */
/* Updated: 2017/01/11 15:38:03 by jhalford ### ########.fr */
/* */
/* ************************************************************************** */

View file

@ -0,0 +1,50 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* reduce_bquotes.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: jhalford <jack@crans.org> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2017/01/11 16:46:27 by jhalford #+# #+# */
/* Updated: 2017/01/11 17:56:40 by jhalford ### ########.fr */
/* */
/* ************************************************************************** */
#include "lexer.h"
int reduce_bquotes(t_list **alst, char *str)
{
t_list *start;
t_list *end;
t_token *token;
int tk;
(void)str;
tk = TK_BQUOTE;
if ((start = ft_lst_find(*alst, &tk, token_cmp_type)))
{
end = start->next;
while (end)
{
token = end->content;
if (token->type == TK_BQUOTE)
break ;
end = end->next;
if (token->type & TK_NON_FREEABLE)
ft_lst_delif(alst, token, ft_addrcmp, ft_lst_cfree);
else
ft_lst_delif(alst, token, ft_addrcmp, token_free);
}
if (end)
{
token = start->content;
token->type = TK_SUBSHELL;
token->data = ft_strbetween(token->data + 1, ((t_token*)end->content)->data);
ft_lst_delif(alst, end->content, ft_addrcmp, ft_lst_cfree);
return (0);
}
return (1);
}
return (0);
}

View file

@ -0,0 +1,55 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* reduce_parens.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: jhalford <jack@crans.org> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2017/01/11 16:13:31 by jhalford #+# #+# */
/* Updated: 2017/01/11 17:06:51 by jhalford ### ########.fr */
/* */
/* ************************************************************************** */
#include "lexer.h"
int reduce_parens(t_list **alst, char *str)
{
t_list *start;
t_list *end;
t_token *token;
int num_p;
int tk;
(void)str;
tk = TK_PAREN_OPEN;
if ((start = ft_lst_find(*alst, &tk, token_cmp_type)))
{
end = start->next;
num_p = 1;
while (end)
{
token = end->content;
if (token->type == TK_PAREN_OPEN)
num_p++;
else if (token->type == TK_PAREN_CLOSE)
num_p--;
if (num_p == 0)
break ;
end = end->next;
if (token->type & TK_NON_FREEABLE)
ft_lst_delif(alst, token, ft_addrcmp, ft_lst_cfree);
else
ft_lst_delif(alst, token, ft_addrcmp, token_free);
}
if (end)
{
token = start->content;
token->type = TK_SUBSHELL;
token->data = ft_strbetween(token->data + 1, ((t_token*)end->content)->data);
ft_lst_delif(alst, end->content, ft_addrcmp, ft_lst_cfree);
return (0);
}
return (1);
}
return (0);
}

View file

@ -6,7 +6,7 @@
/* By: jhalford <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2016/11/10 15:30:25 by jhalford #+# #+# */
/* Updated: 2016/12/05 13:41:34 by jhalford ### ########.fr */
/* Updated: 2017/01/11 15:45:10 by jhalford ### ########.fr */
/* */
/* ************************************************************************** */

View file

@ -6,7 +6,7 @@
/* By: jhalford <jack@crans.org> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2016/11/28 14:39:01 by jhalford #+# #+# */
/* Updated: 2017/01/10 14:39:44 by jhalford ### ########.fr */
/* Updated: 2017/01/11 16:28:42 by jhalford ### ########.fr */
/* */
/* ************************************************************************** */
@ -20,7 +20,7 @@ void token_print(t_list *lst)
while (lst)
{
i = 0;
i = -1;
token = lst->content;
type = token->type;
while (type >> (i++ + 2))

View file

@ -6,7 +6,7 @@
/* By: sbenning <sbenning@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2016/12/08 16:36:43 by sbenning #+# #+# */
/* Updated: 2017/01/10 18:03:01 by jhalford ### ########.fr */
/* Updated: 2017/01/11 13:55:42 by jhalford ### ########.fr */
/* */
/* ************************************************************************** */

View file

@ -6,7 +6,7 @@
/* By: sbenning <sbenning@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2016/12/08 16:50:26 by sbenning #+# #+# */
/* Updated: 2017/01/10 18:04:56 by jhalford ### ########.fr */
/* Updated: 2017/01/11 13:55:40 by jhalford ### ########.fr */
/* */
/* ************************************************************************** */

View file

@ -6,7 +6,7 @@
/* By: sbenning <sbenning@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2016/12/08 18:03:48 by sbenning #+# #+# */
/* Updated: 2017/01/10 16:59:00 by jhalford ### ########.fr */
/* Updated: 2017/01/11 17:35:14 by jhalford ### ########.fr */
/* */
/* ************************************************************************** */
@ -88,8 +88,11 @@ static int rl_loop(t_line *line)
return ((ret < 0 ? -1 : 0));
}
int ft_readline(t_line *line)
int ft_readline()
{
t_line *line;
line = &data_singleton()->line;
if (rl_setup(line) < 0)
return (-1);
if (rl_loop(line) < 0)

View file

@ -6,7 +6,7 @@
/* By: sbenning <sbenning@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2016/12/08 18:07:47 by sbenning #+# #+# */
/* Updated: 2017/01/10 18:02:59 by jhalford ### ########.fr */
/* Updated: 2017/01/11 17:35:12 by jhalford ### ########.fr */
/* */
/* ************************************************************************** */
@ -14,8 +14,10 @@
int rl_setup(t_line *line)
{
do_job_notification();
data_singleton()->mode = MODE_INPUT;
if (SHELL_HAS_JOBC(data_singleton()->opts))
do_job_notification();
data_singleton()->opts &= ~SHELL_MODE_MASK;
data_singleton()->opts |= SHELL_MODE_INPUT;
ft_bzero(line, sizeof(t_line));
if (curs_setup(&line->curs) < 0)
return (-1);
@ -26,7 +28,8 @@ int rl_setup(t_line *line)
int rl_cleanup(t_line *line)
{
data_singleton()->mode = MODE_EXEC;
data_singleton()->opts &= ~SHELL_MODE_MASK;
data_singleton()->opts |= SHELL_MODE_EXEC;
if (curs_cleanup(&line->curs) < 0)
return (-1);
if (rl_merge_line(line) < 0)

View file

@ -6,7 +6,7 @@
/* By: jhalford <jack@crans.org> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2016/11/28 19:26:32 by jhalford #+# #+# */
/* Updated: 2017/01/10 16:49:28 by jhalford ### ########.fr */
/* Updated: 2017/01/11 14:03:16 by jhalford ### ########.fr */
/* */
/* ************************************************************************** */
@ -22,6 +22,7 @@ int data_init(void)
data = data_singleton();
data->line.input = NULL;
data->env = ft_sstrdup(environ);
data->opts = SHELL_OPTS_JOBC;
data->exec.process.path = NULL;
data->exec.process.av = NULL;

View file

@ -6,38 +6,56 @@
/* By: jhalford <jack@crans.org> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2016/12/06 18:40:58 by jhalford #+# #+# */
/* Updated: 2017/01/10 16:50:35 by jhalford ### ########.fr */
/* Updated: 2017/01/11 17:48:10 by jhalford ### ########.fr */
/* */
/* ************************************************************************** */
#include "minishell.h"
int main(void)
int shell_single_command(char *command)
{
t_list *token;
t_btree *ast;
token = NULL;
ast = NULL;
shell_init();
if (!command)
return (0);
DG("{inv}{mag}got command '%s'", command);
if (ft_tokenize(&token, command, DEFAULT))
return (1);
if (!token)
return (0);
token_print(token);
if (ft_post_tokenize(&token, command))
return (1);
DG("after post_tokenize");
token_print(token);
if (ft_parse(&ast, &token))
return (1);
btree_print(STDBUG, ast, &ft_putast);
/* ft_dprintf(STDBUG, "\n--- INFIX BREAKDOWN ---\n"); */
/* btree_apply_infix(ast, &ft_putast2); */
if (ft_exec(&ast))
return (1);
return (0);
}
int main(int ac, char **av)
{
DG("{inv}{bol}{gre}start of shell");
shell_init(ac, av);
DG("job_control is %s", data_singleton()->opts & SHELL_OPTS_JOBC ? "ON" : "OFF");
if (data_singleton()->opts & SHELL_OPTS_LC)
{
shell_single_command(shell_get_avdata());
return (0);
}
while (1)
{
if (ft_readline(&data_singleton()->line))
if (ft_readline())
return (1);
DG("{inv}{mag}got command '%s'", data_singleton()->line.input);
token = NULL;
if (ft_tokenize(&token, data_singleton()->line.input, DEFAULT))
return (1);
if (!token)
continue ;
token_print(token);
if (ft_parse(&ast, &token))
return (1);
btree_print(STDBUG, ast, &ft_putast);
/* ft_dprintf(STDBUG, "\n--- INFIX BREAKDOWN ---\n"); */
/* btree_apply_infix(ast, &ft_putast2); */
if (ft_exec(&ast))
if (shell_single_command(data_singleton()->line.input))
return (1);
}
return (0);

View file

@ -0,0 +1,34 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* shell_get_avdata.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: jhalford <jack@crans.org> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2017/01/11 17:14:52 by jhalford #+# #+# */
/* Updated: 2017/01/11 17:26:32 by jhalford ### ########.fr */
/* */
/* ************************************************************************** */
#include "minishell.h"
char *shell_get_avdata()
{
t_data *data;
char **av;
int i;
data = data_singleton();
av = data->argv;
i = 1;
while (av[i][0] == '-')
{
if (ft_strcmp(av[i], "--") == 0)
{
i++;
break ;
}
i++;
}
return(av[i]);
}

View file

@ -0,0 +1,55 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* shell_get_opts.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: jhalford <jack@crans.org> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2017/01/11 14:04:48 by jhalford #+# #+# */
/* Updated: 2017/01/11 17:14:35 by jhalford ### ########.fr */
/* */
/* ************************************************************************** */
#include "minishell.h"
static void shell_parse_long_opt(char *str)
{
if (ft_strcmp("no-jobcontrol", str) == 0)
data_singleton()->opts &= ~SHELL_OPTS_JOBC;
}
static void shell_parse_short_opt(char *str)
{
int i;
i = 0;
while (str[i])
{
if (*str == 'c')
{
data_singleton()->opts |= SHELL_OPTS_LC;
data_singleton()->opts &= ~SHELL_OPTS_JOBC;
}
i++;
}
}
void shell_get_opts(int ac, char **av)
{
int i;
i = 1;
while (i < ac && av[i][0] == '-')
{
if (ft_strcmp(av[i], "--") == 0)
{
i++;
break ;
}
if (av[i][1] == '-')
shell_parse_long_opt(av[i] + 2);
else
shell_parse_short_opt(av[i] + 1);
i++;
}
}

View file

@ -6,26 +6,29 @@
/* By: jhalford <jack@crans.org> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2016/12/12 17:23:59 by jhalford #+# #+# */
/* Updated: 2017/01/10 17:10:36 by jhalford ### ########.fr */
/* Updated: 2017/01/11 17:07:38 by jhalford ### ########.fr */
/* */
/* ************************************************************************** */
#include "minishell.h"
void shell_init(void)
void shell_init(int ac, char **av)
{
int *shell_pgid;
shell_pgid = &data_singleton()->jobc.shell_pgid;
data_init();
data_singleton()->argc = ac;
data_singleton()->argv = ft_sstrdup(av);
atexit(&shell_exit);
if (isatty(STDIN))
{
shell_pgid = &data_singleton()->jobc.shell_pgid;
while (tcgetpgrp(STDIN) != (*shell_pgid = getpgrp()))
kill(-*shell_pgid, SIGTTIN);
signal(SIGINT, sigint_handler);
signal(SIGQUIT, SIG_IGN);
signal(SIGTSTP, sigtstp_handler);
/* signal(SIGTSTP, SIG_IGN); */
signal(SIGTTIN, sigttin_handler);
signal(SIGTTOU, sigttou_handler);
signal(SIGCHLD, sigchld_handler);
@ -38,4 +41,5 @@ void shell_init(void)
tcsetpgrp(STDIN, *shell_pgid);
tcgetattr(STDIN, &data_singleton()->jobc.shell_tmodes);
}
shell_get_opts(ac, av);
}

View file

@ -6,7 +6,7 @@
/* By: jhalford <jack@crans.org> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2016/11/30 17:14:58 by jhalford #+# #+# */
/* Updated: 2017/01/10 14:20:14 by jhalford ### ########.fr */
/* Updated: 2017/01/11 16:52:25 by jhalford ### ########.fr */
/* */
/* ************************************************************************** */
@ -24,6 +24,7 @@ t_parser g_parser[] =
{TK_DGREAT, &parse_dgreat},
{TK_LESSAND, &parse_lessand},
{TK_GREATAND, &parse_greatand},
{TK_SUBSHELL, &parse_subshell},
{TK_WORD, &parse_word},
{0, 0},
};

View file

@ -0,0 +1,32 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* parse_subshell.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: jhalford <jack@crans.org> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2017/01/11 16:52:44 by jhalford #+# #+# */
/* Updated: 2017/01/11 17:50:54 by jhalford ### ########.fr */
/* */
/* ************************************************************************** */
#include "parser.h"
int parse_subshell(t_btree **ast, t_list **start, t_list **lst)
{
t_astnode *node;
t_token *token;
(void)start;
token = (*lst)->content;
node = (*ast)->item;
node->type = TK_SUBSHELL;
node->data.sstr = malloc(4 * sizeof(char *));
node->data.sstr[0] = ft_strdup(data_singleton()->argv[0]);
node->data.sstr[1] = ft_strdup("-c");
node->data.sstr[2] = ft_strdup(token->data);
node->data.sstr[3] = NULL;
ft_parse(ast, &(*lst)->next);
ft_lst_delif(start, (*lst)->content, &ft_addrcmp, &token_free);
return (0);
}

View file

@ -6,7 +6,7 @@
/* By: jhalford <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2016/11/14 12:49:45 by jhalford #+# #+# */
/* Updated: 2016/12/07 17:37:08 by jhalford ### ########.fr */
/* Updated: 2017/01/11 17:24:55 by jhalford ### ########.fr */
/* */
/* ************************************************************************** */