Add eachfile and mkaliasbn builtins

This commit is contained in:
2025-10-15 21:26:30 +02:00
parent 7936eb92f6
commit 317667cfb8
4 changed files with 127 additions and 8 deletions

View File

@ -167,11 +167,124 @@ bool rt_stackpop(Token *tks) {
return true;
}
void rt_init(void) {
RTCMD("%print", &rt_print);
RTCMD("%mkalias", &rt_mkalias);
RTCMD("%PID", &rt_PID);
RTCMD("%do", &rt_do);
RTCMD("%stackpush", &rt_stackpush);
RTCMD("%stackpop", &rt_stackpop);
typedef struct EachFileSkip {
struct EachFileSkip *next;
char *filename;
} EachFileSkip;
bool rt_eachfile(Token *tks) {
EachFileSkip *skips = NULL;
Token *tk = tks;
char *dirpath;
while (tk && tk->str[0] == '!') {
EachFileSkip *skip = (EachFileSkip *)umalloc(sizeof(*skip));
skip->filename = tk->str + 1;
LL_APPEND(skips, skip);
tk = tk->next;
}
if (tk != NULL) {
dirpath = tk->str;
tk = tk->next;
}
FsStat statbuf; ZERO(&statbuf);
if (fs_stat(dirpath, &statbuf) != E_OK || statbuf.type != FSSTAT_DIR) {
return false;
}
FsDirent *dirents = (FsDirent *)umalloc(statbuf.size * sizeof(*dirents));
for (size_t i = 0; i < statbuf.size; i++) {
fs_fetchdirent(dirpath, &dirents[i], i);
FsDirent *dirent = &dirents[i];
if (string_strcmp(dirent->name, ".") == 0 || string_strcmp(dirent->name, "..") == 0) {
continue;
}
EachFileSkip *skip1, *skip1tmp;
LL_FOREACH_SAFE(skips, skip1, skip1tmp) {
if (string_strcmp(skip1->filename, dirent->name) == 0) {
goto nextiter;
}
}
char tmpbuf[1024]; ZERO(tmpbuf);
string_strcpy(tmpbuf, dirpath);
if (dirpath[string_len(dirpath) - 1] != '/') {
string_combine(tmpbuf, "/");
}
string_combine(tmpbuf, dirent->name);
#define EACHFILE_MAX_STRING 1024
char *s = umalloc(EACHFILE_MAX_STRING);
string_memset(s, 0, EACHFILE_MAX_STRING);
size_t cursor = 0;
Token *argtk, *argtktmp;
LL_FOREACH_SAFE(tk, argtk, argtktmp) {
if (string_strcmp(argtk->str, "&EF-ELEM") == 0) {
size_t len = string_len(tmpbuf);
string_memcpy(&s[cursor], tmpbuf, len);
cursor += len;
s[cursor] = ' ';
cursor++;
} else {
size_t len = string_len(argtk->str);
string_memcpy(&s[cursor], argtk->str, len);
cursor += len;
s[cursor] = ' ';
cursor++;
}
}
InterpResult save; string_memcpy(&save, &RES, sizeof(save));
InterpResult *res;
interp_runstring(s, &res, false, false);
string_memcpy(&RES, &save, sizeof(save));
/* ufree(s); */
nextiter:
}
ufree(dirents);
EachFileSkip *skip1, *skip1tmp;
LL_FOREACH_SAFE(skips, skip1, skip1tmp) {
ufree(skip1);
}
return true;
}
bool rt_mkaliasbn(Token *tks) {
Token *tk = tks;
if (tk == NULL) {
return false;
}
RtAlias *alias = umalloc(sizeof(*alias));
string_memset(alias, 0, sizeof(*alias));
char *basename = (char *)path_basename(tk->str);
string_memcpy(alias->namebuf, basename, MIN(string_len(basename), RTALIAS_NAMEBUF_MAX));
string_memcpy(alias->valbuf, tk->str, MIN(string_len(tk->str), RTALIAS_VALBUF_MAX));
LL_APPEND(RTALIASES, alias);
return true;
}
void rt_init(void) {
RTCMD("print", &rt_print);
RTCMD("mkalias", &rt_mkalias);
RTCMD("PID", &rt_PID);
RTCMD("do", &rt_do);
RTCMD("stackpush", &rt_stackpush);
RTCMD("stackpop", &rt_stackpop);
RTCMD("eachfile", &rt_eachfile);
RTCMD("mkaliasbn", &rt_mkaliasbn);
}