From 094d3c76925cf6c05a8bfcc112849627d16279b8 Mon Sep 17 00:00:00 2001 From: Nicholas Noll Date: Tue, 26 Oct 2021 09:44:47 -0700 Subject: feat(rc): added index operations --- sys/cmd/rc/exec.c | 149 +++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 113 insertions(+), 36 deletions(-) (limited to 'sys/cmd/rc/exec.c') 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 @@ -702,6 +702,119 @@ Xconcatenate(void) runner->args->word = w; } +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) { @@ -743,42 +856,6 @@ Xjoin(void) efree(s); } -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) { -- cgit v1.2.1