Handle script arguments ($N, $*, $@)

This commit is contained in:
Mark
2020-07-30 01:54:53 +03:00
parent 91ea9e1bc1
commit 98defc7a53
4 changed files with 72 additions and 7 deletions
+2
View File
@@ -2,5 +2,7 @@
#include <sys/types.h>
extern int last_status;
extern int script_argc;
extern char **script_argv;
ssize_t var_paste(char *dst, const char *name, size_t limit);
+61 -1
View File
@@ -1,15 +1,75 @@
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <ctype.h>
#include <stdio.h>
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
+1
View File
@@ -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;
+8 -6
View File
@@ -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?