]> git.proxmox.com Git - grub2.git/blame - grub-core/commands/regexp.c
probe: Support probing for partition UUID with --part-uuid
[grub2.git] / grub-core / commands / regexp.c
CommitLineData
3251f0f8
VS
1/* regexp.c -- The regexp command. */
2/*
3 * GRUB -- GRand Unified Bootloader
4 * Copyright (C) 2005,2007 Free Software Foundation, Inc.
5 *
6 * GRUB is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * GRUB is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20#include <grub/dl.h>
21#include <grub/misc.h>
22#include <grub/mm.h>
262b2d73
BC
23#include <grub/err.h>
24#include <grub/env.h>
1355b096 25#include <grub/extcmd.h>
d8b5cd40 26#include <grub/i18n.h>
3c6a9151 27#include <grub/script_sh.h>
74f34747 28#include <regex.h>
3251f0f8 29
e745cf0c
VS
30GRUB_MOD_LICENSE ("GPLv3+");
31
1355b096
BC
32static const struct grub_arg_option options[] =
33 {
34 { "set", 's', GRUB_ARG_OPTION_REPEATABLE,
e7d2559b
VS
35 /* TRANSLATORS: in regexp you can mark some
36 groups with parentheses. These groups are
37 then numbered and you can save some of
38 them in variables. In other programs
39 those components aree often referenced with
40 back slash, e.g. \1. Compare
0ae4f0bd
VS
41 sed -e 's,\([a-z][a-z]*\),lowercase=\1,g'
42 The whole matching component is saved in VARNAME, not its number.
e7d2559b 43 */
9c4b5c13 44 N_("Store matched component NUMBER in VARNAME."),
1355b096
BC
45 N_("[NUMBER:]VARNAME"), ARG_TYPE_STRING },
46 { 0, 0, 0, 0, 0, 0 }
47 };
48
cb758e96
VS
49static grub_err_t
50setvar (char *str, char *v, regmatch_t *m)
51{
52 char ch;
53 grub_err_t err;
54 ch = str[m->rm_eo];
55 str[m->rm_eo] = '\0';
56 err = grub_env_set (v, str + m->rm_so);
57 str[m->rm_eo] = ch;
58 return err;
59}
60
1355b096
BC
61static grub_err_t
62set_matches (char **varnames, char *str, grub_size_t nmatches,
63 regmatch_t *matches)
64{
65 int i;
1355b096
BC
66 char *p;
67 char *q;
68 grub_err_t err;
69 unsigned long j;
70
1355b096
BC
71 for (i = 0; varnames && varnames[i]; i++)
72 {
cb758e96 73 err = GRUB_ERR_NONE;
9c4b5c13
VS
74 p = grub_strchr (varnames[i], ':');
75 if (! p)
1355b096
BC
76 {
77 /* varname w/o index defaults to 1 */
78 if (nmatches < 2 || matches[1].rm_so == -1)
79 grub_env_unset (varnames[i]);
80 else
cb758e96 81 err = setvar (str, varnames[i], &matches[1]);
1355b096
BC
82 }
83 else
84 {
85 j = grub_strtoul (varnames[i], &q, 10);
86 if (q != p)
87 return grub_error (GRUB_ERR_BAD_ARGUMENT,
88 "invalid variable name format %s", varnames[i]);
89
90 if (nmatches <= j || matches[j].rm_so == -1)
91 grub_env_unset (p + 1);
92 else
cb758e96 93 err = setvar (str, p + 1, &matches[j]);
1355b096
BC
94 }
95
96 if (err != GRUB_ERR_NONE)
97 return err;
98 }
99 return GRUB_ERR_NONE;
100}
101
3251f0f8 102static grub_err_t
1355b096 103grub_cmd_regexp (grub_extcmd_context_t ctxt, int argc, char **args)
3251f0f8 104{
3251f0f8
VS
105 regex_t regex;
106 int ret;
107 grub_size_t s;
108 char *comperr;
109 grub_err_t err;
262b2d73 110 regmatch_t *matches = 0;
3251f0f8
VS
111
112 if (argc != 2)
9c4b5c13 113 return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("two arguments expected"));
3251f0f8 114
262b2d73 115 ret = regcomp (&regex, args[0], REG_EXTENDED);
3251f0f8
VS
116 if (ret)
117 goto fail;
118
262b2d73
BC
119 matches = grub_zalloc (sizeof (*matches) * (regex.re_nsub + 1));
120 if (! matches)
121 goto fail;
122
123 ret = regexec (&regex, args[1], regex.re_nsub + 1, matches, 0);
3251f0f8
VS
124 if (!ret)
125 {
1355b096
BC
126 err = set_matches (ctxt->state[0].args, args[1],
127 regex.re_nsub + 1, matches);
3251f0f8 128 regfree (&regex);
262b2d73 129 grub_free (matches);
1355b096 130 return err;
3251f0f8
VS
131 }
132
133 fail:
262b2d73 134 grub_free (matches);
3251f0f8
VS
135 s = regerror (ret, &regex, 0, 0);
136 comperr = grub_malloc (s);
137 if (!comperr)
138 {
139 regfree (&regex);
140 return grub_errno;
141 }
142 regerror (ret, &regex, comperr, s);
143 err = grub_error (GRUB_ERR_TEST_FAILURE, "%s", comperr);
144 regfree (&regex);
145 grub_free (comperr);
146 return err;
147}
148
1355b096 149static grub_extcmd_t cmd;
3251f0f8
VS
150\f
151GRUB_MOD_INIT(regexp)
152{
40211ab8
VS
153 cmd = grub_register_extcmd ("regexp", grub_cmd_regexp, 0,
154 /* TRANSLATORS: This are two arguments. So it's
155 two separate units to translate and pay
156 attention not to reverse them. */
157 N_("REGEXP STRING"),
1355b096 158 N_("Test if REGEXP matches STRING."), options);
3c6a9151
BC
159
160 /* Setup GRUB script wildcard translator. */
cc7b1ab4 161 grub_wildcard_translator = &grub_filename_translator;
3251f0f8
VS
162}
163
164GRUB_MOD_FINI(regexp)
165{
1355b096 166 grub_unregister_extcmd (cmd);
cc7b1ab4 167 grub_wildcard_translator = 0;
3251f0f8 168}