diff --git a/user/tb/interp.c b/user/tb/interp.c index ccafc5c..b461194 100644 --- a/user/tb/interp.c +++ b/user/tb/interp.c @@ -8,7 +8,7 @@ extern PID_t PID; extern Dev_t ps2kbdev; -static InterpResult RES; +InterpResult RES; void tz_init(Tokenizer *tz, char *str) { tz->str = str; @@ -116,6 +116,8 @@ void tz_classify(Tokenizer *tz) { else IF_RTCMD(do) else IF_RTCMD(stackpush) else IF_RTCMD(stackpop) + else IF_RTCMD(eachfile) + else IF_RTCMD(mkaliasbn) else { tk->type = TOK_MISC; } diff --git a/user/tb/interp.h b/user/tb/interp.h index 2d4cbdb..902b3fc 100644 --- a/user/tb/interp.h +++ b/user/tb/interp.h @@ -11,6 +11,8 @@ typedef struct { char errmsg[INTERP_ERRMSG_BUF_MAX]; } InterpResult; +extern InterpResult RES; + typedef struct Token { struct Token *next; char *str; diff --git a/user/tb/runtime.c b/user/tb/runtime.c index 6610b18..4763039 100644 --- a/user/tb/runtime.c +++ b/user/tb/runtime.c @@ -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); } diff --git a/user/tb/runtime.h b/user/tb/runtime.h index 617ae25..95882d4 100644 --- a/user/tb/runtime.h +++ b/user/tb/runtime.h @@ -36,6 +36,8 @@ bool rt_PID(struct Token *); bool rt_do(struct Token *); bool rt_stackpush(struct Token *); bool rt_stackpop(struct Token *); +bool rt_eachfile(struct Token *); +bool rt_mkaliasbn(struct Token *); void rtstringv_stackpushcopy(char *s, size_t len); char *rtstringv_stackpop(void);