fix: manage errors in parse_command

This commit is contained in:
mcolonna 2024-06-10 17:47:23 +02:00
parent 44daaaf097
commit 1b9a8811f8
2 changed files with 38 additions and 17 deletions

View file

@ -17,7 +17,6 @@
- env (with no options or arguments) - env (with no options or arguments)
- exit (with no options) - exit (with no options)
- fix - fix
- `$ |` throws 2 errors
- empty variables aren't freed - empty variables aren't freed
- need to free value returned by readline - need to free value returned by readline
- the builtins should get all arguments and check if they're good - the builtins should get all arguments and check if they're good

View file

@ -6,7 +6,7 @@
/* 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/06/06 15:58:38 by mcolonna ### ########.fr */ /* Updated: 2024/06/10 17:51:31 by mcolonna ### ########.fr */
/* */ /* */
/* ************************************************************************** */ /* ************************************************************************** */
@ -60,7 +60,7 @@ static int heredoc(t_memclass mc, int *readfd, const char *eof)
const t_const_string eof_line = str_join(fatal_error, mc_in, eof, "\n"); const t_const_string eof_line = str_join(fatal_error, mc_in, eof, "\n");
if (pipe(outpipe) == -1) if (pipe(outpipe) == -1)
minishell_error("errno"); return (minishell_error("errno"), errno);
*readfd = outpipe[0]; *readfd = outpipe[0];
while (true) while (true)
{ {
@ -112,29 +112,28 @@ static void skip_blank(t_stream *stream)
// Add 'c' at the end of 'str' and return the result. // Add 'c' at the end of 'str' and return the result.
// Also mem_free() 'str'. // Also mem_free() 'str'.
static char *str_addchar(t_err err, t_memclass mc, const char *str, char c) static char *str_addchar(t_memclass mc, const char *str, char c)
{ {
char *s; char *s;
char *r; char *r;
s = str_dup(fatal_error, mc, "-"); s = str_dup(fatal_error, mc, "-");
s[0] = c; s[0] = c;
r = str_join(err, mc, str, s); r = str_join(fatal_error, mc, str, s);
mem_free(s); mem_free(s);
mem_free((void *)str); mem_free((void *)str);
return (r); return (r);
} }
// Read until a character is in the charset or is '\0' // Read until a character is in the charset or is '\0'
// and append the string to dest.. // and append the string to dest.
static void read_until(t_parsing_args *args, const char **dest, static void read_until(t_parsing_args *args, const char **dest,
const char *stop_charset) const char *stop_charset)
{ {
while (stream_read(&args->stream) while (stream_read(&args->stream)
&& !char_isin(stream_read(&args->stream), stop_charset) && !char_isin(stream_read(&args->stream), stop_charset)
) )
*dest = str_addchar(fatal_error, args->mc, *dest, *dest = str_addchar(args->mc, *dest, stream_pop(&args->stream));
stream_pop(&args->stream));
} }
// Read until a character isn't in the charset or is '\0' // Read until a character isn't in the charset or is '\0'
@ -142,13 +141,12 @@ static void read_until(t_parsing_args *args, const char **dest,
void read_only(t_parsing_args *args, const char **dest, const char *charset) void read_only(t_parsing_args *args, const char **dest, const char *charset)
{ {
while (char_isin(stream_read(&args->stream), charset)) while (char_isin(stream_read(&args->stream), charset))
*dest = str_addchar(fatal_error, args->mc, *dest, *dest = str_addchar(args->mc, *dest, stream_pop(&args->stream));
stream_pop(&args->stream));
} }
// Read the value of the variable and append it to dest. // Read the value of the variable and append it to dest.
// The stream must point to the first char of the variable name. // The stream must point to the first char of the variable name.
// FIXME Manage error (no variable name) // Write a parse error and change args->r.error if no variable name.
static void read_variable_value(t_parsing_args *args, const char **dest) static void read_variable_value(t_parsing_args *args, const char **dest)
{ {
const char *name; const char *name;
@ -157,6 +155,11 @@ static void read_variable_value(t_parsing_args *args, const char **dest)
name = str_dup(fatal_error, args->mc, ""); name = str_dup(fatal_error, args->mc, "");
read_only(args, &name, SYMBOL_CHARS); read_only(args, &name, SYMBOL_CHARS);
if (str_eq(name, ""))
{
args->r.error = parse_error("variable name expected");
return ;
}
value = variables_get(args->variables, name); value = variables_get(args->variables, name);
mem_free((char *)name); mem_free((char *)name);
tmp = *dest; tmp = *dest;
@ -166,6 +169,7 @@ static void read_variable_value(t_parsing_args *args, const char **dest)
// Read a string without quotes. // Read a string without quotes.
// Append it to dest. // Append it to dest.
// Change args->r.error if error.
static void read_string_noquote(t_parsing_args *args, const char **dest, static void read_string_noquote(t_parsing_args *args, const char **dest,
const char *stop_charset) const char *stop_charset)
{ {
@ -180,6 +184,8 @@ static void read_string_noquote(t_parsing_args *args, const char **dest,
{ {
stream_pop(&args->stream); stream_pop(&args->stream);
read_variable_value(args, dest); read_variable_value(args, dest);
if (args->r.error)
return ;
} }
} }
} }
@ -219,6 +225,8 @@ static bool read_string_doublequote(t_parsing_args *args, const char **dest)
{ {
stream_pop(&args->stream); stream_pop(&args->stream);
read_variable_value(args, dest); read_variable_value(args, dest);
if (args->r.error)
return (true);
} }
} }
if (!stream_read(&args->stream)) if (!stream_read(&args->stream))
@ -235,12 +243,15 @@ static bool read_string_doublequote(t_parsing_args *args, const char **dest)
// - /[^(stop_charset)]+/ // - /[^(stop_charset)]+/
// - /'.*'/ // - /'.*'/
// - /".*"/ // - /".*"/
// Change args->r.error and return NULL if error.
static const char *read_string(t_parsing_args *args, const char *stop_charset) static const char *read_string(t_parsing_args *args, const char *stop_charset)
{ {
const char *str; const char *str;
char *const real_stop_charset char *const real_stop_charset
= str_join(fatal_error, args->mc, stop_charset, " \r\n\t"); = str_join(fatal_error, args->mc, stop_charset, " \r\n\t");
if (!stream_read(&args->stream))
return (NULL);
str = str_dup(fatal_error, args->mc, ""); str = str_dup(fatal_error, args->mc, "");
while (!args->r.error while (!args->r.error
&& stream_read(&args->stream) && stream_read(&args->stream)
@ -251,6 +262,8 @@ static const char *read_string(t_parsing_args *args, const char *stop_charset)
read_string_noquote(args, &str, real_stop_charset); read_string_noquote(args, &str, real_stop_charset);
} }
mem_free(real_stop_charset); mem_free(real_stop_charset);
if (args->r.error)
return (NULL);
return (str); return (str);
} }
@ -268,6 +281,8 @@ static int read_call(t_parsing_args *args, const char *stop_charset)
&& !char_isin(stream_read(&args->stream), stop_charset)) && !char_isin(stream_read(&args->stream), stop_charset))
{ {
str = read_string(args, stop_charset); str = read_string(args, stop_charset);
if (args->r.error)
return (args->r.error);
if (!str) if (!str)
return (parse_error("EOF unexpected")); return (parse_error("EOF unexpected"));
list_add(fatal_error, &arguments, list_add(fatal_error, &arguments,
@ -303,6 +318,8 @@ static int read_inputfile(t_parsing_args *args, const char *stop_charset)
stream_pop(&args->stream); stream_pop(&args->stream);
skip_blank(&args->stream); skip_blank(&args->stream);
str = read_string(args, stop_charset); str = read_string(args, stop_charset);
if (args->r.error)
return (args->r.error);
if (!str) if (!str)
return (parse_error("EOF unexpected")); return (parse_error("EOF unexpected"));
if (heredoc) if (heredoc)
@ -336,6 +353,8 @@ static int read_outputfile(t_parsing_args *args, const char *stop_charset)
} }
skip_blank(&args->stream); skip_blank(&args->stream);
str = read_string(args, stop_charset); str = read_string(args, stop_charset);
if (args->r.error)
return (args->r.error);
if (!str) if (!str)
return (parse_error("EOF unexpected")); return (parse_error("EOF unexpected"));
args->r.output_fd = open( args->r.output_fd = open(
@ -353,8 +372,9 @@ static void read_element2(t_parsing_args *args, int *error, char c)
if (c == '|') if (c == '|')
{ {
if (!args->got_first_call) if (!args->got_first_call)
*error = parse_error("'|', '>' or '<' expected"); *error = parse_error("pipe before any call to a program");
*error = read_call(args, "<>|"); else
*error = read_call(args, "<>|");
} }
else if (c == '>') else if (c == '>')
*error = read_outputfile(args, "<>|"); *error = read_outputfile(args, "<>|");
@ -390,7 +410,6 @@ static int read_element(t_parsing_args *args)
// Check if the command is a variable definition. // Check if the command is a variable definition.
// If possible, change 'variables' accordingly and return true. // If possible, change 'variables' accordingly and return true.
// If not, return false. // If not, return false.
// FIXME read_string not possible.
static bool parse_variable_set_command( static bool parse_variable_set_command(
t_parsing_args *args, const char *command, t_list *variables) t_parsing_args *args, const char *command, t_list *variables)
{ {
@ -403,6 +422,10 @@ static bool parse_variable_set_command(
if (str_len(var.name) == 0 || stream_pop(&args->stream) != '=') if (str_len(var.name) == 0 || stream_pop(&args->stream) != '=')
return (false); return (false);
var.value = read_string(args, "<>|/"); var.value = read_string(args, "<>|/");
if (args->r.error)
return (false);
if (!var.value)
var.value = "";
skip_blank(&args->stream); skip_blank(&args->stream);
if (stream_read(&args->stream)) if (stream_read(&args->stream))
return (false); return (false);
@ -451,7 +474,6 @@ static t_parsing_args init_parsing_args(const t_memclass mc,
// an "empty" t_command. // an "empty" t_command.
// - If the command string is empty (or blank), return an "empty" t_command. // - If the command string is empty (or blank), return an "empty" t_command.
// - If there is any error, return a t_command with .error != 0. // - If there is any error, return a t_command with .error != 0.
// FIXME error with heredoc and parse error
t_command parse_command(const t_memclass mc, const char *command, t_command parse_command(const t_memclass mc, const char *command,
t_list *variables) t_list *variables)
{ {
@ -471,7 +493,7 @@ t_command parse_command(const t_memclass mc, const char *command,
return (args.r); return (args.r);
} }
read_command(&args); read_command(&args);
if (args.heredoc) if (!args.r.error && args.heredoc)
heredoc(mc, &args.r.input_fd, args.heredoc); args.r.error = heredoc(mc, &args.r.input_fd, args.heredoc);
return (args.r); return (args.r);
} }