Upgraded GRUB2 to 2.00 release.
[AROS.git] / arch / all-pc / boot / grub2-aros / grub-core / script / argv.c
blob217ec5d1e1b2fda0ca9ff633f60a2f12a57667e3
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>
24 /* Return nearest power of two that is >= v. */
25 static unsigned
26 round_up_exp (unsigned v)
28 COMPILE_TIME_ASSERT (sizeof (v) == 4);
30 v--;
31 v |= v >> 1;
32 v |= v >> 2;
33 v |= v >> 4;
34 v |= v >> 8;
35 v |= v >> 16;
37 v++;
38 v += (v == 0);
40 return v;
43 void
44 grub_script_argv_free (struct grub_script_argv *argv)
46 unsigned i;
48 if (argv->args)
50 for (i = 0; i < argv->argc; i++)
51 grub_free (argv->args[i]);
53 grub_free (argv->args);
56 argv->argc = 0;
57 argv->args = 0;
58 argv->script = 0;
61 /* Make argv from argc, args pair. */
62 int
63 grub_script_argv_make (struct grub_script_argv *argv, int argc, char **args)
65 int i;
66 struct grub_script_argv r = { 0, 0, 0 };
68 for (i = 0; i < argc; i++)
69 if (grub_script_argv_next (&r)
70 || grub_script_argv_append (&r, args[i], grub_strlen (args[i])))
72 grub_script_argv_free (&r);
73 return 1;
75 *argv = r;
76 return 0;
79 /* Prepare for next argc. */
80 int
81 grub_script_argv_next (struct grub_script_argv *argv)
83 char **p = argv->args;
85 if (argv->args && argv->argc && argv->args[argv->argc - 1] == 0)
86 return 0;
88 p = grub_realloc (p, round_up_exp ((argv->argc + 2) * sizeof (char *)));
89 if (! p)
90 return 1;
92 argv->argc++;
93 argv->args = p;
95 if (argv->argc == 1)
96 argv->args[0] = 0;
97 argv->args[argv->argc] = 0;
98 return 0;
101 /* Append `s' to the last argument. */
103 grub_script_argv_append (struct grub_script_argv *argv, const char *s,
104 grub_size_t slen)
106 grub_size_t a;
107 char *p = argv->args[argv->argc - 1];
109 if (! s)
110 return 0;
112 a = p ? grub_strlen (p) : 0;
114 p = grub_realloc (p, round_up_exp ((a + slen + 1) * sizeof (char)));
115 if (! p)
116 return 1;
118 grub_memcpy (p + a, s, slen);
119 p[a+slen] = 0;
120 argv->args[argv->argc - 1] = p;
122 return 0;
125 /* Split `s' and append words as multiple arguments. */
127 grub_script_argv_split_append (struct grub_script_argv *argv, const char *s)
129 const char *p;
130 int errors = 0;
132 if (! s)
133 return 0;
135 while (*s && grub_isspace (*s))
136 s++;
138 while (! errors && *s)
140 p = s;
141 while (*s && ! grub_isspace (*s))
142 s++;
144 errors += grub_script_argv_append (argv, p, s - p);
146 while (*s && grub_isspace (*s))
147 s++;
149 if (*s)
150 errors += grub_script_argv_next (argv);
152 return errors;