ExecAndWait
This commit is contained in:
@@ -42,6 +42,7 @@ struct StdoutPollInfo {
|
||||
struct Process {
|
||||
bool is_valid;
|
||||
String error_message;
|
||||
bool exited;
|
||||
int exit_code;
|
||||
char platform[6 * 8];
|
||||
|
||||
@@ -52,5 +53,6 @@ struct Process {
|
||||
Process CreateCommandLineProcess(String command_line, String working_dir);
|
||||
bool WaitForExit(Process *process);
|
||||
bool PollExitCode(Process *process);
|
||||
void CloseProcess(Process *process);
|
||||
void KillProcess(Process *process);
|
||||
StdoutPollInfo PollStdout(Process *process, char *buffer, int64_t buffer_size);
|
||||
@@ -396,6 +396,7 @@ Process CreateCommandLineProcess(String command_line, String working_dir) {
|
||||
bool PollExitCode(Process *process) {
|
||||
Assert(process->is_valid);
|
||||
Win32Process *p = (Win32Process *)process->platform;
|
||||
if (process->exited) return process->exited;
|
||||
|
||||
if (WaitForSingleObject(p->handle, 0) != WAIT_OBJECT_0) {
|
||||
return false;
|
||||
@@ -407,11 +408,15 @@ bool PollExitCode(Process *process) {
|
||||
exit_code = -1;
|
||||
}
|
||||
|
||||
process->exited = true;
|
||||
process->exit_code = (int)exit_code;
|
||||
Win32CloseProcess(process);
|
||||
return true;
|
||||
}
|
||||
|
||||
void CloseProcess(Process *process) {
|
||||
Win32CloseProcess(process);
|
||||
}
|
||||
|
||||
void KillProcess(Process *process) {
|
||||
Assert(process->is_valid);
|
||||
Win32Process *p = (Win32Process *)process->platform;
|
||||
@@ -437,6 +442,10 @@ StdoutPollInfo PollStdout(Process *process, char *buffer, int64_t buffer_size) {
|
||||
return result;
|
||||
}
|
||||
|
||||
if (!buffer) {
|
||||
return {0, bytes_avail};
|
||||
}
|
||||
|
||||
if (bytes_avail == 0) {
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -114,6 +114,11 @@ void IKnowWhatImDoing_Append(Buffer *buffer, String16 string) {
|
||||
IKnowWhatImDoing_ReplaceText(buffer, GetEndAsRange(*buffer), string);
|
||||
}
|
||||
|
||||
void IKnowWhatImDoing_Append(Buffer *buffer, String string) {
|
||||
Scratch scratch;
|
||||
IKnowWhatImDoing_Append(buffer, ToString16(scratch, string));
|
||||
}
|
||||
|
||||
void IKnowWhatImDoing_Appendf(Buffer *buffer, const char *fmt, ...) {
|
||||
Scratch scratch;
|
||||
STRING_FORMAT(scratch, fmt, string);
|
||||
|
||||
@@ -20,6 +20,7 @@ void UpdateProcesses() {
|
||||
|
||||
bool exited = PollExitCode(&it);
|
||||
if (exited) {
|
||||
CloseProcess(&it);
|
||||
remove_item = true;
|
||||
String s = Format(scratch, "exited with code: %d", it.exit_code);
|
||||
Command_Append(view_id, s, it.scroll_to_end);
|
||||
@@ -32,10 +33,9 @@ void Exec(ViewID view, bool scroll_to_end, String cmd, String working_dir) {
|
||||
if (process.error_message.len) Command_Append(view, process.error_message, process.scroll_to_end);
|
||||
process.view_id = view.id;
|
||||
process.scroll_to_end = scroll_to_end;
|
||||
if (process.is_valid) {
|
||||
Assert(process.error_message.len == 0);
|
||||
Add(&ActiveProcesses, process);
|
||||
}
|
||||
if (!process.is_valid) return;
|
||||
Assert(process.error_message.len == 0);
|
||||
Add(&ActiveProcesses, process);
|
||||
}
|
||||
|
||||
void Exec(ViewID view, bool scroll_to_end, String16 cmd16, String working_dir) {
|
||||
@@ -44,6 +44,27 @@ void Exec(ViewID view, bool scroll_to_end, String16 cmd16, String working_dir) {
|
||||
Exec(view, scroll_to_end, cmd, working_dir);
|
||||
}
|
||||
|
||||
Buffer *ExecAndWait(Allocator allocator, String cmd, String working_dir) {
|
||||
Process process = CreateCommandLineProcess(cmd, working_dir);
|
||||
if (process.error_message.len) ReportWarningf("%.*s", FmtString(process.error_message));
|
||||
if (!process.is_valid) return {};
|
||||
|
||||
Scratch scratch;
|
||||
Buffer *temp_buffer = CreateTempBuffer(allocator, 4096 * 2);
|
||||
char *buffer = AllocArray(scratch, char, 4096);
|
||||
for (;;) {
|
||||
bool exited = PollExitCode(&process);
|
||||
StdoutPollInfo i0 = PollStdout(&process, buffer, 4096);
|
||||
IKnowWhatImDoing_Append(temp_buffer, String{buffer, i0.size_read});
|
||||
if (exited && i0.size_available == 0) {
|
||||
CloseProcess(&process);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return temp_buffer;
|
||||
}
|
||||
|
||||
void KillProcess(ViewID view) {
|
||||
IterRemove(ActiveProcesses) {
|
||||
IterRemovePrepare(ActiveProcesses);
|
||||
|
||||
@@ -128,6 +128,7 @@ void Command_SelectRangeOneCursor(View *view, Range range);
|
||||
void Command_Append(ViewID view_id, String16 string, bool scroll_to_end_if_cursor_on_last_line);
|
||||
void Command_Append(ViewID view_id, String string, bool scroll_to_end_if_cursor_on_last_line);
|
||||
|
||||
void ReportConsolef(const char *fmt, ...);
|
||||
void ReportErrorf(const char *fmt, ...);
|
||||
void ReportWarningf(const char *fmt, ...);
|
||||
|
||||
|
||||
@@ -10,7 +10,6 @@
|
||||
- Change mouse keybindings again (left+ctrl could be load - left+ctrl could be add new cursor), exec could be middle mouse
|
||||
- Store editor metadata in user accessible buffers? (read only)
|
||||
- Find matches using grep, change things in that buffer then apply those changes to all items
|
||||
- assert buffer name unique when createing and changing name
|
||||
|
||||
- apply clang format
|
||||
- apply clang format on save
|
||||
|
||||
Reference in New Issue
Block a user