tpm2_key_protector: Enable build for powerpc_ieee1275
[grub.git] / grub-core / script / argv.c
blob5751fdd57082cd5faf88d90680eddea407a4f2f9
1 /* argv.c - methods for constructing argument vector */
2 /*
3 * GRUB -- GRand Unified Bootloader
4 * Copyright (C) 2010 Free Software Foundation, Inc.
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.
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.
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/>.
20 #include <grub/mm.h>
21 #include <grub/misc.h>
22 #include <grub/script_sh.h>
23 #include <grub/safemath.h>
25 /* Return nearest power of two that is >= v. */
26 static unsigned
27 round_up_exp (unsigned v)
29 COMPILE_TIME_ASSERT (sizeof (v) == 4);
31 v--;
32 v |= v >> 1;
33 v |= v >> 2;
34 v |= v >> 4;
35 v |= v >> 8;
36 v |= v >> 16;
38 v++;
39 v += (v == 0);
41 return v;
44 void
45 grub_script_argv_free (struct grub_script_argv *argv)
47 unsigned i;
49 if (argv->args)
51 for (i = 0; i < argv->argc; i++)
52 grub_free (argv->args[i]);
54 grub_free (argv->args);
57 argv->argc = 0;
58 argv->args = 0;
59 argv->script = 0;
62 /* Make argv from argc, args pair. */
63 int
64 grub_script_argv_make (struct grub_script_argv *argv, int argc, char **args)
66 int i;
67 struct grub_script_argv r = { 0, 0, 0 };
69 for (i = 0; i < argc; i++)
70 if (grub_script_argv_next (&r)
71 || grub_script_argv_append (&r, args[i], grub_strlen (args[i])))
73 grub_script_argv_free (&r);
74 return 1;
76 *argv = r;
77 return 0;
80 /* Prepare for next argc. */
81 int
82 grub_script_argv_next (struct grub_script_argv *argv)
84 char **p = argv->args;
85 grub_size_t sz;
87 if (argv->args && argv->argc && argv->args[argv->argc - 1] == 0)
88 return 0;
90 if (grub_add (argv->argc, 2, &sz) ||
91 grub_mul (sz, sizeof (char *), &sz))
92 return 1;
94 p = grub_realloc (p, round_up_exp (sz));
95 if (! p)
96 return 1;
98 argv->argc++;
99 argv->args = p;
101 if (argv->argc == 1)
102 argv->args[0] = 0;
103 argv->args[argv->argc] = 0;
104 return 0;
107 /* Append `s' to the last argument. */
109 grub_script_argv_append (struct grub_script_argv *argv, const char *s,
110 grub_size_t slen)
112 grub_size_t a;
113 char *p = argv->args[argv->argc - 1];
114 grub_size_t sz;
116 if (! s)
117 return 0;
119 a = p ? grub_strlen (p) : 0;
121 if (grub_add (a, slen, &sz) ||
122 grub_add (sz, 1, &sz) ||
123 grub_mul (sz, sizeof (char), &sz))
124 return 1;
126 p = grub_realloc (p, round_up_exp (sz));
127 if (! p)
128 return 1;
130 grub_memcpy (p + a, s, slen);
131 p[a+slen] = 0;
132 argv->args[argv->argc - 1] = p;
134 return 0;
137 /* Split `s' and append words as multiple arguments. */
139 grub_script_argv_split_append (struct grub_script_argv *argv, const char *s)
141 const char *p;
142 int errors = 0;
144 if (! s)
145 return 0;
147 while (*s && grub_isspace (*s))
148 s++;
150 while (! errors && *s)
152 p = s;
153 while (*s && ! grub_isspace (*s))
154 s++;
156 errors += grub_script_argv_append (argv, p, s - p);
158 while (*s && grub_isspace (*s))
159 s++;
161 if (*s)
162 errors += grub_script_argv_next (argv);
164 return errors;