1- /* nob - v3.6 .0 - Public Domain - https://github.com/tsoding/nob.h
1+ /* nob - v3.7 .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
@@ -303,7 +303,7 @@ typedef struct {
303303
304304NOBDEF bool nob_walk_dir_opt (const char * root , Nob_Walk_Func func , Nob_Walk_Dir_Opt );
305305
306- #define nob_walk_dir (root , func , ...) nob_walk_dir_opt((root), (func), (Nob_Walk_Dir_Opt){__VA_ARGS__})
306+ #define nob_walk_dir (root , func , ...) nob_walk_dir_opt((root), (func), NOB_CLIT (Nob_Walk_Dir_Opt){__VA_ARGS__})
307307
308308typedef struct {
309309 char * name ;
@@ -582,14 +582,14 @@ typedef struct {
582582typedef struct {
583583 const char * stdin_path ;
584584} Nob_Chain_Begin_Opt ;
585- #define nob_chain_begin (chain , ...) nob_chain_begin_opt((chain), (Nob_Chain_Begin_Opt) { __VA_ARGS__ })
585+ #define nob_chain_begin (chain , ...) nob_chain_begin_opt((chain), NOB_CLIT (Nob_Chain_Begin_Opt) { __VA_ARGS__ })
586586NOBDEF bool nob_chain_begin_opt (Nob_Chain * chain , Nob_Chain_Begin_Opt opt );
587587
588588typedef struct {
589589 bool err2out ;
590590 bool dont_reset ;
591591} Nob_Chain_Cmd_Opt ;
592- #define nob_chain_cmd (chain , cmd , ...) nob_chain_cmd_opt((chain), (cmd), (Nob_Chain_Cmd_Opt) { __VA_ARGS__ })
592+ #define nob_chain_cmd (chain , cmd , ...) nob_chain_cmd_opt((chain), (cmd), NOB_CLIT (Nob_Chain_Cmd_Opt) { __VA_ARGS__ })
593593NOBDEF bool nob_chain_cmd_opt (Nob_Chain * chain , Nob_Cmd * cmd , Nob_Chain_Cmd_Opt opt );
594594
595595typedef struct {
@@ -598,7 +598,7 @@ typedef struct {
598598 const char * stdout_path ;
599599 const char * stderr_path ;
600600} Nob_Chain_End_Opt ;
601- #define nob_chain_end (chain , ...) nob_chain_end_opt((chain), (Nob_Chain_End_Opt) { __VA_ARGS__ })
601+ #define nob_chain_end (chain , ...) nob_chain_end_opt((chain), NOB_CLIT (Nob_Chain_End_Opt) { __VA_ARGS__ })
602602NOBDEF bool nob_chain_end_opt (Nob_Chain * chain , Nob_Chain_End_Opt opt );
603603
604604// Get amount of processors on the machine.
@@ -611,7 +611,7 @@ NOBDEF uint64_t nob_nanos_since_unspecified_epoch(void);
611611
612612// Same as nob_cmd_run_opt but using cool variadic macro to set the default options.
613613// See https://x.com/vkrajacic/status/1749816169736073295 for more info on how to use such macros.
614- #define nob_cmd_run (cmd , ...) nob_cmd_run_opt((cmd), (Nob_Cmd_Opt){__VA_ARGS__})
614+ #define nob_cmd_run (cmd , ...) nob_cmd_run_opt((cmd), NOB_CLIT (Nob_Cmd_Opt){__VA_ARGS__})
615615
616616// DEPRECATED:
617617//
@@ -648,9 +648,16 @@ typedef struct {
648648// use it as a C string.
649649NOBDEF void nob_cmd_render (Nob_Cmd cmd , Nob_String_Builder * render );
650650
651- NOBDEF void nob__cmd_append (Nob_Cmd * cmd , size_t n , ...);
651+ // Compound Literal
652+ #if defined(__cplusplus )
653+ #define NOB_CLIT (type ) type
654+ #else
655+ #define NOB_CLIT (type ) (type)
656+ #endif
657+
658+ NOBDEF void nob__cmd_append (Nob_Cmd * cmd , ...);
652659#define nob_cmd_append (cmd , ...) \
653- nob__cmd_append(cmd, (sizeof((const char*[]){ __VA_ARGS__})/sizeof (const char*)), __VA_ARGS__ )
660+ nob__cmd_append(cmd, __VA_ARGS__, (const char*)-1 )
654661
655662// TODO: nob_cmd_extend() evaluates other_cmd twice
656663// It can be fixed by turning nob_cmd_extend() call into a statement.
@@ -947,12 +954,13 @@ static Nob_Proc nob__cmd_start_process(Nob_Cmd cmd, Nob_Fd *fdin, Nob_Fd *fdout,
947954// Any messages with the level below nob_minimal_log_level are going to be suppressed.
948955Nob_Log_Level nob_minimal_log_level = NOB_INFO ;
949956
950- NOBDEF void nob__cmd_append (Nob_Cmd * cmd , size_t n , ...)
957+ NOBDEF void nob__cmd_append (Nob_Cmd * cmd , ...)
951958{
952959 va_list args ;
953- va_start (args , n );
954- for (size_t i = 0 ; i < n ; ++ i ) {
960+ va_start (args , cmd );
961+ for (;; ) {
955962 const char * arg = va_arg (args , const char * );
963+ if (arg == (const char * )-1 ) break ;
956964 nob_da_append (cmd , arg );
957965 }
958966 va_end (args );
@@ -2017,7 +2025,7 @@ bool nob__walk_dir_opt_impl(Nob_String_Builder *file_path, Nob_Walk_Func func, s
20172025
20182026 // Pre-order walking
20192027 if (!opt .post_order ) {
2020- if (!func ((Nob_Walk_Entry ) {
2028+ if (!func (NOB_CLIT (Nob_Walk_Entry ) {
20212029 .path = file_path -> items ,
20222030 .type = file_type ,
20232031 .level = level ,
@@ -2064,7 +2072,7 @@ bool nob__walk_dir_opt_impl(Nob_String_Builder *file_path, Nob_Walk_Func func, s
20642072
20652073 // Post-order walking
20662074 if (opt .post_order ) {
2067- if (!func ((Nob_Walk_Entry ) {
2075+ if (!func (NOB_CLIT (Nob_Walk_Entry ) {
20682076 .path = file_path -> items ,
20692077 .type = file_type ,
20702078 .level = level ,
@@ -2156,7 +2164,7 @@ NOBDEF Nob_File_Type nob_get_file_type(const char *path)
21562164 DWORD attr = GetFileAttributesA (path );
21572165 if (attr == INVALID_FILE_ATTRIBUTES ) {
21582166 nob_log (NOB_ERROR , "Could not get file attributes of %s: %s" , path , nob_win32_error_message (GetLastError ()));
2159- return -1 ;
2167+ return ( Nob_File_Type ) - 1 ;
21602168 }
21612169
21622170 if (attr & FILE_ATTRIBUTE_DIRECTORY ) return NOB_FILE_DIRECTORY ;
@@ -2751,8 +2759,8 @@ NOBDEF char *nob_temp_dir_name(const char *path)
27512759 return nob_temp_strndup (path , i + 1 );
27522760#else
27532761 if (!path ) path = "" ; // Treating NULL as empty.
2754- char * drive = nob_temp_alloc (_MAX_DRIVE );
2755- char * dir = nob_temp_alloc (_MAX_DIR );
2762+ char * drive = ( char * ) nob_temp_alloc (_MAX_DRIVE );
2763+ char * dir = ( char * ) nob_temp_alloc (_MAX_DIR );
27562764 // https://learn.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2010/8e46eyt7(v=vs.100)
27572765 errno_t ret = _splitpath_s (path , drive , _MAX_DRIVE , dir , _MAX_DIR , NULL , 0 , NULL , 0 );
27582766 NOB_ASSERT (ret == 0 );
@@ -2774,8 +2782,8 @@ NOBDEF char *nob_temp_file_name(const char *path)
27742782 return s + i ;
27752783#else
27762784 if (!path ) path = "" ; // Treating NULL as empty.
2777- char * fname = nob_temp_alloc (_MAX_FNAME );
2778- char * ext = nob_temp_alloc (_MAX_EXT );
2785+ char * fname = ( char * ) nob_temp_alloc (_MAX_FNAME );
2786+ char * ext = ( char * ) nob_temp_alloc (_MAX_EXT );
27792787 // https://learn.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2010/8e46eyt7(v=vs.100)
27802788 errno_t ret = _splitpath_s (path , NULL , 0 , NULL , 0 , fname , _MAX_FNAME , ext , _MAX_EXT );
27812789 NOB_ASSERT (ret == 0 );
@@ -2789,7 +2797,7 @@ NOBDEF char *nob_temp_file_ext(const char *path)
27892797 return strrchr (nob_temp_file_name (path ), '.' );
27902798#else
27912799 if (!path ) path = "" ; // Treating NULL as empty.
2792- char * ext = nob_temp_alloc (_MAX_EXT );
2800+ char * ext = ( char * ) nob_temp_alloc (_MAX_EXT );
27932801 // https://learn.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2010/8e46eyt7(v=vs.100)
27942802 errno_t ret = _splitpath_s (path , NULL , 0 , NULL , 0 , NULL , 0 , ext , _MAX_EXT );
27952803 NOB_ASSERT (ret == 0 );
@@ -2942,6 +2950,7 @@ NOBDEF char *nob_temp_running_executable_path(void)
29422950 #define procs_wait_and_reset nob_procs_wait_and_reset
29432951 #define procs_append_with_flush nob_procs_append_with_flush
29442952 #define procs_flush nob_procs_flush
2953+ #define CLIT NOB_CLIT
29452954 #define Cmd Nob_Cmd
29462955 #define Cmd_Redirect Nob_Cmd_Redirect
29472956 #define Cmd_Opt Nob_Cmd_Opt
@@ -3008,6 +3017,8 @@ NOBDEF char *nob_temp_running_executable_path(void)
30083017/*
30093018 Revision history:
30103019
3020+ 3.7.0 (2026-03-24) Add NOB_CLIT()
3021+ Fix compliation on MSVC with /TP
30113022 3.6.0 (2026-03-16) Add nob_sv_chop_suffix()
30123023 Deprecate nob_sv_end_with()
30133024 Add nob_sv_ends_with_cstr() instead of nob_sv_end_with()
0 commit comments