From 1cbaa8c30f63b854696b9a0761376eda5ea87ecd Mon Sep 17 00:00:00 2001 From: Leo Tenenbaum Date: Thu, 4 Mar 2021 10:40:32 -0500 Subject: string arguments --- build.c | 2 +- command.c | 23 ++++++++++++++++++++--- command.h | 3 +++ config.c | 35 +++++++++++++++++++++++++++++++++-- main.c | 2 +- ted.cfg | 2 ++ ted.h | 5 +++++ 7 files changed, 65 insertions(+), 7 deletions(-) diff --git a/build.c b/build.c index be0763e..6ae1d64 100644 --- a/build.c +++ b/build.c @@ -137,7 +137,7 @@ static int parse_nonnegative_integer(char32_t **str, char32_t *end) { // could this character (reasonably) appear in a source file path? static bool is_source_path(char32_t c) { - char const *allowed_ascii_symbols_in_path = "./\\-_"; + char const *allowed_ascii_symbols_in_path = "./\\-_:"; return c > CHAR_MAX || isalnum((char)c) || strchr(allowed_ascii_symbols_in_path, (char)c); } diff --git a/command.c b/command.c index 9521b77..d6108bd 100644 --- a/command.c +++ b/command.c @@ -17,6 +17,17 @@ char const *command_to_str(Command c) { return "???"; } +// get the string corresponding to this argument; returns NULL if it's not a string argument +char const *arg_get_string(Ted *ted, i64 argument) { + if (argument < 0) return NULL; + if (argument & ARG_STRING) { + argument -= ARG_STRING; + if (argument < ted->nstrings) + return ted->strings[argument]; + } + return NULL; +} + void command_execute(Ted *ted, Command c, i64 argument) { TextBuffer *buffer = ted->active_buffer; Node *node = ted->active_node; @@ -336,9 +347,15 @@ void command_execute(Ted *ted, Command c, i64 argument) { case CMD_BUILD_PREV_ERROR: build_prev_error(ted); break; - case CMD_SHELL: - menu_open(ted, MENU_SHELL); - break; + case CMD_SHELL: { + char const *str = arg_get_string(ted, argument); + if (str) { + strbuf_cpy(ted->build_dir, ted->cwd); + build_start_with_command(ted, str); + } else { + menu_open(ted, MENU_SHELL); + } + } break; case CMD_GOTO_DEFINITION: menu_open(ted, MENU_GOTO_DEFINITION); diff --git a/command.h b/command.h index ab5d010..aadac48 100644 --- a/command.h +++ b/command.h @@ -1,3 +1,6 @@ +// i | ARG_STRING = ted->strings[i] +#define ARG_STRING 0x4000000000000000 + ENUM_U16 { CMD_UNKNOWN, CMD_NOOP, // do nothing diff --git a/config.c b/config.c index 721fbba..0583335 100644 --- a/config.c +++ b/config.c @@ -293,8 +293,35 @@ void config_read(Ted *ted, char const *filename) { char *endp; argument = strtoll(value, &endp, 10); value = endp; - while (isspace(*value)) ++value; // skip past space following number + } else if (*value == '"') { + // string argument + int backslashes = 0; + char const *p; + for (p = value + 1; *p; ++p) { + bool done = false; + switch (*p) { + case '\\': + ++backslashes; + break; + case '"': + if (backslashes % 2 == 0) + done = true; + break; + } + if (done) break; + } + if (!*p) { + config_err(cfg, "String doesn't end."); + break; + } + if (ted->nstrings < TED_MAX_STRINGS) { + char *str = strn_dup(value + 1, (size_t)(p - (value + 1))); + argument = ted->nstrings | ARG_STRING; + ted->strings[ted->nstrings++] = str; + } + value = p + 1; } + while (isspace(*value)) ++value; // skip past space following argument if (*value == ':') { // read the command Command command = command_from_str(value + 1); @@ -428,9 +455,13 @@ void config_read(Ted *ted, char const *filename) { } } -static void settings_free(Settings *settings) { +static void config_free(Ted *ted) { + Settings *settings = &ted->settings; for (u16 i = 0; i < LANG_COUNT; ++i) { free(settings->language_extensions[i]); settings->language_extensions[i] = NULL; } + for (u32 i = 0; i < ted->nstrings; ++i) { + free(ted->strings[i]); + } } diff --git a/main.c b/main.c index 674d121..5c7cc6d 100644 --- a/main.c +++ b/main.c @@ -956,7 +956,7 @@ int main(int argc, char **argv) { buffer_free(&ted->argument_buffer); text_font_free(ted->font); text_font_free(ted->font_bold); - settings_free(&ted->settings); + config_free(ted); free(ted); #if _WIN32 for (int i = 0; i < argc; ++i) diff --git a/ted.cfg b/ted.cfg index 68e2b67..283a5ce 100644 --- a/ted.cfg +++ b/ted.cfg @@ -127,6 +127,8 @@ Ctrl+[ = :build-prev-error Ctrl+] = :build-next-error Ctrl+! = :shell +Ctrl+t = "ctags *.c *.h" :shell + Ctrl+d = :goto-definition Ctrl+g = :goto-line diff --git a/ted.h b/ted.h index c99cab8..586fcd9 100644 --- a/ted.h +++ b/ted.h @@ -218,6 +218,8 @@ typedef struct Node { #define TED_MAX_NODES 256 // max tabs per node #define TED_MAX_TABS 100 +// max strings in config file +#define TED_MAX_STRINGS 1000 typedef struct { BufferPos start; @@ -327,6 +329,9 @@ typedef struct Ted { // NOTE: the buffer at index 0 is reserved as a "null buffer" and should not be used. bool buffers_used[TED_MAX_BUFFERS]; TextBuffer buffers[TED_MAX_BUFFERS]; + // config file strings + u32 nstrings; + char *strings[TED_MAX_STRINGS]; char window_title[256]; char error[512]; char error_shown[512]; // error display in box on screen -- cgit v1.2.3