summaryrefslogtreecommitdiff
path: root/build.c
diff options
context:
space:
mode:
Diffstat (limited to 'build.c')
-rw-r--r--build.c204
1 files changed, 119 insertions, 85 deletions
diff --git a/build.c b/build.c
index 376566f..216c28e 100644
--- a/build.c
+++ b/build.c
@@ -1,46 +1,78 @@
-// clear build errors.
-static void build_clear(Ted *ted) {
+// clear build errors and stop
+static void build_stop(Ted *ted) {
+ if (ted->building)
+ process_kill(&ted->build_process);
+ ted->building = false;
+ ted->build_shown = false;
arr_foreach_ptr(ted->build_errors, BuildError, err) {
free(err->filename);
}
arr_clear(ted->build_errors);
+ arr_foreach_ptr(ted->build_queue, char *, cmd) {
+ free(*cmd);
+ }
+ arr_clear(ted->build_queue);
}
-static void build_stop(Ted *ted) {
- if (ted->building)
- process_kill(&ted->build_process);
- ted->building = false;
- ted->build_shown = false;
- build_clear(ted);
+// call before adding anything to the build queue
+static void build_queue_start(Ted *ted) {
+ build_stop(ted);
}
-// make sure you set ted->build_dir before running this!
-static void build_start_with_command(Ted *ted, char const *command) {
+// add a command to the build queue
+static void build_queue_command(Ted *ted, char const *command) {
+ char *copy = str_dup(command);
+ if (copy)
+ arr_add(ted->build_queue, copy);
+}
+
+// returns true if there are still commands left in the queue
+static bool build_run_next_command_in_queue(Ted *ted) {
+ if (!ted->build_queue)
+ return false;
assert(*ted->build_dir);
change_directory(ted->build_dir);
- if (ted->building) {
- build_stop(ted);
- }
- build_clear(ted); // clear errors from previous build
+ char *command = ted->build_queue[0];
+ arr_remove(ted->build_queue, 0);
if (ted_save_all(ted)) {
if (process_run(&ted->build_process, command)) {
ted->building = true;
ted->build_shown = true;
TextBuffer *build_buffer = &ted->build_buffer;
- // new empty build output buffer
- buffer_new_file(build_buffer, NULL);
- build_buffer->store_undo_events = false; // don't need undo events for build output buffer
char32_t text[] = {'$', ' '};
buffer_insert_text_at_cursor(build_buffer, str32(text, 2));
buffer_insert_utf8_at_cursor(build_buffer, command);
buffer_insert_char_at_cursor(build_buffer, '\n');
build_buffer->view_only = true;
+ free(command);
+ return true;
} else {
ted_seterr(ted, "Couldn't start build: %s", process_geterr(&ted->build_process));
+ build_stop(ted);
+ return false;
}
+ } else {
+ build_stop(ted);
+ return false;
}
}
+// make sure you set ted->build_dir before running this!
+static void build_queue_finish(Ted *ted) {
+ // new empty build output buffer
+ TextBuffer *build_buffer = &ted->build_buffer;
+ buffer_new_file(build_buffer, NULL);
+ build_buffer->store_undo_events = false; // don't need undo events for build output buffer
+ build_run_next_command_in_queue(ted); // run the first command
+}
+
+// make sure you set ted->build_dir before running this!
+static void build_start_with_command(Ted *ted, char const *command) {
+ build_queue_start(ted);
+ build_queue_command(ted, command);
+ build_queue_finish(ted);
+}
+
static void build_start(Ted *ted) {
bool cargo = false, make = false;
@@ -59,17 +91,17 @@ static void build_start(Ted *ted) {
if (fs_file_exists("Cargo.toml")) {
cargo = true;
} else if (fs_file_exists(".." PATH_SEPARATOR_STR "Cargo.toml")) {
- ted_full_path(ted, "..", ted->build_dir, sizeof ted->build_dir);
+ ted_path_full(ted, "..", ted->build_dir, sizeof ted->build_dir);
cargo = true;
} else if (fs_file_exists(".." PATH_SEPARATOR_STR ".." PATH_SEPARATOR_STR "Cargo.toml")) {
- ted_full_path(ted, "../..", ted->build_dir, sizeof ted->build_dir);
+ ted_path_full(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")) {
- ted_full_path(ted, "..", ted->build_dir, sizeof ted->build_dir);
+ ted_path_full(ted, "..", ted->build_dir, sizeof ted->build_dir);
make = true;
}
@@ -209,79 +241,81 @@ static void build_frame(Ted *ted, float x1, float y1, float x2, float y2) {
// hasn't exited yet
} else {
buffer_insert_utf8_at_cursor(buffer, message);
- ted->building = false;
-
- // check for errors
- for (u32 line_idx = 0; line_idx < buffer->nlines; ++line_idx) {
- Line *line = &buffer->lines[line_idx];
- if (line->len < 3) {
- continue;
- }
- bool is_error = true;
- char32_t *p = line->str, *end = p + line->len;
-
- {
- // rust errors look like:
- // " --> file:line:column"
- while (p != end && *p == ' ') {
- ++p;
+ buffer_insert_utf8_at_cursor(buffer, "\n");
+ if (!build_run_next_command_in_queue(ted)) {
+ ted->building = false;
+ // done command queue; check for errors
+ for (u32 line_idx = 0; line_idx < buffer->nlines; ++line_idx) {
+ Line *line = &buffer->lines[line_idx];
+ if (line->len < 3) {
+ continue;
}
- if (end - p >= 4 && p[0] == '-' && p[1] == '-' && p[2] == '>' && p[3] == ' ') {
- p += 4;
+ bool is_error = true;
+ char32_t *p = line->str, *end = p + line->len;
+
+ {
+ // rust errors look like:
+ // " --> file:line:column"
+ while (p != end && *p == ' ') {
+ ++p;
+ }
+ if (end - p >= 4 && p[0] == '-' && p[1] == '-' && p[2] == '>' && p[3] == ' ') {
+ p += 4;
+ }
}
- }
-
- // check if we have something like main.c:5 or main.c(5)
-
- // get file name
- char32_t *filename_start = p;
- while (p != end) {
- if ((*p == ':' || *p == '(')
- && p != line->str + 1) // don't catch "C:\thing\whatever.c" as "filename: C, line number: \thing\whatever.c"
- break;
- if (!is_source_path(*p)) {
- is_error = false;
- break;
+
+ // check if we have something like main.c:5 or main.c(5)
+
+ // get file name
+ char32_t *filename_start = p;
+ while (p != end) {
+ if ((*p == ':' || *p == '(')
+ && p != line->str + 1) // don't catch "C:\thing\whatever.c" as "filename: C, line number: \thing\whatever.c"
+ break;
+ if (!is_source_path(*p)) {
+ is_error = false;
+ break;
+ }
+ ++p;
}
- ++p;
- }
- if (p == end) is_error = false;
- u32 filename_len = (u32)(p - filename_start);
- if (filename_len == 0) is_error = false;
-
- if (is_error) {
- ++p; // move past : or (
- int line_number = parse_nonnegative_integer(&p, end);
- if (p != end && line_number > 0) {
- // it's an error
- line_number -= 1; // line numbers in output start from 1.
- int column_number = 0;
- // check if there's a column number
- if (*p == ':') {
- ++p; // move past :
- int num = parse_nonnegative_integer(&p, end);
- if (num > 0) {
- column_number = num - 1; // column numbers in output start from 1
+ if (p == end) is_error = false;
+ u32 filename_len = (u32)(p - filename_start);
+ if (filename_len == 0) is_error = false;
+
+ if (is_error) {
+ ++p; // move past : or (
+ int line_number = parse_nonnegative_integer(&p, end);
+ if (p != end && line_number > 0) {
+ // it's an error
+ line_number -= 1; // line numbers in output start from 1.
+ int column_number = 0;
+ // check if there's a column number
+ if (*p == ':') {
+ ++p; // move past :
+ int num = parse_nonnegative_integer(&p, end);
+ if (num > 0) {
+ column_number = num - 1; // column numbers in output start from 1
+ }
+ }
+ char *filename = str32_to_utf8_cstr(str32(filename_start, filename_len));
+ if (filename) {
+ char full_path[TED_PATH_MAX];
+ path_full(ted->build_dir, filename, full_path, sizeof full_path);
+ BuildError error = {
+ .filename = str_dup(full_path),
+ .pos = {.line = (u32)line_number, .index = (u32)column_number},
+ .build_output_line = line_idx
+ };
+ arr_add(ted->build_errors, error);
}
- }
- char *filename = str32_to_utf8_cstr(str32(filename_start, filename_len));
- if (filename) {
- char full_path[TED_PATH_MAX];
- path_full(ted->build_dir, filename, full_path, sizeof full_path);
- BuildError error = {
- .filename = str_dup(full_path),
- .pos = {.line = (u32)line_number, .index = (u32)column_number},
- .build_output_line = line_idx
- };
- arr_add(ted->build_errors, error);
}
}
}
+
+ // go to the first error (if there is one)
+ ted->build_error = 0;
+ build_go_to_error(ted);
}
-
- // go to the first error (if there is one)
- ted->build_error = 0;
- build_go_to_error(ted);
}
buffer->view_only = true;
}