aboutsummaryrefslogtreecommitdiff
path: root/sys/cmd/rc/exec.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/cmd/rc/exec.c')
-rw-r--r--sys/cmd/rc/exec.c149
1 files changed, 113 insertions, 36 deletions
diff --git a/sys/cmd/rc/exec.c b/sys/cmd/rc/exec.c
index e8d59c1..fbcfb9b 100644
--- a/sys/cmd/rc/exec.c
+++ b/sys/cmd/rc/exec.c
@@ -703,6 +703,119 @@ Xconcatenate(void)
}
void
+Xdollar(void)
+{
+ int n;
+ char *s, *t;
+ Word *a, *star;
+
+ if(count(runner->args->word)!=1){
+ Xerror("variable name not singleton!\n");
+ return;
+ }
+ s = runner->args->word->str;
+ // deglob(s);
+ n = 0;
+
+ for(t = s;'0'<=*t && *t<='9';t++)
+ n = n*10+*t-'0';
+
+ a = runner->args->link->word;
+
+ if(n==0 || *t)
+ a = copywords(var(s)->val, a);
+ else{
+ star = var("*")->val;
+ if(star && 1<=n && n<=count(star)){
+ while(--n)
+ star = star->link;
+
+ a = makeword(star->str, a);
+ }
+ }
+
+ poplist();
+ runner->args->word = a;
+}
+
+static
+Word*
+cpwords(Word *array, Word *tail, int n)
+{
+ Word *cp, **end;
+
+ cp = nil, end = &cp;
+ while(n-- > 0){
+ *end = makeword(array->str, nil);
+ end = &(*end)->link;
+ array = array->link;
+ }
+ *end = tail;
+
+ return cp;
+}
+
+
+static
+Word*
+getindex(Word *array, int len, Word *index, Word *tail)
+{
+ char *s;
+ int n, m;
+ if(!index)
+ return tail;
+
+ tail = getindex(array, len, index->link, tail);
+
+ s = index->str;
+ //deglob(s)
+
+ m = 0, n = 0;
+ while('0' <= *s && *s <= '9')
+ n = 10*n + (*s++ - '0');
+ if(*s == '-'){
+ if(*++s == 0)
+ m = len - n;
+ else{
+ while('0' <= *s && *s <= '9')
+ m = 10*m + (*s++ - '0');
+ m -= n;
+ }
+ }
+
+ if(n<1 || n > len || m < 0)
+ return tail;
+ if(n+m > len)
+ m = len-n;
+ while(--n > 0)
+ array = array->link;
+ return cpwords(array, tail, m+1);
+}
+
+void
+Xindex(void)
+{
+ char *s;
+ Word *val, *ret;
+
+ if(count(runner->args->word) != 1){
+ Xerror("variable name not a singleton");
+ return;
+ }
+ s = runner->args->word->str;
+ //deglob(s)
+ val = var(s)->val;
+ poplist();
+
+ ret = runner->args->link->word; // pointer to next stack frame
+ ret = getindex(val, count(val), runner->args->word, ret);
+ poplist();
+
+ // push result back on stack
+ runner->args->word = ret;
+}
+
+void
Xjoin(void)
{
int n;
@@ -744,42 +857,6 @@ Xjoin(void)
}
void
-Xdollar(void)
-{
- int n;
- char *s, *t;
- Word *a, *star;
-
- if(count(runner->args->word)!=1){
- Xerror("variable name not singleton!\n");
- return;
- }
- s = runner->args->word->str;
- // deglob(s);
- n = 0;
-
- for(t = s;'0'<=*t && *t<='9';t++)
- n = n*10+*t-'0';
-
- a = runner->args->link->word;
-
- if(n==0 || *t)
- a = copywords(var(s)->val, a);
- else{
- star = var("*")->val;
- if(star && 1<=n && n<=count(star)){
- while(--n)
- star = star->link;
-
- a = makeword(star->str, a);
- }
- }
-
- poplist();
- runner->args->word = a;
-}
-
-void
Xassign(void)
{
Var *v;