summaryrefslogtreecommitdiff
path: root/apps
diff options
context:
space:
mode:
authorAnton Babushkin <anton.babushkin@me.com>2014-01-10 11:00:25 +0100
committerAnton Babushkin <anton.babushkin@me.com>2014-01-10 11:00:25 +0100
commit583fe5754d51e04d16ac9d24e779d2f1a9fd3e95 (patch)
tree7607668da6d2cb1855d7eb2abbcf120e5964d215 /apps
parent736567ee04ead042b24a73791997f92d7a0c0a13 (diff)
downloadpx4-nuttx-583fe5754d51e04d16ac9d24e779d2f1a9fd3e95.tar.gz
px4-nuttx-583fe5754d51e04d16ac9d24e779d2f1a9fd3e95.tar.bz2
px4-nuttx-583fe5754d51e04d16ac9d24e779d2f1a9fd3e95.zip
nsh: env variables expansion
Diffstat (limited to 'apps')
-rw-r--r--apps/nshlib/nsh_parse.c164
1 files changed, 164 insertions, 0 deletions
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);
}