]> git.ipfire.org Git - thirdparty/grub.git/commitdiff
move wildcard translator into regexp module
authorBVK Chaitanya <bvk.groups@gmail.com>
Thu, 29 Jul 2010 18:02:56 +0000 (23:32 +0530)
committerBVK Chaitanya <bvk.groups@gmail.com>
Thu, 29 Jul 2010 18:02:56 +0000 (23:32 +0530)
commands/regexp.c
commands/wildcard.c [new file with mode: 0644]
conf/common.rmk
script/argv.c
script/execute.c
tests/grub_script_expansion.in

index e8e8243b5e6eefc65ead4bc20c5f15ecb7b7b35b..05f6d55ad3e46f76a436bf83b458a24ce173b4d7 100644 (file)
@@ -22,6 +22,7 @@
 #include <grub/mm.h>
 #include <grub/command.h>
 #include <grub/i18n.h>
+#include <grub/script_sh.h>
 #include <regex.h>
 
 static grub_err_t
@@ -69,9 +70,14 @@ static grub_command_t cmd;
 \f
 GRUB_MOD_INIT(regexp)
 {
+  extern struct grub_script_wildcard_translator translator;
+
   cmd = grub_register_command ("regexp", grub_cmd_regexp,
                               N_("REGEXP STRING"),
                               N_("Test if REGEXP matches STRING."));
+
+  /* Setup GRUB script wildcard translator.  */
+  wildcard_translator = &translator;
 }
 
 GRUB_MOD_FINI(regexp)
diff --git a/commands/wildcard.c b/commands/wildcard.c
new file mode 100644 (file)
index 0000000..7f37c84
--- /dev/null
@@ -0,0 +1,493 @@
+/* wildcard.c - Wildcard character expansion for GRUB script.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2010  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/mm.h>
+#include <grub/fs.h>
+#include <grub/env.h>
+#include <grub/file.h>
+#include <grub/device.h>
+#include <grub/script_sh.h>
+
+#include <regex.h>
+
+static inline int isregexop (char ch);
+static char ** merge (char **lhs, char **rhs);
+static char *make_dir (const char *prefix, const char *start, const char *end);
+static int make_regex (const char *regex_start, const char *regex_end,
+                      regex_t *regexp);
+static void split_path (const char *path, const char **suffix_end, const char **regex_end);
+static char ** match_devices (const regex_t *regexp, int noparts);
+static char ** match_files (const char *prefix, const char *suffix_start,
+                           const char *suffix_end, const regex_t *regexp);
+
+static char* wildcard_escape (const char *s);
+static char* wildcard_unescape (const char *s);
+static grub_err_t wildcard_expand (const char *s, char ***strs);
+
+struct grub_script_wildcard_translator translator = {
+  .expand = wildcard_expand,
+  .escape = wildcard_escape,
+  .unescape = wildcard_unescape
+};
+
+static char **
+merge (char **dest, char **ps)
+{
+  int i;
+  int j;
+  char **p;
+
+  if (! dest)
+    return ps;
+
+  if (! ps)
+    return dest;
+
+  for (i = 0; dest[i]; i++)
+    ;
+  for (j = 0; ps[j]; j++)
+    ;
+
+  p = grub_realloc (dest, sizeof (char*) * (i + j + 1));
+  if (! p)
+    {
+      grub_free (dest);
+      grub_free (ps);
+      return 0;
+    }
+
+  for (j = 0; ps[j]; j++)
+    dest[i++] = ps[j];
+  dest[i] = 0;
+
+  grub_free (ps);
+  return dest;
+}
+
+static inline int
+isregexop (char ch)
+{
+  return grub_strchr ("*.\\", ch) ? 1 : 0;
+}
+
+static char *
+make_dir (const char *prefix, const char *start, const char *end)
+{
+  char ch;
+  unsigned i;
+  unsigned n;
+  char *result;
+
+  i = grub_strlen (prefix);
+  n = i + end - start;
+
+  result = grub_malloc (n + 1);
+  if (! result)
+    return 0;
+
+  grub_strcpy (result, prefix);
+  while (start < end && (ch = *start++))
+    if (ch == '\\' && isregexop (*start))
+      result[i++] = *start++;
+    else
+      result[i++] = ch;
+
+  result[i] = '\0';
+  return result;
+}
+
+static int
+make_regex (const char *start, const char *end, regex_t *regexp)
+{
+  char ch;
+  int i = 0;
+  unsigned len = end - start;
+  char *buffer = grub_malloc (len * 2 + 2 + 1); /* worst case size. */
+
+  if (! buffer)
+    return 1;
+
+  buffer[i++] = '^';
+  while (start < end)
+    {
+      /* XXX Only * expansion for now.  */
+      switch ((ch = *start++))
+       {
+       case '\\':
+         buffer[i++] = ch;
+         if (*start != '\0')
+           buffer[i++] = *start++;
+         break;
+
+       case '.':
+         buffer[i++] = '\\';
+         buffer[i++] = '.';
+         break;
+
+       case '*':
+         buffer[i++] = '.';
+         buffer[i++] = '*';
+         break;
+
+       default:
+         buffer[i++] = ch;
+       }
+    }
+  buffer[i++] = '$';
+  buffer[i] = '\0';
+
+  if (regcomp (regexp, buffer, RE_SYNTAX_GNU_AWK))
+    {
+      grub_free (buffer);
+      return 1;
+    }
+
+  grub_free (buffer);
+  return 0;
+}
+
+/* Split `str' into two parts: (1) dirname that is regexop free (2)
+   dirname that has a regexop.  */
+static void
+split_path (const char *str, const char **noregexop, const char **regexop)
+{
+  char ch = 0;
+  int regex = 0;
+
+  const char *end;
+  const char *split;  /* points till the end of dirnaname that doesn't
+                        need expansion.  */
+
+  split = end = str;
+  while ((ch = *end))
+    {
+      if (ch == '\\' && end[1])
+       end++;
+
+      else if (isregexop (ch))
+       regex = 1;
+
+      else if (ch == '/' && ! regex)
+       split = end + 1;  /* forward to next regexop-free dirname */
+
+      else if (ch == '/' && regex)
+       break;  /* stop at the first dirname with a regexop */
+
+      end++;
+    }
+
+  *regexop = end;
+  if (! regex)
+    *noregexop = end;
+  else
+    *noregexop = split;
+}
+
+static char **
+match_devices (const regex_t *regexp, int noparts)
+{
+  int i;
+  int ndev;
+  char **devs;
+
+  auto int match (const char *name);
+  int match (const char *name)
+  {
+    char **t;
+    char *buffer;
+
+    /* skip partitions if asked to. */
+    if (noparts && grub_strchr(name, ','))
+      return 0;
+
+    buffer = grub_xasprintf ("(%s)", name);
+    if (! buffer)
+      return 1;
+
+    grub_dprintf ("expand", "matching: %s\n", buffer);
+    if (regexec (regexp, buffer, 0, 0, 0))
+      {
+       grub_free (buffer);
+       return 0;
+      }
+
+    t = grub_realloc (devs, sizeof (char*) * (ndev + 2));
+    if (! t)
+      return 1;
+
+    devs = t;
+    devs[ndev++] = buffer;
+    devs[ndev] = 0;
+    return 0;
+  }
+
+  ndev = 0;
+  devs = 0;
+
+  if (grub_device_iterate (match))
+    goto fail;
+
+  return devs;
+
+ fail:
+
+  for (i = 0; devs && devs[i]; i++)
+    grub_free (devs[i]);
+
+  if (devs)
+    grub_free (devs);
+
+  return 0;
+}
+
+static char **
+match_files (const char *prefix, const char *suffix, const char *end,
+            const regex_t *regexp)
+{
+  int i;
+  int error;
+  char **files;
+  unsigned nfile;
+  char *dir;
+  const char *path;
+  char *device_name;
+  grub_fs_t fs;
+  grub_device_t dev;
+
+  auto int match (const char *name, const struct grub_dirhook_info *info);
+  int match (const char *name, const struct grub_dirhook_info *info)
+  {
+    char **t;
+    char *buffer;
+
+    /* skip hidden files, . and .. */
+    if (name[0] == '.')
+      return 0;
+
+    grub_dprintf ("expand", "matching: %s in %s\n", name, dir);
+    if (regexec (regexp, name, 0, 0, 0))
+      return 0;
+
+    buffer = grub_xasprintf ("%s%s", dir, name);
+    if (! buffer)
+      return 1;
+
+    t = grub_realloc (files, sizeof (char*) * (nfile + 2));
+    if (! t)
+      {
+       grub_free (buffer);
+       return 1;
+      }
+
+    files = t;
+    files[nfile++] = buffer;
+    files[nfile] = 0;
+    return 0;
+  }
+
+  nfile = 0;
+  files = 0;
+  dev = 0;
+  device_name = 0;
+  grub_error_push ();
+
+  dir = make_dir (prefix, suffix, end);
+  if (! dir)
+    goto fail;
+
+  device_name = grub_file_get_device_name (dir);
+  dev = grub_device_open (device_name);
+  if (! dev)
+    goto fail;
+
+  fs = grub_fs_probe (dev);
+  if (! fs)
+    goto fail;
+
+  path = grub_strchr (dir, ')');
+  if (! path)
+    goto fail;
+  path++;
+
+  if (fs->dir (dev, path, match))
+    goto fail;
+
+  grub_free (dir);
+  grub_device_close (dev);
+  grub_free (device_name);
+  grub_error_pop ();
+  return files;
+
+ fail:
+
+  if (dir)
+    grub_free (dir);
+
+  for (i = 0; files && files[i]; i++)
+    grub_free (files[i]);
+
+  if (files)
+    grub_free (files);
+
+  if (dev)
+    grub_device_close (dev);
+
+  if (device_name)
+    grub_free (device_name);
+
+  grub_error_pop ();
+  return 0;
+}
+
+static char*
+wildcard_escape (const char *s)
+{
+  int i;
+  int len;
+  char ch;
+  char *p;
+
+  len = grub_strlen (s);
+  p = grub_malloc (len * 2 + 1);
+  if (! p)
+    return NULL;
+
+  i = 0;
+  while ((ch = *s++))
+    {
+      if (isregexop (ch))
+       p[i++] = '\\';
+      p[i++] = ch;
+    }
+  p[i] = '\0';
+  return p;
+}
+
+static char*
+wildcard_unescape (const char *s)
+{
+  int i;
+  int len;
+  char ch;
+  char *p;
+
+  len = grub_strlen (s);
+  p = grub_malloc (len + 1);
+  if (! p)
+    return NULL;
+
+  i = 0;
+  while ((ch = *s++))
+    {
+      if (ch == '\\' && isregexop (*s))
+       p[i++] = *s++;
+      else
+       p[i++] = ch;
+    }
+  p[i] = '\0';
+  return p;
+}
+
+static grub_err_t
+wildcard_expand (const char *s, char ***strs)
+{
+  const char *start;
+  const char *regexop;
+  const char *noregexop;
+  char **paths = 0;
+
+  unsigned i;
+  regex_t regexp;
+
+  start = s;
+  while (*start)
+    {
+      split_path (start, &noregexop, &regexop);
+      if (noregexop >= regexop) /* no more wildcards */
+       break;
+
+      if (make_regex (noregexop, regexop, &regexp))
+       goto fail;
+
+      if (paths == 0)
+       {
+         if (start == noregexop) /* device part has regexop */
+           paths = match_devices (&regexp, *start != '(');
+
+         else if (*start == '(') /* device part explicit wo regexop */
+           paths = match_files ("", start, noregexop, &regexp);
+
+         else if (*start == '/') /* no device part */
+           {
+             char **r;
+             unsigned n;
+             char *root;
+             char *prefix;
+
+             root = grub_env_get ("root");
+             if (! root)
+               goto fail;
+
+             prefix = grub_xasprintf ("(%s)", root);
+             if (! prefix)
+               goto fail;
+
+             paths = match_files (prefix, start, noregexop, &regexp);
+             grub_free (prefix);
+           }
+       }
+      else
+       {
+         char **r = 0;
+
+         for (i = 0; paths[i]; i++)
+           {
+             char **p;
+
+             p = match_files (paths[i], start, noregexop, &regexp);
+             if (! p)
+               continue;
+
+             r = merge (r, p);
+             if (! r)
+               goto fail;
+           }
+         paths = r;
+       }
+
+      regfree (&regexp);
+      if (! paths)
+       goto done;
+
+      start = regexop;
+    }
+
+ done:
+
+  *strs = paths;
+  return 0;
+
+ fail:
+
+  for (i = 0; paths && paths[i]; i++)
+    grub_free (paths[i]);
+  grub_free (paths[i]);
+  regfree (&regexp);
+  return grub_errno;
+}
index 24d7921f5bf7cced41abd3e06f303b8bb72f6c6e..24baa3bfc2d060b0f6eab9dac7b9c02b1fb69b8a 100644 (file)
@@ -638,7 +638,7 @@ normal_mod_SOURCES = normal/main.c normal/cmdline.c normal/dyncmd.c \
        normal/misc.c normal/crypto.c normal/term.c normal/context.c \
        script/main.c script/script.c script/execute.c script/argv.c unidata.c \
        script/function.c script/lexer.c grub_script.tab.c grub_script.yy.c
-normal_mod_CFLAGS = $(COMMON_CFLAGS) $(POSIX_CFLAGS) $(GNULIB_CFLAGS) -Wno-error
+normal_mod_CFLAGS = $(COMMON_CFLAGS) $(POSIX_CFLAGS) -Wno-error
 normal_mod_LDFLAGS = $(COMMON_LDFLAGS)
 
 ifneq (, $(FONT_SOURCE))
@@ -764,7 +764,7 @@ setjmp_mod_ASFLAGS = $(COMMON_ASFLAGS)
 setjmp_mod_LDFLAGS = $(COMMON_LDFLAGS)
 
 pkglib_MODULES += regexp.mod
-regexp_mod_SOURCES = gnulib/regex.c commands/regexp.c
+regexp_mod_SOURCES = gnulib/regex.c commands/regexp.c commands/wildcard.c
 regexp_mod_CFLAGS = $(COMMON_CFLAGS) $(GNULIB_CFLAGS)
 regexp_mod_LDFLAGS = $(COMMON_LDFLAGS)
 
index 15c6c6ed4c79b9a58378b6db8b9ce5038b8f3d08..6e93edaeecb7cb28bd390a6d706b6e61c46ac982 100644 (file)
  */
 
 #include <grub/mm.h>
-#include <grub/fs.h>
-#include <grub/env.h>
-#include <grub/file.h>
-#include <grub/device.h>
+#include <grub/misc.h>
 #include <grub/script_sh.h>
 
-#include <regex.h>
-
-#define ARG_ALLOCATION_UNIT  (32 * sizeof (char))
-#define ARGV_ALLOCATION_UNIT (8 * sizeof (void*))
-
 static unsigned
 round_up_exp (unsigned v)
 {
@@ -48,27 +40,6 @@ round_up_exp (unsigned v)
   return v;
 }
 
-static inline int isregexop (char ch);
-static char ** merge (char **lhs, char **rhs);
-static char *make_dir (const char *prefix, const char *start, const char *end);
-static int make_regex (const char *regex_start, const char *regex_end,
-                      regex_t *regexp);
-static void split_path (const char *path, const char **suffix_end, const char **regex_end);
-static char ** match_devices (const regex_t *regexp, int noparts);
-static char ** match_files (const char *prefix, const char *suffix_start,
-                           const char *suffix_end, const regex_t *regexp);
-
-static char* wildcard_escape (const char *s);
-static char* wildcard_unescape (const char *s);
-static grub_err_t wildcard_expand (const char *s, char ***strs);
-
-static struct grub_script_wildcard_translator translator = {
-  .expand = wildcard_expand,
-  .escape = wildcard_escape,
-  .unescape = wildcard_unescape
-};
-struct grub_script_wildcard_translator *wildcard_translator = &translator;
-
 void
 grub_script_argv_free (struct grub_script_argv *argv)
 {
@@ -162,444 +133,3 @@ grub_script_argv_split_append (struct grub_script_argv *argv, char *s)
     }
   return errors;
 }
-
-static char **
-merge (char **dest, char **ps)
-{
-  int i;
-  int j;
-  char **p;
-
-  if (! dest)
-    return ps;
-
-  if (! ps)
-    return dest;
-
-  for (i = 0; dest[i]; i++)
-    ;
-  for (j = 0; ps[j]; j++)
-    ;
-
-  p = grub_realloc (dest, sizeof (char*) * (i + j + 1));
-  if (! p)
-    {
-      grub_free (dest);
-      grub_free (ps);
-      return 0;
-    }
-
-  for (j = 0; ps[j]; j++)
-    dest[i++] = ps[j];
-  dest[i] = 0;
-
-  grub_free (ps);
-  return dest;
-}
-
-static inline int
-isregexop (char ch)
-{
-  return grub_strchr ("*.\\", ch) ? 1 : 0;
-}
-
-static char *
-make_dir (const char *prefix, const char *start, const char *end)
-{
-  char ch;
-  unsigned i;
-  unsigned n;
-  char *result;
-
-  i = grub_strlen (prefix);
-  n = i + end - start;
-
-  result = grub_malloc (n + 1);
-  if (! result)
-    return 0;
-
-  grub_strcpy (result, prefix);
-  while (start < end && (ch = *start++))
-    if (ch == '\\' && isregexop (*start))
-      result[i++] = *start++;
-    else
-      result[i++] = ch;
-
-  result[i] = '\0';
-  return result;
-}
-
-static int
-make_regex (const char *start, const char *end, regex_t *regexp)
-{
-  char ch;
-  int i = 0;
-  unsigned len = end - start;
-  char *buffer = grub_malloc (len * 2 + 1); /* worst case size. */
-
-  while (start < end)
-    {
-      /* XXX Only * expansion for now.  */
-      switch ((ch = *start++))
-       {
-       case '\\':
-         buffer[i++] = ch;
-         if (*start != '\0')
-           buffer[i++] = *start++;
-         break;
-
-       case '.':
-         buffer[i++] = '\\';
-         buffer[i++] = '.';
-         break;
-
-       case '*':
-         buffer[i++] = '.';
-         buffer[i++] = '*';
-         break;
-
-       default:
-         buffer[i++] = ch;
-       }
-    }
-  buffer[i] = '\0';
-
-  if (regcomp (regexp, buffer, RE_SYNTAX_GNU_AWK))
-    {
-      grub_free (buffer);
-      return 1;
-    }
-
-  grub_free (buffer);
-  return 0;
-}
-
-/* Split `str' into two parts: (1) dirname that is regexop free (2)
-   dirname that has a regexop.  */
-static void
-split_path (const char *str, const char **noregexop, const char **regexop)
-{
-  char ch = 0;
-  int regex = 0;
-
-  const char *end;
-  const char *split;  /* points till the end of dirnaname that doesn't
-                        need expansion.  */
-
-  split = end = str;
-  while ((ch = *end))
-    {
-      if (ch == '\\' && end[1])
-       end++;
-
-      else if (isregexop (ch))
-       regex = 1;
-
-      else if (ch == '/' && ! regex)
-       split = end + 1;  /* forward to next regexop-free dirname */
-
-      else if (ch == '/' && regex)
-       break;  /* stop at the first dirname with a regexop */
-
-      end++;
-    }
-
-  *regexop = end;
-  if (! regex)
-    *noregexop = end;
-  else
-    *noregexop = split;
-}
-
-static char **
-match_devices (const regex_t *regexp, int noparts)
-{
-  int i;
-  int ndev;
-  char **devs;
-
-  auto int match (const char *name);
-  int match (const char *name)
-  {
-    char **t;
-    char *buffer;
-
-    /* skip partitions if asked to. */
-    if (noparts && grub_strchr(name, ','))
-      return 0;
-
-    buffer = grub_xasprintf ("(%s)", name);
-    if (! buffer)
-      return 1;
-
-    grub_dprintf ("expand", "matching: %s\n", buffer);
-    if (regexec (regexp, buffer, 0, 0, 0))
-      {
-       grub_free (buffer);
-       return 0;
-      }
-
-    t = grub_realloc (devs, sizeof (char*) * (ndev + 2));
-    if (! t)
-      return 1;
-
-    devs = t;
-    devs[ndev++] = buffer;
-    devs[ndev] = 0;
-    return 0;
-  }
-
-  ndev = 0;
-  devs = 0;
-
-  if (grub_device_iterate (match))
-    goto fail;
-
-  return devs;
-
- fail:
-
-  for (i = 0; devs && devs[i]; i++)
-    grub_free (devs[i]);
-
-  if (devs)
-    grub_free (devs);
-
-  return 0;
-}
-
-static char **
-match_files (const char *prefix, const char *suffix, const char *end,
-            const regex_t *regexp)
-{
-  int i;
-  int error;
-  char **files;
-  unsigned nfile;
-  char *dir;
-  const char *path;
-  char *device_name;
-  grub_fs_t fs;
-  grub_device_t dev;
-
-  auto int match (const char *name, const struct grub_dirhook_info *info);
-  int match (const char *name, const struct grub_dirhook_info *info)
-  {
-    char **t;
-    char *buffer;
-
-    /* skip hidden files, . and .. */
-    if (name[0] == '.')
-      return 0;
-
-    grub_dprintf ("expand", "matching: %s in %s\n", name, dir);
-    if (regexec (regexp, name, 0, 0, 0))
-      return 0;
-
-    buffer = grub_xasprintf ("%s%s", dir, name);
-    if (! buffer)
-      return 1;
-
-    t = grub_realloc (files, sizeof (char*) * (nfile + 2));
-    if (! t)
-      {
-       grub_free (buffer);
-       return 1;
-      }
-
-    files = t;
-    files[nfile++] = buffer;
-    files[nfile] = 0;
-    return 0;
-  }
-
-  nfile = 0;
-  files = 0;
-  dev = 0;
-  device_name = 0;
-  grub_error_push ();
-
-  dir = make_dir (prefix, suffix, end);
-  if (! dir)
-    goto fail;
-
-  device_name = grub_file_get_device_name (dir);
-  dev = grub_device_open (device_name);
-  if (! dev)
-    goto fail;
-
-  fs = grub_fs_probe (dev);
-  if (! fs)
-    goto fail;
-
-  path = grub_strchr (dir, ')');
-  if (! path)
-    goto fail;
-  path++;
-
-  if (fs->dir (dev, path, match))
-    goto fail;
-
-  grub_free (dir);
-  grub_device_close (dev);
-  grub_free (device_name);
-  grub_error_pop ();
-  return files;
-
- fail:
-
-  if (dir)
-    grub_free (dir);
-
-  for (i = 0; files && files[i]; i++)
-    grub_free (files[i]);
-
-  if (files)
-    grub_free (files);
-
-  if (dev)
-    grub_device_close (dev);
-
-  if (device_name)
-    grub_free (device_name);
-
-  grub_error_pop ();
-  return 0;
-}
-
-static char*
-wildcard_escape (const char *s)
-{
-  int i;
-  int len;
-  char ch;
-  char *p;
-
-  len = grub_strlen (s);
-  p = grub_malloc (len * 2 + 1);
-  if (! p)
-    return NULL;
-
-  i = 0;
-  while ((ch = *s++))
-    {
-      if (isregexop (ch))
-       p[i++] = '\\';
-      p[i++] = ch;
-    }
-  p[i] = '\0';
-  return p;
-}
-
-static char*
-wildcard_unescape (const char *s)
-{
-  int i;
-  int len;
-  char ch;
-  char *p;
-
-  len = grub_strlen (s);
-  p = grub_malloc (len + 1);
-  if (! p)
-    return NULL;
-
-  i = 0;
-  while ((ch = *s++))
-    {
-      if (ch == '\\' && isregexop (*s))
-       p[i++] = *s++;
-      else
-       p[i++] = ch;
-    }
-  p[i] = '\0';
-  return p;
-}
-
-static grub_err_t
-wildcard_expand (const char *s, char ***strs)
-{
-  const char *start;
-  const char *regexop;
-  const char *noregexop;
-  char **paths = 0;
-
-  unsigned i;
-  regex_t regexp;
-
-  start = s;
-  while (*start)
-    {
-      split_path (start, &noregexop, &regexop);
-      if (noregexop >= regexop) /* no more wildcards */
-       break;
-
-      if (make_regex (noregexop, regexop, &regexp))
-       goto fail;
-
-      if (paths == 0)
-       {
-         if (start == noregexop) /* device part has regexop */
-           paths = match_devices (&regexp, *start != '(');
-
-         else if (*start == '(') /* device part explicit wo regexop */
-           paths = match_files ("", start, noregexop, &regexp);
-
-         else if (*start == '/') /* no device part */
-           {
-             char **r;
-             unsigned n;
-             char *root;
-             char *prefix;
-
-             root = grub_env_get ("root");
-             if (! root)
-               goto fail;
-
-             prefix = grub_xasprintf ("(%s)", root);
-             if (! prefix)
-               goto fail;
-
-             paths = match_files (prefix, start, noregexop, &regexp);
-             grub_free (prefix);
-           }
-       }
-      else
-       {
-         char **r = 0;
-
-         for (i = 0; paths[i]; i++)
-           {
-             char **p;
-
-             p = match_files (paths[i], start, noregexop, &regexp);
-             if (! p)
-               continue;
-
-             r = merge (r, p);
-             if (! r)
-               goto fail;
-           }
-         paths = r;
-       }
-
-      regfree (&regexp);
-      if (! paths)
-       goto done;
-
-      start = regexop;
-    }
-
- done:
-
-  *strs = paths;
-  return 0;
-
- fail:
-
-  for (i = 0; paths && paths[i]; i++)
-    grub_free (paths[i]);
-  grub_free (paths[i]);
-  regfree (&regexp);
-  return grub_errno;
-}
index a41719091ff07905622969d0b151d6acc8fa4eea..20ad42add6d8698b19016cb46f616bd4cc803152 100644 (file)
@@ -37,6 +37,9 @@ struct grub_script_scope
 };
 static struct grub_script_scope *scope = 0;
 
+/* Wildcard translator for GRUB script.  */
+struct grub_script_wildcard_translator *wildcard_translator;
+
 static int
 grub_env_special (const char *name)
 {
index 11aafc8539f502357d674104593b13a05ee693f4..d1e8d55c99541464662840170c58d59c778f6598 100644 (file)
@@ -17,7 +17,7 @@
 # along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
 
 disks=`echo ls | @builddir@/grub-shell`
-other=`echo echo \* | @builddir@/grub-shell`
+other=`echo insmod regexp\; echo \* | @builddir@/grub-shell`
 for d in $disks; do
     if echo "$d" |grep ',' >/dev/null; then
        if echo "$other" | grep "$d" >/dev/null; then
@@ -32,7 +32,7 @@ for d in $disks; do
     fi
 done
 
-other=`echo echo '(*)' | @builddir@/grub-shell`
+other=`echo insmod regexp\; echo '(*)' | @builddir@/grub-shell`
 for d in $disks; do
     if ! echo "$other" | grep "$d" >/dev/null; then
        echo "$d missing from (*) expansion" >&2