tb Implement a string stack
This commit is contained in:
@ -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_
|
||||||
|
@ -122,6 +122,20 @@ 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) {
|
||||||
|
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;
|
RtAlias *alias, *aliastmp;
|
||||||
LL_FOREACH_SAFE(RTALIASES, alias, aliastmp) {
|
LL_FOREACH_SAFE(RTALIASES, alias, aliastmp) {
|
||||||
if (string_strcmp(alias->namebuf, tk->str+1) == 0) {
|
if (string_strcmp(alias->namebuf, tk->str+1) == 0) {
|
||||||
@ -135,6 +149,7 @@ void tz_expandspecial(Tokenizer *tz) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#define LINE_MAX 1024
|
#define LINE_MAX 1024
|
||||||
|
@ -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);
|
||||||
|
if (r > 0) {
|
||||||
stringbuffer_appendcstr(&outbuf, buf);
|
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);
|
||||||
}
|
}
|
||||||
|
@ -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_
|
||||||
|
Reference in New Issue
Block a user