+ } else {
+ cur = talloc_strndup(argv->argv, text, len);
+ }
+
+ argv->argv[argv->argc-1] = cur;
+}
+
+/* Add a word to the argv array. Depending on the word type, and presence of
+ * delimiter characters, we may add multiple items to the array.
+ */
+static void append_word_to_argv(struct grub2_script *script,
+ struct grub2_argv *argv, struct grub2_word *word)
+{
+ const char *text, *pos;
+ int i, len;
+
+ /* If it's a variable, perform substitution */
+ if (word->type == GRUB2_WORD_VAR)
+ text = expand_var(script, word);
+ else
+ text = word->text;
+
+ len = strlen(text);
+
+ /* If we have no text, we leave the current word as-is. The caller
+ * has allocated an empty string for the case where this is the
+ * first text token */
+ if (!len)
+ return;
+
+ /* If we're not splitting, we just add the entire block to the
+ * current argv item */
+ if (!word->split) {
+ append_text_to_current_arg(argv, text, len);
+ return;
+ }
+
+ /* Scan for delimiters. If we find a word-end boundary, add the word
+ * to the argv array, and start a new argv item */
+ pos = !is_delim(text[0]) ? text : NULL;
+ for (i = 0; i < len; i++) {
+
+ /* first delimiter after a word: add the accumulated word to
+ * argv */
+ if (pos && is_delim(text[i])) {
+ append_text_to_current_arg(argv, pos,
+ text + i - pos);
+ pos = NULL;
+
+ /* first non-delimeter after a delimiter: record the starting
+ * position, and create another argv item */
+ } else if (!pos && !is_delim(text[i])) {
+ pos = text + i;
+ argv->argc++;
+ argv->argv = talloc_realloc(argv, argv->argv, char *,
+ argv->argc);
+ argv->argv[argv->argc - 1] = NULL;
+ }
+ }
+
+ /* add remaining word characters */
+ if (pos)
+ append_text_to_current_arg(argv, pos, text + len - pos);