Skip to content

Commit 97deef5

Browse files
committed
Revise Nob_Cmd_Opt
- Replace .fd* options with .std*_path options. - Remove .no_reset (always reset).
1 parent 186a1a6 commit 97deef5

3 files changed

Lines changed: 77 additions & 74 deletions

File tree

how_to/005_parallel_build/nob.c

Lines changed: 17 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -15,24 +15,23 @@ int main(int argc, char **argv)
1515

1616
if (!mkdir_if_not_exists(BUILD_FOLDER)) return 1;
1717

18-
// Spawn three async processes collecting them to procs dynamic array
19-
nob_cc(&cmd);
20-
nob_cc_flags(&cmd);
21-
nob_cc_output(&cmd, BUILD_FOLDER"foo");
22-
nob_cc_inputs(&cmd, SRC_FOLDER"foo.c");
23-
if (!cmd_run(&cmd, .async = &procs)) return 1;
24-
25-
nob_cc(&cmd);
26-
nob_cc_flags(&cmd);
27-
nob_cc_output(&cmd, BUILD_FOLDER"bar");
28-
nob_cc_inputs(&cmd, SRC_FOLDER"bar.c");
29-
if (!cmd_run(&cmd, .async = &procs)) return 1;
30-
31-
nob_cc(&cmd);
32-
nob_cc_flags(&cmd);
33-
nob_cc_output(&cmd, BUILD_FOLDER"baz");
34-
nob_cc_inputs(&cmd, SRC_FOLDER"baz.c");
35-
if (!cmd_run(&cmd, .async = &procs)) return 1;
18+
static struct {
19+
const char *bin_path;
20+
const char *src_path;
21+
} targets[] = {
22+
{ .bin_path = BUILD_FOLDER"foo", .src_path = SRC_FOLDER"foo.c" },
23+
{ .bin_path = BUILD_FOLDER"bar", .src_path = SRC_FOLDER"bar.c" },
24+
{ .bin_path = BUILD_FOLDER"baz", .src_path = SRC_FOLDER"baz.c" },
25+
};
26+
27+
// Spawn one async process per target collecting them to procs dynamic array
28+
for (size_t i = 0; i < ARRAY_LEN(targets); ++i) {
29+
nob_cc(&cmd);
30+
nob_cc_flags(&cmd);
31+
nob_cc_output(&cmd, targets[i].bin_path);
32+
nob_cc_inputs(&cmd, targets[i].src_path);
33+
if (!cmd_run(&cmd, .async = &procs)) return 1;
34+
}
3635

3736
// Wait on all the async processes to finish and reset procs dynamic array to 0
3837
if (!procs_flush(&procs)) return 1;

nob.h

Lines changed: 59 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -393,18 +393,16 @@ typedef struct {
393393

394394
// Options for nob_cmd_run_opt() function.
395395
typedef struct {
396-
// Do not reset the cmd array and do not close the stdin, stdout, stderr files
397-
bool no_reset;
398396
// Run the command asynchronously appending its Nob_Proc to the provided Nob_Procs array
399397
Nob_Procs *async;
400398
// Maximum processes allowed in the .async list. Zero implies nob_nprocs().
401399
size_t max_procs;
402-
// Redirect stdin
403-
Nob_Fd *fdin;
404-
// Redirect stdout
405-
Nob_Fd *fdout;
406-
// Redirect stderr
407-
Nob_Fd *fderr;
400+
// Redirect stdin to file
401+
const char *stdin_path;
402+
// Redirect stdout to file
403+
const char *stdout_path;
404+
// Redirect stderr to file
405+
const char *stderr_path;
408406
} Nob_Cmd_Opt;
409407

410408
// Run the command with options.
@@ -438,16 +436,12 @@ NOBDEF Nob_Proc nob_cmd_start_process(Nob_Cmd cmd, Nob_Fd *fdin, Nob_Fd *fdout,
438436
// })) fail();
439437
// ```
440438
//
441-
// But these days you should do everything through nob_cmd_run:
439+
// But these days you should do:
442440
//
443441
// ```c
444-
// Nob_Fd fdin = nob_fd_open_for_read("input.txt");
445-
// if (fdin == NOB_INVALID_FD) fail();
446-
// Nob_Fd fdout = nob_fd_open_for_write("output.txt");
447-
// if (fdout == NOB_INVALID_FD) fail();
448442
// Nob_Cmd cmd = {0};
449443
// nob_cmd_append(&cmd, "cat");
450-
// if (!nob_cmd_run(&cmd, .stdin = &fdin, .stdout = &fdout)) fail();
444+
// if (!nob_cmd_run(&cmd, .stdin_path = "input.txt", .stdout_path = "output.txt")) fail();
451445
// ```
452446
typedef struct {
453447
Nob_Fd *fdin;
@@ -473,33 +467,34 @@ NOBDEF void nob_cmd_render(Nob_Cmd cmd, Nob_String_Builder *render);
473467
#define nob_cmd_free(cmd) NOB_FREE(cmd.items)
474468

475469
// Run command asynchronously
476-
NOB_DEPRECATED("Use `nob_cmd_run(&cmd, .async = &procs, .no_reset = true)` instead.")
470+
NOB_DEPRECATED("Use `nob_cmd_run(&cmd, .async = &procs)` instead, but keep in mind that it always resets the cmd array.")
477471
NOBDEF Nob_Proc nob_cmd_run_async(Nob_Cmd cmd);
478472

479473
// nob_cmd_run_async_and_reset() is just like nob_cmd_run_async() except it also resets cmd.count to 0
480474
// so the Nob_Cmd instance can be seamlessly used several times in a row
481-
NOB_DEPRECATED("Use `nob_cmd_run(&cmd, .async = &procs)` intead")
475+
NOB_DEPRECATED("Use `nob_cmd_run(&cmd, .async = &procs)` intead.")
482476
NOBDEF Nob_Proc nob_cmd_run_async_and_reset(Nob_Cmd *cmd);
483477

484478
// Run redirected command asynchronously
485479
NOB_DEPRECATED("Use `nob_cmd_run(&cmd, "
486480
".async = &procs, "
487-
".stdin = &fdin, "
488-
".stdout = &fdout, "
489-
".stderr = &fderr, "
490-
".no_reset = true)` instead")
481+
".stdin_path = \"path/to/stdin\", "
482+
".stdout_path = \"path/to/stdout\", "
483+
".stderr_path = \"path/to/stderr\")` instead, "
484+
"but keep in mind that it always resets the cmd array.")
491485
NOBDEF Nob_Proc nob_cmd_run_async_redirect(Nob_Cmd cmd, Nob_Cmd_Redirect redirect);
492486

493487
// Run redirected command asynchronously and set cmd.count to 0 and close all the opened files
494488
NOB_DEPRECATED("Use `nob_cmd_run(&cmd, "
495489
".async = &procs, "
496-
".stdin = &fdin, "
497-
".stdout = &fdout, "
498-
".stderr = &fderr)` instead.")
490+
".stdin_path = \"path/to/stdin\", "
491+
".stdout_path = \"path/to/stdout\", "
492+
".stderr_path = \"path/to/stderr\")` instead.")
499493
NOBDEF Nob_Proc nob_cmd_run_async_redirect_and_reset(Nob_Cmd *cmd, Nob_Cmd_Redirect redirect);
500494

501495
// Run command synchronously
502-
NOB_DEPRECATED("Use `nob_cmd_run(&cmd, .no_reset = true)` instead")
496+
NOB_DEPRECATED("Use `nob_cmd_run(&cmd)` instead, "
497+
"but keep in mind that it always resets the cmd array.")
503498
NOBDEF bool nob_cmd_run_sync(Nob_Cmd cmd);
504499

505500
// NOTE: nob_cmd_run_sync_and_reset() is just like nob_cmd_run_sync() except it also resets cmd.count to 0
@@ -509,17 +504,17 @@ NOBDEF bool nob_cmd_run_sync_and_reset(Nob_Cmd *cmd);
509504

510505
// Run redirected command synchronously
511506
NOB_DEPRECATED("Use `nob_cmd_run(&cmd, "
512-
".stdin = &fdin, "
513-
".stdout = &fdout, "
514-
".stderr = &fderr, "
515-
".no_reset = true)` instead.")
507+
".stdin_path = \"path/to/stdin\", "
508+
".stdout_path = \"path/to/stdout\", "
509+
".stderr_path = \"path/to/stderr\")` instead, "
510+
"but keep in mind that it always resets the cmd array.")
516511
NOBDEF bool nob_cmd_run_sync_redirect(Nob_Cmd cmd, Nob_Cmd_Redirect redirect);
517512

518513
// Run redirected command synchronously and set cmd.count to 0 and close all the opened files
519-
NOB_DEPRECATED("Use nob_cmd_run(&cmd, "
520-
".stdin = &fdin, "
521-
".stdout = &fdout, "
522-
".stderr = &fderr); instead.")
514+
NOB_DEPRECATED("Use `nob_cmd_run(&cmd, "
515+
".stdin_path = \"path/to/stdin\", "
516+
".stdout_path = \"path/to/stdout\", "
517+
".stderr_path = \"path/to/stderr\")` instead.")
523518
NOBDEF bool nob_cmd_run_sync_redirect_and_reset(Nob_Cmd *cmd, Nob_Cmd_Redirect redirect);
524519

525520
#ifndef NOB_TEMP_CAPACITY
@@ -1026,13 +1021,21 @@ NOBDEF int nob_nprocs(void)
10261021

10271022
NOBDEF bool nob_cmd_run_opt(Nob_Cmd *cmd, Nob_Cmd_Opt opt)
10281023
{
1024+
bool result = true;
1025+
Nob_Fd fdin = NOB_INVALID_FD;
1026+
Nob_Fd fdout = NOB_INVALID_FD;
1027+
Nob_Fd fderr = NOB_INVALID_FD;
1028+
Nob_Fd *opt_fdin = NULL;
1029+
Nob_Fd *opt_fdout = NULL;
1030+
Nob_Fd *opt_fderr = NULL;
1031+
10291032
size_t max_procs = opt.max_procs > 0 ? opt.max_procs : (size_t) nob_nprocs() + 1;
10301033

10311034
if (opt.async && max_procs > 0) {
10321035
while (opt.async->count >= max_procs) {
10331036
for (size_t i = 0; i < opt.async->count; ++i) {
10341037
int ret = nob__proc_wait_async(opt.async->items[i], 1);
1035-
if (ret < 0) return false;
1038+
if (ret < 0) nob_return_defer(false);
10361039
if (ret) {
10371040
nob_da_remove_unordered(opt.async, i);
10381041
break;
@@ -1041,32 +1044,36 @@ NOBDEF bool nob_cmd_run_opt(Nob_Cmd *cmd, Nob_Cmd_Opt opt)
10411044
}
10421045
}
10431046

1044-
Nob_Proc proc = nob_cmd_start_process(*cmd, opt.fdin, opt.fdout, opt.fderr);
1045-
1046-
if (!opt.no_reset) {
1047-
cmd->count = 0;
1048-
if (opt.fdin) {
1049-
nob_fd_close(*opt.fdin);
1050-
*opt.fdin = NOB_INVALID_FD;
1051-
}
1052-
if (opt.fdout) {
1053-
nob_fd_close(*opt.fdout);
1054-
*opt.fdout = NOB_INVALID_FD;
1055-
}
1056-
if (opt.fderr) {
1057-
nob_fd_close(*opt.fderr);
1058-
*opt.fderr = NOB_INVALID_FD;
1059-
}
1047+
if (opt.stdin_path) {
1048+
fdin = nob_fd_open_for_read(opt.stdin_path);
1049+
if (fdin == NOB_INVALID_FD) nob_return_defer(false);
1050+
opt_fdin = &fdin;
1051+
}
1052+
if (opt.stdout_path) {
1053+
fdout = nob_fd_open_for_write(opt.stdout_path);
1054+
if (fdout == NOB_INVALID_FD) nob_return_defer(false);
1055+
opt_fdout = &fdout;
10601056
}
1057+
if (opt.stderr_path) {
1058+
fderr = nob_fd_open_for_write(opt.stderr_path);
1059+
if (fderr == NOB_INVALID_FD) nob_return_defer(false);
1060+
opt_fderr = &fderr;
1061+
}
1062+
Nob_Proc proc = nob_cmd_start_process(*cmd, opt_fdin, opt_fdout, opt_fderr);
10611063

10621064
if (opt.async) {
1063-
if (proc == NOB_INVALID_PROC) return false;
1065+
if (proc == NOB_INVALID_PROC) nob_return_defer(false);
10641066
nob_da_append(opt.async, proc);
10651067
} else {
1066-
if (!nob_proc_wait(proc)) return false;
1068+
if (!nob_proc_wait(proc)) nob_return_defer(false);
10671069
}
10681070

1069-
return true;
1071+
defer:
1072+
if (opt_fdin) nob_fd_close(*opt_fdin);
1073+
if (opt_fdout) nob_fd_close(*opt_fdout);
1074+
if (opt_fderr) nob_fd_close(*opt_fderr);
1075+
cmd->count = 0;
1076+
return result;
10701077
}
10711078

10721079
NOBDEF Nob_Proc nob_cmd_run_async_redirect(Nob_Cmd cmd, Nob_Cmd_Redirect redirect)

tests/cmd_redirect.c

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -39,11 +39,8 @@ int main(void)
3939
message = "Hello, World";
4040
message_file_path = "./echo_message.txt";
4141

42-
fdout = fd_open_for_write(message_file_path);
43-
if (fdout == INVALID_FD) return_defer(1);
44-
4542
cmd_append(&cmd, "./echo", message);
46-
if (!cmd_run(&cmd, .fdout = &fdout)) return_defer(1);
43+
if (!cmd_run(&cmd, .stdout_path = message_file_path)) return_defer(1);
4744

4845
if (!read_entire_file(message_file_path, &sb)) return_defer(1);
4946
actual_message = sb_to_sv(sb);

0 commit comments

Comments
 (0)