1 /* argv.c - methods for constructing argument vector */
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/>.
21 #include <grub/misc.h>
22 #include <grub/script_sh.h>
24 /* Return nearest power of two that is >= v. */
26 round_up_exp (unsigned v
)
28 COMPILE_TIME_ASSERT (sizeof (v
) == 4);
44 grub_script_argv_free (struct grub_script_argv
*argv
)
50 for (i
= 0; i
< argv
->argc
; i
++)
51 grub_free (argv
->args
[i
]);
53 grub_free (argv
->args
);
61 /* Make argv from argc, args pair. */
63 grub_script_argv_make (struct grub_script_argv
*argv
, int argc
, char **args
)
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
);
79 /* Prepare for next argc. */
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)
88 p
= grub_realloc (p
, round_up_exp ((argv
->argc
+ 2) * sizeof (char *)));
97 argv
->args
[argv
->argc
] = 0;
101 /* Append `s' to the last argument. */
103 grub_script_argv_append (struct grub_script_argv
*argv
, const char *s
,
107 char *p
= argv
->args
[argv
->argc
- 1];
112 a
= p
? grub_strlen (p
) : 0;
114 p
= grub_realloc (p
, round_up_exp ((a
+ slen
+ 1) * sizeof (char)));
118 grub_memcpy (p
+ a
, s
, slen
);
120 argv
->args
[argv
->argc
- 1] = p
;
125 /* Split `s' and append words as multiple arguments. */
127 grub_script_argv_split_append (struct grub_script_argv
*argv
, const char *s
)
135 while (*s
&& grub_isspace (*s
))
138 while (! errors
&& *s
)
141 while (*s
&& ! grub_isspace (*s
))
144 errors
+= grub_script_argv_append (argv
, p
, s
- p
);
146 while (*s
&& grub_isspace (*s
))
150 errors
+= grub_script_argv_next (argv
);