Fix Windows build and several cross-platform bugs

Cross-platform bugs:

- ncomplib.c: fseek was called as fseek(f, whence, offset) instead of
  fseek(f, offset, whence). Seeks only worked correctly when offset
  happened to numerically equal a valid whence constant.

- neonucleus.c: nn_realloc passed memory pointer instead of ctx to
  nn_alloc in the NULL and sentinel paths. Any call with memory=NULL
  dereferences NULL as a context struct and crashes. Confirmed by
  test_realloc.c which crashes before fix and passes after.

- neonucleus.h: NN_TiB was defined as (1024 * NN_TiB), referencing
  itself. Fixed to ((size_t)1024 * NN_GiB).

- luaarch.c: unicode functions were registered on the component Lua
  table instead of the unicode table. Wrong stack index variable was
  used in all five lua_setfield calls.

- neonucleus.c: NN_ATOMIC_NONE versions of nn_incRef/nn_decRef took
  1 argument but were called with 2 everywhere. Added the missing
  size_t n parameter.

Windows build:

- neonucleus.c: NN_LOCK_CREATE in NN_THREAD_WINDOWS was missing a
  return statement, falling through into NN_LOCK_DESTROY and
  immediately closing the freshly created mutex handle.

- ncomplib.c: Added Windows implementations for opendir, readdir,
  closedir, stat, mkdir and directory removal using FindFirstFileA,
  FindNextFileA, _stat, _mkdir and _rmdir.

- main.c: Fall back to USERNAME env var when USER is not set.

- neonucleus.h: Added NN_VLA macro. Expands to a plain VLA on
  GCC/Clang, uses _alloca on MSVC. Applied in luaarch.c and
  neonucleus.c where VLAs were used.

- neonucleus.h: Added NN_INIT macro. Expands to a compound literal
  cast on GCC/Clang, expands to nothing on MSVC which does not
  support compound literals as constant initializers at file scope.
  Applied to all global struct initializers in neonucleus.c.

- neonucleus.c: Auto-define NN_ATOMIC_NONE on MSVC in C mode since
  MSVC does not provide stdatomic.h outside of C++ mode.
This commit is contained in:
shorekeeper
2026-04-01 19:18:00 +03:00
parent 3f6ef63737
commit 8d37628ae7
8 changed files with 418 additions and 46 deletions

View File

@@ -9,21 +9,43 @@ extern "C" {
// Used internally as well.
// Based off https://stackoverflow.com/questions/5919996/how-to-detect-reliably-mac-os-x-ios-linux-windows-in-c-preprocessor
#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__NT__)
//define something for Windows (32-bit and 64-bit, this part is common)
#ifndef NN_WINDOWS
#define NN_WINDOWS
#endif
#elif __APPLE__
#ifndef NN_MACOS
#define NN_MACOS
#endif
#elif __linux__
#ifndef NN_LINUX
#define NN_LINUX
#endif
#endif
#if __unix__ // all unices not caught above
// Unix
#if __unix__
#ifndef NN_UNIX
#define NN_UNIX
#endif
#ifndef NN_POSIX
#define NN_POSIX
#endif
#elif defined(_POSIX_VERSION)
// POSIX
#ifndef NN_POSIX
#define NN_POSIX
#endif
#endif
#if defined(_MSC_VER) && !defined(__cplusplus)
#ifndef NN_ATOMIC_NONE
#define NN_ATOMIC_NONE
#endif
#endif
#ifdef _MSC_VER
#define NN_INIT(type)
#else
#define NN_INIT(type) (type)
#endif
// every C standard header we depend on, conveniently put here
@@ -31,6 +53,19 @@ extern "C" {
#include <stdint.h> // for intptr_t
#include <stdbool.h> // for true, false and bool
/* MSVC can't use VLA;
* What we see : NN_VLA(const char *, comps, len);
* What compiler see after preproccessor : const char * comps[len];
* What actaully was : const char *comps[len];
*/
// Test: gcc -E -DNN_VLA\(type,name,count\)="type name[count]" -x c - <<< 'NN_VLA(const char *, comps, len);'
#ifdef _MSC_VER
#include <malloc.h>
#define NN_VLA(type, name, count) type *name = (type *)_alloca(sizeof(type) * (count))
#else
#define NN_VLA(type, name, count) type name[count]
#endif
// Internally we need stdatomic.h and, if NN_BAREMETAL is not defined, stdlib.h and time.h
// The entire NeoNucleus API, in one header file
@@ -40,7 +75,8 @@ extern "C" {
#define NN_KiB (1024)
#define NN_MiB (1024 * NN_KiB)
#define NN_GiB (1024 * NN_MiB)
#define NN_TiB (1024 * NN_TiB)
// probably recursive: #define NN_TiB (1024 * NN_TiB)
#define NN_TiB ((size_t)1024 * NN_GiB)
// the alignment an allocation should have
#define NN_ALLOC_ALIGN 16