From 583fe5754d51e04d16ac9d24e779d2f1a9fd3e95 Mon Sep 17 00:00:00 2001 From: Anton Babushkin Date: Fri, 10 Jan 2014 11:00:25 +0100 Subject: nsh: env variables expansion --- apps/nshlib/nsh_parse.c | 164 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 164 insertions(+) (limited to 'apps') diff --git a/apps/nshlib/nsh_parse.c b/apps/nshlib/nsh_parse.c index 3f17149f5..6fd7c04cc 100644 --- a/apps/nshlib/nsh_parse.c +++ b/apps/nshlib/nsh_parse.c @@ -1311,6 +1311,140 @@ int nsh_parse(FAR struct nsh_vtbl_s *vtbl, char *cmdline) #endif vtbl->np.np_redirect = false; +#ifndef CONFIG_DISABLE_ENVIRON + /* Expand environment variables before parsing the line */ + + FAR char *cmdline_exp = NULL; + bool do_expand = false; + char *src_ptr = cmdline; + unsigned int res_size = 0; + char *var_name_start = NULL; + char *var_name_end; + bool bracket = false; + + while (true) { + char c = *src_ptr++; + if (var_name_start) { + /* Parsing variable name */ + if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9') || c == '_') { + /* Valid variable char */ + continue; + } else { + /* Not valid variable char */ + if (src_ptr - var_name_start == 1) { + /* Empty, it was not a variable */ + res_size++; + var_name_start = NULL; + } else { + /* End of variable name */ + if (bracket == (c != '}')) { + /* Bad substitution */ + goto errout; + } + do_expand = true; + var_name_end = src_ptr - 1; + char tmp_char = *var_name_end; + *var_name_end = '\0'; + char *var_value = getenv(var_name_start); + *var_name_end = tmp_char; + res_size += strlen(var_value); + var_name_start = NULL; + if (c == '}') { + bracket = false; + continue; + } + } + } + } + if (c == '$') { + /* Start parsing variable */ + if (*src_ptr == '{') { + bracket = true; + src_ptr++; + } + var_name_start = src_ptr; + continue; + } + /* Normal char */ + res_size++; + if (c == '\0') + break; + } + if (do_expand) { + /* Second pass: allocate buffer and expand command line */ + + printf("Orig: %s", cmdline); + printf("Expand, size: %d\n", res_size); + + cmdline_exp = (char*) malloc(res_size); + + src_ptr = cmdline; + char *res_ptr = cmdline_exp; + var_name_start = NULL; + + while (true) { + char c = *src_ptr++; + if (var_name_start) { + /* Parsing variable name */ + if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9') || c == '_') { + /* Valid variable char */ + continue; + } else { + /* Not valid variable char */ + if (src_ptr - var_name_start == 1) { + /* Empty, it was not a variable */ + *res_ptr++ = *(src_ptr - 1); + var_name_start = NULL; + } else { + /* End of variable name */ + if (bracket == (c != '}')) { + /* Bad substitution */ + goto errout; + } + do_expand = true; + var_name_end = src_ptr - 1; + char tmp_char = *var_name_end; + *var_name_end = '\0'; + char *var_value = getenv(var_name_start); + printf("VAR: %s = %s\n", var_name_start, var_value); + *var_name_end = tmp_char; + //res_ptr = stpcpy(res_ptr, var_value); + if (var_value) { + for (int i = 0; true; i++) { + char a = var_value[i]; + if (a == '\0') + break; + *res_ptr++ = a; + } + } + var_name_start = NULL; + if (c == '}') { + bracket = false; + continue; + } + } + } + } + if (c == '$') { + /* Start parsing variable */ + if (*src_ptr == '{') { + bracket = true; + src_ptr++; + } + var_name_start = src_ptr; + continue; + } + /* Normal char */ + *res_ptr++ = c; + if (c == '\0') + break; + } + + printf("Expanded: %s", cmdline_exp); + cmdline = cmdline_exp; + } +#endif + /* Parse out the command at the beginning of the line */ saveptr = cmdline; @@ -1349,6 +1483,12 @@ int nsh_parse(FAR struct nsh_vtbl_s *vtbl, char *cmdline) * command status. */ +#ifndef CONFIG_DISABLE_ENVIRON + if (cmdline_exp != NULL) { + free(cmdline_exp); + } +#endif + return OK; } @@ -1454,6 +1594,12 @@ int nsh_parse(FAR struct nsh_vtbl_s *vtbl, char *cmdline) /* Save the result: success if 0; failure if 1 */ +#ifndef CONFIG_DISABLE_ENVIRON + if (cmdline_exp != NULL) { + free(cmdline_exp); + } +#endif + return nsh_saveresult(vtbl, ret != OK); } @@ -1497,6 +1643,12 @@ int nsh_parse(FAR struct nsh_vtbl_s *vtbl, char *cmdline) /* Save the result: success if 0; failure if 1 */ +#ifndef CONFIG_DISABLE_ENVIRON + if (cmdline_exp != NULL) { + free(cmdline_exp); + } +#endif + return nsh_saveresult(vtbl, ret != OK); } @@ -1673,6 +1825,12 @@ int nsh_parse(FAR struct nsh_vtbl_s *vtbl, char *cmdline) * command task succeeded). */ +#ifndef CONFIG_DISABLE_ENVIRON + if (cmdline_exp != NULL) { + free(cmdline_exp); + } +#endif + return nsh_saveresult(vtbl, false); #ifndef CONFIG_NSH_DISABLEBG @@ -1683,5 +1841,11 @@ errout_with_redirect: } #endif errout: +#ifndef CONFIG_DISABLE_ENVIRON + if (cmdline_exp != NULL) { + free(cmdline_exp); + } +#endif + return nsh_saveresult(vtbl, true); } -- cgit v1.2.3