[ADD] redirection '<<'

This commit is contained in:
mcolonna 2024-05-07 14:00:26 +02:00
parent c86126ec9d
commit 0fac25fd81

View file

@ -6,12 +6,44 @@
/* By: mcolonna <marvin@42.fr> +#+ +:+ +#+ */ /* By: mcolonna <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */ /* +#+#+#+#+#+ +#+ */
/* Created: 2024/04/24 13:47:40 by mcolonna #+# #+# */ /* Created: 2024/04/24 13:47:40 by mcolonna #+# #+# */
/* Updated: 2024/05/02 15:15:36 by mcolonna ### ########.fr */ /* Updated: 2024/05/07 13:59:30 by mcolonna ### ########.fr */
/* */ /* */
/* ************************************************************************** */ /* ************************************************************************** */
#include "include.h" #include "include.h"
// Ask the user for data and set readfd to the fd which will receive this
// data.
// Returns 'errno' on error.
static int heredoc(t_memclass mc, int *readfd, const char *eof)
{
const t_memclass mc_in = mem_subclass(fatal_error, mc);
int outpipe[2];
t_const_string line;
const t_const_string eof_line = str_join(fatal_error, mc_in, eof, "\n");
if (pipe(outpipe) == -1)
minishell_error("errno");
*readfd = outpipe[0];
while (true)
{
print_str(fatal_error, 1, "\e[38;5;33m( 'o')> \e[0m");
line = NULL;
while (!line)
line = read_line(fatal_error, mc_in, 0);
if (str_eq(line, eof) || str_eq(line, eof_line))
break ;
print_str(err_remember, outpipe[1], line);
mem_free((void *)line);
if (err_get())
return (minishell_error("errno"), errno);
}
mem_freeall(mc_in);
if (close(outpipe[1]) == -1)
return (minishell_error("errno"), errno);
return (0);
}
// To call when a parse error occurs. // To call when a parse error occurs.
// Always returns 1 (parse error's status). // Always returns 1 (parse error's status).
static int parse_error(const char *msg) static int parse_error(const char *msg)
@ -31,6 +63,7 @@ typedef struct s_parsing_args
t_stream stream; t_stream stream;
t_list calls; t_list calls;
bool got_first_call; // got at least the first program call? bool got_first_call; // got at least the first program call?
const char *heredoc;
} t_parsing_args; } t_parsing_args;
// Skip blank characters // Skip blank characters
@ -116,17 +149,27 @@ static int get_call(t_parsing_args *args, const char *stop_charset)
static int get_inputfile(t_parsing_args *args, const char *stop_charset) static int get_inputfile(t_parsing_args *args, const char *stop_charset)
{ {
const char *str; const char *str;
bool heredoc;
if (args->r.input_fd != 0) if (args->r.input_fd != 0)
return (parse_error("several input files")); return (parse_error("several input files"));
if (!stream_read(&args->stream)) if (!stream_read(&args->stream))
return (parse_error("EOF unexpected")); return (parse_error("EOF unexpected"));
heredoc = stream_read(&args->stream) == '<';
if (heredoc)
stream_pop(&args->stream);
skip_blank(&args->stream);
str = get_string(args, stop_charset); str = get_string(args, stop_charset);
if (!str) if (!str)
return (parse_error("EOF unexpected")); return (parse_error("EOF unexpected"));
args->r.input_fd = open(str, O_RDONLY); if (heredoc)
if (args->r.input_fd == -1) args->heredoc = str;
return (perror(str), errno); else
{
args->r.input_fd = open(str, O_RDONLY);
if (args->r.input_fd == -1)
return (perror(str), errno);
}
return (0); return (0);
} }
@ -208,6 +251,7 @@ t_parsing_args init_parsing_args(const t_memclass mc)
}, },
.calls = list_createempty(mc), .calls = list_createempty(mc),
.got_first_call = false, .got_first_call = false,
.heredoc = NULL,
}; };
return (r); return (r);
@ -237,5 +281,7 @@ t_command parse_command(const t_memclass mc, const char *command)
fatal_error, args.mc, &args.calls, sizeof(t_call)); fatal_error, args.mc, &args.calls, sizeof(t_call));
if (error) if (error)
args.r.error = error; args.r.error = error;
if (args.heredoc)
heredoc(mc, &args.r.input_fd, args.heredoc);
return (args.r); return (args.r);
} }