summaryrefslogtreecommitdiffstats
path: root/stand/common/interp_parse.c
diff options
context:
space:
mode:
authorkevans <kevans@FreeBSD.org>2018-02-12 20:51:28 +0000
committerkevans <kevans@FreeBSD.org>2018-02-12 20:51:28 +0000
commita239b274313bcfa27726c1d9af0f963714437eed (patch)
tree1c72fbbf83c11d36a7833c222b7029b3f18d0b89 /stand/common/interp_parse.c
parent2a0e9a6c008fb27a60779d5ad13cb567da02a659 (diff)
downloadFreeBSD-src-a239b274313bcfa27726c1d9af0f963714437eed.zip
FreeBSD-src-a239b274313bcfa27726c1d9af0f963714437eed.tar.gz
MFC Loader Fixes Final: r327612,r327703,r327704,r327878,r327879,r327881,
r328007,r328029,r328030,r328031,r328061,r328156,r328169,r328288,r328289, r328290,r328291,r328292,r328411,r328536,r328603,r328614,r328642,r328769, r328779,r328780,r328781,r328782,r328783,r328806,r328808,r328826,r328835, r328911,r328986,r328987,r328990,r328999,r329000,r329019,r329050,r329054, r329060 r327612: Invent new #defines for the biospci_{read,write}_config function r327703: Define __dmadat after #include'ing ufsread.c. r327704: Fix printf missing format variables warnings. r327878: Add GUID for UEFI boot manager variables. r327879: Report the boot order and where we are in that boot order. r327881: Allow this file to be included r328007: Fix booting on some arm64 systems after r327879 by fixing the call to utf8_to_ucs2 r328029: When returning an error and freeing allocated memory from ucs2_to_utf8, NULL the return pointer. r328030: Check the return value from utf8_to_ucs2 instead of whether or not uv is NULL. r328031: Need to free uv after we're done using it. r328061: utf8_to_ucs2() should check for malloc failure r328156: stand: Move sections around to fix stand/ build with ld.lld on armv7 r328169: Remove extra copy of bootinfo.c. It's a bit rotted copy of the one in efi/loader. r328288: Fix some resource leaks. r328289: Don't leak memory when displaying help. r328290: On malloc failure, be sure to close the include file that triggered it. r328291: getenv does not return tainted data in the boot loader. Attempt to clue Coverity into that fact. r328292: There's no tainted data here, tag it as such to avoid false positives. r328411: loader.efi: add missing EFI GUIDs r328536: loader: support for mixed-endianness ELF/loader and POWER8 r328603: Add missing non-POWERPC case to give the scr value something non-zero. r328614: Move libstand.3 to libsa.3. Update libsa.3 to include functions r328642: Break out the interpreters (simple and forth) w/o ifdefs. r328769: Centralize several variables. r328779: Retire pnp.4th and the code needed only for 4th words used here. r328780: These 4th words were an attempt to allow integration into the boot loader scripts. However, that path won't be taken after all it seems. r328781: Remove pcibios forth support. r328782: Now that we no longer conditionally compile some files outside of ficl r328783: Invent new LDR_INTERP for the loader interpreter to use. r328806: We need more heap space to properly load newer powerpc kernels. r328808: Implement strcoll as strcmp. r328826: Make cross-endian loader changes apply only to powerpc r328835: Fix regression introduced in r328806, preventing boot on many platforms. r328911: Ignore relocation tables for non-memory-resident sections. r328986: Fix relative location of USB sources after recent move. r328987: A more definitions to kernel emulation shim in order to build stand/usb. r328990: Move the stand/usb test loader into its own directory. r328999: Fix indentation to FreeBSD standard for interp files r329000: Move simple interpreter 'perform' into interp.c and call it r329019: Move to tabs for indentation and to 8-space notches, per style(9). r329050: Fix build of userboot.so r329054: Set script.lang in the environment to either 'forth' or 'simple' to reflect what scripting language was compiled into the loader. r329060: loader: fix endianness conversion PR: 225323
Diffstat (limited to 'stand/common/interp_parse.c')
-rw-r--r--stand/common/interp_parse.c259
1 files changed, 132 insertions, 127 deletions
diff --git a/stand/common/interp_parse.c b/stand/common/interp_parse.c
index 670273e..c46a497 100644
--- a/stand/common/interp_parse.c
+++ b/stand/common/interp_parse.c
@@ -50,143 +50,146 @@ static char *args[MAXARGS];
*/
#define PARSE_FAIL(expr) \
-if (expr) { \
- printf("fail at line %d\n", __LINE__); \
- clean(); \
- free(copy); \
- free(buf); \
- return 1; \
-}
+ if (expr) { \
+ printf("fail at line %d\n", __LINE__); \
+ clean(); \
+ free(copy); \
+ free(buf); \
+ return 1; \
+ }
/* Accept the usual delimiters for a variable, returning counterpart */
static char
isdelim(int ch)
{
- if (ch == '{')
- return '}';
- else if (ch == '(')
- return ')';
- return '\0';
+
+ if (ch == '{')
+ return '}';
+ else if (ch == '(')
+ return ')';
+ return '\0';
}
static int
isquote(int ch)
{
- return (ch == '\'');
+
+ return (ch == '\'');
}
static int
isdquote(int ch)
{
- return (ch == '"');
+
+ return (ch == '"');
}
int
parse(int *argc, char ***argv, const char *str)
{
- int ac;
- char *val, *p, *q, *copy = NULL;
- size_t i = 0;
- char token, tmp, quote, dquote, *buf;
- enum { STR, VAR, WHITE } state;
-
- ac = *argc = 0;
- dquote = quote = 0;
- if (!str || (p = copy = backslash(str)) == NULL)
- return 1;
-
- /* Initialize vector and state */
- clean();
- state = STR;
- buf = (char *)malloc(PARSE_BUFSIZE);
- token = 0;
-
- /* And awaaaaaaaaay we go! */
- while (*p) {
- switch (state) {
- case STR:
- if ((*p == '\\') && p[1]) {
- p++;
- PARSE_FAIL(i == (PARSE_BUFSIZE - 1));
- buf[i++] = *p++;
- } else if (isquote(*p)) {
- quote = quote ? 0 : *p;
- if (dquote) { /* keep quote */
- PARSE_FAIL(i == (PARSE_BUFSIZE - 1));
- buf[i++] = *p++;
- } else
- ++p;
- } else if (isdquote(*p)) {
- dquote = dquote ? 0 : *p;
- if (quote) { /* keep dquote */
- PARSE_FAIL(i == (PARSE_BUFSIZE - 1));
- buf[i++] = *p++;
- } else
- ++p;
- } else if (isspace(*p) && !quote && !dquote) {
- state = WHITE;
- if (i) {
- buf[i] = '\0';
- PARSE_FAIL(insert(&ac, buf));
- i = 0;
+ int ac;
+ char *val, *p, *q, *copy = NULL;
+ size_t i = 0;
+ char token, tmp, quote, dquote, *buf;
+ enum { STR, VAR, WHITE } state;
+
+ ac = *argc = 0;
+ dquote = quote = 0;
+ if (!str || (p = copy = backslash(str)) == NULL)
+ return 1;
+
+ /* Initialize vector and state */
+ clean();
+ state = STR;
+ buf = (char *)malloc(PARSE_BUFSIZE);
+ token = 0;
+
+ /* And awaaaaaaaaay we go! */
+ while (*p) {
+ switch (state) {
+ case STR:
+ if ((*p == '\\') && p[1]) {
+ p++;
+ PARSE_FAIL(i == (PARSE_BUFSIZE - 1));
+ buf[i++] = *p++;
+ } else if (isquote(*p)) {
+ quote = quote ? 0 : *p;
+ if (dquote) { /* keep quote */
+ PARSE_FAIL(i == (PARSE_BUFSIZE - 1));
+ buf[i++] = *p++;
+ } else
+ ++p;
+ } else if (isdquote(*p)) {
+ dquote = dquote ? 0 : *p;
+ if (quote) { /* keep dquote */
+ PARSE_FAIL(i == (PARSE_BUFSIZE - 1));
+ buf[i++] = *p++;
+ } else
+ ++p;
+ } else if (isspace(*p) && !quote && !dquote) {
+ state = WHITE;
+ if (i) {
+ buf[i] = '\0';
+ PARSE_FAIL(insert(&ac, buf));
+ i = 0;
+ }
+ ++p;
+ } else if (*p == '$' && !quote) {
+ token = isdelim(*(p + 1));
+ if (token)
+ p += 2;
+ else
+ ++p;
+ state = VAR;
+ } else {
+ PARSE_FAIL(i == (PARSE_BUFSIZE - 1));
+ buf[i++] = *p++;
+ }
+ break;
+
+ case WHITE:
+ if (isspace(*p))
+ ++p;
+ else
+ state = STR;
+ break;
+
+ case VAR:
+ if (token) {
+ PARSE_FAIL((q = strchr(p, token)) == NULL);
+ } else {
+ q = p;
+ while (*q && !isspace(*q))
+ ++q;
+ }
+ tmp = *q;
+ *q = '\0';
+ if ((val = variable_lookup(p)) != NULL) {
+ size_t len = strlen(val);
+
+ strncpy(buf + i, val, PARSE_BUFSIZE - (i + 1));
+ i += min(len, PARSE_BUFSIZE - 1);
+ }
+ *q = tmp; /* restore value */
+ p = q + (token ? 1 : 0);
+ state = STR;
+ break;
}
- ++p;
- } else if (*p == '$' && !quote) {
- token = isdelim(*(p + 1));
- if (token)
- p += 2;
- else
- ++p;
- state = VAR;
- } else {
- PARSE_FAIL(i == (PARSE_BUFSIZE - 1));
- buf[i++] = *p++;
- }
- break;
-
- case WHITE:
- if (isspace(*p))
- ++p;
- else
- state = STR;
- break;
-
- case VAR:
- if (token) {
- PARSE_FAIL((q = strchr(p, token)) == NULL);
- } else {
- q = p;
- while (*q && !isspace(*q))
- ++q;
- }
- tmp = *q;
- *q = '\0';
- if ((val = variable_lookup(p)) != NULL) {
- size_t len = strlen(val);
-
- strncpy(buf + i, val, PARSE_BUFSIZE - (i + 1));
- i += min(len, PARSE_BUFSIZE - 1);
- }
- *q = tmp; /* restore value */
- p = q + (token ? 1 : 0);
- state = STR;
- break;
}
- }
- /* missing terminating ' or " */
- PARSE_FAIL(quote || dquote);
- /* If at end of token, add it */
- if (i && state == STR) {
- buf[i] = '\0';
- PARSE_FAIL(insert(&ac, buf));
- }
- args[ac] = NULL;
- *argc = ac;
- *argv = (char **)malloc((sizeof(char *) * ac + 1));
- bcopy(args, *argv, sizeof(char *) * ac + 1);
- free(buf);
- free(copy);
- return 0;
+ /* missing terminating ' or " */
+ PARSE_FAIL(quote || dquote);
+ /* If at end of token, add it */
+ if (i && state == STR) {
+ buf[i] = '\0';
+ PARSE_FAIL(insert(&ac, buf));
+ }
+ args[ac] = NULL;
+ *argc = ac;
+ *argv = (char **)malloc((sizeof(char *) * ac + 1));
+ bcopy(args, *argv, sizeof(char *) * ac + 1);
+ free(buf);
+ free(copy);
+ return 0;
}
#define MAXARGS 20
@@ -195,28 +198,30 @@ parse(int *argc, char ***argv, const char *str)
static void
clean(void)
{
- int i;
+ int i;
- for (i = 0; i < MAXARGS; i++) {
- if (args[i] != NULL) {
- free(args[i]);
- args[i] = NULL;
+ for (i = 0; i < MAXARGS; i++) {
+ if (args[i] != NULL) {
+ free(args[i]);
+ args[i] = NULL;
+ }
}
- }
}
static int
insert(int *argcp, char *buf)
{
- if (*argcp >= MAXARGS)
- return 1;
- args[(*argcp)++] = strdup(buf);
- return 0;
+
+ if (*argcp >= MAXARGS)
+ return 1;
+ args[(*argcp)++] = strdup(buf);
+ return 0;
}
static char *
variable_lookup(char *name)
{
- /* XXX search "special variable" space first? */
- return (char *)getenv(name);
+
+ /* XXX search "special variable" space first? */
+ return (char *)getenv(name);
}
OpenPOWER on IntegriCloud