fix: manage errors in parse_command
This commit is contained in:
parent
44daaaf097
commit
1b9a8811f8
2 changed files with 38 additions and 17 deletions
1
dev/TODO
1
dev/TODO
|
@ -17,7 +17,6 @@
|
|||
- env (with no options or arguments)
|
||||
- exit (with no options)
|
||||
- fix
|
||||
- `$ |` throws 2 errors
|
||||
- empty variables aren't freed
|
||||
- need to free value returned by readline
|
||||
- the builtins should get all arguments and check if they're good
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
/* By: mcolonna <marvin@42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* 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");
|
||||
|
||||
if (pipe(outpipe) == -1)
|
||||
minishell_error("errno");
|
||||
return (minishell_error("errno"), errno);
|
||||
*readfd = outpipe[0];
|
||||
while (true)
|
||||
{
|
||||
|
@ -112,29 +112,28 @@ static void skip_blank(t_stream *stream)
|
|||
|
||||
// Add 'c' at the end of 'str' and return the result.
|
||||
// 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 *r;
|
||||
|
||||
s = str_dup(fatal_error, mc, "-");
|
||||
s[0] = c;
|
||||
r = str_join(err, mc, str, s);
|
||||
r = str_join(fatal_error, mc, str, s);
|
||||
mem_free(s);
|
||||
mem_free((void *)str);
|
||||
return (r);
|
||||
}
|
||||
|
||||
// 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,
|
||||
const char *stop_charset)
|
||||
{
|
||||
while (stream_read(&args->stream)
|
||||
&& !char_isin(stream_read(&args->stream), stop_charset)
|
||||
)
|
||||
*dest = str_addchar(fatal_error, args->mc, *dest,
|
||||
stream_pop(&args->stream));
|
||||
*dest = str_addchar(args->mc, *dest, stream_pop(&args->stream));
|
||||
}
|
||||
|
||||
// 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)
|
||||
{
|
||||
while (char_isin(stream_read(&args->stream), charset))
|
||||
*dest = str_addchar(fatal_error, args->mc, *dest,
|
||||
stream_pop(&args->stream));
|
||||
*dest = str_addchar(args->mc, *dest, stream_pop(&args->stream));
|
||||
}
|
||||
|
||||
// Read the value of the variable and append it to dest.
|
||||
// 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)
|
||||
{
|
||||
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, "");
|
||||
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);
|
||||
mem_free((char *)name);
|
||||
tmp = *dest;
|
||||
|
@ -166,6 +169,7 @@ static void read_variable_value(t_parsing_args *args, const char **dest)
|
|||
|
||||
// Read a string without quotes.
|
||||
// Append it to dest.
|
||||
// Change args->r.error if error.
|
||||
static void read_string_noquote(t_parsing_args *args, const char **dest,
|
||||
const char *stop_charset)
|
||||
{
|
||||
|
@ -180,6 +184,8 @@ static void read_string_noquote(t_parsing_args *args, const char **dest,
|
|||
{
|
||||
stream_pop(&args->stream);
|
||||
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);
|
||||
read_variable_value(args, dest);
|
||||
if (args->r.error)
|
||||
return (true);
|
||||
}
|
||||
}
|
||||
if (!stream_read(&args->stream))
|
||||
|
@ -235,12 +243,15 @@ static bool read_string_doublequote(t_parsing_args *args, const char **dest)
|
|||
// - /[^(stop_charset)]+/
|
||||
// - /'.*'/
|
||||
// - /".*"/
|
||||
// Change args->r.error and return NULL if error.
|
||||
static const char *read_string(t_parsing_args *args, const char *stop_charset)
|
||||
{
|
||||
const char *str;
|
||||
char *const real_stop_charset
|
||||
= 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, "");
|
||||
while (!args->r.error
|
||||
&& 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);
|
||||
}
|
||||
mem_free(real_stop_charset);
|
||||
if (args->r.error)
|
||||
return (NULL);
|
||||
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))
|
||||
{
|
||||
str = read_string(args, stop_charset);
|
||||
if (args->r.error)
|
||||
return (args->r.error);
|
||||
if (!str)
|
||||
return (parse_error("EOF unexpected"));
|
||||
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);
|
||||
skip_blank(&args->stream);
|
||||
str = read_string(args, stop_charset);
|
||||
if (args->r.error)
|
||||
return (args->r.error);
|
||||
if (!str)
|
||||
return (parse_error("EOF unexpected"));
|
||||
if (heredoc)
|
||||
|
@ -336,6 +353,8 @@ static int read_outputfile(t_parsing_args *args, const char *stop_charset)
|
|||
}
|
||||
skip_blank(&args->stream);
|
||||
str = read_string(args, stop_charset);
|
||||
if (args->r.error)
|
||||
return (args->r.error);
|
||||
if (!str)
|
||||
return (parse_error("EOF unexpected"));
|
||||
args->r.output_fd = open(
|
||||
|
@ -353,7 +372,8 @@ static void read_element2(t_parsing_args *args, int *error, char c)
|
|||
if (c == '|')
|
||||
{
|
||||
if (!args->got_first_call)
|
||||
*error = parse_error("'|', '>' or '<' expected");
|
||||
*error = parse_error("pipe before any call to a program");
|
||||
else
|
||||
*error = read_call(args, "<>|");
|
||||
}
|
||||
else if (c == '>')
|
||||
|
@ -390,7 +410,6 @@ static int read_element(t_parsing_args *args)
|
|||
// Check if the command is a variable definition.
|
||||
// If possible, change 'variables' accordingly and return true.
|
||||
// If not, return false.
|
||||
// FIXME read_string not possible.
|
||||
static bool parse_variable_set_command(
|
||||
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) != '=')
|
||||
return (false);
|
||||
var.value = read_string(args, "<>|/");
|
||||
if (args->r.error)
|
||||
return (false);
|
||||
if (!var.value)
|
||||
var.value = "";
|
||||
skip_blank(&args->stream);
|
||||
if (stream_read(&args->stream))
|
||||
return (false);
|
||||
|
@ -451,7 +474,6 @@ static t_parsing_args init_parsing_args(const t_memclass mc,
|
|||
// 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.
|
||||
// FIXME error with heredoc and parse error
|
||||
t_command parse_command(const t_memclass mc, const char *command,
|
||||
t_list *variables)
|
||||
{
|
||||
|
@ -471,7 +493,7 @@ t_command parse_command(const t_memclass mc, const char *command,
|
|||
return (args.r);
|
||||
}
|
||||
read_command(&args);
|
||||
if (args.heredoc)
|
||||
heredoc(mc, &args.r.input_fd, args.heredoc);
|
||||
if (!args.r.error && args.heredoc)
|
||||
args.r.error = heredoc(mc, &args.r.input_fd, args.heredoc);
|
||||
return (args.r);
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue