#include "arena_alloc.h" #include "context.h" #include "interp.h" #include "strbuf.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define PROMPT "$ " bool print_commands = false; void* wmalloc(void* ctx, size_t size) { (void)ctx; return malloc(size); } void* wrealloc(void* ctx, void* mem, size_t old, size_t new) { (void)ctx, (void)old; return realloc(mem, new); } void wfree(void* ctx, void* mem) { (void)ctx; free(mem); } void* warena_malloc(void* ctx, size_t size) { struct arena* a = ctx; return arena_malloc(a, size); } void* warena_realloc(void* ctx, void* mem, size_t old, size_t new) { struct arena* a = ctx; return arena_realloc(a, mem, old, new); } void warena_free(void* ctx, void* mem) { (void)ctx, (void)mem; } struct edit_line { struct in_gb gb; size_t cursor; }; static void exec_line(const char* line) { struct list_node_link* tokens = NULL; if (print_commands) mprintf("+%s\n", line); tokenize(&tokens, line); if (tokens != NULL) parse_and_execute(tokens); } static bool split_lines_cb(void* ctx, const char* start, size_t len) { (void)ctx; char* line = malloc(len + 1); memcpy(line, start, len); line[len] = '\0'; if (line[0] != '\0') exec_line(line); free(line); return true; } static bool split_args_cb(void* ctx, const char* start, size_t len) { (void)ctx; if (posvar_count >= POSVAR_MAX) return false; struct posvar* posvar = &posvars[posvar_count++]; memset(posvar, 0, sizeof(*posvar)); memcpy(posvar->buf, start, min(len, sizeof(posvar->buf) - 1)); return true; } void app_main(void) { char scriptpathbuf[PATH_MAX]; char posvarsbuf[2048]; char printcmdsbuf[4]; char line[1024]; if (env_get(process_get_pgid(), "printcmds", (void*)printcmdsbuf, sizeof(printcmdsbuf)) == ST_OK && strcmp(printcmdsbuf, "yes") == 0) { print_commands = true; } memset(scriptpathbuf, 0, sizeof(scriptpathbuf)); int has_script = env_get(process_get_pgid(), "s", (void*)scriptpathbuf, sizeof(scriptpathbuf)); if (has_script == ST_OK) { if (env_get(process_get_pgid(), "args", (void*)posvarsbuf, sizeof(posvarsbuf)) == ST_OK) { strtokenize(posvarsbuf, ' ', NULL, &split_args_cb); } char volume[VOLUME_MAX]; const char* path; int ret; if (!path_parse(scriptpathbuf, volume, &path)) { mprintf("ERROR bad path '%s'\n", scriptpathbuf); return; } struct filereader fr; if ((ret = filereader_init(&fr, volume, path)) < 0) { mprintf("ERROR could not initialize filereader for '%s:%s'\n", volume, path); return; } char* buffer = malloc(fr.file_size + 1); memset(buffer, 0, fr.file_size + 1); if ((ret = filereader_read(&fr, (uint8_t*)buffer, fr.file_size)) < 0) { mprintf("ERROR could not read script: '%s:%s'\n", volume, path); free(buffer); filereader_fini(&fr); return; } str_split_lines(buffer, strlen(buffer), NULL, &split_lines_cb); free(buffer); } else { while (interp_is_running()) { memset(line, 0, sizeof(line)); in_stream_read_line(PROMPT, line, sizeof(line) - 1); if (line[0] != '\0') exec_line(line); } } }