--- /dev/null
+vg/source/foundation/options.c
+vg/source/foundation/logging.c
+vg/source/foundation/allocator_heap.c
+vg/source/foundation/allocator_stack.c
+vg/source/foundation/allocator_pool.c
+vg/source/foundation/allocator_queue.c
+vg/source/foundation/allocator_stretchy.c
+vg/source/foundation/stream.c
+vg/source/foundation/string.c
+vg/source/foundation/keyvalues.c
+vg/source/foundation/exit.c
+vg/source/foundation/io.c
+vg/source/foundation/buffer_operations.c
static inline f32 f32_sign( f32 a ) { return a < 0.0f? -1.0f: 1.0f; }
void _exit_init(void);
-void _fatal_exit( const c8 *reason );
-void _normal_exit( const c8 *reason );
+void _fatal_exit(void);
+void _normal_exit(void);
#define ASSERT_CRITICAL( CONDITION ) \
- if( !(CONDITION) ) \
- _fatal_exit( "("__BECOME_STRING__(CONDITION) ") evaluated to 0\nLocation: " __LINE_STRING__ "\n" );
+ if( !(CONDITION) ) { $log( $fatal, {$TO_STRING(CONDITION) "== 0"} ); _fatal_exit(); }
/* Command line options
* ------------------------------------------------------------------------------------------------------------------ */
void string_append_u64( struct stream *string, u64 value, u64 base );
void string_append_f64( struct stream *string, f64 value, u64 base, u32 decimal_places );
+struct v_string_arg
+{
+ const c8 *_string;
+ union
+ {
+ u64 _u64;
+ i64 _i64;
+ f64 _f64;
+ };
+
+ u32 type;
+ u32 base;
+ u32 decimals;
+};
+void v_string( struct stream *string, struct v_string_arg *argument_list );
+
+#define k_$end 99
+#define k_$string 0
+#define k_$unsigned 2
+#define k_$signed 3
+#define k_$float 4
+#define k_$errno 5
+
+#define $unsigned( X, ... ) { .type=k_$unsigned, ._u64=X, __VA_ARGS__ }
+#define $signed( X, ... ) { .type=k_$signed, ._i64=X, __VA_ARGS__ }
+#define $float( X, ... ) { .type=k_$float, ._f64=X, __VA_ARGS__ }
+#define $errno( ... ) { .type=k_$errno, __VA_ARGS__ }
+#define $v_string( STRING, ... ) v_string( STRING, (struct v_string_arg[]){ __VA_ARGS__, {.type=k_$end} } )
+
enum string_parse_result
{
k_string_parse_ok,
/* Logging
* ------------------------------------------------------------------------------------------------------------------ */
-enum log_event
-{
- k_log_low = 0x1,
- k_log_info = 0x2,
- k_log_ok = 0x4,
- k_log_warning = 0x8,
- k_log_error = 0x10
-};
+
+#define $low 0x1
+#define $info 0x2
+#define $ok 0x4
+#define $warning 0x8
+#define $error 0x10
+#define $fatal 0x20
/* One day we will replace this shit with a good pre-processor. */
-#define __BECOME_STRING__(S) __BECOME_STRING_REALLY__(S)
-#define __BECOME_STRING_REALLY__(S) #S
-#define __LINE_STRING__ __FILE__ ":" __BECOME_STRING__(__LINE__)
-#define _log( TYPE, TEXT ) _log_event( TYPE, TEXT, __LINE_STRING__ )
+#define $TO_STRING( S ) $TO_STRING_1( S )
+#define $TO_STRING_1( S ) #S
+#define $line __FILE__ ":" $TO_STRING(__LINE__)
+#define $log( C, ... ) $v_string( _log_event( C, $line ), __VA_ARGS__ )
-struct stream *_log_event( enum log_event type, const c8 *text, const c8 *code_location );
-void _log_append_errno( struct stream *stream );
+struct stream *_log_event( u32 type, const c8 *code_location );
struct stream *_get_console_stream();
/* Keyvalues
-#include "common_api.h"
#include <stdlib.h>
void *_heap_allocate( u64 size )
{
void *buffer = malloc( size );
- if( !buffer ) _fatal_exit( "Out of heap memory (malloc)" );
+ if( !buffer )
+ {
+ $log( $fatal, {"Out of heap memory (malloc)"} );
+ _fatal_exit();
+ }
return buffer;
}
void *_heap_reallocate( void *buf, u64 size )
{
void *new_buffer = realloc( buf, size );
- if( !new_buffer ) _fatal_exit( "Out of heap memory (realloc)" );
+ if( !new_buffer )
+ {
+ $log( $fatal, {"Out of heap memory (malloc)"} );
+ _fatal_exit();
+ }
return new_buffer;
}
-#include "common_api.h"
-
void pool_init( struct pool_allocator *pool, struct pool_node *nodes, u16 node_count, struct pool_chain *full_chain )
{
pool->nodes = nodes;
-#include "common_api.h"
-
void stack_init( struct stack_allocator *stack, void *buffer, u32 capacity, const c8 *debug_name )
{
zero_buffer( stack, sizeof(struct stack_allocator) );
u32 new_usage = stack->offset + size + alignment;
if( new_usage > stack->capacity )
{
- struct stream *log = _log_event( k_log_error, "Stack @", __LINE_STRING__ );
- string_append_u64( log, (u64)stack, 16 );
- string_append( log, ", capacity: " );
- string_append_u64( log, stack->capacity, 10 );
- string_append( log, ", used: " );
- string_append_u64( log, stack->offset, 10 );
- string_append( log, ", new_usage: " );
- string_append_u64( log, new_usage, 10 );
- string_append( log, "\n" );
- _fatal_exit( "Stack allocator overflow" );
- // log( F"Stack @{here}, capacity: {stack->capacity}, used: {stack->used}, new_usage: {new_usage}" );
+ $log( $fatal, {"stack @0x"}, $unsigned( (u64)stack, .base=16 ),
+ {", capacity: "}, $unsigned( stack->capacity ),
+ {", used: "}, $unsigned( stack->offset ),
+ {", new: "}, $unsigned( new_usage ) );
+ _fatal_exit();
}
while( ((u64)stack->data + stack->offset) & (alignment-1) )
stack->offset ++;
-#include "common_api.h"
#define SMALL_SEGMENTS 1
-
void stretchy_init( struct stretchy_allocator *stretchy, u32 element_size )
{
stretchy->count = 0;
u32 c = 1;
for( u32 i=0; stretchy->count >= c; i ++ )
{
- struct stream *log = _log( k_log_info, "" );
- string_append_u64( log, i, 10 );
- string_append( log, " freed: " );
- string_append_u64( log, (u64)stretchy->segments[i], 16 );
- string_append( log, "\n" );
-
_heap_free( stretchy->segments[i] );
c += 1 << (SMALL_SEGMENTS + i);
stretchy->segments[i] = NULL;
-#include "common_api.h"
-
void zero_buffer( void *buffer, u32 length )
{
for( u32 i=0; i<length; i ++ )
-#include "common_api.h"
#include <signal.h>
#include <execinfo.h>
#include <stdio.h>
static void sync_signal_handler( i32 signum )
{
raise( SIGTRAP );
- if( signum == SIGSEGV ) _fatal_exit( "SIGSEGV" );
- if( signum == SIGBUS ) _fatal_exit( "SIGBUS" );
- if( signum == SIGFPE ) _fatal_exit( "SIGFPE" );
- if( signum == SIGILL ) _fatal_exit( "SIGILL" );
- _fatal_exit( "UNKNOWN SIGNAL" );
+ if( signum == SIGSEGV ) $log( $fatal, { "SIGSEGV" } );
+ if( signum == SIGBUS ) $log( $fatal, { "SIGBUS" } );
+ if( signum == SIGFPE ) $log( $fatal, { "SIGFPE" } );
+ if( signum == SIGILL ) $log( $fatal, { "SIGILL" } );
+ $log( $fatal, { "UNKNOWN SIGNAL" } );
+ _fatal_exit();
}
void _exit_init(void)
signal( SIGILL, sync_signal_handler );
}
-void _fatal_exit( const c8 *reason )
+void _fatal_exit(void)
{
fflush( stdout );
- write( STDOUT_FILENO, reason, strlen(reason) );
-
void *functions[20];
int count = backtrace( functions, 20 );
backtrace_symbols_fd( functions, count, STDOUT_FILENO );
exit(-1);
}
-void _normal_exit( const c8 *reason )
+void _normal_exit(void)
{
exit(0);
}
-#include "common_api.h"
#define _DEFAULT_SOURCE
#include <dirent.h>
#include <stdio.h>
-#include "common_api.h"
#include <string.h>
#define KV_PAGE_COUNT 32
-#include "common_api.h"
#include <stdio.h>
-#include <errno.h>
#include <string.h>
static struct stream _stdout_stream;
return &_stdout_stream;
}
-struct stream *_log_event( enum log_event type, const c8 *text, const c8 *code_location )
+struct stream *_log_event( u32 type, const c8 *code_location )
{
struct stream *output = _get_console_stream();
string_append( output, code_location );
- string_append( output, "|LOGGY| " );
- string_append( output, text );
- return output;
-}
+ while( output->offset < 20 ) string_append_c8( output, ' ' );
-void _log_append_errno( struct stream *stream )
-{
- string_append( stream, " Errno: " );
- string_append_u64( stream, errno, 10 );
- string_append( stream, " (" );
- string_append( stream, strerror(errno) );
- string_append( stream, ")\n" );
+ if( type == $error ) string_append( output, "ERR|" );
+ else if( type == $warning ) string_append( output, "WRN|" );
+ else if( type == $ok ) string_append( output, "OK |" );
+ else if( type == $info ) string_append( output, "LOG|" );
+ else if( type == $low ) string_append( output, "LOW|" );
+ else if( type == $fatal ) string_append( output, "!!!|" );
+ return output;
}
-#include "common_api.h"
#define MAX_OPTIONS 32
#define MAX_ARGUMENTS 32
string_append( console, desc );
string_append_c8( console, '\n' );
}
- _normal_exit( "Help page" );
+ _normal_exit();
}
bool errors = 0;
}
if( errors )
- _normal_exit( "Invalid argument" );
+ _normal_exit();
}
bool _option_flag( c8 c, const c8 *desc )
-#include "common_api.h"
#include <stdio.h>
#include <errno.h>
#include <string.h>
#if defined( VG_ENGINE )
if( !_thread_has_flags( ENGINE_THREAD_BACKGROUND ) )
{
- _log_event( k_log_warning,
- "Performance: I/O file stream opened in main thread. This will cause frame stalls!\n",
- __LINE_STRING__ );
+ $log( $warning, {"Performance: I/O file stream opened in main thread. This will cause frame stalls!"} )
}
#endif
stream->posix_stream = fopen( path, (flags & k_stream_write)? "wb": "rb" );
return 1;
else
{
- struct stream *log = _log_event( k_log_error, "Failure to open file stream ( ", __LINE_STRING__ );
- string_append_u64( log, errno, 10 );
- string_append( log, ": " );
- string_append( log, strerror(errno) );
- string_append( log, " )\n" );
+ $log( $error, {"Failure to open file stream "}, $errno() );
return 0;
}
}
{
if( ferror( stream->posix_stream ) )
{
- struct stream *log = _log_event( k_log_error, "FILE read error ( ", __LINE_STRING__ );
- string_append_u64( log, errno, 10 );
- string_append( log, ": " );
- string_append( log, strerror(errno) );
- string_append( log, " )\n" );
-
+ $log( $fatal, {"FILE read error "}, $errno() );
fclose( stream->posix_stream );
- _fatal_exit( "FILE stream read error" );
+ _fatal_exit();
}
else
{
+ $log( $fatal, {"FILE stream read error (no reason was given)"} );
fclose( stream->posix_stream );
- _fatal_exit( "FILE stream read error (no reason was given)" );
+ _fatal_exit();
}
}
}
{
if( ferror( stream->posix_stream ) )
{
- struct stream *log = _log_event( k_log_error, "FILE write error ( ", __LINE_STRING__ );
- string_append_u64( log, errno, 10 );
- string_append( log, ": " );
- string_append( log, strerror(errno) );
- string_append( log, " )\n" );
- fclose( stream->posix_stream );
- _fatal_exit( "FILE stream write error" );
+ $log( $fatal, {"FILE write error "}, $errno() );
+ _fatal_exit();
}
else
{
fclose( stream->posix_stream );
- _fatal_exit( "FILE stream write error (no reason was given)" );
+ $log( $fatal, {"FILE stream write error (no reason was given)"} );
+ _fatal_exit();
}
}
}
{
if( fseek( stream->posix_stream, offset, SEEK_SET ) == -1 )
{
- struct stream *log = _log_event( k_log_error, "FILE seek error ( ", __LINE_STRING__ );
- string_append_u64( log, errno, 10 );
- string_append( log, ": " );
- string_append( log, strerror(errno) );
- string_append( log, " )\n" );
+ $log( $fatal, {"File seek error "}, $errno() );
fclose( stream->posix_stream );
- _fatal_exit( "FILE stream seek error" );
+ _fatal_exit();
}
}
stream->offset = offset;
-#include "common_api.h"
+#include <errno.h>
+#include <string.h>
void string_init( struct stream *string, c8 *buffer, u32 buffer_length )
{
*value = (f64)sign * (int_part + decimal_part);
return (got||got_decimal)? info: k_string_parse_eof;
}
+
+void v_string( struct stream *string, struct v_string_arg *argument_list )
+{
+ for( u32 i=0; i<1000; i ++ )
+ {
+ struct v_string_arg *arg = &argument_list[i];
+ if( arg->type == k_$end )
+ break;
+ else if( arg->type == k_$unsigned )
+ string_append_u64( string, arg->_u64, arg->base? arg->base: 10 );
+ else if( arg->type == k_$signed )
+ string_append_i64( string, arg->_i64, arg->base? arg->base: 10 );
+ else if( arg->type == k_$float )
+ string_append_f64( string, arg->_f64, arg->base? arg->base: 10, arg->decimals? arg->decimals: 2 );
+ else if( arg->type == k_$string )
+ string_append( string, arg->_string );
+ else if( arg->type == k_$errno )
+ {
+ string_append( string, "<errno#" );
+ string_append_u64( string, errno, 10 );
+ string_append( string, " (" );
+ string_append( string, strerror(errno) );
+ string_append( string, ")>" );
+ }
+ }
+ string_append_c8( string, '\n' );
+}
+