#include #include #include #include "interp.h" #include "runtime.h" #include "macros.h" extern uint64_t PID; static InterpResult RES; void tz_init(Tokenizer *tz, char *str) { tz->str = str; tz->tokens = NULL; } void tz_free(Tokenizer *tz) { Token *tk, *tktmp; LL_FOREACH_SAFE(tz->tokens, tk, tktmp) { ufree(tk->str); ufree(tk); } tz->tokens = NULL; } #define TZ_MAX_TK 1024 void tz_tokenize(Tokenizer *tz) { size_t len = string_len(tz->str); for (size_t i = 0; i < len; i++) { if (tz->str[i] == '\'') { char *str = umalloc(TZ_MAX_TK); string_memset(str, 0, TZ_MAX_TK); i++; size_t j = 0; while (i < len && tz->str[i] != '\'') { str[j++] = tz->str[i++]; } Token *tk = umalloc(sizeof(*tk)); tk->str = str; tk->next = NULL; LL_APPEND(tz->tokens, tk); } else { char *tkstr = umalloc(TZ_MAX_TK); string_memset(tkstr, 0, TZ_MAX_TK); size_t j = 0; while (i < len && !string_chr_isspace(tz->str[i])) { tkstr[j++] = tz->str[i++]; } Token *tk = umalloc(sizeof(*tk)); tk->str = tkstr; tk->next = NULL; LL_APPEND(tz->tokens, tk); } } } void tz_classify(Tokenizer *tz) { Token *tk, *tktmp; LL_FOREACH_SAFE(tz->tokens, tk, tktmp) { if (tk->str[0] == '"') { tk->type = TOK_STRING; } else if (tk->str[0] == '%') { RtCmd *cmd, *cmdtmp; LL_FOREACH_SAFE(RTCMDS, cmd, cmdtmp) { if (string_strcmp(tk->str, cmd->cmdname) == 0) { tk->type = TOK_CMD; tk->cmd = cmd; break; } } } else { tk->type = TOK_MISC; } } } void tz_expandspecial(Tokenizer *tz) { Token *tk, *tktmp; LL_FOREACH_SAFE(tz->tokens, tk, tktmp) { /* if (tk->ptr[0] == '$' && tk->len > 1) { */ /* char aliasbuf[RTALIAS_NAMEBUF_MAX]; */ /* string_memset(aliasbuf, 0, sizeof(aliasbuf)); */ /* string_memcpy(aliasbuf, &tk->ptr[1], MIN(tk->len - 1, RTALIAS_NAMEBUF_MAX)); */ /* RtAlias *alias, *aliastmp; */ /* LL_FOREACH_SAFE(RTALIASES, alias, aliastmp) { */ /* if (string_strcmp(alias->namebuf, aliasbuf) == 0) { */ /* tk->ptr = alias->valbuf; */ /* tk->len = string_len(alias->valbuf); */ /* break; */ /* } */ /* } */ /* } */ } } #define LINE_MAX 1024 bool interp_runstring(char *string, InterpResult **res, bool logcmds, bool interactive) { *res = &RES; string_memset(RES.errmsg, 0, sizeof(RES.errmsg)); rt_init(); bool ok = true; char *line = string_tokenizealloc(string, "\n"); while (line != NULL) { if (logcmds) { uprintf("+%s\n", line); } Tokenizer tz; ZERO(&tz); tz_init(&tz, line); tz_tokenize(&tz); tz_classify(&tz); tz_expandspecial(&tz); Token *cmdtk = tz.tokens; if (cmdtk->type == TOK_CMD) { ok = cmdtk->cmd->fn(cmdtk->next); if (!ok) { usprintf(RES.errmsg, "cmd %s failed", cmdtk->str); goto next; } } else if (cmdtk->type == TOK_MISC) { } next: tz_free(&tz); ufree(line); line = string_tokenizealloc(NULL, "\n"); } #if 0 char line[LINE_MAX]; size_t pos = 0; while (string[pos] != '\0') { string_memset(line, 0, sizeof(line)); size_t next = inter_readline(string, pos, line, sizeof(line)); if (next == pos) { break; } if (logcmds) { uprintf("+%s\n", line); } /* Tokenizer tz; ZERO(&tz); */ /* tz_init(&tz, line, string_len(line)); */ /* Token tktmp; ZERO(&tktmp); */ /* while (tz_next(&tz, &tktmp)) { */ /* Token *tk = dlmalloc(sizeof(*tk)); */ /* tk->ptr = tktmp.ptr; */ /* tk->len = tktmp.len; */ /* tk->next = NULL; */ /* LL_APPEND(tz.tokens, tk); */ /* } */ /* tz_classify(&tz); */ /* tz_expandspecial(&tz); */ /* Token *cmdtk = tz.tokens; */ /* if (cmdtk->type == TOK_CMD) { */ /* ok = cmdtk->cmd->fn(cmdtk->next); */ /* if (!ok) { */ /* usprintf(RES.errmsg, "cmd %.*s failed", (int)cmdtk->len, cmdtk->ptr); */ /* tz_free(&tz); */ /* goto done; */ /* } */ /* } else if (cmdtk->type == TOK_MISC) { */ /* } */ /* nextline: { */ /* tz_free(&tz); */ pos = next; /* } */ } /* char *bg = NULL, *end = NULL; */ /* interp_readline((char *)string, NULL, NULL); */ /* while (interp_readline(NULL, &bg, &end)) { */ /* size_t linelen = (size_t)(end - bg); */ /* if (logcmds) { */ /* uprintf("+ %.*s\n", (int)linelen, bg); */ /* } */ /* Tokenizer tz = {0}; */ /* tz_init(&tz, bg, linelen); */ /* Token toktmp = {0}; */ #if 0 while (tz_next(&tz, &toktmp)) { Token *tok = dlmalloc(sizeof(*tok)); tok->ptr = toktmp.ptr; tok->len = toktmp.len; tok->next = NULL; LL_APPEND(tz.tokens, tok); string_memset(&toktmp, 0, sizeof(toktmp)); } tz_classify(&tz); tz_expandspecial(&tz); Token *cmdtk = tz.tokens; if (cmdtk->type == TOK_CMD) { /* ok = cmdtk->cmd->fn(cmdtk->next); */ /* if (!ok) { */ /* usprintf(RES.errmsg, "cmd %.*s failed", (int)cmdtk->len, cmdtk->ptr); */ /* tz_free(&tz); */ /* goto done; */ /* } */ } else if (cmdtk->type == TOK_MISC) { /* const int appname_max = 128; */ /* char *appname = dlmalloc(appname_max); */ /* string_memset(appname, 0, appname_max); */ /* string_memcpy(appname, cmdtk->ptr, MIN(cmdtk->len, appname_max)); */ /* usnprintf(appname, appname_max, "%.*s", (int)cmdtk->len, cmdtk->ptr); */ /* size_t argslen1; */ /* LL_FOREACH_SAFE_IDX(cmdtk->next, argtk, argtktmp, argslen1); */ /* size_t i; */ /* char **args1 = (char **)dlmalloc(sizeof(char *) * argslen1); */ /* LL_FOREACH_SAFE_IDX(cmdtk->next, argtk, argtktmp, i) { */ /* args1[i] = (char *)dlmalloc(PROC_ARG_MAX); */ /* string_memset(args1[i], 0, PROC_ARG_MAX); */ /* string_memcpy(args1[i], argtk->ptr, argtk->len); */ /* } */ /* int32_t app = processctl(-1, PCTL_SPAWN, (uint64_t)appname, (uint64_t)args1, argslen1); */ /* if (app < 0) { */ /* usprintf(RES.errmsg, "Could not run %s: %s\n", appname, ERRSTRING(app)); */ /* ok = false; */ /* goto cleanup; */ /* } */ /* processctl(app, PCTL_RUN, 0, 0, 0); */ /* uint8_t b; */ /* while(processctl(app, PCTL_POLLSTATE, 0, 0, 0) != 4) { */ /* if (interactive) { */ /* int32_t nrd = ipcpipe(PID, IPCPIPE_IN, IPCPIPE_READ, &b, 1); */ /* if (nrd > 0 && b == C('S')) { */ /* processctl(app, PCTL_KILL, 0, 0, 0); */ /* goto cleanup; */ /* } */ /* } */ /* schedrelease(); */ /* } */ cleanup: { /* for (size_t j = 0; j < argslen1; j++) dlfree(args1[j]); */ /* dlfree(args1); */ /* dlfree((void*)appname); */ } } tz_free(&tz); #endif /* } */ #endif done: return ok; }