summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLeo Tenenbaum <pommicket@gmail.com>2021-02-18 14:55:10 -0500
committerLeo Tenenbaum <pommicket@gmail.com>2021-02-18 14:55:10 -0500
commit8f039627ab777d2b08c0c46d5acacbe84817d20f (patch)
tree0ac67f93e41e29b2b5da836df2bdef54e037947f
parente239b66691200163c1983b645c28b34825f32ea4 (diff)
:build working (i think)
-rw-r--r--build.c50
-rw-r--r--config.c19
-rw-r--r--main.c2
-rw-r--r--process-posix.c4
-rw-r--r--process-win.c38
-rw-r--r--process.h3
-rw-r--r--ted.cfg1
-rw-r--r--ted.h1
8 files changed, 78 insertions, 40 deletions
diff --git a/build.c b/build.c
index 60cd70f..0112c0c 100644
--- a/build.c
+++ b/build.c
@@ -7,16 +7,26 @@ static void build_clear(Ted *ted) {
}
static void build_start(Ted *ted) {
+ Settings *settings = &ted->settings;
+
ted_save_all(ted);
// get rid of any old build errors
build_clear(ted);
- bool cargo = false;
+ bool cargo = false, make = false;
change_directory(ted->cwd);
strcpy(ted->build_dir, ted->cwd);
+ char *command = settings->build_default_command;
+
+#if _WIN32
+ if (fs_file_exists("make.bat")) {
+ command = "make.bat";
+ } else
+#endif
+ // check if Cargo.toml exists in this or the parent/parent's parent directory
if (fs_file_exists("Cargo.toml")) {
cargo = true;
} else if (fs_file_exists(".." PATH_SEPARATOR_STR "Cargo.toml")) {
@@ -27,34 +37,28 @@ static void build_start(Ted *ted) {
change_directory(".." PATH_SEPARATOR_STR "..");
ted_full_path(ted, "../..", ted->build_dir, sizeof ted->build_dir);
cargo = true;
+ } else
+ // Check if Makefile exists in this or the parent directory
+ if (fs_file_exists("Makefile")) {
+ make = true;
+ } else if (fs_file_exists(".." PATH_SEPARATOR_STR "Makefile")) {
+ change_directory("..");
+ ted_full_path(ted, "..", ted->build_dir, sizeof ted->build_dir);
+ make = true;
}
-
-#if __unix__
- char *program = "/bin/sh";
- char *argv[5] = {
- program, "-c", NULL, NULL, NULL
- };
- if (cargo) {
- argv[2] = "cargo build";
- } else {
- argv[2] = "make";
- }
-#else
- char *program = NULL;
- char *argv[2] = {NULL, NULL};
+
+ // @TODO(eventually): go build
+
if (cargo) {
- program = "cargo";
- argv[0] = "build";
- } else if (fs_file_exists("make.bat")) {
- program = "make.bat";
- } else {
- program = "make";
+ command = "cargo build";
+ } else if (make) {
+ command = "make";
}
-#endif
- if (process_exec(&ted->build_process, program, argv)) {
+ if (process_run(&ted->build_process, command)) {
ted->building = true;
ted->build_shown = true;
+ // new empty build output buffer
buffer_new_file(&ted->build_buffer, NULL);
ted->build_buffer.store_undo_events = false; // don't need undo events for build output buffer
ted->build_buffer.view_only = true;
diff --git a/config.c b/config.c
index 9589749..23fe5c9 100644
--- a/config.c
+++ b/config.c
@@ -169,6 +169,11 @@ void config_read(Ted *ted, char const *filename) {
char const *name;
u16 *control, min, max;
} OptionU16;
+ typedef struct {
+ char const *name;
+ char *control;
+ size_t buf_size;
+ } OptionString;
// core options
// (these go at the start so they don't need to be re-computed each time)
OptionBool const options_bool[] = {
@@ -195,6 +200,9 @@ void config_read(Ted *ted, char const *filename) {
{"max-menu-width", &settings->max_menu_width, 10, U16_MAX},
{"error-display-time", &settings->error_display_time, 0, U16_MAX},
};
+ OptionString const options_string[] = {
+ {"build-default-command", settings->build_default_command, sizeof settings->build_default_command},
+ };
FILE *fp = fopen(filename, "rb");
if (fp) {
@@ -377,6 +385,17 @@ void config_read(Ted *ted, char const *filename) {
config_err(cfg, "Invalid %s: %s. This should be a number from %g to %g.", option->name, value, option->min, option->max);
}
}
+
+ for (size_t i = 0; i < arr_count(options_string); ++i) {
+ OptionString const *option = &options_string[i];
+ if (streq(key, option->name)) {
+ if (strlen(value) >= option->buf_size) {
+ config_err(cfg, "%s is too long (length: %zu, maximum length: %zu).", key, strlen(value), option->buf_size - 1);
+ } else {
+ str_cpy(option->control, option->buf_size, value);
+ }
+ }
+ }
} break;
}
diff --git a/main.c b/main.c
index 878afbe..eafb1c0 100644
--- a/main.c
+++ b/main.c
@@ -1,6 +1,4 @@
// @TODO:
-// - :build (F4) -- cargo build if editing .rs file or file called Cargo.toml, otherwise make.
-
// - go to definition (with ctags) -- ctrl+click would be nice
// - :run -- if .html file, open in browser, otherwise figure out a way of sending a command to bash??
diff --git a/process-posix.c b/process-posix.c
index 6434f6e..8bfe036 100644
--- a/process-posix.c
+++ b/process-posix.c
@@ -9,7 +9,7 @@ struct Process {
char error[64];
};
-bool process_exec(Process *proc, char const *program, char **argv) {
+bool process_run(Process *proc, char const *command) {
memset(proc, 0, sizeof *proc);
bool success = false;
@@ -24,6 +24,8 @@ bool process_exec(Process *proc, char const *program, char **argv) {
dup2(pipefd[1], STDERR_FILENO);
close(pipefd[0]);
close(pipefd[1]);
+ char *program = "/bin/sh";
+ char *argv[] = {program, "-c", (char *)command, NULL};
if (execv(program, argv) == -1) {
dprintf(STDERR_FILENO, "%s: %s\n", program, strerror(errno));
exit(127);
diff --git a/process-win.c b/process-win.c
index 95f3fbe..b24dd68 100644
--- a/process-win.c
+++ b/process-win.c
@@ -3,13 +3,26 @@
struct Process {
HANDLE pipe_read, pipe_write;
PROCESS_INFORMATION process_info;
- char error[64];
+ char error[200];
};
-bool process_exec(Process *process, char const *program, char **argv) {
+static void get_last_error_str(char *out, size_t out_sz) {
+ size_t size = FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
+ NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), out, (DWORD)out_sz - 1, NULL);
+ out[size] = 0;
+ char *cr = strchr(out, '\r');
+ if (cr) *cr = '\0'; // get rid of carriage return+newline at end of error
+}
+
+bool process_run(Process *process, char const *command) {
// thanks to https://stackoverflow.com/a/35658917
bool success = false;
memset(process, 0, sizeof *process);
+ char *command_line = str_dup(command);
+ if (!command_line) {
+ strbuf_printf(process->error, "Out of memory.");
+ return false;
+ }
HANDLE pipe_read, pipe_write;
SECURITY_ATTRIBUTES security_attrs = {sizeof(SECURITY_ATTRIBUTES)};
security_attrs.bInheritHandle = TRUE;
@@ -20,28 +33,25 @@ bool process_exec(Process *process, char const *program, char **argv) {
startup.hStdError = pipe_write;
startup.wShowWindow = SW_HIDE;
- // fuckin windows
- char command_line[4096];
- strbuf_cpy(command_line, program);
- strbuf_catf(command_line, " ");
- for (int i = 0; argv[i]; ++i) {
- strbuf_catf(command_line, "%s ", argv[i]);
- }
-
if (CreateProcessA(NULL, command_line, NULL, NULL, TRUE, CREATE_NEW_CONSOLE,
NULL, NULL, &startup, &process->process_info)) {
process->pipe_read = pipe_read;
process->pipe_write = pipe_write;
success = true;
} else {
- strbuf_printf(process->error, "Couldn't create process (error code %u)", (unsigned)GetLastError());
+ char buf[150];
+ get_last_error_str(buf, sizeof buf);
+ strbuf_printf(process->error, "Couldn't run `%s`: %s", command, buf);
}
+ free(command_line);
if (!success) {
CloseHandle(pipe_read);
CloseHandle(pipe_write);
}
} else {
- strbuf_printf(process->error, "Couldn't create pipe (error code %u)", (unsigned)GetLastError());
+ char buf[150];
+ get_last_error_str(buf, sizeof buf);
+ strbuf_printf(process->error, "Couldn't create pipe: %s", buf);
}
return success;
}
@@ -60,7 +70,9 @@ long long process_read(Process *process, char *data, size_t size) {
return bytes_read;
}
} else {
- strbuf_printf(process->error, "Couldn't read from pipe (error code %u)", (unsigned)GetLastError());
+ char buf[150];
+ get_last_error_str(buf, sizeof buf);
+ strbuf_printf(process->error, "Couldn't read from pipe: %s", buf);
return -2;
}
}
diff --git a/process.h b/process.h
index 2e91598..4db864e 100644
--- a/process.h
+++ b/process.h
@@ -4,8 +4,9 @@
typedef struct Process Process;
+// execute the given command (like if it was passed to system()).
// returns false on failure
-bool process_exec(Process *process, char const *program, char **argv);
+bool process_run(Process *process, char const *command);
// returns the error last error produced, or NULL if there was no error.
char const *process_geterr(Process *process);
// returns:
diff --git a/ted.cfg b/ted.cfg
index 2a8214d..38d8c05 100644
--- a/ted.cfg
+++ b/ted.cfg
@@ -23,6 +23,7 @@ syntax-highlighting = on
line-numbers = on
# If set to "on", when a file is changed by another program, it will be reloaded by ted without asking you.
auto-reload = off
+build-default-command = timeout /t 5
[keyboard]
# motion and selection
diff --git a/ted.h b/ted.h
index 9b839c2..e5bc126 100644
--- a/ted.h
+++ b/ted.h
@@ -78,6 +78,7 @@ typedef struct {
u8 border_thickness;
u8 padding;
u8 scrolloff;
+ char build_default_command[256];
// [i] = comma-separated string of file extensions for language i, or NULL for none
char *language_extensions[LANG_COUNT];
} Settings;