diff --git a/include/env.h b/include/env.h index 9ffc86a..61e5635 100644 --- a/include/env.h +++ b/include/env.h @@ -2,5 +2,7 @@ #include extern int last_status; +extern int script_argc; +extern char **script_argv; ssize_t var_paste(char *dst, const char *name, size_t limit); diff --git a/src/env.c b/src/env.c index 8083af5..9850bc5 100644 --- a/src/env.c +++ b/src/env.c @@ -1,15 +1,75 @@ #include #include #include +#include #include +int script_argc; +char **script_argv; int last_status = 0; ssize_t var_paste(char *dst, const char *name, size_t limit) { - size_t l; + size_t l, t; // Special variables if (name[0] && !name[1]) { + if (isdigit(name[0])) { + // Lol + int r = name[0] - '0'; + + if (r < script_argc) { + l = strlen(script_argv[r]); + + if (l > limit) { + l = limit; + } + strncpy(dst, script_argv[r], limit); + return l; + } else { + return 0; + } + } switch (name[0]) { + // TODO: merge the following two + case '*': + t = 0; + for (int i = 0; script_argv[i]; ++i) { + const char *arg = script_argv[i]; + l = strlen(arg); + if (t + l + 1 > limit) { + // TODO: handle this properly + t = limit; + break; + } + strncpy(dst + t, arg, l); + t += l; + if (i != script_argc - 1) { + dst[t++] = ' '; + } + } + return t; + case '@': + t = 0; + for (int i = 1; script_argv[i]; ++i) { + const char *arg = script_argv[i]; + l = strlen(arg); + if (t + l + 1 > limit) { + // TODO: handle this properly + t = limit; + break; + } + strncpy(dst + t, arg, l); + t += l; + if (i != script_argc - 1) { + dst[t++] = ' '; + } + } + return t; + case '#': + l = snprintf(dst, limit, "%d", script_argc); + if (l > limit) { + l = limit; + } + return l; case '$': l = snprintf(dst, limit, "%d", getpid()); // Output was truncated diff --git a/src/parse.c b/src/parse.c index e0529e2..0bc50e9 100644 --- a/src/parse.c +++ b/src/parse.c @@ -23,6 +23,7 @@ static int cmd_unit_parse(const char *str, struct cmd_unit *unit) { switch ((c = *str)) { case '$': case '?': + case '@': varlen = 1; var[0] = c; ++str; diff --git a/src/sh.c b/src/sh.c index bd5b881..971ce3b 100644 --- a/src/sh.c +++ b/src/sh.c @@ -141,9 +141,8 @@ int main(int argc, char **argv) { signal(SIGINT, signal_handle); signal(SIGSTOP, signal_handle); - const char *script = NULL; + char **script = NULL; const char *single_command = NULL; - //const char **script_args = NULL; for (int i = 1; i < argc; ++i) { if (argv[i][0] == '-') { @@ -165,18 +164,21 @@ int main(int argc, char **argv) { break; } } else { - script = argv[i]; + script = &argv[i]; break; } } if (script) { - fp = fopen(script, "r"); + fp = fopen(script[0], "r"); if (!fp) { - perror(script); - return EXIT_FAILURE; + perror(script[0]); + return -1; } + + script_argv = script; + for (script_argc = 0; script_argv[script_argc]; ++script_argc); } // TODO: source /etc/profile?