Commit a56b467

kravantokh <kravantokh@noreply.codeberg.org>
2026-08-29 15:39:46
Add an alternative main function.
1 parent 61b200b
testing/tests/000_entry_exit.c
@@ -1,3 +1,4 @@
+#define NOTLIBC_NOMAIN
 #include "notlibc.c"
 
 void entry(void) {
testing/tests/001_main_test.c
@@ -0,0 +1,6 @@
+#include "notlibc.c"
+
+Status c_main( StrSlcs *args, StrSlcs *env ) {
+	(void)args; (void)env;
+	return S_SUCCESS;
+}
testing/tests/001_safemath.c → testing/tests/002_safemath.c
@@ -1,3 +1,4 @@
+#define NOTLIBC_NOMAIN
 #include "notlibc.c"
 
 #define N 12
testing/tests/002_round.c → testing/tests/003_round.c
@@ -1,3 +1,4 @@
+#define NOTLIBC_NOMAIN
 #include "notlibc.c"
 
 #define N 13
testing/tests/012_mem_basic.c
@@ -1,3 +1,4 @@
+#define NOTLIBC_NOMAIN
 #include "notlibc.c"
 
 #define PAGECOUNT 2
testing/tests/013_arena_basic.c
@@ -1,3 +1,4 @@
+#define NOTLIBC_NOMAIN
 #include "notlibc.c"
 
 Arena a = {0};
testing/tests/014_heap.c
@@ -1,3 +1,4 @@
+#define NOTLIBC_NOMAIN
 #include "notlibc.c"
 
 void entry(void) {
testing/tests/015_array_basic.c
@@ -1,3 +1,4 @@
+#define NOTLIBC_NOMAIN
 #include "notlibc.c"
 
 void entry(void) {
testing/tests/016_strings_and_slices.c
@@ -1,3 +1,4 @@
+#define NOTLIBC_NOMAIN
 #include "notlibc.c"
 
 void entry(void) {
@@ -50,15 +51,16 @@ void entry(void) {
 
 	assert( S_OK( StrAsm_reset( &sa ) ) );
 
+	StrSlc slc = {0};
+
 	STRING( numbers_hex, "0xfe" "0xffff" "0xffffffff" "0xffffffffffffffff" );
 	assert( S_OK( StrAsm_fmtx_u8( &sa, 0xfe ) ) );
 	assert( S_OK( StrAsm_fmtx_u16( &sa, 0xffff ) ) );
 	assert( S_OK( StrAsm_fmtx_u32( &sa, 0xffffffff) ) );
 	assert( S_OK( StrAsm_fmtx_u64( &sa, 0xffffffffffffffff ) ) );
 
-	assert( S_OK( StrAsm_store_onto_heap( &sa, &h, &s_h ) ) );
-	assert( Str_equals( s_h, (const Str*)&numbers_hex ) == 1 );
-	Heap_free( &h, (void**)&s_h );
+	slc = StrAsm_as_StrSlc( &sa );
+	assert( StrSlc_equals_Str( slc, (const Str*)&numbers_hex ) == 1 );
 
 	assert( S_OK( StrAsm_reset( &sa ) ) );
 
@@ -68,9 +70,8 @@ void entry(void) {
 	assert( S_OK( StrAsm_fmtd_u32( &sa, 4294967295) ) );
 	assert( S_OK( StrAsm_fmtd_u64( &sa, 18446744073709551615u ) ) );
 
-	assert( S_OK( StrAsm_store_onto_heap( &sa, &h, &s_h ) ) );
-	assert( Str_equals( s_h, (const Str*)&numbers_dec ) == 1 );
-	Heap_free( &h, (void**)&s_h );
+	slc = StrAsm_as_StrSlc( &sa );
+	assert( StrSlc_equals_Str( slc, (const Str*)&numbers_dec ) == 1 );
 
 	assert( S_OK( StrAsm_reset( &sa ) ) );
 
@@ -80,9 +81,8 @@ void entry(void) {
 	assert( S_OK( StrAsm_fmtd_s32( &sa, -2147483648 ) ) );
 	assert( S_OK( StrAsm_fmtd_s64( &sa, -9223372036854775807LL - 1 ) ) );
 
-	assert( S_OK( StrAsm_store_onto_heap( &sa, &h, &s_h ) ) );
-	assert( Str_equals( s_h, (const Str*)&numbers_dec_s ) == 1 );
-	Heap_free( &h, (void**)&s_h );
+	slc = StrAsm_as_StrSlc( &sa );
+	assert( StrSlc_equals_Str( slc, (const Str*)&numbers_dec_s ) == 1 );
 
 	assert( S_OK( StrAsm_destroy( &sa ) ));
 	assert( S_OK( Arena_destroy( &a ) ));
testing/tests/020_file_basic.c
@@ -1,3 +1,4 @@
+#define NOTLIBC_NOMAIN
 #include "notlibc.c"
 
 void test_existing_open_missing_create(void);
testing/tests/021_fileview.c
@@ -1,3 +1,4 @@
+#define NOTLIBC_NOMAIN
 #include "notlibc.c"
 
 void entry(void) {
notlibc.c
@@ -43,7 +43,7 @@ void *memcpy( void *dest, const void *src, unsigned long n ) {
 	}
 
 	Status Arena_destroy( Arena *a ) {
-		TRY( mem_relinquish( a->start, a->claimed ) );
+		TRY( mem_relinquish( a->start, a->claimed/sizeof(Page) ) );
 
 		mem_set( a, sizeof(*a), 0 );
 		return S_SUCCESS;
@@ -735,6 +735,11 @@ Status StrAsm_store_onto_heap( StrAsm *sa, Heap *dst, Str **out ) {
 	return S_SUCCESS;
 }
 
+StrSlc StrAsm_as_StrSlc( const StrAsm *sa ) {
+	return (StrSlc){ .len = sa->a.taken, .data = (u8*)sa->a.start };
+}
+
+
 Status StrAsm_cat_char ( StrAsm *sa, u8 value ) {
 	u8 *data = 0;
 	TRY( Arena_take( &sa->a, sizeof(value), &data ) );
@@ -917,6 +922,91 @@ Status StrAsm_fmtd_s64( StrAsm *sa, s64 value) {
 #endif
 
 
+
+usize c_strlen( const u8* str ) {
+	usize res = 0;
+	while( str[res] )
+		res++;
+	return res;
+}
+
+Status _linux_get_args_and_env( Heap *h, StrSlcs **args, StrSlcs **env ) {
+
+	usize *it = (usize*)_linux_startup_sp;
+	usize argc = *it;
+
+	/* start with args */
+	it++;
+
+	*args = 0;
+	*env = 0;
+
+	TRY( StrSlcs_create( h, argc, args ) );
+
+	for( usize i = 0; i < (*args)->len; ++i ) {
+		(*args)->data[i] = (StrSlc){
+			.data = (u8*)*(it + i),
+			.len = c_strlen( (u8*)*(it + i) ),
+		};
+	}
+
+	it += argc;
+	if( *it != 0 ) {
+		DEBUG( breakpoint(); );
+		return S_FAILURE | ERR_GENERIC | ERRSRC_PLATFORM;
+	}
+
+	/* env */
+	it++;
+	usize *envptrs = it;
+
+	while( *it != 0 ) {
+		it++;
+	}
+
+	usize envc = it - envptrs;
+	TRY( StrSlcs_create( h, envc, env) );
+
+	for( usize i = 0; i < (*env)->len; ++i ) {
+		(*env)->data[i] = (StrSlc){
+			.data = (u8*)*(envptrs + i),
+			.len = c_strlen( (u8*)*(envptrs + i) ),
+		};
+	}
+
+	return S_SUCCESS;
+}
+
+#ifndef NOTLIBC_NOMAIN
+	Heap _linux_heap = {0};
+
+	void entry(void) {
+		StrSlcs *args = 0;
+		StrSlcs *env = 0;
+
+		if(!S_OK( Heap_create( &_linux_heap, KiB(16) ) )) {
+			DEBUG( breakpoint(); );
+			terminate(2);
+		}
+
+		_linux_get_args_and_env( &_linux_heap, &args, &env );
+
+		Status res = c_main( args, env );
+
+		if(!S_OK( Heap_destroy( &_linux_heap ) )) {
+			DEBUG( breakpoint(); );
+			terminate(2);
+		}
+
+		if( !S_OK(res) ) {
+			terminate(res);
+		}
+
+		terminate(0);
+		UNREACHABLE;
+	}
+#endif
+
 /*=============================== Memory =====================================*/
 
 Status mem_claim( u32 page_count, Page **ptr_out) {
notlibc.h
@@ -1272,11 +1272,16 @@ STRUCT( Str,
 	u8 data[];
 );
 
+GEN_POINTER_TYPE( Str );
+GEN_ARRAY_TYPE( Strp )
+
 STRUCT( StrSlc,
 	usize len;
 	const u8 *data;
 );
 
+GEN_ARRAY_TYPE( StrSlc )
+
 /* On typical platforms that already have/need nul-termination we keep the
  * nul-termination alongside the explicit length notation.
  * Hacky, but no one wants to copy strings/paths for syscalls.
@@ -1331,6 +1336,7 @@ Status StrAsm_destroy( StrAsm *out );
 
 Status StrAsm_store_into_arena( StrAsm *sa, Arena *dst, Str **out );
 Status StrAsm_store_onto_heap( StrAsm *sa, Heap *dst, Str **out );
+StrSlc StrAsm_as_StrSlc( const StrAsm *sa );
 
 /* String, character */
 Status StrAsm_cat_char ( StrAsm *sa, u8 value );
@@ -1571,9 +1577,14 @@ static inline Status File_open_validate_flags( usize flags, Status err_source )
 
 /*============================= Entrypoint ===================================*/
 
-extern u8* linux_startup_sp;
+extern u8* _linux_startup_sp;
 void entry(void);
 
+#ifndef NOTLIBC_NOMAIN
+	extern Heap _linux_heap;
+	extern Status c_main( StrSlcs *args, StrSlcs *env );
+#endif
+
 /*============================ Linux defines =================================*/
 
 #define LINUX_SYSCALL_ERROR_RANGE_START ((usize)-4095)