summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--main.c28
-rw-r--r--ted.c46
-rw-r--r--ted.h9
3 files changed, 66 insertions, 17 deletions
diff --git a/main.c b/main.c
index 7ee1bc4..0926d5d 100644
--- a/main.c
+++ b/main.c
@@ -1,7 +1,6 @@
/*
@TODO:
- ted.h documentation
-- broken session fix: close buffers not in any used node
- handle multiple symbols with same name in go-to-definition menu
- better non-error window/showMessage(Request)
- document lsp.h and lsp.c.
@@ -394,14 +393,15 @@ int main(int argc, char **argv) {
}
- FILE *log = NULL;
{
// open log file
+ FILE *log = NULL;
char log_filename[TED_PATH_MAX];
strbuf_printf(log_filename, "%s/log.txt", ted->local_data_dir);
log = fopen(log_filename, "w");
+ setbuf(log, NULL);
+ ted->log = log;
}
- ted->log = log;
{ // get current working directory
fs_get_cwd(ted->cwd, sizeof ted->cwd);
@@ -1021,16 +1021,13 @@ int main(int argc, char **argv) {
ted->error_time = ted->frame_time;
str_cpy(ted->error_shown, sizeof ted->error_shown, ted->error);
- { // output error to log file
- char tstr[256];
- time_t t = time(NULL);
- struct tm *tm = localtime(&t);
- strftime(tstr, sizeof tstr, "%Y-%m-%d %H:%M:%S", tm);
- if (log) {
- fprintf(log, "[ERROR %s] %s\n", tstr, ted->error);
- fflush(log);
- }
- }
+ // output error to log file
+ char tstr[256];
+ time_t t = time(NULL);
+ struct tm *tm = localtime(&t);
+ strftime(tstr, sizeof tstr, "%Y-%m-%d %H:%M:%S", tm);
+ ted_log(ted, "[ERROR %s] %s\n", tstr, ted->error);
+
ted_clearerr(ted);
}
@@ -1064,6 +1061,8 @@ int main(int argc, char **argv) {
text_render(font);
}
}
+
+ ted_check_for_node_problems(ted);
#if !NDEBUG
for (u16 i = 0; i < TED_MAX_BUFFERS; ++i)
@@ -1144,7 +1143,7 @@ int main(int argc, char **argv) {
free(*cmd);
}
arr_free(ted->shell_history);
-
+ fclose(ted->log), ted->log = NULL;
SDL_FreeCursor(ted->cursor_arrow);
SDL_FreeCursor(ted->cursor_ibeam);
SDL_FreeCursor(ted->cursor_wait);
@@ -1155,7 +1154,6 @@ int main(int argc, char **argv) {
SDL_GL_DeleteContext(glctx);
SDL_DestroyWindow(window);
SDL_Quit();
- if (log) fclose(log);
definitions_selector_close(ted);
for (u16 i = 0; i < TED_MAX_BUFFERS; ++i)
if (ted->buffers_used[i])
diff --git a/ted.c b/ted.c
index 840244d..a6c10ca 100644
--- a/ted.c
+++ b/ted.c
@@ -16,6 +16,23 @@ void die(const char *fmt, ...) {
exit(EXIT_FAILURE);
}
+void ted_seterr(Ted *ted, const char *fmt, ...) {
+ va_list args;
+ va_start(args, fmt);
+ vsnprintf(ted->error, sizeof ted->error - 1, fmt, args);
+ va_end(args);
+}
+
+void ted_log(Ted *ted, const char *fmt, ...) {
+ if (!ted->log) return;
+
+ va_list args;
+ va_start(args, fmt);
+ vfprintf(ted->log, fmt, args);
+ va_end(args);
+}
+
+
void ted_seterr_to_buferr(Ted *ted, TextBuffer *buffer) {
size_t size = sizeof ted->error;
if (sizeof buffer->error < size) size = sizeof buffer->error;
@@ -578,3 +595,32 @@ void ted_go_to_lsp_document_position(Ted *ted, LSP *lsp, LSPDocumentPosition pos
void ted_cancel_lsp_request(Ted *ted, LSPID lsp, LSPRequestID request) {
lsp_cancel_request(ted_get_lsp_by_id(ted, lsp), request);
}
+
+
+static void mark_node_reachable(Ted *ted, u16 node, bool reachable[TED_MAX_NODES]) {
+ if (reachable[node]) {
+ ted_seterr(ted, "NODE CYCLE %u\nThis should never happen.", node);
+ ted_log(ted, "NODE CYCLE %u\n", node);
+ node_close(ted, node);
+ return;
+ }
+ reachable[node] = true;
+ Node *n = &ted->nodes[node];
+ if (!n->tabs) {
+ mark_node_reachable(ted, n->split_a, reachable);
+ mark_node_reachable(ted, n->split_b, reachable);
+ }
+}
+
+void ted_check_for_node_problems(Ted *ted) {
+ bool reachable[TED_MAX_NODES] = {0};
+ if (ted->nodes_used[0])
+ mark_node_reachable(ted, 0, reachable);
+ for (u16 i = 0; i < TED_MAX_NODES; ++i) {
+ if (ted->nodes_used[i] && !reachable[i]) {
+ ted_seterr(ted, "ORPHANED NODE %u\nThis should never happen.", i);
+ ted_log(ted, "ORPHANED NODE %u\n", i);
+ node_close(ted, i);
+ }
+ }
+}
diff --git a/ted.h b/ted.h
index 16aa07d..33293ec 100644
--- a/ted.h
+++ b/ted.h
@@ -589,6 +589,7 @@ typedef struct Ted {
char build_dir[TED_PATH_MAX]; // directory where we run the build command
char tags_dir[TED_PATH_MAX]; // where we are reading tags from
bool nodes_used[TED_MAX_NODES];
+ // nodes[0] is always the "root node", if any buffers are open.
Node nodes[TED_MAX_NODES];
// NOTE: the buffer at index 0 is reserved as a "null buffer" and should not be used.
bool buffers_used[TED_MAX_BUFFERS];
@@ -1031,10 +1032,12 @@ bool tag_goto(Ted *ted, const char *tag);
SymbolInfo *tags_get_symbols(Ted *ted);
// === ted.c ===
-#define ted_seterr(ted, ...) \
- snprintf((ted)->error, sizeof (ted)->error - 1, __VA_ARGS__)
// for fatal errors
void die(PRINTF_FORMAT_STRING const char *fmt, ...) ATTRIBUTE_PRINTF(1, 2);
+// for non-fatal errors that should be displayed to the user
+void ted_seterr(Ted *ted, PRINTF_FORMAT_STRING const char *fmt, ...) ATTRIBUTE_PRINTF(2, 3);
+// for information that should be logged
+void ted_log(Ted *ted, PRINTF_FORMAT_STRING const char *fmt, ...) ATTRIBUTE_PRINTF(2, 3);
void *ted_malloc(Ted *ted, size_t size);
void *ted_calloc(Ted *ted, size_t n, size_t size);
void *ted_realloc(Ted *ted, void *p, size_t new_size);
@@ -1086,6 +1089,8 @@ void ted_go_to_lsp_document_position(Ted *ted, LSP *lsp, LSPDocumentPosition pos
void ted_cancel_lsp_request(Ted *ted, LSPID lsp, LSPRequestID request);
// how tall is a line buffer?
float ted_line_buffer_height(Ted *ted);
+// check for orphaned nodes and node cycles
+void ted_check_for_node_problems(Ted *ted);
// === ui.c ===
void selector_up(Ted *ted, Selector *s, i64 n);