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>
23 #include <grub/safemath.h>
25 /* Return nearest power of two that is >= v. */
27 round_up_exp (unsigned v
)
29 COMPILE_TIME_ASSERT (sizeof (v
) == 4);
45 grub_script_argv_free (struct grub_script_argv
*argv
)
51 for (i
= 0; i
< argv
->argc
; i
++)
52 grub_free (argv
->args
[i
]);
54 grub_free (argv
->args
);
62 /* Make argv from argc, args pair. */
64 grub_script_argv_make (struct grub_script_argv
*argv
, int argc
, char **args
)
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
);
80 /* Prepare for next argc. */
82 grub_script_argv_next (struct grub_script_argv
*argv
)
84 char **p
= argv
->args
;
87 if (argv
->args
&& argv
->argc
&& argv
->args
[argv
->argc
- 1] == 0)
90 if (grub_add (argv
->argc
, 2, &sz
) ||
91 grub_mul (sz
, sizeof (char *), &sz
))
94 p
= grub_realloc (p
, round_up_exp (sz
));
103 argv
->args
[argv
->argc
] = 0;
107 /* Append `s' to the last argument. */
109 grub_script_argv_append (struct grub_script_argv
*argv
, const char *s
,
113 char *p
= argv
->args
[argv
->argc
- 1];
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
))
126 p
= grub_realloc (p
, round_up_exp (sz
));
130 grub_memcpy (p
+ a
, s
, slen
);
132 argv
->args
[argv
->argc
- 1] = p
;
137 /* Split `s' and append words as multiple arguments. */
139 grub_script_argv_split_append (struct grub_script_argv
*argv
, const char *s
)
147 while (*s
&& grub_isspace (*s
))
150 while (! errors
&& *s
)
153 while (*s
&& ! grub_isspace (*s
))
156 errors
+= grub_script_argv_append (argv
, p
, s
- p
);
158 while (*s
&& grub_isspace (*s
))
162 errors
+= grub_script_argv_next (argv
);