summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--colors.c28
-rw-r--r--command.c27
-rw-r--r--config.c1
-rw-r--r--lsp-write.c1
-rw-r--r--main.c4
-rw-r--r--os-posix.c56
-rw-r--r--os-win.c2
-rw-r--r--os.h2
-rw-r--r--ted.h2
9 files changed, 93 insertions, 30 deletions
diff --git a/colors.c b/colors.c
index fe5aaad..896f0e3 100644
--- a/colors.c
+++ b/colors.c
@@ -7,7 +7,7 @@ typedef struct {
const char *name;
} ColorName;
-static ColorName const color_names[] = {
+static ColorName color_names[] = {
{COLOR_UNKNOWN, "unknown"},
{COLOR_TEXT, "text"},
{COLOR_TEXT_SECONDARY, "text-secondary"},
@@ -62,12 +62,28 @@ static ColorName const color_names[] = {
static_assert_if_possible(arr_count(color_names) == COLOR_COUNT)
+int color_name_cmp(const void *av, const void *bv) {
+ const ColorName *a = av, *b = bv;
+ return strcmp(a->name, b->name);
+}
+
+void color_init(void) {
+ qsort(color_names, arr_count(color_names), sizeof *color_names, color_name_cmp);
+}
+
ColorSetting color_setting_from_str(const char *str) {
- // @TODO(optimize): sort color_names, binary search
- for (int i = 0; i < COLOR_COUNT; ++i) {
- ColorName const *n = &color_names[i];
- if (streq(n->name, str))
- return n->setting;
+ int lo = 0;
+ int hi = COLOR_COUNT;
+ while (lo < hi) {
+ int mid = (lo + hi) / 2;
+ int cmp = strcmp(color_names[mid].name, str);
+ if (cmp < 0) {
+ lo = mid + 1;
+ } else if (cmp > 0) {
+ hi = mid;
+ } else {
+ return color_names[mid].setting;
+ }
}
return COLOR_UNKNOWN;
}
diff --git a/command.c b/command.c
index 7e33229..bafb4f6 100644
--- a/command.c
+++ b/command.c
@@ -7,7 +7,7 @@ typedef struct {
const char *name;
Command cmd;
} CommandName;
-static CommandName const command_names[] = {
+static CommandName command_names[] = {
{"unknown", CMD_UNKNOWN},
{"noop", CMD_NOOP},
{"left", CMD_LEFT},
@@ -99,11 +99,28 @@ static CommandName const command_names[] = {
static_assert_if_possible(arr_count(command_names) == CMD_COUNT)
+int command_name_cmp(const void *av, const void *bv) {
+ const CommandName *a = av, *b = bv;
+ return strcmp(a->name, b->name);
+}
+
+void command_init(void) {
+ qsort(command_names, arr_count(command_names), sizeof *command_names, command_name_cmp);
+}
+
Command command_from_str(const char *str) {
- // @TODO(optimize): sort command_names, do a binary search
- for (int i = 0; i < CMD_COUNT; ++i) {
- if (streq(command_names[i].name, str))
- return command_names[i].cmd;
+ int lo = 0;
+ int hi = CMD_COUNT;
+ while (lo < hi) {
+ int mid = (lo + hi) / 2;
+ int cmp = strcmp(command_names[mid].name, str);
+ if (cmp < 0) {
+ lo = mid + 1;
+ } else if (cmp > 0) {
+ hi = mid;
+ } else {
+ return command_names[mid].cmd;
+ }
}
return CMD_UNKNOWN;
}
diff --git a/config.c b/config.c
index f16e7b7..41dc3dd 100644
--- a/config.c
+++ b/config.c
@@ -279,7 +279,6 @@ static u32 config_parse_key_combo(ConfigReader *cfg, const char *str) {
{"Enter", NULL, SDLK_RETURN},
{"Equals", "Equal", SDLK_EQUALS},
};
- // @TODO(optimize): sort key_names (and split keyname1/2); do a binary search
for (size_t i = 0; i < arr_count(key_names); ++i) {
KeyName const *k = &key_names[i];
if (streq_case_insensitive(str, k->keyname1) || (k->keyname2 && streq_case_insensitive(str, k->keyname2))) {
diff --git a/lsp-write.c b/lsp-write.c
index bb41d03..c32b8f6 100644
--- a/lsp-write.c
+++ b/lsp-write.c
@@ -332,7 +332,6 @@ static void message_writer_write_and_free(LSP *lsp, JSONWriter *o) {
printf("%s%s%s\n",term_bold(stdout),content,term_clear(stdout));
#endif
- // @TODO: does write always write the full amount? probably not. this should be fixed.
process_write(lsp->process, content, strlen(content));
str_builder_free(&builder);
diff --git a/main.c b/main.c
index e99f12f..0a9e379 100644
--- a/main.c
+++ b/main.c
@@ -28,6 +28,7 @@ FUTURE FEATURES:
- write first to <path>.tmp then rename to <path>.
this prevents freak occurences, e.g. power outage during file write,
from losing (all) data.
+- manual.md
- better handling of backspace with space indentation
- CSS highlighting
- styles ([color] sections)
@@ -318,6 +319,9 @@ int main(int argc, char **argv) {
setlocale(LC_ALL, "C.UTF-8");
#endif
+ command_init();
+ color_init();
+
// read command-line arguments
const char *starting_filename = NULL;
switch (argc) {
diff --git a/os-posix.c b/os-posix.c
index f98f029..3f19534 100644
--- a/os-posix.c
+++ b/os-posix.c
@@ -249,29 +249,53 @@ const char *process_geterr(Process *p) {
}
long long process_write(Process *proc, const char *data, size_t size) {
- assert(proc->stdin_pipe); // check that process hasn't been killed
- ssize_t bytes_written = write(proc->stdin_pipe, data, size);
- if (bytes_written >= 0) {
- return (long long)bytes_written;
- } else if (errno == EAGAIN) {
- return 0;
- } else {
- strbuf_printf(proc->error, "%s", strerror(errno));
+ if (!proc->stdin_pipe) { // check that process hasn't been killed
+ strbuf_printf(proc->error, "Process terminated");
+ return -2;
+ }
+ if (size > LLONG_MAX) {
+ strbuf_printf(proc->error, "Too much data to write.");
return -2;
}
+ size_t so_far = 0;
+ while (so_far < size) {
+ ssize_t bytes_written = write(proc->stdin_pipe, data + so_far, size - so_far);
+ if (bytes_written >= 0) {
+ so_far += (size_t)bytes_written;
+ } else if (errno == EAGAIN) {
+ return (long long)so_far;
+ } else {
+ strbuf_printf(proc->error, "%s", strerror(errno));
+ return -2;
+ }
+ }
+ return (long long)size;
}
static long long process_read_fd(Process *proc, int fd, char *data, size_t size) {
- assert(fd);
- ssize_t bytes_read = read(fd, data, size);
- if (bytes_read >= 0) {
- return (long long)bytes_read;
- } else if (errno == EAGAIN) {
- return -1;
- } else {
- strbuf_printf(proc->error, "%s", strerror(errno));
+ if (!fd) { // check that process hasn't been killed
+ strbuf_printf(proc->error, "Process terminated");
+ return -2;
+ }
+ if (size > LLONG_MAX) {
+ strbuf_printf(proc->error, "Too much data to read.");
return -2;
}
+ size_t so_far = 0;
+ while (so_far < size) {
+ ssize_t bytes_read = read(fd, data + so_far, size - so_far);
+ if (bytes_read > 0) {
+ so_far += (size_t)bytes_read;
+ } else if (bytes_read == 0) {
+ return (long long)so_far;
+ } else if (errno == EAGAIN) {
+ return so_far == 0 ? -1 : (long long)so_far;
+ } else {
+ strbuf_printf(proc->error, "%s", strerror(errno));
+ return -2;
+ }
+ }
+ return (long long)size;
}
long long process_read(Process *proc, char *data, size_t size) {
diff --git a/os-win.c b/os-win.c
index a32215a..0e88e68 100644
--- a/os-win.c
+++ b/os-win.c
@@ -130,7 +130,7 @@ void time_sleep_ns(u64 ns) {
}
#error "@TODO : implement process_write, separate_stderr, working_directory"
-
+#error "@TODO : make sure process_read & process_write do what they're supposed to for both blocking & non-blocking read/writes."
#include "process.h"
struct Process {
diff --git a/os.h b/os.h
index fd4bf8e..b7d189e 100644
--- a/os.h
+++ b/os.h
@@ -104,6 +104,7 @@ const char *process_geterr(Process *process);
// returns:
// -2 on error
// or a non-negative number indicating the number of bytes written.
+// If stdin is set to blocking, fewer than `size` bytes will be written only if an error occured.
long long process_write(Process *process, const char *data, size_t size);
// read from stdout+stderr
// returns:
@@ -111,6 +112,7 @@ long long process_write(Process *process, const char *data, size_t size);
// -1 if no data is available right now
// 0 on end of file
// or a positive number indicating the number of bytes read to data (at most size)
+// If stdout is set to blocking, fewer than `size` bytes will be read only if an error occured or end-of-file was reached.
long long process_read(Process *process, char *data, size_t size);
// like process_read, but reads stderr.
// this function ALWAYS RETURNS -2 if separate_stderr is not specified in the ProcessSettings.
diff --git a/ted.h b/ted.h
index ff24530..0443087 100644
--- a/ted.h
+++ b/ted.h
@@ -1009,6 +1009,7 @@ void build_check_for_errors(Ted *ted);
void build_frame(Ted *ted, float x1, float y1, float x2, float y2);
// === colors.c ===
+void color_init(void);
ColorSetting color_setting_from_str(const char *str);
const char *color_setting_to_str(ColorSetting s);
Status color_from_str(const char *str, u32 *color);
@@ -1017,6 +1018,7 @@ Status color_from_str(const char *str, u32 *color);
ColorSetting color_for_symbol_kind(SymbolKind kind);
// === command.c ===
+void command_init(void);
Command command_from_str(const char *str);
const char *command_to_str(Command c);
void command_execute(Ted *ted, Command c, i64 argument);