From 73effcd52ab51114ace9800c0465cc957fa1dc52 Mon Sep 17 00:00:00 2001 From: kamkow1 Date: Wed, 1 Oct 2025 21:26:22 +0200 Subject: [PATCH] tb Implement a string stack --- ulib/linklist.h | 12 ++++++++++ user/tb/interp.c | 33 +++++++++++++++++++------- user/tb/runtime.c | 60 +++++++++++++++++++++++++++++++++++++++++++---- user/tb/runtime.h | 9 +++++++ 4 files changed, 101 insertions(+), 13 deletions(-) diff --git a/ulib/linklist.h b/ulib/linklist.h index 07df5e7..0180315 100644 --- a/ulib/linklist.h +++ b/ulib/linklist.h @@ -68,4 +68,16 @@ var != NULL && (idx) < (max); \ var = tmp, tmp = (var ? var->next : NULL), (idx)++) +#define LL_BACK(head, out) \ + do { \ + (out) = NULL; \ + if ((head) != NULL) { \ + typeof((head)) __tmp = (head); \ + while (__tmp->next != NULL) { \ + __tmp = __tmp->next; \ + } \ + (out) = __tmp; \ + } \ + } while(0) + #endif // ULIB_LINKLIST_H_ diff --git a/user/tb/interp.c b/user/tb/interp.c index 01cbdbc..0cf85ca 100644 --- a/user/tb/interp.c +++ b/user/tb/interp.c @@ -122,15 +122,30 @@ void tz_expandspecial(Tokenizer *tz) { Token *tk, *tktmp; LL_FOREACH_SAFE(tz->tokens, tk, tktmp) { if (tk->str[0] == '$' && string_len(tk->str) > 1) { - RtAlias *alias, *aliastmp; - LL_FOREACH_SAFE(RTALIASES, alias, aliastmp) { - if (string_strcmp(alias->namebuf, tk->str+1) == 0) { - ufree(tk->str); - size_t len = string_len(alias->valbuf)+1; - tk->str = umalloc(len); - string_memset(tk->str, 0, len); - string_memcpy(tk->str, alias->valbuf, string_len(alias->valbuf)); - break; + if (string_strcmp(tk->str, "$stack") == 0) { + char *s = rtstringv_stackpeek(); + ufree(tk->str); + if (s == NULL) { + tk->str = umalloc(1); + tk->str[0] = '\0'; + } else { + size_t len = string_len(s); + char *copy = umalloc(len+1); + string_memcpy(copy, s, len); + copy[len] = '\0'; + tk->str = copy; + } + } else { + RtAlias *alias, *aliastmp; + LL_FOREACH_SAFE(RTALIASES, alias, aliastmp) { + if (string_strcmp(alias->namebuf, tk->str+1) == 0) { + ufree(tk->str); + size_t len = string_len(alias->valbuf)+1; + tk->str = umalloc(len); + string_memset(tk->str, 0, len); + string_memcpy(tk->str, alias->valbuf, string_len(alias->valbuf)); + break; + } } } } diff --git a/user/tb/runtime.c b/user/tb/runtime.c index 71dcf3a..eab552a 100644 --- a/user/tb/runtime.c +++ b/user/tb/runtime.c @@ -4,6 +4,38 @@ #include "runtime.h" #include "interp.h" +RtStringV *RTSTRINGV_STACK = NULL; + +void rtstringv_stackpushcopy(char *s, size_t len) { + char *c = umalloc(len+1); + string_memcpy(c, s, len); + c[len] = '\0'; + RtStringV *v = umalloc(sizeof(*v)); + v->data = c; + LL_APPEND(RTSTRINGV_STACK, v); +} + +char *rtstringv_stackpop(void) { + RtStringV *v; + LL_BACK(RTSTRINGV_STACK, v); + if (v == NULL) { + return NULL; + } + LL_REMOVE(RTSTRINGV_STACK, v); + char *d = v->data; + ufree(v); + return d; +} + +char *rtstringv_stackpeek(void) { + RtStringV *v; + LL_BACK(RTSTRINGV_STACK, v); + if (v == NULL) { + return NULL; + } + return v->data; +} + extern PID_t PID; RtCmd *RTCMDS = NULL; @@ -25,7 +57,6 @@ bool rt_print(Token *tks) { uprintf(" "); } } - uprintf("\n"); return true; } @@ -52,7 +83,7 @@ bool rt_PID(Token *tks) { return true; } -bool rt_subsh(Token *tks) { +bool rt_do(Token *tks) { bool ok = true; char *prepended_args[] = { "-m", "runstring", "-preload", "base:/scripts/rc.tb", "-rs" }; @@ -100,11 +131,15 @@ bool rt_subsh(Token *tks) { string_memset(buf, 0, sizeof(buf)); r = ipcpipe(app, IPCPIPE_OUT, IPCPIPE_READ, (uint8_t *)buf, sizeof(buf)-1); - stringbuffer_appendcstr(&outbuf, buf); + if (r > 0) { + stringbuffer_appendcstr(&outbuf, buf); + } } ipcpipe(PID, 10, IPCPIPE_DELETE, NULL, 0); + rtstringv_stackpushcopy(outbuf.data, outbuf.count); + stringbuffer_free(&outbuf); done: @@ -116,9 +151,26 @@ done: return ok; } +bool rt_stackpush(Token *tks) { + Token *tk, *tktmp; + LL_FOREACH_SAFE(tks, tk, tktmp) { + rtstringv_stackpushcopy(tk->str, string_len(tk->str)); + } + return true; +} + +bool rt_stackpop(Token *tks) { + (void)tks; + char *s = rtstringv_stackpop(); + if (s) ufree(s); + return true; +} + void rt_init(void) { RTCMD("%print", &rt_print); RTCMD("%mkalias", &rt_mkalias); RTCMD("%PID", &rt_PID); - RTCMD("%subsh", &rt_subsh); + RTCMD("%do", &rt_do); + RTCMD("%stackpush", &rt_stackpush); + RTCMD("%stackpop", &rt_stackpop); } diff --git a/user/tb/runtime.h b/user/tb/runtime.h index 9287488..fb7140f 100644 --- a/user/tb/runtime.h +++ b/user/tb/runtime.h @@ -20,9 +20,18 @@ typedef struct RtAlias { char valbuf[RTALIAS_VALBUF_MAX]; } RtAlias; +typedef struct RtStringV { + struct RtStringV *next; + char *data; +} RtStringV; + void rt_init(void); extern RtCmd *RTCMDS; extern RtAlias *RTALIASES; +void rtstringv_stackpushcopy(char *s, size_t len); +char *rtstringv_stackpop(void); +char *rtstringv_stackpeek(void); + #endif // TB_RUNTIME_H_