Skip to content

Commit 160caed

Browse files
authored
Merge pull request #173 from tsoding/v1.26.0
Release v1.26.0 - Logging Handlers
2 parents 7deb15d + a05191f commit 160caed

3 files changed

Lines changed: 111 additions & 12 deletions

File tree

nob.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ const char *test_names[] = {
2626
"temp_aligned_alloc",
2727
"temp_path_comps",
2828
"temp_running_executable_path",
29+
"no_echo",
2930
};
3031
#define test_names_count ARRAY_LEN(test_names)
3132

@@ -56,6 +57,8 @@ bool build_and_run_test(Cmd *cmd, const char *test_name)
5657

5758
int main(int argc, char **argv)
5859
{
60+
set_log_handler(cancer_log_handler);
61+
5962
NOB_GO_REBUILD_URSELF_PLUS(argc, argv, "nob.h", "shared.h");
6063

6164
Cmd cmd = {0};

nob.h

Lines changed: 85 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/* nob - v1.25.1 - Public Domain - https://github.com/tsoding/nob.h
1+
/* nob - v1.26.0 - Public Domain - https://github.com/tsoding/nob.h
22
33
This library is the next generation of the [NoBuild](https://github.com/tsoding/nobuild) idea.
44
@@ -100,8 +100,10 @@
100100
#ifndef NOB_H_
101101
#define NOB_H_
102102
#ifdef _WIN32
103-
#define _CRT_SECURE_NO_WARNINGS (1)
104-
#endif
103+
# ifndef _CRT_SECURE_NO_WARNINGS
104+
# define _CRT_SECURE_NO_WARNINGS (1)
105+
# endif // _CRT_SECURE_NO_WARNINGS
106+
#endif // _WIN32
105107

106108
#ifndef NOBDEF
107109
/*
@@ -207,6 +209,14 @@ typedef enum {
207209
// Any messages with the level below nob_minimal_log_level are going to be suppressed.
208210
extern Nob_Log_Level nob_minimal_log_level;
209211

212+
typedef void (nob_log_handler)(Nob_Log_Level level, const char *fmt, va_list args);
213+
214+
NOBDEF void nob_set_log_handler(nob_log_handler *handler);
215+
NOBDEF nob_log_handler *nob_get_log_handler(void);
216+
217+
NOBDEF nob_log_handler nob_default_log_handler;
218+
NOBDEF nob_log_handler nob_cancer_log_handler;
219+
210220
NOBDEF void nob_log(Nob_Log_Level level, const char *fmt, ...) NOB_PRINTF_FORMAT(2, 3);
211221

212222
// It is an equivalent of shift command from bash (do `help shift` in bash). It basically
@@ -541,6 +551,7 @@ NOBDEF char *nob_temp_strdup(const char *cstr);
541551
NOBDEF char *nob_temp_strndup(const char *cstr, size_t size);
542552
NOBDEF void *nob_temp_alloc(size_t size);
543553
NOBDEF char *nob_temp_sprintf(const char *format, ...) NOB_PRINTF_FORMAT(1, 2);
554+
NOBDEF char *nob_temp_vsprintf(const char *format, va_list ap);
544555
// nob_temp_reset() - Resets the entire temporary storage to 0.
545556
//
546557
// It is generally not recommended to call this function ever. What you usually want to do is let's say you have a loop,
@@ -1143,8 +1154,8 @@ static Nob_Proc nob__cmd_start_process(Nob_Cmd cmd, Nob_Fd *fdin, Nob_Fd *fdout,
11431154
return NOB_INVALID_PROC;
11441155
}
11451156

1146-
#ifndef NOB_NO_ECHO
11471157
Nob_String_Builder sb = {0};
1158+
#ifndef NOB_NO_ECHO
11481159
nob_cmd_render(cmd, &sb);
11491160
nob_sb_append_null(&sb);
11501161
nob_log(NOB_INFO, "CMD: %s", sb.items);
@@ -1535,7 +1546,19 @@ NOBDEF bool nob_cmd_run_sync_redirect_and_reset(Nob_Cmd *cmd, Nob_Cmd_Redirect r
15351546
return nob_proc_wait(p);
15361547
}
15371548

1538-
NOBDEF void nob_log(Nob_Log_Level level, const char *fmt, ...)
1549+
static nob_log_handler *nob__log_handler = &nob_default_log_handler;
1550+
1551+
NOBDEF void nob_set_log_handler(nob_log_handler *handler)
1552+
{
1553+
nob__log_handler = handler;
1554+
}
1555+
1556+
NOBDEF nob_log_handler *nob_get_log_handler(void)
1557+
{
1558+
return nob__log_handler;
1559+
}
1560+
1561+
NOBDEF void nob_default_log_handler(Nob_Log_Level level, const char *fmt, va_list args)
15391562
{
15401563
if (level < nob_minimal_log_level) return;
15411564

@@ -1551,14 +1574,40 @@ NOBDEF void nob_log(Nob_Log_Level level, const char *fmt, ...)
15511574
break;
15521575
case NOB_NO_LOGS: return;
15531576
default:
1554-
NOB_UNREACHABLE("nob_log");
1577+
NOB_UNREACHABLE("Nob_Log_Level");
15551578
}
15561579

1580+
vfprintf(stderr, fmt, args);
1581+
fprintf(stderr, "\n");
1582+
}
1583+
1584+
NOBDEF void nob_cancer_log_handler(Nob_Log_Level level, const char *fmt, va_list args)
1585+
{
1586+
switch (level) {
1587+
case NOB_INFO:
1588+
fprintf(stderr, "ℹ️ \x1b[36m[INFO]\x1b[0m ");
1589+
break;
1590+
case NOB_WARNING:
1591+
fprintf(stderr, "⚠️ \x1b[33m[WARNING]\x1b[0m ");
1592+
break;
1593+
case NOB_ERROR:
1594+
fprintf(stderr, "🚨 \x1b[31m[ERROR]\x1b[0m ");
1595+
break;
1596+
case NOB_NO_LOGS: return;
1597+
default:
1598+
NOB_UNREACHABLE("Nob_Log_Level");
1599+
}
1600+
1601+
vfprintf(stderr, fmt, args);
1602+
fprintf(stderr, "\n");
1603+
}
1604+
1605+
NOBDEF void nob_log(Nob_Log_Level level, const char *fmt, ...)
1606+
{
15571607
va_list args;
15581608
va_start(args, fmt);
1559-
vfprintf(stderr, fmt, args);
1609+
nob__log_handler(level, fmt, args);
15601610
va_end(args);
1561-
fprintf(stderr, "\n");
15621611
}
15631612

15641613
NOBDEF bool nob_read_entire_dir(const char *parent, Nob_File_Paths *children)
@@ -1770,24 +1819,33 @@ NOBDEF void *nob_temp_alloc(size_t requested_size)
17701819
return result;
17711820
}
17721821

1773-
NOBDEF char *nob_temp_sprintf(const char *format, ...)
1822+
NOBDEF char *nob_temp_vsprintf(const char *format, va_list ap)
17741823
{
17751824
va_list args;
1776-
va_start(args, format);
1825+
va_copy(args, ap);
17771826
int n = vsnprintf(NULL, 0, format, args);
17781827
va_end(args);
17791828

17801829
NOB_ASSERT(n >= 0);
17811830
char *result = (char*)nob_temp_alloc(n + 1);
17821831
NOB_ASSERT(result != NULL && "Extend the size of the temporary allocator");
17831832
// TODO: use proper arenas for the temporary allocator;
1784-
va_start(args, format);
1833+
va_copy(args, ap);
17851834
vsnprintf(result, n + 1, format, args);
17861835
va_end(args);
17871836

17881837
return result;
17891838
}
17901839

1840+
NOBDEF char *nob_temp_sprintf(const char *format, ...)
1841+
{
1842+
va_list args;
1843+
va_start(args, format);
1844+
char *result = nob_temp_vsprintf(format, args);
1845+
va_end(args);
1846+
return result;
1847+
}
1848+
17911849
NOBDEF void nob_temp_reset(void)
17921850
{
17931851
nob_temp_size = 0;
@@ -2341,6 +2399,11 @@ NOBDEF int closedir(DIR *dirp)
23412399
#define NO_LOGS NOB_NO_LOGS
23422400
#define Log_Level Nob_Log_Level
23432401
#define minimal_log_level nob_minimal_log_level
2402+
#define log_handler nob_log_handler
2403+
#define set_log_handler nob_set_log_handler
2404+
#define get_log_handler nob_get_log_handler
2405+
#define default_log_handler nob_default_log_handler
2406+
#define cancer_log_handler nob_cancer_log_handler
23442407
// NOTE: Name log is already defined in math.h and historically always was the natural logarithmic function.
23452408
// So there should be no reason to strip the `nob_` prefix in this specific case.
23462409
// #define log nob_log
@@ -2411,6 +2474,7 @@ NOBDEF int closedir(DIR *dirp)
24112474
#define temp_strndup nob_temp_strndup
24122475
#define temp_alloc nob_temp_alloc
24132476
#define temp_sprintf nob_temp_sprintf
2477+
#define temp_vsprintf nob_temp_vsprintf
24142478
#define temp_reset nob_temp_reset
24152479
#define temp_save nob_temp_save
24162480
#define temp_rewind nob_temp_rewind
@@ -2449,7 +2513,16 @@ NOBDEF int closedir(DIR *dirp)
24492513
/*
24502514
Revision history:
24512515
2452-
1.25.1 (2025-11-06) Fix forward declaration of _NSGetExecutablePath on MacOS (by agss0)
2516+
1.26.0 (2025-12-28) Introduce customizable log handlers (by @rexim)
2517+
- Add nob_log_handler
2518+
- Add nob_set_log_handler
2519+
- Add nob_get_log_handler
2520+
- Add nob_default_log_handler
2521+
- Add nob_cancer_log_handler
2522+
Introduce nob_temp_vsprintf (by @rexim)
2523+
Fix compilation error on Windows when NOB_NO_ECHO is enabled (by @mlorenc227)
2524+
Do not redefine _CRT_SECURE_NO_WARNINGS if it's already defined (by @vylsaz)
2525+
1.25.1 (2025-11-06) Fix forward declaration of _NSGetExecutablePath on MacOS (by @agss0)
24532526
1.25.0 (2025-10-25) - Add nob_sb_pad_align()
24542527
- Add nob_swap()
24552528
- Add nob_temp_strndup()

tests/no_echo.c

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
#define NOB_IMPLEMENTATION
2+
#define NOB_STRIP_PREFIX
3+
#define NOB_NO_ECHO
4+
#include "nob.h"
5+
6+
int main(void)
7+
{
8+
Cmd cmd = {0};
9+
10+
const char *empty_src = "int main() { return 0; }";
11+
if (!write_entire_file("empty.c", empty_src, strlen(empty_src))) return 1;
12+
13+
nob_cc(&cmd);
14+
nob_cc_flags(&cmd);
15+
nob_cc_output(&cmd, "empty");
16+
nob_cc_inputs(&cmd, "empty.c");
17+
if (!cmd_run(&cmd)) return 1;
18+
19+
cmd_append(&cmd, "./empty");
20+
if (!cmd_run(&cmd)) return 1;
21+
22+
return 0;
23+
}

0 commit comments

Comments
 (0)