Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 29 additions & 13 deletions nob.h
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,12 @@
# include <fcntl.h>
#endif

#ifdef __cplusplus
# define CPP_CAST(type) (decltype(type))
#else
# define CPP_CAST(type)
#endif

#ifdef _WIN32
# define NOB_LINE_END "\r\n"
#else
Expand Down Expand Up @@ -290,7 +296,7 @@ bool nob_delete_file(const char *path);
while ((expected_capacity) > (da)->capacity) { \
(da)->capacity *= 2; \
} \
(da)->items = NOB_REALLOC((da)->items, (da)->capacity * sizeof(*(da)->items)); \
(da)->items = CPP_CAST((da)->items) NOB_REALLOC((da)->items, (da)->capacity * sizeof(*(da)->items)); \
NOB_ASSERT((da)->items != NULL && "Buy more RAM lol"); \
} \
} while (0)
Expand Down Expand Up @@ -507,7 +513,11 @@ bool nob_set_current_dir(const char *path);
# define nob_cc(cmd) nob_cmd_append(cmd, "cl.exe")
# endif
# else
# define nob_cc(cmd) nob_cmd_append(cmd, "cc")
# if defined(__cplusplus)
# define nob_cc(cmd) nob_cmd_append(cmd, "c++")
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cc stands for C Compiler. I don't think anybody using this would expect CC to be a c++ compiler (the two are not easily interchangeable specifically planed for)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cc stands for C Compiler. I don't think anybody using this would expect CC to be a c++ compiler (the two are not easily interchangeable specifically planed for)

tho you can name main.cc and it stands for C++ (C with Classes, is a old way to do it but..)

# else
# define nob_cc(cmd) nob_cmd_append(cmd, "cc")
# endif
# endif
#endif // nob_cc

Expand Down Expand Up @@ -823,7 +833,7 @@ bool nob_copy_file(const char *src_path, const char *dst_path)
int src_fd = -1;
int dst_fd = -1;
size_t buf_size = 32*1024;
char *buf = NOB_REALLOC(NULL, buf_size);
char *buf = (char *) NOB_REALLOC(NULL, buf_size);
NOB_ASSERT(buf != NULL && "Buy more RAM lol!!");
bool result = true;

Expand Down Expand Up @@ -1280,6 +1290,7 @@ bool nob_read_entire_dir(const char *parent, Nob_File_Paths *children)
DIR *dir = NULL;

dir = opendir(parent);
struct dirent *ent = readdir(dir);
if (dir == NULL) {
#ifdef _WIN32
nob_log(NOB_ERROR, "Could not open directory %s: %s", parent, nob_win32_error_message(GetLastError()));
Expand All @@ -1290,7 +1301,6 @@ bool nob_read_entire_dir(const char *parent, Nob_File_Paths *children)
}

errno = 0;
struct dirent *ent = readdir(dir);
while (ent != NULL) {
nob_da_append(children, nob_temp_strdup(ent->d_name));
ent = readdir(dir);
Expand All @@ -1313,6 +1323,7 @@ bool nob_read_entire_dir(const char *parent, Nob_File_Paths *children)
bool nob_write_entire_file(const char *path, const void *data, size_t size)
{
bool result = true;
const char *buf = (const char *) data;

FILE *f = fopen(path, "wb");
if (f == NULL) {
Expand All @@ -1326,7 +1337,6 @@ bool nob_write_entire_file(const char *path, const void *data, size_t size)
// ^
// data

const char *buf = data;
while (size > 0) {
size_t n = fwrite(buf, 1, size, f);
if (ferror(f)) {
Expand Down Expand Up @@ -1358,7 +1368,7 @@ Nob_File_Type nob_get_file_type(const char *path)
struct stat statbuf;
if (stat(path, &statbuf) < 0) {
nob_log(NOB_ERROR, "Could not get stat of %s: %s", path, strerror(errno));
return -1;
return (Nob_File_Type) -1;
}

if (S_ISREG(statbuf.st_mode)) return NOB_FILE_REGULAR;
Expand Down Expand Up @@ -1453,7 +1463,7 @@ bool nob_copy_directory_recursively(const char *src_path, const char *dst_path)
char *nob_temp_strdup(const char *cstr)
{
size_t n = strlen(cstr);
char *result = nob_temp_alloc(n + 1);
char *result = (char *) nob_temp_alloc(n + 1);
NOB_ASSERT(result != NULL && "Increase NOB_TEMP_CAPACITY");
memcpy(result, cstr, n);
result[n] = '\0';
Expand All @@ -1476,7 +1486,7 @@ char *nob_temp_sprintf(const char *format, ...)
va_end(args);

NOB_ASSERT(n >= 0);
char *result = nob_temp_alloc(n + 1);
char *result = (char *) nob_temp_alloc(n + 1);
NOB_ASSERT(result != NULL && "Extend the size of the temporary allocator");
// TODO: use proper arenas for the temporary allocator;
va_start(args, format);
Expand All @@ -1503,7 +1513,7 @@ void nob_temp_rewind(size_t checkpoint)

const char *nob_temp_sv_to_cstr(Nob_String_View sv)
{
char *result = nob_temp_alloc(sv.count + 1);
char *result = (char *) nob_temp_alloc(sv.count + 1);
NOB_ASSERT(result != NULL && "Extend the size of the temporary allocator");
memcpy(result, sv.data, sv.count);
result[sv.count] = '\0';
Expand Down Expand Up @@ -1616,21 +1626,27 @@ bool nob_rename(const char *old_path, const char *new_path)
bool nob_read_entire_file(const char *path, Nob_String_Builder *sb)
{
bool result = true;
size_t new_count;
#ifndef _WIN32
long m;
#else
long long m;
#endif
Comment on lines +1629 to +1634
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why did you separate declaration and initialization? does c++ not work without it?


FILE *f = fopen(path, "rb");
if (f == NULL) nob_return_defer(false);
if (fseek(f, 0, SEEK_END) < 0) nob_return_defer(false);
#ifndef _WIN32
long m = ftell(f);
m = ftell(f);
#else
long long m = _ftelli64(f);
m = _ftelli64(f);
#endif
if (m < 0) nob_return_defer(false);
if (fseek(f, 0, SEEK_SET) < 0) nob_return_defer(false);

size_t new_count = sb->count + m;
new_count = sb->count + m;
if (new_count > sb->capacity) {
sb->items = NOB_REALLOC(sb->items, new_count);
sb->items = CPP_CAST(sb->items) NOB_REALLOC(sb->items, new_count);
NOB_ASSERT(sb->items != NULL && "Buy more RAM lool!!");
sb->capacity = new_count;
}
Expand Down
18 changes: 13 additions & 5 deletions tests/cmd_redirect.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@ int main(void)
Cmd cmd = {0};
Fd fdout = INVALID_FD;
String_Builder sb = {0};
const char *message;
const char *message_file_path;
Proc p;
String_View actual_message;
Comment on lines +12 to +15
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same question here

Copy link
Author

@lmarzocchetti lmarzocchetti Apr 28, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because the preprocessor (and goto) rules in C++ are strictier than the C. The usage of "return_defer" macro must be after all declaration. So you cannot jump with goto after a declaration+initialization of a variable. So i simply separated them and all works as expected


const char *echo_src =
"#include <assert.h>\n"
Expand All @@ -33,23 +37,27 @@ int main(void)
nob_cc_inputs(&cmd, "./echo.c");
if (!cmd_run_sync_and_reset(&cmd)) return_defer(1);

const char *message = "Hello, World";
const char *message_file_path = "./echo_message.txt";
// TODO: fix the rendering of the shell command on Windows.
// It prevents use from using the message with spaces here.
// Steal some code from C3 compiler, I already implemented it there.
// const char *message = "Hello, World";
message = "Hello";
message_file_path = "./echo_message.txt";

fdout = fd_open_for_write(message_file_path);
if (fdout == INVALID_FD) return_defer(1);

cmd_append(&cmd, "./echo", message);
Proc p = cmd_run_async_redirect_and_reset(&cmd, (Cmd_Redirect) {.fdout = &fdout});
p = cmd_run_async_redirect_and_reset(&cmd, (Cmd_Redirect) {.fdout = &fdout});
if (p == INVALID_PROC) return_defer(1);
if (!proc_wait(p)) return_defer(1);

if (!read_entire_file(message_file_path, &sb)) return_defer(1);
String_View actual_message = sb_to_sv(sb);
actual_message = sb_to_sv(sb);
if (!sv_eq(sv_trim(actual_message), sv_from_cstr(message))) {
nob_log(ERROR, "Unexpected message");
nob_log(ERROR, "Expected: %s", message);
nob_log(ERROR, "Actual: "SV_Fmt, SV_Arg(actual_message));
nob_log(ERROR, "Actual: " SV_Fmt, SV_Arg(actual_message));
return_defer(1);
}

Expand Down