diff options
Diffstat (limited to 'src/p_args.c')
-rw-r--r-- | src/p_args.c | 158 |
1 files changed, 158 insertions, 0 deletions
diff --git a/src/p_args.c b/src/p_args.c new file mode 100644 index 0000000..54a95a7 --- /dev/null +++ b/src/p_args.c @@ -0,0 +1,158 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* p_args.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: rbousset <marvin@42.fr> +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2020/02/14 17:19:27 by rbousset #+# #+# */ +/* Updated: 2020/02/14 17:19:29 by rbousset ### ########lyon.fr */ +/* */ +/* ************************************************************************** */ + +#include <libft.h> +#include <stdint.h> +#include <stdlib.h> + +#include "d_define.h" +#include "p_args.h" +#include "p_args_next.h" +#include "p_args_escape.h" +#include "u_parse.h" +#include "u_utils.h" + +static void + p_meet_bs(char *ptr, t_quote_mode mode) +{ + if (mode != Q_SINGLE) + { + if (*(ptr + 1) == C_BACKS) + { + *ptr = C_SUB; + *(ptr + 1) = C_SUB; + } + } +} + +static t_bool + p_meet_whitespace(char *head, char *ptr, t_quote_mode mode) +{ + if (mode == Q_NONE && u_is_not_escaped(head, ptr) == TRUE) + { + return (TRUE); + } + return (FALSE); +} + +static char + *p_skip_whitespace(char *ptr) +{ + while (*ptr != C_NUL && ft_iswhitespace(*ptr)) + ptr++; + return (ptr); +} + +static uint16_t + p_count_args(const char word[], size_t start[]) +{ + char *ptr; + t_quote_mode mode; + uint16_t count; + + ptr = (char *)word; + mode = Q_NONE; + count = 1; + ptr = p_skip_whitespace(ptr); + start[0] = (ptr - word); + while (*ptr != C_NUL) + { + if (*ptr == C_BACKS) + p_meet_bs(ptr, mode); + if (*ptr == C_DQUOTE) + mode = u_meet_dquote(word, ptr, mode); + else if (*ptr == C_SQUOTE) + mode = u_meet_squote(word, ptr, mode); + if (ft_iswhitespace(*ptr) == TRUE && + p_meet_whitespace((char*)word, ptr, mode) == TRUE) + { + ptr = p_skip_whitespace(ptr); + start[count] = (ptr - word); + if (*ptr != C_NUL) + count += 1; + ptr -= 1; + } + ptr++; + } + return (count); + /* TODO: quotes parse error */ +} + +static char + **p_split_words_no_rdr(const char word[]) +{ + char **words; + size_t start[512]; + uint16_t argc; + uint16_t to_del; + + argc = p_count_args(word, start); + if ((words = (char**)malloc((argc + 1) * sizeof(char*))) == NULL) + return (NULL); + words[argc] = NULL; + if ((to_del = p_dup_words(words, word, argc, start)) != argc) + { + p_del_alloced_words(words, to_del); + return (NULL); + } + p_args_escape_chars_and_quotes(words); + return (words); +} + +char + **p_split_args(char word[], int8_t redir) +{ + char **words; + size_t i; + + words = NULL; + if (redir == 0) + { + if ((words = p_split_words_no_rdr(word)) == NULL) + return (NULL); + return (words); + } + i = ft_strlen(word); + while (ft_ischarset("<>", word[i]) == FALSE) + i--; + i--; + while (redir > 0 && ft_isdigit(word[i]) == TRUE) + i--; + word[i] = C_NUL; + if ((words = p_split_words_no_rdr(word)) == NULL) + return (NULL); + return (words); + /* char **words; */ + /* char *subst; */ + /* size_t i; */ + + /* if (redir == 0) */ + /* { */ + /* if (!(words = ft_split(word, ' '))) */ + /* return (NULL); */ + /* return (words); */ + /* } */ + /* i = 0; */ + /* while (word[i] && ft_ischarset("<>", word[i]) == FALSE) */ + /* i++; */ + /* while (redir > 0 && ft_isdigit(word[i]) == TRUE) */ + /* i--; */ + /* if (!(subst = ft_substr(word, 0, i))) */ + /* return (NULL); */ + /* if (!(words = ft_split(subst, ' '))) */ + /* { */ + /* ft_memdel((void*)&subst); */ + /* return (NULL); */ + /* } */ + /* ft_memdel((void*)&subst); */ + /* return (words); */ +} |