SUCCEED_RETURN(errctx); } /** * Set in HANDLE_DEFAULT and read after FINISH. Returning from inside a HANDLE * block leaves before RELEASE_ERROR and leaks the context's pool slot; AGENTS.md * spells that out, and a documentation example is a bad place to teach it wrong. */ static int docs_failed = 0; int main(void) { PREPARE_ERROR(errctx); /* * Set here as well as in the environment, so the program answers the same * whether the harness ran it or a reader did. */ SDL_SetHint(SDL_HINT_VIDEO_DRIVER, "dummy"); SDL_SetHint(SDL_HINT_RENDER_DRIVER, "software"); SDL_SetHint(SDL_HINT_AUDIO_DRIVER, "dummy"); ATTEMPT { CATCH(errctx, akgl_error_init()); akgl_renderer = &akgl_default_renderer; FAIL_ZERO_BREAK(errctx, SDL_Init(SDL_INIT_VIDEO), AKGL_ERR_SDL, "Couldn't initialize SDL: %s", SDL_GetError()); FAIL_ZERO_BREAK( errctx, SDL_CreateWindowAndRenderer( "net/aklabs/libakgl/docs", 320, 240, 0, &akgl_window, &akgl_renderer->sdl_renderer), AKGL_ERR_SDL, "Couldn't create window/renderer: %s", SDL_GetError()); CATCH(errctx, akgl_render_2d_bind(akgl_renderer)); CATCH(errctx, akgl_heap_init()); CATCH(errctx, akgl_registry_init()); akgl_camera = &akgl_default_camera; akgl_camera->x = 0.0f; akgl_camera->y = 0.0f; akgl_camera->w = 320.0f; akgl_camera->h = 240.0f; CATCH(errctx, docs_example()); } CLEANUP { if ( akgl_window != NULL ) { SDL_DestroyWindow(akgl_window); akgl_window = NULL; } SDL_Quit(); } PROCESS(errctx) { } HANDLE_DEFAULT(errctx) { LOG_ERROR_WITH_MESSAGE(errctx, "the documented example failed"); docs_failed = 1; /* * FINISH_NORETURN rather than FINISH: FINISH expands a * `return __err_context` that an int-returning function cannot compile, * even where the branch is unreachable. src/main.c in akbasic and * tools/docs_screenshot.c do the same and say so. */ } FINISH_NORETURN(errctx); return docs_failed; }