Fix the type, macro and state-table defects, and the leftover debris

Closes internal-consistency items 19 through 36, 38 and 41. Item 37, the ~180
redundant casts, is deliberately left open with its reasoning in TODO.md: the
benefit only arrives once the build turns on the warnings those casts suppress,
and doing it before that is churn across the two files with the most
outstanding functional defects.

The two that were real bugs are in the actor state table.
AKGL_ACTOR_STATE_STRING_NAMES was declared [AKGL_ACTOR_MAX_STATES+1] and
defined [32], so a consumer trusting the declared bound read past the object;
and indices 11 and 12 were named UNDEFINED_11 and UNDEFINED_12 where actor.h
has MOVING_IN and MOVING_OUT, so no character JSON could bind a sprite to
either state. tests/registry.c now walks the whole table -- every entry
non-NULL, every entry resolving to its own bit, no two entries sharing a name.

The bitmask macros are parenthesized and AKGL_BITMASK_CLEAR has lost the
semicolon inside its body. Writing tests/bitmasks.c for that turned up
something worth knowing: the obvious test does not catch it. For a bit that is
set, the misparse `!(mask & bit) == bit` gives the same answer as the correct
one. It only diverges for an unset bit whose value is not 1, and that is the
shape the suite uses now.

akgl_draw_background was the last public function outside the error protocol.
It takes a backend like everything else in draw.h, restores the draw colour it
found, and is tested -- TODO.md had it filed under "needs the offscreen
renderer harness", which was never true; what it needed was to stop reading the
global.

All eight registry initializers go through one helper, so the seven that leaked
an SDL_PropertiesID on every call after the first no longer do. Fixed in the
same place because it is the same function: akgl_registry_init never called
akgl_registry_init_properties, which made akgl_set_property a silent no-op for
anyone not going through akgl_game_init -- Defects, Known and still open item 3.

Also: AKGL_COLLIDE_RECTANGLES (three open parens, two closes) and akgl_Frame
deleted, float32_t/float64_t used consistently, the developer-specific debug
logging removed from the controller inner loop, the abandoned SDL_GetBasePath
comments removed, nine unused locals removed, and dst renamed to dest.

akgl_game_update's default flags no longer OR the same bit twice. That changes
nothing today, and the reason is Performance item 32: the loop never reads
either bit, which is why every actor is updated sixteen times a frame. Still
open.

25/25 pass, memcheck clean, reindent --check clean.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-08-01 00:15:36 -04:00
parent a60220d39b
commit 19530f6a97
28 changed files with 735 additions and 398 deletions

View File

@@ -1,39 +1,59 @@
/**
* @file actor_state_string_names.c
* @brief Implements the actor state string names subsystem.
* @brief Bit position -> state name, as text. Maintained by hand.
*
* An earlier comment in `actor.h` said this file was "built by a utility script
* and not kept in git, see the Makefile for lib_src/actor_state_string_names.c".
* None of that is true: there is no Makefile (the project is CMake), no
* `lib_src/`, no such script under `scripts/` or `util/`, and this file is
* tracked. It is maintained by hand, and the two things that keeps costing are
* worth stating here rather than rediscovering.
*
* **Entry `i` must name the bit `1 << i` in `actor.h`.** Bits 11 and 12 read
* `UNDEFINED_11` and `UNDEFINED_12` here for as long as `actor.h` has called
* them `MOVING_IN` and `MOVING_OUT`, which meant a character JSON could not
* bind a sprite to either state -- the name it would have to write did not
* exist in the registry akgl_registry_init_actor_state_strings builds out of
* this array.
*
* **The array is sized by #AKGL_ACTOR_MAX_STATES**, not by a literal. It was
* `[32]` here against `[AKGL_ACTOR_MAX_STATES+1]` in the header, so a consumer
* trusting the declared bound read one entry past the object.
*/
char *AKGL_ACTOR_STATE_STRING_NAMES[32] = {
"AKGL_ACTOR_STATE_FACE_DOWN",
"AKGL_ACTOR_STATE_FACE_LEFT",
"AKGL_ACTOR_STATE_FACE_RIGHT",
"AKGL_ACTOR_STATE_FACE_UP",
"AKGL_ACTOR_STATE_ALIVE",
"AKGL_ACTOR_STATE_DYING",
"AKGL_ACTOR_STATE_DEAD",
"AKGL_ACTOR_STATE_MOVING_LEFT",
"AKGL_ACTOR_STATE_MOVING_RIGHT",
"AKGL_ACTOR_STATE_MOVING_UP",
"AKGL_ACTOR_STATE_MOVING_DOWN",
"AKGL_ACTOR_STATE_UNDEFINED_11",
"AKGL_ACTOR_STATE_UNDEFINED_12",
"AKGL_ACTOR_STATE_UNDEFINED_13",
"AKGL_ACTOR_STATE_UNDEFINED_14",
"AKGL_ACTOR_STATE_UNDEFINED_15",
"AKGL_ACTOR_STATE_UNDEFINED_16",
"AKGL_ACTOR_STATE_UNDEFINED_17",
"AKGL_ACTOR_STATE_UNDEFINED_18",
"AKGL_ACTOR_STATE_UNDEFINED_19",
"AKGL_ACTOR_STATE_UNDEFINED_20",
"AKGL_ACTOR_STATE_UNDEFINED_21",
"AKGL_ACTOR_STATE_UNDEFINED_22",
"AKGL_ACTOR_STATE_UNDEFINED_23",
"AKGL_ACTOR_STATE_UNDEFINED_24",
"AKGL_ACTOR_STATE_UNDEFINED_25",
"AKGL_ACTOR_STATE_UNDEFINED_26",
"AKGL_ACTOR_STATE_UNDEFINED_27",
"AKGL_ACTOR_STATE_UNDEFINED_28",
"AKGL_ACTOR_STATE_UNDEFINED_29",
"AKGL_ACTOR_STATE_UNDEFINED_30",
"AKGL_ACTOR_STATE_UNDEFINED_31",
#include <akgl/actor.h>
char *AKGL_ACTOR_STATE_STRING_NAMES[AKGL_ACTOR_MAX_STATES] = {
"AKGL_ACTOR_STATE_FACE_DOWN", // 1 << 0
"AKGL_ACTOR_STATE_FACE_LEFT", // 1 << 1
"AKGL_ACTOR_STATE_FACE_RIGHT", // 1 << 2
"AKGL_ACTOR_STATE_FACE_UP", // 1 << 3
"AKGL_ACTOR_STATE_ALIVE", // 1 << 4
"AKGL_ACTOR_STATE_DYING", // 1 << 5
"AKGL_ACTOR_STATE_DEAD", // 1 << 6
"AKGL_ACTOR_STATE_MOVING_LEFT", // 1 << 7
"AKGL_ACTOR_STATE_MOVING_RIGHT", // 1 << 8
"AKGL_ACTOR_STATE_MOVING_UP", // 1 << 9
"AKGL_ACTOR_STATE_MOVING_DOWN", // 1 << 10
"AKGL_ACTOR_STATE_MOVING_IN", // 1 << 11
"AKGL_ACTOR_STATE_MOVING_OUT", // 1 << 12
"AKGL_ACTOR_STATE_UNDEFINED_13", // 1 << 13
"AKGL_ACTOR_STATE_UNDEFINED_14", // 1 << 14
"AKGL_ACTOR_STATE_UNDEFINED_15", // 1 << 15
"AKGL_ACTOR_STATE_UNDEFINED_16", // 1 << 16
"AKGL_ACTOR_STATE_UNDEFINED_17", // 1 << 17
"AKGL_ACTOR_STATE_UNDEFINED_18", // 1 << 18
"AKGL_ACTOR_STATE_UNDEFINED_19", // 1 << 19
"AKGL_ACTOR_STATE_UNDEFINED_20", // 1 << 20
"AKGL_ACTOR_STATE_UNDEFINED_21", // 1 << 21
"AKGL_ACTOR_STATE_UNDEFINED_22", // 1 << 22
"AKGL_ACTOR_STATE_UNDEFINED_23", // 1 << 23
"AKGL_ACTOR_STATE_UNDEFINED_24", // 1 << 24
"AKGL_ACTOR_STATE_UNDEFINED_25", // 1 << 25
"AKGL_ACTOR_STATE_UNDEFINED_26", // 1 << 26
"AKGL_ACTOR_STATE_UNDEFINED_27", // 1 << 27
"AKGL_ACTOR_STATE_UNDEFINED_28", // 1 << 28
"AKGL_ACTOR_STATE_UNDEFINED_29", // 1 << 29
"AKGL_ACTOR_STATE_UNDEFINED_30", // 1 << 30
"AKGL_ACTOR_STATE_UNDEFINED_31", // 1 << 31
};

View File

@@ -24,7 +24,6 @@ akerr_ErrorContext *akgl_load_start_bgm(char *fname)
//CATCH(errctx, akgl_heap_next_string(&tmpstr));
//CATCH(errctx, akgl_string_initialize(tmpstr, NULL));
//SDL_snprintf((char *)&tmpstr->data, AKGL_MAX_STRING_LENGTH, "%s%s", SDL_GetBasePath(), fname);
SDL_Log("Loading music asset from %s", fname);
akgl_bgm = MIX_LoadAudio(akgl_mixer, fname, true);
FAIL_ZERO_BREAK(errctx, akgl_bgm, AKERR_NULLPOINTER, "Failed to load music asset %s : %s", fname, SDL_GetError());

View File

@@ -56,7 +56,6 @@ akerr_ErrorContext *akgl_character_sprite_add(akgl_Character *basechar, akgl_Spr
akerr_ErrorContext *akgl_character_sprite_get(akgl_Character *basechar, int state, akgl_Sprite **dest)
{
akgl_Sprite *target = NULL;
PREPARE_ERROR(errctx);
char stateval[32];
FAIL_ZERO_RETURN(errctx, dest, AKERR_NULLPOINTER, "NULL pointer to sprite pointer (**dest)");
@@ -65,8 +64,6 @@ akerr_ErrorContext *akgl_character_sprite_get(akgl_Character *basechar, int stat
SDL_itoa(state, (char *)&stateval, 10);
*dest = (akgl_Sprite *)SDL_GetPointerProperty(basechar->state_sprites, (char *)&stateval, NULL);
FAIL_ZERO_RETURN(errctx, *dest, AKERR_KEY, "Sprite for state %d (%b) not found in the character's registry", state, state);
target = *dest;
//SDL_Log("Sprite state %d (%s) has character %s", state, (char *)&stateval, target->name);
SUCCEED_RETURN(errctx);
}
@@ -228,7 +225,6 @@ akerr_ErrorContext *akgl_character_load_json(char *filename)
CATCH(errctx, akgl_heap_next_character(&obj));
//CATCH(errctx, akgl_heap_next_string(&tmpstr));
//CATCH(errctx, akgl_string_initialize(tmpstr, NULL));
//SDL_snprintf((char *)&tmpstr->data, AKGL_MAX_STRING_LENGTH, "%s%s", SDL_GetBasePath(), filename);
json = (json_t *)json_load_file(filename, 0, &error);
FAIL_ZERO_BREAK(
errctx,

View File

@@ -279,13 +279,6 @@ akerr_ErrorContext *akgl_controller_handle_event(void *appstate, SDL_Event *even
event->key.which == curmap->kbid &&
event->key.key == curcontrol->key)
);
if ( event->type == 768 && event->key.which == 11 && event->key.key == 13 ) {
SDL_Log("Event type=%d, keyboard=%d, key=%d", event->type, event->key.which, event->key.key);
SDL_Log("ControlMap[%d].Controls[%d] keyboard=%d, key=%d", i, j, curmap->kbid, curcontrol->key);
SDL_Log("event %d -> control on %d off %d", event->type, curcontrol->event_on, curcontrol->event_off);
SDL_Log("eventButtonComboMatch for controlmap %d id %d = %d",
i, j, eventButtonComboMatch);
}
if ( event->type == curcontrol->event_on && eventButtonComboMatch) {
CATCH(errctx, curcontrol->handler_on(curmap->target, event));
goto _akgl_controller_handle_event_success;

View File

@@ -28,32 +28,6 @@ typedef struct {
*/
static FloodSpan floodspans[AKGL_DRAW_MAX_FLOOD_SPANS];
/* Draw a Gimpish background pattern to show transparency in the image */
void akgl_draw_background(int w, int h)
{
SDL_Color col[2] = {
{ 0x66, 0x66, 0x66, 0xff },
{ 0x99, 0x99, 0x99, 0xff },
};
int i, x, y;
SDL_FRect rect;
const int dx = 8, dy = 8;
rect.w = (float)dx;
rect.h = (float)dy;
for (y = 0; y < h; y += dy) {
for (x = 0; x < w; x += dx) {
/* use an 8x8 checkerboard pattern */
i = (((x ^ y) >> 3) & 1);
SDL_SetRenderDrawColor(akgl_renderer->sdl_renderer, col[i].r, col[i].g, col[i].b, col[i].a);
rect.x = (float)x;
rect.y = (float)y;
SDL_RenderFillRect(akgl_renderer->sdl_renderer, &rect);
}
}
}
/**
* @brief Remember the renderer's draw color and replace it with @p color.
*
@@ -116,6 +90,63 @@ static akerr_ErrorContext *pop_draw_color(akgl_RenderBackend *self, SDL_Color *p
SUCCEED_RETURN(errctx);
}
/* Draw a Gimpish background pattern to show transparency in the image */
akerr_ErrorContext *akgl_draw_background(akgl_RenderBackend *self, int w, int h)
{
PREPARE_ERROR(errctx);
SDL_Color col[2] = {
{ 0x66, 0x66, 0x66, 0xff },
{ 0x99, 0x99, 0x99, 0xff },
};
SDL_Color previous;
SDL_FRect rect;
const int dx = 8, dy = 8;
bool pushed = false;
bool drawfailed = false;
int i = 0;
int x = 0;
int y = 0;
FAIL_ZERO_RETURN(errctx, self, AKERR_NULLPOINTER, "self");
FAIL_ZERO_RETURN(errctx, self->sdl_renderer, AKERR_NULLPOINTER, "No valid SDL rendering backend");
rect.w = (float)dx;
rect.h = (float)dy;
ATTEMPT {
CATCH(errctx, push_draw_color(self, col[0], &previous));
pushed = true;
// The two SDL calls are checked through a flag rather than with
// FAIL_ZERO_BREAK. Inside these loops a `break` would leave the loop,
// not the ATTEMPT block, and the fill would carry on with the failure
// unnoticed -- the hazard AGENTS.md describes for CATCH inside a loop.
for ( y = 0; (y < h) && (drawfailed == false); y += dy ) {
for ( x = 0; x < w; x += dx ) {
/* use an 8x8 checkerboard pattern */
i = (((x ^ y) >> 3) & 1);
if ( SDL_SetRenderDrawColor(self->sdl_renderer, col[i].r, col[i].g, col[i].b, col[i].a) == false ) {
drawfailed = true;
break;
}
rect.x = (float)x;
rect.y = (float)y;
if ( SDL_RenderFillRect(self->sdl_renderer, &rect) == false ) {
drawfailed = true;
break;
}
}
}
FAIL_NONZERO_BREAK(errctx, drawfailed, AKGL_ERR_SDL, "%s", SDL_GetError());
} CLEANUP {
if ( pushed == true ) {
IGNORE(pop_draw_color(self, &previous));
}
} PROCESS(errctx) {
} FINISH(errctx, true);
SUCCEED_RETURN(errctx);
}
/**
* @brief Fill the four-connected region of @p oldpixel around a seed pixel.
*

View File

@@ -131,9 +131,6 @@ void akgl_game_lowfps(void)
akerr_ErrorContext *akgl_game_init(void)
{
int screenwidth = 0;
int screenheight = 0;
int i = 0;
PREPARE_ERROR(errctx);
// First, before anything that can raise: everything below reports through
@@ -639,10 +636,13 @@ akerr_ErrorContext *akgl_game_update(akgl_Iterator *opflags)
{
PREPARE_ERROR(errctx);
akgl_Iterator defflags = {
.flags = (AKGL_ITERATOR_OP_LAYERMASK | AKGL_ITERATOR_OP_LAYERMASK),
// Was (LAYERMASK | LAYERMASK). Nothing in the loop below reads either
// bit today, so this is a statement of intent rather than a behaviour
// change -- and the reason the loop ignores LAYERMASK is TODO.md
// Performance item 32, which is still open.
.flags = (AKGL_ITERATOR_OP_UPDATE | AKGL_ITERATOR_OP_LAYERMASK),
.layerid = 0
};
SDL_Time curTime = SDL_GetTicksNS();
akgl_Actor *actor = NULL;
if ( opflags == NULL ) {

View File

@@ -52,7 +52,7 @@ akerr_ErrorContext *akgl_get_json_integer_value(json_t *obj, char *key, int *des
SUCCEED_RETURN(errctx);
}
akerr_ErrorContext *akgl_get_json_number_value(json_t *obj, char *key, float *dest)
akerr_ErrorContext *akgl_get_json_number_value(json_t *obj, char *key, float32_t *dest)
{
PREPARE_ERROR(errctx);
FAIL_ZERO_RETURN(errctx, obj, AKERR_NULLPOINTER, "NULL pointer reference");
@@ -65,7 +65,7 @@ akerr_ErrorContext *akgl_get_json_number_value(json_t *obj, char *key, float *de
SUCCEED_RETURN(errctx);
}
akerr_ErrorContext *akgl_get_json_double_value(json_t *obj, char *key, double *dest)
akerr_ErrorContext *akgl_get_json_double_value(json_t *obj, char *key, float64_t *dest)
{
PREPARE_ERROR(errctx);
FAIL_ZERO_RETURN(errctx, obj, AKERR_NULLPOINTER, "NULL pointer reference");

View File

@@ -25,6 +25,34 @@ SDL_PropertiesID AKGL_REGISTRY_MUSIC = 0;
SDL_PropertiesID AKGL_REGISTRY_FONT = 0;
SDL_PropertiesID AKGL_REGISTRY_PROPERTIES = 0;
/**
* @brief Create one registry, replacing whatever set was held under it.
*
* All eight initializers go through this so they behave the same way on a
* second call. Only akgl_registry_init_actor used to destroy the old set --
* akgl_heap_init_actor's counterpart, so resetting actors between levels was
* the one path that did not leak -- and the other seven abandoned their
* SDL_PropertiesID every time they were called again.
*
* @param dest The registry handle to (re)create. Required.
* @param what What it holds, for the failure message. Required.
* @return `NULL` on success, otherwise an error context owned by the caller.
* @throws AKERR_NULLPOINTER If @p dest is `NULL`, or if SDL cannot create the
* property set.
*/
static akerr_ErrorContext *registry_create(SDL_PropertiesID *dest, const char *what)
{
PREPARE_ERROR(errctx);
FAIL_ZERO_RETURN(errctx, dest, AKERR_NULLPOINTER, "dest");
if ( *dest != 0 ) {
SDL_DestroyProperties(*dest);
*dest = 0;
}
*dest = SDL_CreateProperties();
FAIL_ZERO_RETURN(errctx, *dest, AKERR_NULLPOINTER, "Error initializing %s registry", what);
SUCCEED_RETURN(errctx);
}
akerr_ErrorContext *akgl_registry_init(void)
{
PREPARE_ERROR(errctx);
@@ -36,6 +64,12 @@ akerr_ErrorContext *akgl_registry_init(void)
CATCH(errctx, akgl_registry_init_actor_state_strings());
CATCH(errctx, akgl_registry_init_font());
CATCH(errctx, akgl_registry_init_music());
// Missing until 0.5.0. Without it AKGL_REGISTRY_PROPERTIES stayed 0,
// akgl_set_property was a silent no-op, akgl_get_property always
// returned the caller's default, and akgl_physics_init_arcade and
// akgl_render_2d_init quietly ignored their configuration. Only callers
// going through akgl_game_init, which calls it separately, escaped that.
CATCH(errctx, akgl_registry_init_properties());
} CLEANUP {
} PROCESS(errctx) {
} FINISH(errctx, true);
@@ -45,35 +79,28 @@ akerr_ErrorContext *akgl_registry_init(void)
akerr_ErrorContext *akgl_registry_init_actor(void)
{
PREPARE_ERROR(errctx);
if ( AKGL_REGISTRY_ACTOR != 0 ) {
SDL_DestroyProperties(AKGL_REGISTRY_ACTOR);
}
AKGL_REGISTRY_ACTOR = SDL_CreateProperties();
FAIL_ZERO_RETURN(errctx, AKGL_REGISTRY_ACTOR, AKERR_NULLPOINTER, "Error initializing actor registry");
PASS(errctx, registry_create(&AKGL_REGISTRY_ACTOR, "actor"));
SUCCEED_RETURN(errctx);
}
akerr_ErrorContext *akgl_registry_init_font(void)
{
PREPARE_ERROR(errctx);
AKGL_REGISTRY_FONT = SDL_CreateProperties();
FAIL_ZERO_RETURN(errctx, AKGL_REGISTRY_FONT, AKERR_NULLPOINTER, "Error initializing font registry");
PASS(errctx, registry_create(&AKGL_REGISTRY_FONT, "font"));
SUCCEED_RETURN(errctx);
}
akerr_ErrorContext *akgl_registry_init_music(void)
{
PREPARE_ERROR(errctx);
AKGL_REGISTRY_MUSIC = SDL_CreateProperties();
FAIL_ZERO_RETURN(errctx, AKGL_REGISTRY_MUSIC, AKERR_NULLPOINTER, "Error initializing music registry");
PASS(errctx, registry_create(&AKGL_REGISTRY_MUSIC, "music"));
SUCCEED_RETURN(errctx);
}
akerr_ErrorContext *akgl_registry_init_properties(void)
{
PREPARE_ERROR(errctx);
AKGL_REGISTRY_PROPERTIES = SDL_CreateProperties();
FAIL_ZERO_RETURN(errctx, AKGL_REGISTRY_PROPERTIES, AKERR_NULLPOINTER, "Error initializing properties registry");
PASS(errctx, registry_create(&AKGL_REGISTRY_PROPERTIES, "properties"));
SUCCEED_RETURN(errctx);
}
@@ -82,8 +109,7 @@ akerr_ErrorContext *akgl_registry_init_actor_state_strings(void)
int i = 0;
int flag = 0;
PREPARE_ERROR(errctx);
AKGL_REGISTRY_ACTOR_STATE_STRINGS = SDL_CreateProperties();
FAIL_ZERO_RETURN(errctx, AKGL_REGISTRY_ACTOR_STATE_STRINGS, AKERR_NULLPOINTER, "Error initializing actor state strings registry");
PASS(errctx, registry_create(&AKGL_REGISTRY_ACTOR_STATE_STRINGS, "actor state strings"));
for ( i = 0 ; i < AKGL_ACTOR_MAX_STATES; i++ ) {
flag = (1 << i);
SDL_SetNumberProperty(
@@ -97,24 +123,21 @@ akerr_ErrorContext *akgl_registry_init_actor_state_strings(void)
akerr_ErrorContext *akgl_registry_init_sprite(void)
{
PREPARE_ERROR(errctx);
AKGL_REGISTRY_SPRITE = SDL_CreateProperties();
FAIL_ZERO_RETURN(errctx, AKGL_REGISTRY_SPRITE, AKERR_NULLPOINTER, "Error initializing sprite registry");
PASS(errctx, registry_create(&AKGL_REGISTRY_SPRITE, "sprite"));
SUCCEED_RETURN(errctx);
}
akerr_ErrorContext *akgl_registry_init_spritesheet(void)
{
PREPARE_ERROR(errctx);
AKGL_REGISTRY_SPRITESHEET = SDL_CreateProperties();
FAIL_ZERO_RETURN(errctx, AKGL_REGISTRY_SPRITESHEET, AKERR_NULLPOINTER, "Error initializing spritesheet registry");
PASS(errctx, registry_create(&AKGL_REGISTRY_SPRITESHEET, "spritesheet"));
SUCCEED_RETURN(errctx);
}
akerr_ErrorContext *akgl_registry_init_character(void)
{
PREPARE_ERROR(errctx);
AKGL_REGISTRY_CHARACTER = SDL_CreateProperties();
FAIL_ZERO_RETURN(errctx, AKGL_REGISTRY_CHARACTER, AKERR_NULLPOINTER, "Error initializing character registry");
PASS(errctx, registry_create(&AKGL_REGISTRY_CHARACTER, "character"));
SUCCEED_RETURN(errctx);
}

View File

@@ -126,9 +126,7 @@ akerr_ErrorContext *akgl_render_2d_draw_world(akgl_RenderBackend *self, akgl_Ite
{
PREPARE_ERROR(errctx);
akgl_Iterator defflags;
SDL_Time curTime = SDL_GetTicksNS();
akgl_Actor *actor = NULL;
int j = 0;
FAIL_ZERO_RETURN(errctx, self, AKERR_NULLPOINTER, "self");

View File

@@ -136,7 +136,6 @@ akerr_ErrorContext *akgl_sprite_load_json(char *filename)
CATCH(errctx, akgl_heap_next_string(&spritename));
CATCH(errctx, akgl_string_initialize(spritename, NULL));
//SDL_snprintf((char *)&tmpstr->data, AKGL_MAX_STRING_LENGTH, "%s%s", SDL_GetBasePath(), filename);
json = (json_t *)json_load_file(filename, 0, &error);
FAIL_ZERO_BREAK(
errctx,
@@ -221,7 +220,6 @@ akerr_ErrorContext *akgl_spritesheet_initialize(akgl_SpriteSheet *sheet, int spr
//CATCH(errctx, akgl_string_initialize(tmpstr, NULL));
strncpy((char *)&sheet->name, filename, AKGL_SPRITE_SHEET_MAX_FILENAME_LENGTH);
//snprintf((char *)&tmpstr->data, AKGL_MAX_STRING_LENGTH, "%s%s", SDL_GetBasePath(), filename);
sheet->texture = IMG_LoadTexture(akgl_renderer->sdl_renderer, filename);
FAIL_ZERO_BREAK(errctx, sheet->texture, AKGL_ERR_SDL, "Failed loading asset %s : %s", filename, SDL_GetError());

View File

@@ -20,15 +20,15 @@ akerr_ErrorContext *akgl_string_initialize(akgl_String *obj, char *init)
SUCCEED_RETURN(errctx);
}
akerr_ErrorContext *akgl_string_copy(akgl_String *src, akgl_String *dst, int count)
akerr_ErrorContext *akgl_string_copy(akgl_String *src, akgl_String *dest, int count)
{
PREPARE_ERROR(errctx);
FAIL_ZERO_RETURN(errctx, src, AKERR_NULLPOINTER, "NULL argument");
FAIL_ZERO_RETURN(errctx, dst, AKERR_NULLPOINTER, "NULL argument");
FAIL_ZERO_RETURN(errctx, dest, AKERR_NULLPOINTER, "NULL argument");
if ( count == 0 ) {
count = AKGL_MAX_STRING_LENGTH;
}
if ( (char *)dst->data != strncpy((char *)&dst->data, (char *)&src->data, count) ) {
if ( (char *)dest->data != strncpy((char *)&dest->data, (char *)&src->data, count) ) {
FAIL_RETURN(errctx, errno, "strncpy");
}
SUCCEED_RETURN(errctx);

View File

@@ -100,7 +100,7 @@ akerr_ErrorContext *akgl_get_json_properties_integer(json_t *obj, char *key, int
SUCCEED_RETURN(errctx);
}
akerr_ErrorContext *akgl_get_json_properties_number(json_t *obj, char *key, float *dest)
akerr_ErrorContext *akgl_get_json_properties_number(json_t *obj, char *key, float32_t *dest)
{
PREPARE_ERROR(errctx);
json_t *property = NULL;
@@ -110,7 +110,7 @@ akerr_ErrorContext *akgl_get_json_properties_number(json_t *obj, char *key, floa
SUCCEED_RETURN(errctx);
}
akerr_ErrorContext *akgl_get_json_properties_float(json_t *obj, char *key, float *dest)
akerr_ErrorContext *akgl_get_json_properties_float(json_t *obj, char *key, float32_t *dest)
{
PREPARE_ERROR(errctx);
json_t *property = NULL;
@@ -120,7 +120,7 @@ akerr_ErrorContext *akgl_get_json_properties_float(json_t *obj, char *key, float
SUCCEED_RETURN(errctx);
}
akerr_ErrorContext *akgl_get_json_properties_double(json_t *obj, char *key, double *dest)
akerr_ErrorContext *akgl_get_json_properties_double(json_t *obj, char *key, float64_t *dest)
{
PREPARE_ERROR(errctx);
json_t *property = NULL;
@@ -558,7 +558,6 @@ akerr_ErrorContext *akgl_tilemap_load(char *fname, akgl_Tilemap *dest)
ATTEMPT {
//CATCH(errctx, akgl_heap_next_string(&tmpstr));
//CATCH(errctx, akgl_string_initialize(tmpstr, NULL));
//SDL_snprintf(tmpstr->data, AKGL_MAX_STRING_LENGTH, "%s%s", SDL_GetBasePath(), fname);
CATCH(errctx, aksl_realpath(fname, (char *)&dirnamestr->data, sizeof(dirnamestr->data)));
dirname((char *)&dirnamestr->data);

View File

@@ -21,7 +21,7 @@
#include <akstdlib.h>
/**
* @brief Resolve @p path against @p root and write the absolute result to @p dst.
* @brief Resolve @p path against @p root and write the absolute result to @p dest.
*
* The second half of akgl_path_relative: joins the two with a `/` and resolves
* the join, so symlinks and `..` are folded out and the result is absolute. It
@@ -36,10 +36,10 @@
* @param path Relative path to resolve. Required. An absolute @p path still gets
* @p root pasted in front of it, which will not exist -- so callers
* must not send absolute paths down this branch.
* @param dst Receives the resolved absolute path. Required, and must already be
* @param dest Receives the resolved absolute path. Required, and must already be
* a claimed pool string.
* @return `NULL` on success, otherwise an error context owned by the caller.
* @throws AKERR_NULLPOINTER If @p root, @p path, or @p dst is `NULL`.
* @throws AKERR_NULLPOINTER If @p root, @p path, or @p dest is `NULL`.
* @throws AKERR_OUTOFBOUNDS If `root + path` is at least #AKGL_MAX_STRING_LENGTH
* bytes. The message reports both the combined length and the limit.
* @throws ENOENT If the joined path does not exist. Any other `errno`
@@ -51,19 +51,18 @@
* scratch strings are never released. This is exactly the hazard AGENTS.md
* warns about; it wants a `FAIL_BREAK`.
*/
static akerr_ErrorContext *path_relative_root(char *root, char *path, akgl_String *dst)
static akerr_ErrorContext *path_relative_root(char *root, char *path, akgl_String *dest)
{
PREPARE_ERROR(errctx);
akgl_String *pathbuf;
akgl_String *strbuf;
char *result;
int rootlen;
int pathlen;
int count;
FAIL_ZERO_RETURN(errctx, root, AKERR_NULLPOINTER, "NULL argument");
FAIL_ZERO_RETURN(errctx, path, AKERR_NULLPOINTER, "NULL argument");
FAIL_ZERO_RETURN(errctx, dst, AKERR_NULLPOINTER, "NULL argument");
FAIL_ZERO_RETURN(errctx, dest, AKERR_NULLPOINTER, "NULL argument");
PASS(errctx, akgl_heap_next_string(&strbuf));
PASS(errctx, akgl_heap_next_string(&pathbuf));
@@ -86,7 +85,7 @@ static akerr_ErrorContext *path_relative_root(char *root, char *path, akgl_Strin
));
RESTORE_GCC_WARNINGS
CATCH(errctx, aksl_realpath((char *)&pathbuf->data, (char *)&strbuf->data, sizeof(strbuf->data)));
CATCH(errctx, akgl_string_copy(strbuf, dst, 0));
CATCH(errctx, akgl_string_copy(strbuf, dest, 0));
} CLEANUP {
IGNORE(akgl_heap_release_string(strbuf));
IGNORE(akgl_heap_release_string(pathbuf));
@@ -95,16 +94,15 @@ static akerr_ErrorContext *path_relative_root(char *root, char *path, akgl_Strin
SUCCEED_RETURN(errctx);
}
akerr_ErrorContext *akgl_path_relative(char *root, char *path, akgl_String *dst)
akerr_ErrorContext *akgl_path_relative(char *root, char *path, akgl_String *dest)
{
PREPARE_ERROR(errctx);
akgl_String *strbuf;
char *result;
bool relative_to_root = false;
FAIL_ZERO_RETURN(errctx, root, AKERR_NULLPOINTER, "NULL argument");
FAIL_ZERO_RETURN(errctx, path, AKERR_NULLPOINTER, "NULL argument");
FAIL_ZERO_RETURN(errctx, dst, AKERR_NULLPOINTER, "NULL argument");
FAIL_ZERO_RETURN(errctx, dest, AKERR_NULLPOINTER, "NULL argument");
PASS(errctx, akgl_heap_next_string(&strbuf));
@@ -112,7 +110,7 @@ akerr_ErrorContext *akgl_path_relative(char *root, char *path, akgl_String *dst)
// Is path relative to our current working directory?
CATCH(errctx, aksl_realpath(path, (char *)&strbuf->data, sizeof(strbuf->data)));
// Yes it is. strbuf->data contains the absolute path.
CATCH(errctx, akgl_string_copy(strbuf, dst, 0));
CATCH(errctx, akgl_string_copy(strbuf, dest, 0));
} CLEANUP {
IGNORE(akgl_heap_release_string(strbuf));
} PROCESS(errctx) {
@@ -129,7 +127,7 @@ akerr_ErrorContext *akgl_path_relative(char *root, char *path, akgl_String *dst)
} FINISH(errctx, true);
if ( relative_to_root == true ) {
PASS(errctx, path_relative_root(root, path, dst));
PASS(errctx, path_relative_root(root, path, dest));
}
SUCCEED_RETURN(errctx);
}