Handle quotes in WORD tokens
authorLukas Jiriste <ljiriste@student.42prague.com>
Mon, 22 Jul 2024 20:14:17 +0000 (22:14 +0200)
committerLukas Jiriste <ljiriste@student.42prague.com>
Mon, 22 Jul 2024 20:14:17 +0000 (22:14 +0200)
src/execution.c

index 04dea5863d49fa29c763e0acef2f0597917b3b37..8e1200c078a3ba5527bbf45f76ba3ea04a6bb799 100644 (file)
@@ -6,7 +6,7 @@
 /*   By: ljiriste <ljiriste@student.42prague.com>   +#+  +:+       +#+        */
 /*                                                +#+#+#+#+#+   +#+           */
 /*   Created: 2024/07/21 08:57:54 by ljiriste          #+#    #+#             */
-/*   Updated: 2024/07/22 20:42:30 by ljiriste         ###   ########.fr       */
+/*   Updated: 2024/07/22 22:11:44 by ljiriste         ###   ########.fr       */
 /*                                                                            */
 /* ************************************************************************** */
 
@@ -370,11 +370,15 @@ int       add_word(t_vec *exp_str, const char *word, const t_execution_env *env)
        size_t          i;
        char            *var;
        const char      *value;
+       int                     single_quoted;
 
+       single_quoted = 0;
        i = 0;
        while (word[i])
        {
-               if (word[i] == '$')
+               if (word[i] == '\'')
+                       single_quoted = !single_quoted;
+               if (word[i] == '$' && !single_quoted)
                {
                        ++i;
                        var = get_var_name(word + i);
@@ -418,12 +422,115 @@ int      expand_cmd(t_vec *exp_str, const t_parse_tree_node *node, const t_execution_
        return (0);
 }
 
+size_t get_next_word_size(const char *str)
+{
+       size_t  n;
+       char    quote;
+
+       quote = 0;
+       n = 0;
+       while (str[n])
+       {
+               if (str[n] == ' ' && !quote)
+                       break ;
+               if ((str[n] == '"' || str[n] == '\''))
+               {
+                       if (!quote)
+                               quote = str[n];
+                       else if (quote == str[n])
+                               quote = 0;
+               }
+               ++n;
+       }
+       return (n);
+}
+
+void   unquote_field(char *field)
+{
+       size_t  i;
+       char    quote;
+
+       quote = 0;
+       i = 0;
+       while (field[i])
+       {
+               if (field[i] == '"' || field[i] == '\'')
+               {
+                       if (!quote)
+                               quote = field[i];
+                       else if (quote == field[i])
+                               quote = 0;
+                       else
+                       {
+                               ++i;
+                               continue ;
+                       }
+                       ft_memmove(field + i, field + i + 1, ft_strlen(field + i + 1) + 1);
+               }
+               else
+                       ++i;
+       }
+       return ;
+}
+
+void   unquote(char **fields)
+{
+       size_t  i;
+
+       i = 0;
+       while (fields[i])
+       {
+               unquote_field(fields[i]);
+               ++i;
+       }
+       return ;
+}
+
+static const void      *nullptr = NULL;
+
+char   **quoted_split(const char *str)
+{
+       size_t  i;
+       size_t  n;
+       t_vec   fields;
+       char    *new_str;
+
+       if (ft_vec_init(&fields, sizeof(char *)) != success)
+               return (NULL);
+       i = 0;
+       while (str[i])
+       {
+               while (str[i] == ' ')
+                       ++i;
+               n = get_next_word_size(str + i);
+               new_str = ft_strndup(str + i, n);
+               if (!new_str)
+               {
+                       ft_vec_free(&fields, free);
+                       return (NULL);
+               }
+               if (ft_vec_append(&fields, &new_str) != success)
+               {
+                       ft_vec_free(&fields, free);
+                       free(new_str);
+                       return (NULL);
+               }
+               i += n;
+       }
+       if (ft_vec_append(&fields, &nullptr) != success)
+       {
+               ft_vec_free(&fields, free);
+               return (NULL);
+       }
+       return (fields.vec);
+}
+
 static const char      null_char = '\0';
 
 char   **expand(t_parse_tree_node *simple_command, const t_execution_env *env)
 {
        size_t                          i;
-       char                            **res;
+       char                            **fields;
        t_vec                           expanded_str;
        t_parse_tree_node       *subnode;
 
@@ -448,9 +555,10 @@ char       **expand(t_parse_tree_node *simple_command, const t_execution_env *env)
                ft_vec_free(&expanded_str, NULL);
                return (NULL);
        }
-       res = ft_split(expanded_str.vec, " ");
+       fields = quoted_split(expanded_str.vec);
        ft_vec_free(&expanded_str, NULL);
-       return (res);
+       unquote(fields);
+       return (fields);
 }
 
 int    assignments_to_env(const t_vec *assignments, t_execution_env *env)