diff options
Diffstat (limited to 'build.c')
-rw-r--r-- | build.c | 204 |
1 files changed, 119 insertions, 85 deletions
@@ -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; } |