tb Implement a string stack

This commit is contained in:
2025-10-01 21:26:22 +02:00
parent 62cf07afc7
commit 73effcd52a
4 changed files with 101 additions and 13 deletions

View File

@ -68,4 +68,16 @@
var != NULL && (idx) < (max); \ var != NULL && (idx) < (max); \
var = tmp, tmp = (var ? var->next : NULL), (idx)++) 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_ #endif // ULIB_LINKLIST_H_

View File

@ -122,15 +122,30 @@ void tz_expandspecial(Tokenizer *tz) {
Token *tk, *tktmp; Token *tk, *tktmp;
LL_FOREACH_SAFE(tz->tokens, tk, tktmp) { LL_FOREACH_SAFE(tz->tokens, tk, tktmp) {
if (tk->str[0] == '$' && string_len(tk->str) > 1) { if (tk->str[0] == '$' && string_len(tk->str) > 1) {
RtAlias *alias, *aliastmp; if (string_strcmp(tk->str, "$stack") == 0) {
LL_FOREACH_SAFE(RTALIASES, alias, aliastmp) { char *s = rtstringv_stackpeek();
if (string_strcmp(alias->namebuf, tk->str+1) == 0) { ufree(tk->str);
ufree(tk->str); if (s == NULL) {
size_t len = string_len(alias->valbuf)+1; tk->str = umalloc(1);
tk->str = umalloc(len); tk->str[0] = '\0';
string_memset(tk->str, 0, len); } else {
string_memcpy(tk->str, alias->valbuf, string_len(alias->valbuf)); size_t len = string_len(s);
break; 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;
}
} }
} }
} }

View File

@ -4,6 +4,38 @@
#include "runtime.h" #include "runtime.h"
#include "interp.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; extern PID_t PID;
RtCmd *RTCMDS = NULL; RtCmd *RTCMDS = NULL;
@ -25,7 +57,6 @@ bool rt_print(Token *tks) {
uprintf(" "); uprintf(" ");
} }
} }
uprintf("\n");
return true; return true;
} }
@ -52,7 +83,7 @@ bool rt_PID(Token *tks) {
return true; return true;
} }
bool rt_subsh(Token *tks) { bool rt_do(Token *tks) {
bool ok = true; bool ok = true;
char *prepended_args[] = { "-m", "runstring", "-preload", "base:/scripts/rc.tb", "-rs" }; 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)); string_memset(buf, 0, sizeof(buf));
r = ipcpipe(app, IPCPIPE_OUT, IPCPIPE_READ, (uint8_t *)buf, sizeof(buf)-1); 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); ipcpipe(PID, 10, IPCPIPE_DELETE, NULL, 0);
rtstringv_stackpushcopy(outbuf.data, outbuf.count);
stringbuffer_free(&outbuf); stringbuffer_free(&outbuf);
done: done:
@ -116,9 +151,26 @@ done:
return ok; 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) { void rt_init(void) {
RTCMD("%print", &rt_print); RTCMD("%print", &rt_print);
RTCMD("%mkalias", &rt_mkalias); RTCMD("%mkalias", &rt_mkalias);
RTCMD("%PID", &rt_PID); RTCMD("%PID", &rt_PID);
RTCMD("%subsh", &rt_subsh); RTCMD("%do", &rt_do);
RTCMD("%stackpush", &rt_stackpush);
RTCMD("%stackpop", &rt_stackpop);
} }

View File

@ -20,9 +20,18 @@ typedef struct RtAlias {
char valbuf[RTALIAS_VALBUF_MAX]; char valbuf[RTALIAS_VALBUF_MAX];
} RtAlias; } RtAlias;
typedef struct RtStringV {
struct RtStringV *next;
char *data;
} RtStringV;
void rt_init(void); void rt_init(void);
extern RtCmd *RTCMDS; extern RtCmd *RTCMDS;
extern RtAlias *RTALIASES; extern RtAlias *RTALIASES;
void rtstringv_stackpushcopy(char *s, size_t len);
char *rtstringv_stackpop(void);
char *rtstringv_stackpeek(void);
#endif // TB_RUNTIME_H_ #endif // TB_RUNTIME_H_