Add warnings

This commit is contained in:
David Gonzalez Martin 2025-01-06 11:21:35 -06:00 committed by David
parent 9c7f3d99a7
commit 5df281f4b6
13 changed files with 298 additions and 305 deletions

View File

@ -1,14 +1,17 @@
#if 0
#include <std/base.h>
#include <std/project.h>
#include <std/os.h>
#include <std/base.c>
#include <std/os.c>
#if 0
#include <std/project.h>
#include <std/virtual_buffer.h>
#include <std/windowing.h>
#include <std/rendering.h>
#include <std/ui_core.h>
#include <std/ui_builder.h>
#include <std/base.c>
#include <std/os.c>
#include <std/virtual_buffer.c>
#include <std/windowing.c>
@ -274,8 +277,11 @@ int main()
return 0;
}
#else
int main()
int main(int argc, char** argv, char** envp)
{
unused(argc);
unused(argv);
unused(envp);
return 0;
}
#endif

View File

@ -2361,7 +2361,7 @@ fn Node* thread_node_get(Thread* thread, NodeIndex node_index)
return node;
}
may_be_unused fn String node_id_to_string(NodeId node_id)
fn String node_id_to_string(NodeId node_id)
{
switch (node_id)
{
@ -3568,7 +3568,7 @@ global_variable const auto ip_interface_register_mask = (InternPoolInterface) {
fn Hash32 lower ## _hash_index(Thread* thread, T ## Index item_index); \
fn Hash32 lower ## _hash(Thread* thread, const T * const restrict item); \
\
may_be_unused fn T ## GetOrPut ip_ ## T ## _get_or_put(InternPool(T)* pool, Thread* thread, T ## Index item_index) \
fn T ## GetOrPut ip_ ## T ## _get_or_put(InternPool(T)* pool, Thread* thread, T ## Index item_index) \
{ \
auto hash = lower ## _hash_index(thread, item_index); \
auto* item = thread_ ## lower ## _get(thread, item_index); \
@ -3581,7 +3581,7 @@ may_be_unused fn T ## GetOrPut ip_ ## T ## _get_or_put(InternPool(T)* pool, Thre
.existing = result.existing,\
};\
}\
may_be_unused fn T ## GetOrPut ip_ ## T ## _get_or_put_new(InternPool(T)* pool, Thread* thread, const T* item) \
fn T ## GetOrPut ip_ ## T ## _get_or_put_new(InternPool(T)* pool, Thread* thread, const T* item) \
{ \
auto hash = lower ## _hash(thread, item); \
auto result = ip_generic_get_or_put((GenericInternPool*)pool, thread, 0, (void*)item, sizeof(T), hash, &ip_interface_ ## lower); \
@ -3591,7 +3591,7 @@ may_be_unused fn T ## GetOrPut ip_ ## T ## _get_or_put_new(InternPool(T)* pool,
.existing = result.existing,\
};\
}\
may_be_unused fn T ## Index ip_ ## T ## _remove(InternPool(T)* pool, Thread* thread, T ## Index item_index)\
fn T ## Index ip_ ## T ## _remove(InternPool(T)* pool, Thread* thread, T ## Index item_index)\
{\
auto existing_capacity = pool->capacity;\
auto* item = thread_ ## lower ## _get(thread, item_index);\
@ -4778,7 +4778,7 @@ global_variable const NodeVirtualTable node_functions[NODE_COUNT] = {
// },
};
may_be_unused fn String type_id_to_string(Type* type)
fn String type_id_to_string(Type* type)
{
switch (type->id)
{
@ -6791,7 +6791,7 @@ fn void analyze_file(Thread* thread, File* file)
// }
// }
// may_be_unused fn void print_function(Thread* thread, Function* function)
// fn void print_function(Thread* thread, Function* function)
// {
// print("fn {s}\n====\n", function->name);
// VirtualBuffer(NodeIndex) nodes = {};
@ -7534,7 +7534,7 @@ fn void uleb128_encode(VirtualBuffer(u8)* buffer, u32 value)
*vb_add(buffer, 1) = out;
}
may_be_unused fn void dwarf_playground(Thread* thread)
fn void dwarf_playground(Thread* thread)
{
auto file = file_read(thread->arena,
#ifdef __APPLE__
@ -7838,7 +7838,7 @@ STRUCT(FileBuffer)
VirtualBuffer(u8) buffer;
};
may_be_unused fn String write_elf(Thread* thread, ObjectOptions options)
fn String write_elf(Thread* thread, ObjectOptions options)
{
ELFBuilder builder_stack = {};
ELFBuilder* restrict builder = &builder_stack;
@ -20654,7 +20654,7 @@ fn String pdb_build(Thread* thread)
return (String) { pdb_file.pointer, pdb_file.length };
}
may_be_unused fn String write_pe(Thread* thread, ObjectOptions options)
fn String write_pe(Thread* thread, ObjectOptions options)
{
VirtualBuffer(u8) file = {};
@ -22056,7 +22056,7 @@ fn u8 can_remat(Thread* thread, NodeIndex node_index)
}
}
may_be_unused fn f32 get_spill_cost(Thread* thread, VirtualRegister* virtual_register)
fn f32 get_spill_cost(Thread* thread, VirtualRegister* virtual_register)
{
auto spill_cost = virtual_register->spill_cost;
if (__builtin_isnan(spill_cost))
@ -23431,7 +23431,7 @@ STRUCT(MachOSection)
};
static_assert(sizeof(MachOSection) == 0x50);
may_be_unused fn String write_macho(Thread* restrict thread, ObjectOptions options)
fn String write_macho(Thread* restrict thread, ObjectOptions options)
{
unused(thread);
unused(options);

View File

@ -1,11 +1,20 @@
#pragma once
#if _MSC_VER
extern u64 _lzcnt_u64(u64);
extern u64 _tzcnt_u64(u64);
#endif
fn u8 log2_alignment(u64 alignment)
{
assert(alignment != 0);
assert((alignment & (alignment - 1)) == 0);
u64 left = (sizeof(alignment) * 8) - 1;
#if _MSC_VER
let_cast(u64, right, _lzcnt_u64(alignment));
#else
let_cast(u64, right, __builtin_clzll(alignment));
#endif
let_cast(u8, result, left - right);
return result;
}
@ -32,7 +41,7 @@ fn u64 u64_from_u128(u128 n)
fn u128 u128_shift_right(u128 value, u16 n)
{
#if defined (__TINYC__) || defined(_MSC_VER)
u128 result = {0, 0};
u128 result = {};
if (n < 128)
{
@ -59,7 +68,7 @@ fn u128 u128_shift_right(u128 value, u16 n)
fn u128 u128_shift_left(u128 value, u16 n)
{
#if defined(__TINYC__) || defined(_MSC_VER)
u128 result = {0, 0};
u128 result = {};
if (n < 128)
{
@ -115,7 +124,7 @@ fn u128 u128_u64_add(u128 a, u64 b)
fn u128 u128_u64_mul(u128 a, u64 b)
{
#if defined(__TINYC__) || defined(_MSC_VER)
u128 result = {0, 0};
u128 result = {};
// Compute low and high parts of the product
u64 low_low = (a.low & 0xFFFFFFFF) * (b & 0xFFFFFFFF);
@ -147,8 +156,8 @@ fn u64 u128_shift_right_by_64(u128 n)
// Lehmer's generator
// https://lemire.me/blog/2019/03/19/the-fastest-conventional-random-number-generator-that-can-pass-big-crush/
may_be_unused global_variable u128 rn_state;
may_be_unused fn u64 generate_random_number()
global_variable u128 rn_state;
fn u64 generate_random_number()
{
rn_state = u128_u64_mul(rn_state, 0xda942042e4dd58b5);
return u128_shift_right_by_64(rn_state);
@ -167,7 +176,7 @@ fn u64 round_up_to_next_power_of_2(u64 n)
return n;
}
may_be_unused fn u64 absolute_int(s64 n)
fn u64 absolute_int(s64 n)
{
return n < 0 ? cast_to(u64, -n) : cast_to(u64, n);
}
@ -230,7 +239,7 @@ fn u64 is_decimal_digit(u8 ch)
fn u64 is_hex_digit(u8 ch)
{
return (is_decimal_digit(ch) | ((ch == 'a' | ch == 'A') | (ch == 'b' | ch == 'B'))) | (((ch == 'c' | ch == 'C') | (ch == 'd' | ch == 'D')) | ((ch == 'e' | ch == 'E') | (ch == 'f' | ch == 'F')));
return (is_decimal_digit(ch) | (((ch == 'a') | (ch == 'A')) | ((ch == 'b') | (ch == 'B')))) | ((((ch == 'c') | (ch == 'C')) | ((ch == 'd') | (ch == 'D'))) | (((ch == 'e') | (ch == 'E')) | ((ch == 'f') | (ch == 'F'))));
}
fn u64 is_identifier_start(u8 ch)
@ -293,14 +302,28 @@ fn u8 is_power_of_two(u64 value)
fn u8 first_bit_set_32(u32 value)
{
#if _MSC_VER
DWORD result_dword;
u8 result_u8 = _BitScanForward(&result_dword, value);
unused(result_u8);
let_cast(u8, result, result_dword);
#else
let(result, (u8)__builtin_ffs((s32)value));
#endif
result -= result != 0;
return result;
}
fn u64 first_bit_set_64(u64 value)
{
#if _MSC_VER
DWORD result_dword;
u8 result_u8 = _BitScanForward64(&result_dword, value);
unused(result_u8);
let_cast(u8, result, result_dword);
#else
let(result, (u8) __builtin_ffs((s64)value));
#endif
result -= result != 0;
return result;
}

View File

@ -1,5 +1,9 @@
#pragma once
#if _WIN32
#define _CRT_SECURE_NO_WARNINGS
#endif
#define LINK_LIBC 1
#ifdef NDEBUG
@ -20,6 +24,7 @@
#endif
#include <stdint.h>
#include <stddef.h>
#include <stdarg.h>
#define BB_SAFETY BB_DEBUG
@ -32,6 +37,33 @@
#define MAX(a, b) (((a) > (b)) ? (a) : (b))
#define CLAMP(a, x, b) (((a)>(x))?(a):((b)<(x))?(b):(x))
#ifdef __TINYC__
#define declare_vector_type #error
#else
#ifdef __clang__
#define declare_vector_type(T, count, name) typedef T name __attribute__((ext_vector_type(count)))
#else
#define declare_vector_type(T, count, name) typedef T name __attribute__((vector_size(count)))
#endif
#endif
#define array_length(arr) sizeof(arr) / sizeof((arr)[0])
#define KB(n) ((n) * 1024)
#define MB(n) ((n) * 1024 * 1024)
#define GB(n) ((u64)(n) * 1024 * 1024 * 1024)
#define TB(n) ((u64)(n) * 1024 * 1024 * 1024 * 1024)
#define unused(x) (void)(x)
#if _MSC_VER
#define BB_NORETURN __declspec(noreturn)
#define BB_COLD __declspec(noinline)
#elif defined(__TINYC__)
#define BB_NORETURN __attribute__((noreturn))
#define BB_COLD __attribute__((cold))
#else
#define BB_NORETURN [[noreturn]]
#define BB_COLD [[gnu::cold]]
#endif
#define TRUNCATE(Destination, source) (Destination)(source)
#if _MSC_VER
#define ENUM_START(EnumName, T) typedef T EnumName; typedef enum EnumName ## Flags
#define ENUM_END(EnumName) EnumName ## Flags
@ -76,7 +108,10 @@ typedef __int128_t s128;
typedef size_t usize;
#if !defined(__TINYC__) && !defined(_MSC_VER)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wpedantic"
typedef _Float16 f16;
#pragma GCC diagnostic pop
#endif
typedef float f32;
typedef double f64;
@ -84,8 +119,34 @@ typedef double f64;
typedef u32 Hash32;
typedef u64 Hash64;
#define Slice(T) Slice_ ## T
#define SliceP(T) SliceP_ ## T
#define declare_slice_ex(T, StructName) STRUCT(StructName) \
{\
T* pointer;\
u64 length;\
}
#define declare_slice(T) declare_slice_ex(T, Slice(T))
#define declare_slice_p(T) declare_slice_ex(T*, SliceP(T))
declare_slice(u8);
declare_slice(u16);
declare_slice(u32);
declare_slice(u64);
declare_slice(s8);
declare_slice(s16);
declare_slice(s32);
declare_slice(s64);
declare_slice_p(char);
declare_slice_p(void);
typedef Slice(u8) String;
declare_slice(String);
#if BB_DEBUG
#define assert(x) if (unlikely(!(x))) { my_panic("Assert failed: \"" # x "\" at {cstr}:{u32}\n", __FILE__, __LINE__); }
#define assert(x) (unlikely(!(x)) ? panic("Assert failed: \"" # x "\" at {cstr}:{u32}\n", __FILE__, __LINE__) : unused(0))
#else
#define assert(x) unused(likely(x))
#endif
@ -101,18 +162,15 @@ typedef u64 Hash64;
#undef unreachable
#endif
#if BB_DEBUG
#define unreachable() my_panic("Unreachable triggered\n", __FILE__, __LINE__)
#define unreachable() panic("Unreachable triggered\n", __FILE__, __LINE__)
#else
#define unreachable() unreachable_raw()
#endif
#ifdef __TINYC__
#define fix_unreachable() unreachable_raw()
#else
#define fix_unreachable()
#endif
#ifndef static_assert
#define static_assert(x) _Static_assert((x), "Static assert failed!")
#endif
#define alignof(x) _Alignof(x)
#else
#define restrict __restrict
@ -135,38 +193,30 @@ typedef u64 Hash64;
#define likely(x) expect(x, 1)
#define unlikely(x) expect(x, 0)
#define breakpoint() __builtin_debugtrap()
#define failed_execution() my_panic("Failed execution at {cstr}:{u32}\n", __FILE__, __LINE__)
#define todo() my_panic("TODO at {cstr}:{u32}\n", __FILE__, __LINE__)
#define failed_execution() panic("Failed execution at {cstr}:{u32}\n", __FILE__, __LINE__)
#define todo() panic("TODO at {cstr}:{u32}\n", __FILE__, __LINE__); fix_unreachable()
fn void print(const char* format, ...);
fn u8 os_is_being_debugged();
fn void os_exit(u32 exit_code);
#define my_panic(...) do \
{\
print(__VA_ARGS__);\
if (os_is_being_debugged())\
{\
trap();\
fix_unreachable();\
}\
else\
{\
os_exit(1);\
fix_unreachable();\
}\
} while (0)
BB_NORETURN BB_COLD fn void os_exit(u32 exit_code);
#if _MSC_VER
#define trap() __fastfail(1)
#elif __has_builtin(__builtin_trap)
#define trap() __builtin_trap()
#else
fn void trap()
extern BB_NORETURN BB_COLD void abort(void);
fn BB_NORETURN BB_COLD void trap_ext()
{
#ifdef __x86_64__
asm volatile("ud2");
}
#else
abort();
#endif
}
#define trap() (trap_ext(), __builtin_unreachable())
#endif
#define panic(format, ...) (print(format, __VA_ARGS__), os_exit(1))
#define let_pointer_cast(PointerChildType, var_name, value) PointerChildType* var_name = (PointerChildType*)(value)
#if defined(__TINYC__) || defined(_MSC_VER)
@ -174,92 +224,17 @@ fn void trap()
#else
#define let(name, value) __auto_type name = (value)
#endif
#define let_cast_unchecked(name, T, value) T name = (T)(value)
#define let_cast(T, name, value) T name = cast_to(T, value)
#define let_va_arg(T, name, args) T name = va_arg(args, T)
#define assign_cast(to, from) to = cast_to(typeof(to), from)
#define let_va_arg(T, name, args) T name = va_arg(args, T)
#define transmute(D, source) *(D*)&source
UNION(SafeInteger)
{
s64 signed_value;
u64 unsigned_value;
};
fn SafeInteger safe_integer_cast(SafeInteger value, u64 to_size, u64 to_signedness, u64 from_size, u64 from_signedness)
{
SafeInteger result;
let(shifter, to_size * 8 - to_signedness);
let(to_max, (u64)(1 << shifter) - 1);
// A fix for 64-bit wrapping
to_max = to_max == 0 ? UINT64_MAX : to_max;
let(to_signed_min, -((s64)1 << shifter));
if (from_signedness == to_signedness)
{
if (to_size < from_size)
{
switch (to_signedness)
{
case 0:
{
if (value.unsigned_value > to_max)
{
todo();
}
} break;
case 1:
{
if (value.signed_value < to_signed_min)
{
todo();
}
if (value.signed_value > (s64)to_max)
{
todo();
}
}
}
}
}
else
{
if (from_signedness)
{
if (value.signed_value < 0)
{
todo();
}
else if (value.unsigned_value > to_max)
{
todo();
}
}
else
{
if (value.unsigned_value > to_max)
{
todo();
}
}
}
result = value;
return result;
}
#define type_is_signed(T) ((T)(-1) < 0)
#if BB_SAFETY
#define safe_integer_cast_function(To, value) (To) ((value) < 0 ? (safe_integer_cast((SafeInteger) { .signed_value = (value) }, sizeof(To), type_is_signed(To), sizeof(typeof(value)), type_is_signed(typeof(value)))).signed_value : (safe_integer_cast((SafeInteger) { .signed_value = (value) }, sizeof(To), type_is_signed(To), sizeof(typeof(value)), type_is_signed(typeof(value)))).unsigned_value)
#endif
#if BB_SAFETY
#define cast_to(T, value) safe_integer_cast_function(T, value)
#define cast_to(T, value) (assert((typeof(value)) (T) (value) == (value) && ((value) > 0) == ((T) (value) > 0)), (T) (value))
#else
#define cast_to(T, value) (T)(value)
#endif
typedef enum Corner
{
CORNER_00,
@ -288,33 +263,6 @@ typedef enum Axis2
#define NO_EXCEPT
#endif
#define Slice(T) Slice_ ## T
#define SliceP(T) SliceP_ ## T
#define declare_slice_ex(T, StructName) STRUCT(StructName) \
{\
T* pointer;\
u64 length;\
}
#define declare_slice(T) declare_slice_ex(T, Slice(T))
#define declare_slice_p(T) declare_slice_ex(T*, SliceP(T))
declare_slice(u8);
declare_slice(u16);
declare_slice(u32);
declare_slice(u64);
declare_slice(s8);
declare_slice(s16);
declare_slice(s32);
declare_slice(s64);
declare_slice_p(char);
declare_slice_p(void);
typedef Slice(u8) String;
declare_slice(String);
#define NamedEnumMemberEnum(e, enum_member) e ## _ ## enum_member
#define NamedEnumMemberString(e, enum_member) strlit(#enum_member)
@ -338,38 +286,6 @@ for (typeof(bits) _bits_ = (bits), it = (start); _bits_; _bits_ >>= 1, ++it) if
#define FOREACH_SET(it, set) \
FOR_N(_i, 0, ((set)->arr.capacity + 63) / 64) FOR_BIT(it, _i*64, (set)->arr.pointer[_i])
#ifdef __TINYC__
#define declare_vector_type #error
#else
#ifdef __clang__
#define declare_vector_type(T, count, name) typedef T name __attribute__((ext_vector_type(count)))
#else
#define declare_vector_type(T, count, name) typedef T name __attribute__((vector_size(count)))
#endif
#endif
#define array_length(arr) sizeof(arr) / sizeof((arr)[0])
#define KB(n) ((n) * 1024)
#define MB(n) ((n) * 1024 * 1024)
#define GB(n) ((u64)(n) * 1024 * 1024 * 1024)
#define TB(n) ((u64)(n) * 1024 * 1024 * 1024 * 1024)
#define unused(x) (void)(x)
#ifdef __clang__
#define may_be_unused __attribute__((unused))
#else
#define may_be_unused
#endif
#if _MSC_VER
#define BB_NORETURN __declspec(noreturn)
#define BB_COLD __declspec(noinline)
#elif defined(__TINYC__)
#define BB_NORETURN __attribute__((noreturn))
#define BB_COLD __attribute__((cold))
#else
#define BB_NORETURN [[noreturn]]
#define BB_COLD [[gnu::cold]]
#endif
#define TRUNCATE(Destination, source) (Destination)(source)
#define size_until_end(T, field_name) (sizeof(T) - offsetof(T, field_name))
#define SWAP(a, b) \
do {\
@ -393,21 +309,20 @@ FOR_N(_i, 0, ((set)->arr.capacity + 63) / 64) FOR_BIT(it, _i*64, (set)->arr.poin
#define case_to_name(prefix, e) case prefix ## e: return strlit(#e)
const may_be_unused global_variable u8 brace_open = '{';
const may_be_unused global_variable u8 brace_close = '}';
global_variable const u8 brace_open = '{';
global_variable const u8 brace_close = '}';
const may_be_unused global_variable u8 parenthesis_open = '(';
const may_be_unused global_variable u8 parenthesis_close = ')';
global_variable const u8 parenthesis_open = '(';
global_variable const u8 parenthesis_close = ')';
const may_be_unused global_variable u8 bracket_open = '[';
const may_be_unused global_variable u8 bracket_close = ']';
global_variable const u8 bracket_open = '[';
global_variable const u8 bracket_close = ']';
#define s_get(s, i) (s).pointer[i]
#define s_get_pointer(s, i) &((s).pointer[i])
#define s_get_slice(T, s, start, end) (Slice(T)){ .pointer = ((s).pointer) + (start), .length = (end) - (start) }
#define s_equal(a, b) ((a).length == (b).length && memcmp((a).pointer, (b).pointer, sizeof(*((a).pointer)) * (a).length) == 0)
fn u64 align_forward(u64 value, u64 alignment);
fn u64 align_backward(u64 value, u64 alignment);
fn u8 log2_alignment(u64 alignment);
@ -415,25 +330,6 @@ fn u8 is_power_of_two(u64 value);
fn u8 first_bit_set_32(u32 value);
fn u64 first_bit_set_64(u64 value);
fn u8 cast_u32_to_u8(u32 source, const char* name, int line);
fn u16 cast_u32_to_u16(u32 source, const char* name, int line);
fn s16 cast_u32_to_s16(u32 source, const char* name, int line);
fn s32 cast_u32_to_s32(u32 source, const char* name, int line);
fn u8 cast_u64_to_u8(u64 source, const char* name, int line);
fn u16 cast_u64_to_u16(u64 source, const char* name, int line);
fn u32 cast_u64_to_u32(u64 source, const char* name, int line);
fn s32 cast_u64_to_s32(u64 source, const char* name, int line);
fn s64 cast_u64_to_s64(u64 source, const char* name, int line);
fn u8 cast_s32_to_u8(s32 source, const char* name, int line);
fn u16 cast_s32_to_u16(s32 source, const char* name, int line);
fn u32 cast_s32_to_u32(s32 source, const char* name, int line);
fn u64 cast_s32_to_u64(s32 source, const char* name, int line);
fn s16 cast_s32_to_s16(s32 source, const char* name, int line);
fn u16 cast_s64_to_u16(s64 source, const char* name, int line);
fn u32 cast_s64_to_u32(s64 source, const char* name, int line);
fn u64 cast_s64_to_u64(s64 source, const char* name, int line);
fn s32 cast_s64_to_s32(s64 source, const char* name, int line);
fn u32 format_decimal(String buffer, u64 decimal);
fn u32 format_hexadecimal(String buffer, u64 hexadecimal);
fn u64 format_float(String buffer, f64 value_double);

View File

@ -73,7 +73,7 @@ STRUCT(SmallIntResult)
{
u64 mantissa;
s32 exponent;
u8 is_small_int;
u32 is_small_int:1;
};
#define double_mantissa_bits 52
@ -301,7 +301,7 @@ fn u64 mul_shift_64(const u64 m, const u64* const mul, const s32 j)
{
const u128 b0 = u128_u64_mul(u128_from_u64(m), mul[0]);
const u128 b2 = u128_u64_mul(u128_from_u64(m), mul[1]);
return u64_from_u128(u128_shift_right(u128_u64_add(b2, u128_shift_right_by_64(b0)), j - 64));
return u64_from_u128(u128_shift_right(u128_u64_add(b2, u128_shift_right_by_64(b0)), cast_to(u16, j - 64)));
// return (u64) (((b0 >> 64) + b2) >> (j - 64));
}
@ -555,9 +555,10 @@ STRUCT(Double)
{
u64 mantissa;
s32 exponent;
u32 reserved;
};
may_be_unused fn Double double_transform(u64 ieee_mantissa, u32 ieee_exponent)
fn Double double_transform(u64 ieee_mantissa, u32 ieee_exponent)
{
u64 m2;
s32 e2;
@ -651,7 +652,7 @@ may_be_unused fn Double double_transform(u64 ieee_mantissa, u32 ieee_exponent)
}
u32 vm_mod10 = ((u32)vm) - 10 * ((u32)vm_div10);
u32 vr_div10 = div10(vr);
u64 vr_div10 = div10(vr);
u32 vr_mod10 = ((u32)vr) - 10 * ((u32)vr_div10);
vm_is_trailing_zeroes &= vm_mod10 == 0;
vr_is_trailing_zeroes &= last_removed_digit == 0;
@ -740,7 +741,7 @@ may_be_unused fn Double double_transform(u64 ieee_mantissa, u32 ieee_exponent)
};
}
may_be_unused fn SmallIntResult small_int(u64 ieee_mantissa, u32 ieee_exponent)
fn SmallIntResult small_int(u64 ieee_mantissa, u32 ieee_exponent)
{
SmallIntResult result = {};
let(m2, ((u64)1 << double_mantissa_bits) | ieee_mantissa);
@ -798,10 +799,11 @@ fn u32 decimalLength17(const u64 v) {
// A floating decimal representing m * 10^e.
STRUCT(floating_decimal_64)
{
uint64_t mantissa;
u64 mantissa;
// Decimal exponent's range is -324 to 308
// inclusive, and can fit in a short if needed.
int32_t exponent;
s32 exponent;
u32 reserved;
};
fn u8* digits2(u64 value)
@ -1065,6 +1067,14 @@ fn u64 format_float(String buffer, f64 value_double)
return buffer_i;
}
typedef enum IntegerFormat
{
INTEGER_FORMAT_HEXADECIMAL,
INTEGER_FORMAT_DECIMAL,
INTEGER_FORMAT_OCTAL,
INTEGER_FORMAT_BINARY,
} IntegerFormat;
fn String format_string_va(String buffer, const char* format, va_list args)
{
u8* it = (u8*)format;
@ -1171,15 +1181,7 @@ fn String format_string_va(String buffer, const char* format, va_list args)
u8* bit_count_end = it;
u64 bit_count = parse_decimal(slice_from_pointer_range(u8, (u8*)bit_count_start, (u8*)bit_count_end));
typedef enum IntegerFormat
{
INTEGER_FORMAT_HEXADECIMAL,
INTEGER_FORMAT_DECIMAL,
INTEGER_FORMAT_OCTAL,
INTEGER_FORMAT_BINARY,
} IntegerFormat;
IntegerFormat format = INTEGER_FORMAT_DECIMAL;
IntegerFormat integer_format = INTEGER_FORMAT_DECIMAL;
if (*it == ':')
{
@ -1187,16 +1189,16 @@ fn String format_string_va(String buffer, const char* format, va_list args)
switch (*it)
{
case 'x':
format = INTEGER_FORMAT_HEXADECIMAL;
integer_format = INTEGER_FORMAT_HEXADECIMAL;
break;
case 'd':
format = INTEGER_FORMAT_DECIMAL;
integer_format = INTEGER_FORMAT_DECIMAL;
break;
case 'o':
format = INTEGER_FORMAT_OCTAL;
integer_format = INTEGER_FORMAT_OCTAL;
break;
case 'b':
format = INTEGER_FORMAT_BINARY;
integer_format = INTEGER_FORMAT_BINARY;
break;
default:
unreachable();
@ -1222,7 +1224,7 @@ fn String format_string_va(String buffer, const char* format, va_list args)
String buffer_slice = s_get_slice(u8, buffer, buffer_i, buffer.length);
switch (format)
switch (integer_format)
{
case INTEGER_FORMAT_HEXADECIMAL:
{
@ -1287,7 +1289,7 @@ fn String format_string_va(String buffer, const char* format, va_list args)
INTEGER_FORMAT_BINARY,
} IntegerFormat;
IntegerFormat format = INTEGER_FORMAT_DECIMAL;
IntegerFormat integer_format = INTEGER_FORMAT_DECIMAL;
if (*it == ':')
{
@ -1295,16 +1297,16 @@ fn String format_string_va(String buffer, const char* format, va_list args)
switch (*it)
{
case 'x':
format = INTEGER_FORMAT_HEXADECIMAL;
integer_format = INTEGER_FORMAT_HEXADECIMAL;
break;
case 'd':
format = INTEGER_FORMAT_DECIMAL;
integer_format = INTEGER_FORMAT_DECIMAL;
break;
case 'o':
format = INTEGER_FORMAT_OCTAL;
integer_format = INTEGER_FORMAT_OCTAL;
break;
case 'b':
format = INTEGER_FORMAT_BINARY;
integer_format = INTEGER_FORMAT_BINARY;
break;
default:
unreachable();
@ -1330,7 +1332,7 @@ fn String format_string_va(String buffer, const char* format, va_list args)
let(buffer_slice, s_get_slice(u8, buffer, buffer_i, buffer.length));
switch (format)
switch (integer_format)
{
case INTEGER_FORMAT_HEXADECIMAL:
{

View File

@ -54,7 +54,7 @@ global_variable u8 md5_padding[] = {0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
may_be_unused fn MD5Context md5_init()
fn MD5Context md5_init()
{
return (MD5Context) {
.buffer = { MD5_A, MD5_B, MD5_C, MD5_D },
@ -66,7 +66,7 @@ fn u32 rotate_left_u32(u32 x, u32 n)
return (x << n) | (x >> (32 - n));
}
may_be_unused fn void md5_step(u32* buffer, u32* input)
fn void md5_step(u32* buffer, u32* input)
{
u32 aa = buffer[0];
u32 bb = buffer[1];
@ -114,7 +114,7 @@ may_be_unused fn void md5_step(u32* buffer, u32* input)
buffer[3] += dd;
}
may_be_unused fn void md5_update(MD5Context* context, String input_argument)
fn void md5_update(MD5Context* context, String input_argument)
{
u32 input_local[16];
auto offset = context->size % 64;
@ -139,7 +139,7 @@ may_be_unused fn void md5_update(MD5Context* context, String input_argument)
}
}
may_be_unused fn MD5Result md5_end(MD5Context* context)
fn MD5Result md5_end(MD5Context* context)
{
u32 input[16];
auto offset = context->size % 64;

View File

@ -123,7 +123,7 @@ fn String path_base(String string)
#if _WIN32
if (!result.pointer)
{
let(index, string_last_ch(string, '\\'));
index = string_last_ch(string, '\\');
if (index != STRING_NO_MATCH)
{
result = s_get_slice(u8, string, index + 1, string.length);
@ -148,21 +148,21 @@ fn String path_no_extension(String string)
#if LINK_LIBC == 0
#ifdef __linux__
may_be_unused fn forceinline long syscall0(long n)
fn forceinline long syscall0(long n)
{
long ret;
__asm__ __volatile__ ("syscall" : "=a"(ret) : "a"(n) : "rcx", "r11", "memory");
return ret;
}
may_be_unused fn forceinline long syscall1(long n, long a1)
fn forceinline long syscall1(long n, long a1)
{
long ret;
__asm__ __volatile__ ("syscall" : "=a"(ret) : "a"(n), "D"(a1) : "rcx", "r11", "memory");
return ret;
}
may_be_unused fn forceinline long syscall2(long n, long a1, long a2)
fn forceinline long syscall2(long n, long a1, long a2)
{
long ret;
__asm__ __volatile__ ("syscall" : "=a"(ret) : "a"(n), "D"(a1), "S"(a2)
@ -170,7 +170,7 @@ may_be_unused fn forceinline long syscall2(long n, long a1, long a2)
return ret;
}
may_be_unused fn forceinline long syscall3(long n, long a1, long a2, long a3)
fn forceinline long syscall3(long n, long a1, long a2, long a3)
{
long ret;
__asm__ __volatile__ ("syscall" : "=a"(ret) : "a"(n), "D"(a1), "S"(a2),
@ -178,7 +178,7 @@ may_be_unused fn forceinline long syscall3(long n, long a1, long a2, long a3)
return ret;
}
may_be_unused fn forceinline long syscall4(long n, long a1, long a2, long a3, long a4)
fn forceinline long syscall4(long n, long a1, long a2, long a3, long a4)
{
long ret;
register long r10 __asm__("r10") = a4;
@ -187,7 +187,7 @@ may_be_unused fn forceinline long syscall4(long n, long a1, long a2, long a3, lo
return ret;
}
may_be_unused fn forceinline long syscall5(long n, long a1, long a2, long a3, long a4, long a5)
fn forceinline long syscall5(long n, long a1, long a2, long a3, long a4, long a5)
{
long ret;
register long r10 __asm__("r10") = a4;
@ -197,7 +197,7 @@ may_be_unused fn forceinline long syscall5(long n, long a1, long a2, long a3, lo
return ret;
}
may_be_unused fn forceinline long syscall6(long n, long a1, long a2, long a3, long a4, long a5, long a6)
fn forceinline long syscall6(long n, long a1, long a2, long a3, long a4, long a5, long a6)
{
long ret;
register long r10 __asm__("r10") = a4;
@ -582,7 +582,7 @@ enum SyscallX86_64 : u64 {
#endif
#ifndef _WIN32
may_be_unused fn void* posix_mmap(void* address, size_t length, int protection_flags, int map_flags, int fd, signed long offset)
fn void* posix_mmap(void* address, size_t length, int protection_flags, int map_flags, int fd, signed long offset)
{
#if LINK_LIBC
return mmap(address, length, protection_flags, map_flags, fd, offset);
@ -595,7 +595,7 @@ may_be_unused fn void* posix_mmap(void* address, size_t length, int protection_f
#endif
}
may_be_unused fn int syscall_mprotect(void *address, size_t length, int protection_flags)
fn int syscall_mprotect(void *address, size_t length, int protection_flags)
{
#if LINK_LIBC
return mprotect(address, length, protection_flags);
@ -608,7 +608,7 @@ may_be_unused fn int syscall_mprotect(void *address, size_t length, int protecti
#endif
}
may_be_unused fn int syscall_open(const char *file_path, int flags, int mode)
fn int syscall_open(const char *file_path, int flags, int mode)
{
#if LINK_LIBC
return open(file_path, flags, mode);
@ -621,7 +621,7 @@ may_be_unused fn int syscall_open(const char *file_path, int flags, int mode)
#endif
}
may_be_unused fn int syscall_close(int fd)
fn int syscall_close(int fd)
{
#if LINK_LIBC
return close(fd);
@ -647,7 +647,7 @@ fn int syscall_fstat(int fd, struct stat *buffer)
#endif
}
may_be_unused fn ssize_t syscall_read(int fd, void* buffer, size_t bytes)
fn ssize_t syscall_read(int fd, void* buffer, size_t bytes)
{
#if LINK_LIBC
return read(fd, buffer, bytes);
@ -660,7 +660,7 @@ may_be_unused fn ssize_t syscall_read(int fd, void* buffer, size_t bytes)
#endif
}
may_be_unused fn ssize_t syscall_write(int fd, const void *buffer, size_t bytes)
fn ssize_t syscall_write(int fd, const void *buffer, size_t bytes)
{
#if LINK_LIBC
return write(fd, buffer, bytes);
@ -673,7 +673,7 @@ may_be_unused fn ssize_t syscall_write(int fd, const void *buffer, size_t bytes)
#endif
}
may_be_unused fn int syscall_mkdir(String path, u32 mode)
fn int syscall_mkdir(String path, u32 mode)
{
assert(path.pointer[path.length] == 0);
#if LINK_LIBC
@ -683,7 +683,7 @@ may_be_unused fn int syscall_mkdir(String path, u32 mode)
#endif
}
may_be_unused fn int syscall_rmdir(String path)
fn int syscall_rmdir(String path)
{
assert(path.pointer[path.length] == 0);
#if LINK_LIBC
@ -693,7 +693,7 @@ may_be_unused fn int syscall_rmdir(String path)
#endif
}
may_be_unused fn int syscall_unlink(String path)
fn int syscall_unlink(String path)
{
assert(path.pointer[path.length] == 0);
#if LINK_LIBC
@ -703,7 +703,7 @@ may_be_unused fn int syscall_unlink(String path)
#endif
}
may_be_unused fn pid_t syscall_fork()
fn pid_t syscall_fork()
{
#if LINK_LIBC
return fork();
@ -713,7 +713,7 @@ may_be_unused fn pid_t syscall_fork()
}
may_be_unused fn signed long syscall_execve(const char* path, char *const argv[], char *const envp[])
fn signed long syscall_execve(const char* path, char *const argv[], char *const envp[])
{
#if LINK_LIBC
return execve(path, argv, envp);
@ -722,7 +722,7 @@ may_be_unused fn signed long syscall_execve(const char* path, char *const argv[]
#endif
}
may_be_unused fn pid_t syscall_waitpid(pid_t pid, int* status, int options)
fn pid_t syscall_waitpid(pid_t pid, int* status, int options)
{
#if LINK_LIBC
return waitpid(pid, status, options);
@ -731,7 +731,7 @@ may_be_unused fn pid_t syscall_waitpid(pid_t pid, int* status, int options)
#endif
}
may_be_unused fn int syscall_gettimeofday(struct timeval* tv, struct timezone* tz)
fn int syscall_gettimeofday(struct timeval* tv, struct timezone* tz)
{
#if LINK_LIBC
return gettimeofday(tv, tz);
@ -740,7 +740,7 @@ may_be_unused fn int syscall_gettimeofday(struct timeval* tv, struct timezone* t
#endif
}
may_be_unused BB_NORETURN BB_COLD fn void syscall_exit(int status)
BB_NORETURN BB_COLD fn void syscall_exit(int status)
{
#if LINK_LIBC
_exit(status);
@ -755,12 +755,12 @@ may_be_unused BB_NORETURN BB_COLD fn void syscall_exit(int status)
}
#endif
may_be_unused fn u64 os_timer_freq()
fn u64 os_timer_freq()
{
return 1000 * 1000;
}
may_be_unused fn u64 os_timer_get()
fn u64 os_timer_get()
{
#if _WIN32
LARGE_INTEGER large_integer;
@ -787,6 +787,8 @@ fn FileDescriptor os_file_open(String path, OSFileOpenFlags flags, OSFilePermiss
{
assert(path.pointer[path.length] == 0);
#if _WIN32
unused(permissions);
DWORD dwDesiredAccess = 0;
dwDesiredAccess |= flags.read * GENERIC_READ;
dwDesiredAccess |= flags.write * GENERIC_WRITE;
@ -854,7 +856,7 @@ fn void os_file_write(FileDescriptor fd, String content)
#endif
}
may_be_unused fn u64 os_file_read(FileDescriptor fd, String buffer, u64 byte_count)
fn u64 os_file_read(FileDescriptor fd, String buffer, u64 byte_count)
{
assert(byte_count);
assert(byte_count <= buffer.length);
@ -966,22 +968,24 @@ BB_NORETURN BB_COLD fn void os_exit(u32 exit_code)
exit(exit_code);
}
fn void vprint(const char* format, va_list args)
{
u8 stack_buffer[16*1024];
String buffer = { .pointer = stack_buffer, .length = array_length(stack_buffer) };
String final_string = format_string_va(buffer, format, args);
os_file_write(os_stdout_get(), final_string);
}
fn void print(const char* format, ...)
{
#ifndef SILENT
u8 stack_buffer[16*1024];
String buffer = { .pointer = stack_buffer, .length = array_length(stack_buffer) };
va_list args;
va_start(args, format);
String final_string = format_string_va(buffer, format, args);
va_end(args);
os_file_write(os_stdout_get(), final_string);
#endif
va_list args;
va_start(args, format);
vprint(format, args);
va_end(args);
}
static_assert(sizeof(Arena) == 64);
const global_variable u64 minimum_position = sizeof(Arena);
global_variable const u64 minimum_position = sizeof(Arena);
fn Arena* arena_initialize(u64 reserved_size, u64 granularity, u64 initial_size)
{
@ -1157,7 +1161,7 @@ fn void run_command(Arena* arena, CStringSlice arguments, char* envp[], RunComma
{
let(len, strlen(argument));
memcpy(&bytes[byte_i], argument, len);
byte_i += len;
byte_i += cast_to(u32, len);
bytes[byte_i] = ' ';
byte_i += 1;
}
@ -1219,6 +1223,7 @@ fn void run_command(Arena* arena, CStringSlice arguments, char* envp[], RunComma
0,
NULL
);
unused(bufSize);
print("CreateProcessA call failed: {cstr}\n", lpMsgBuf);
todo();
}
@ -1242,8 +1247,9 @@ fn void run_command(Arena* arena, CStringSlice arguments, char* envp[], RunComma
// close(pipes[0]);
// fcntl(pipes[1], F_SETFD, FD_CLOEXEC);
let(result, syscall_execve(arguments.pointer[0], arguments.pointer, envp));
unused(result);
#if LINK_LIBC
my_panic("Execve failed! Error: {cstr}\n", strerror(errno));
panic("Execve failed! Error: {cstr}\n", strerror(errno));
#else
todo();
#endif
@ -1322,7 +1328,7 @@ fn u8 os_is_being_debugged()
{
u8 result = 0;
#if _WIN32
result = IsDebuggerPresent();
result = IsDebuggerPresent() != 0;
#else
#ifdef __APPLE__
let(request, PT_TRACE_ME);
@ -1366,6 +1372,7 @@ fn String os_get_environment_variable(const char* name)
return result;
}
#ifndef _WIN32
fn u64 os_readlink(String path, String buffer)
{
u64 result = 0;
@ -1396,7 +1403,6 @@ fn String os_readlink_allocate(Arena* arena, String path)
return result;
}
#ifndef _WIN32
fn String os_realpath(String path, String buffer)
{
String result = {};
@ -1434,7 +1440,7 @@ fn OSLibrary os_library_load(const char* library_name)
fn OSSymbol os_symbol_load(OSLibrary library, const char* symbol_name)
{
OSSymbol symbol = GetProcAddress(library.handle, symbol_name);
OSSymbol symbol = (OSSymbol)GetProcAddress(library.handle, symbol_name);
return symbol;
}
#else

View File

@ -1,7 +1,5 @@
#pragma once
#include <stdarg.h>
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
@ -85,20 +83,21 @@ STRUCT(FileWriteOptions)
{
String path;
String content;
u8 executable;
u64 executable:1;
};
#if __APPLE__
#define MY_PAGE_SIZE KB(16)
#else
#ifndef __APPLE__
#define MY_PAGE_SIZE KB(4)
#else
#define MY_PAGE_SIZE KB(16)
#endif
const global_variable u64 page_size = MY_PAGE_SIZE;
global_variable const u64 page_size = MY_PAGE_SIZE;
global_variable u64 minimum_granularity = MY_PAGE_SIZE;
// global_variable u64 middle_granularity = MB(2);
global_variable u64 default_size = GB(4);
fn void vprint(const char* format, va_list args);
fn void print(const char* format, ...);
fn void run_command(Arena* arena, CStringSlice arguments, char* envp[], RunCommandOptions options);
fn String file_read(Arena* arena, String path);

View File

@ -124,6 +124,9 @@ u64 string_first_occurrence(String string, String substring)
fn u64 string_last_occurrence(String string, String substring)
{
unused(string);
unused(substring);
todo();
}

View File

@ -263,7 +263,7 @@ BB_NORETURN BB_COLD fn void wrong_vulkan_result(VkResult result, String call_str
unused(line);
String result_name = vulkan_result_to_string(result);
my_panic("Wrong Vulkan result {s} at \"{s}\" {s}:{u32}\n", result_name, call_string, file, line);
panic("Wrong Vulkan result {s} at \"{s}\" {s}:{u32}\n", result_name, call_string, file, line);
}
fn void buffer_copy_to_local_command(VkCommandBuffer command_buffer, Slice(LocalBufferCopy) copies)

View File

@ -9,9 +9,18 @@ if not defined BB_BUILD_TYPE (
set BB_BUILD_TYPE=debug
)
if not defined BB_ERROR_ON_WARNINGS (
set BB_ERROR_ON_WARNINGS=%BB_CI%
)
if not defined BB_ERROR_LIMIT (
set /a BB_ERROR_LIMIT=1-%BB_CI%
)
set BUILD_DIR=cache
mkdir %BUILD_DIR% > NUL 2>&1
set BUILD_OUT=cache\build.exe
set BB_ERROR_ON_WARNINGS=%BB_CI%
if "%BB_CI%" == "0" (
%VK_SDK_PATH%\Bin\glslangValidator.exe -V bootstrap\std\shaders\rect.vert -o cache\rect.vert.spv --quiet || exit /b 1
@ -19,5 +28,5 @@ if "%BB_CI%" == "0" (
)
cl /Zi /Y- /Gm- /std:clatest /diagnostics:caret -FC /nologo build.c /Fd%BUILD_DIR%\ /Fo%BUILD_DIR%\ /Fe%BUILD_OUT% -Ibootstrap -DBB_TIMETRACE=0 -DBB_BUILD_TYPE=\"%BB_BUILD_TYPE%\" -DBB_CI=%BB_CI% /link /INCREMENTAL:NO || exit /b 1
cl /Zi /Y- /Gm- /std:clatest /diagnostics:caret -FC /nologo build.c /Fd%BUILD_DIR%\ /Fo%BUILD_DIR%\ /Fe%BUILD_OUT% -Ibootstrap -DBB_TIMETRACE=0 -DBB_BUILD_TYPE=\"%BB_BUILD_TYPE%\" -DBB_CI=%BB_CI% -DBB_ERROR_ON_WARNINGS=%BB_ERROR_ON_WARNINGS% -DBB_ERROR_LIMIT=%BB_ERROR_LIMIT% /link /INCREMENTAL:NO || exit /b 1
%BUILD_OUT%

63
build.c
View File

@ -97,7 +97,7 @@ global_variable char* compiler_switches[COMPILER_ARGUMENT_STYLE_COUNT][COMPILER_
},
};
fn String file_find_in_path(Arena* arena, String file, String path_env)
fn String file_find_in_path(Arena* arena, String file, String path_env, String extension)
{
String result = {};
assert(path_env.pointer);
@ -130,11 +130,11 @@ fn String file_find_in_path(Arena* arena, String file, String path_env)
memcpy(&buffer[i], file.pointer, file.length);
i += file.length;
#if _WIN32
String exe_extension = strlit(".exe");
memcpy(&buffer[i], exe_extension.pointer, exe_extension.length);
i += exe_extension.length;
#endif
if (extension.length)
{
memcpy(&buffer[i], extension.pointer, extension.length);
i += extension.length;
}
buffer[i] = 0;
i += 1;
@ -239,6 +239,10 @@ fn String get_c_compiler_path(Arena* arena)
String cc_path = {};
String cc_env = os_get_environment_variable("CC");
String path_env = os_get_environment_variable("PATH");
String extension = {};
#if _WIN32
extension = strlit(".exe");
#endif
if (cc_env.pointer)
{
cc_path = cc_env;
@ -246,14 +250,14 @@ fn String get_c_compiler_path(Arena* arena)
#ifndef _WIN32
else
{
cc_path = file_find_in_path(arena, strlit("cc"), path_env);
cc_path = file_find_in_path(arena, strlit("cc"), path_env, extension);
}
#endif
if (!cc_path.pointer)
{
#if _WIN32
cc_path = strlit("cl.exe");
cc_path = strlit("cl");
#elif defined(__APPLE__)
cc_path = strlit("clang");
#elif defined(__linux__)
@ -269,7 +273,7 @@ fn String get_c_compiler_path(Arena* arena)
#endif
if (no_path_sep)
{
cc_path = file_find_in_path(arena, cc_path, path_env);
cc_path = file_find_in_path(arena, cc_path, path_env, extension);
}
#ifndef _WIN32
@ -296,7 +300,7 @@ fn String get_c_compiler_path(Arena* arena)
if (preferred_c_compiler != C_COMPILER_COUNT && c_compiler_is_supported_by_os(preferred_c_compiler))
{
String find_result = file_find_in_path(arena, c_compiler_to_string(preferred_c_compiler), path_env);
String find_result = file_find_in_path(arena, c_compiler_to_string(preferred_c_compiler), path_env, extension);
if (find_result.pointer)
{
cc_path = find_result;
@ -448,6 +452,7 @@ fn void compile_program(Arena* arena, CompileOptions options)
print("Could not find a valid compiler for CC: \"{cstr}\"\n", cc_env ? cc_env : "");
print("PATH: {cstr}\n", getenv("PATH"));
}
failed_execution();
}
@ -474,6 +479,7 @@ fn void compile_program(Arena* arena, CompileOptions options)
u64 arg_i = 0;
#define add_arg(arg) args[arg_i++] = (arg)
add_arg(string_to_c(options.compiler_path));
if (c_compiler == C_COMPILER_MSVC)
{
add_arg("/nologo");
@ -541,6 +547,41 @@ fn void compile_program(Arena* arena, CompileOptions options)
add_arg(optimization_switches[c_compiler == C_COMPILER_MSVC][options.build_type]);
}
// Inmutable options
switch (c_compiler)
{
case C_COMPILER_MSVC:
{
add_arg("/Wall");
#if BB_ERROR_ON_WARNINGS
add_arg("/WX");
#endif
add_arg("/wd4255");
} break;
default:
{
add_arg("-pedantic");
add_arg("-Wall");
add_arg("-Wextra");
add_arg("-Wpedantic");
add_arg("-Wno-unused-function");
add_arg("-Wno-nested-anon-types");
add_arg("-Wno-keyword-macro");
add_arg("-Wno-gnu-auto-type");
#ifndef __APPLE__
add_arg("-Wno-auto-decl-extensions");
#endif
add_arg("-Wno-gnu-empty-initializer");
add_arg("-Wno-fixed-enum-extension");
#if BB_ERROR_ON_WARNINGS
add_arg("-Werror");
#endif
add_arg("-fno-strict-aliasing");
add_arg("-fwrapv");
} break;
}
if (options.flags.colored_output && c_compiler_supports_colored_output(c_compiler))
{
add_arg("-fdiagnostics-color=auto");
@ -715,7 +756,7 @@ int main(int argc, char* argv[], char** envp)
.build_type = build_type_pick(),
.flags = {
.colored_output = 1,
.error_limit = 1,
.error_limit = BB_ERROR_LIMIT,
.debug = 1,
.time_trace = BB_TIMETRACE,
},

View File

@ -9,6 +9,14 @@ if [[ -z "${BB_BUILD_TYPE-}" ]]; then
BB_BUILD_TYPE=debug
fi
if [[ -z "${BB_ERROR_ON_WARNINGS-}" ]]; then
BB_ERROR_ON_WARNINGS=$BB_CI
fi
if [[ -z "${BB_ERROR_LIMIT-}" ]]; then
BB_ERROR_LIMIT=$((1 - BB_CI))
fi
BUILD_DIR=cache
mkdir -p $BUILD_DIR
@ -37,6 +45,6 @@ elif [[ $C_COMPILER == "gcc"* ]]; then
GCC_ARGS=-fmax-errors=1
fi
$C_COMPILER build.c -g -o $BUILD_OUT -Ibootstrap -std=gnu2x $CLANG_ARGS $GCC_ARGS -DBB_TIMETRACE=$BB_TIMETRACE -DBB_CI=$BB_CI -DBB_BUILD_TYPE=\"$BB_BUILD_TYPE\"
$C_COMPILER build.c -g -o $BUILD_OUT -Ibootstrap -std=gnu2x $CLANG_ARGS $GCC_ARGS -DBB_TIMETRACE=$BB_TIMETRACE -DBB_CI=$BB_CI -DBB_BUILD_TYPE=\"$BB_BUILD_TYPE\" -DBB_ERROR_ON_WARNINGS=$BB_ERROR_ON_WARNINGS -DBB_ERROR_LIMIT=$BB_ERROR_LIMIT
$BUILD_OUT $@
exit 0