libghostty: add GHOSTTY_ENUM_TYPED and GHOSTTY_ENUM_MAX_VALUE to all C enums

GHOSTTY_ENUM_TYPED: expands to `: int` on C23 (where explicit enum
underlying types are supported), empty on older standards.
This commit is contained in:
Mitchell Hashimoto
2026-04-08 10:41:08 -07:00
parent 9897d6caba
commit f282f13a21
20 changed files with 77 additions and 62 deletions

View File

@@ -35,7 +35,7 @@ extern "C" {
/**
* Build optimization mode.
*/
typedef enum {
typedef enum GHOSTTY_ENUM_TYPED {
GHOSTTY_OPTIMIZE_DEBUG = 0,
GHOSTTY_OPTIMIZE_RELEASE_SAFE = 1,
GHOSTTY_OPTIMIZE_RELEASE_SMALL = 2,
@@ -48,7 +48,7 @@ typedef enum {
*
* Each variant documents the expected output pointer type.
*/
typedef enum {
typedef enum GHOSTTY_ENUM_TYPED {
/** Invalid data type. Never results in any data extraction. */
GHOSTTY_BUILD_INFO_INVALID = 0,

View File

@@ -71,7 +71,7 @@ extern "C" {
*
* @ingroup terminal
*/
typedef enum {
typedef enum GHOSTTY_ENUM_TYPED {
GHOSTTY_COLOR_SCHEME_LIGHT = 0,
GHOSTTY_COLOR_SCHEME_DARK = 1,
GHOSTTY_COLOR_SCHEME_MAX_VALUE = GHOSTTY_ENUM_MAX_VALUE,

View File

@@ -35,7 +35,7 @@ extern "C" {
/**
* Focus event types for focus reporting mode (mode 1004).
*/
typedef enum {
typedef enum GHOSTTY_ENUM_TYPED {
/** Terminal window gained focus */
GHOSTTY_FOCUS_GAINED = 0,
/** Terminal window lost focus */

View File

@@ -37,7 +37,7 @@ extern "C" {
*
* @ingroup formatter
*/
typedef enum {
typedef enum GHOSTTY_ENUM_TYPED {
/** Plain text (no escape sequences). */
GHOSTTY_FORMATTER_FORMAT_PLAIN,

View File

@@ -64,7 +64,7 @@ typedef uint8_t GhosttyKittyKeyFlags;
*
* @ingroup key
*/
typedef enum {
typedef enum GHOSTTY_ENUM_TYPED {
/** Option key is not treated as alt */
GHOSTTY_OPTION_AS_ALT_FALSE = 0,
/** Option key is treated as alt */
@@ -84,7 +84,7 @@ typedef enum {
*
* @ingroup key
*/
typedef enum {
typedef enum GHOSTTY_ENUM_TYPED {
/** Terminal DEC mode 1: cursor key application mode (value: bool) */
GHOSTTY_KEY_ENCODER_OPT_CURSOR_KEY_APPLICATION = 0,

View File

@@ -28,7 +28,7 @@ typedef struct GhosttyKeyEventImpl *GhosttyKeyEvent;
*
* @ingroup key
*/
typedef enum {
typedef enum GHOSTTY_ENUM_TYPED {
/** Key was released */
GHOSTTY_KEY_ACTION_RELEASE = 0,
/** Key was pressed */
@@ -104,7 +104,7 @@ typedef uint16_t GhosttyMods;
*
* @ingroup key
*/
typedef enum {
typedef enum GHOSTTY_ENUM_TYPED {
GHOSTTY_KEY_UNIDENTIFIED = 0,
// Writing System Keys (W3C § 3.1.1)

View File

@@ -107,7 +107,7 @@ extern "C" {
*
* @ingroup kitty_graphics
*/
typedef enum {
typedef enum GHOSTTY_ENUM_TYPED {
/** Invalid / sentinel value. */
GHOSTTY_KITTY_GRAPHICS_DATA_INVALID = 0,
@@ -127,7 +127,7 @@ typedef enum {
*
* @ingroup kitty_graphics
*/
typedef enum {
typedef enum GHOSTTY_ENUM_TYPED {
/** Invalid / sentinel value. */
GHOSTTY_KITTY_GRAPHICS_PLACEMENT_DATA_INVALID = 0,
@@ -228,7 +228,7 @@ typedef enum {
*
* @ingroup kitty_graphics
*/
typedef enum {
typedef enum GHOSTTY_ENUM_TYPED {
GHOSTTY_KITTY_PLACEMENT_LAYER_ALL = 0,
GHOSTTY_KITTY_PLACEMENT_LAYER_BELOW_BG = 1,
GHOSTTY_KITTY_PLACEMENT_LAYER_BELOW_TEXT = 2,
@@ -241,7 +241,7 @@ typedef enum {
*
* @ingroup kitty_graphics
*/
typedef enum {
typedef enum GHOSTTY_ENUM_TYPED {
/**
* Set the z-layer filter for the iterator.
*
@@ -256,7 +256,7 @@ typedef enum {
*
* @ingroup kitty_graphics
*/
typedef enum {
typedef enum GHOSTTY_ENUM_TYPED {
GHOSTTY_KITTY_IMAGE_FORMAT_RGB = 0,
GHOSTTY_KITTY_IMAGE_FORMAT_RGBA = 1,
GHOSTTY_KITTY_IMAGE_FORMAT_PNG = 2,
@@ -270,7 +270,7 @@ typedef enum {
*
* @ingroup kitty_graphics
*/
typedef enum {
typedef enum GHOSTTY_ENUM_TYPED {
GHOSTTY_KITTY_IMAGE_COMPRESSION_NONE = 0,
GHOSTTY_KITTY_IMAGE_COMPRESSION_ZLIB_DEFLATE = 1,
GHOSTTY_KITTY_IMAGE_COMPRESSION_MAX_VALUE = GHOSTTY_ENUM_MAX_VALUE,
@@ -281,7 +281,7 @@ typedef enum {
*
* @ingroup kitty_graphics
*/
typedef enum {
typedef enum GHOSTTY_ENUM_TYPED {
/** Invalid / sentinel value. */
GHOSTTY_KITTY_IMAGE_DATA_INVALID = 0,

View File

@@ -146,7 +146,7 @@ static inline bool ghostty_mode_ansi(GhosttyMode mode) {
* These correspond to the Ps2 parameter in a DECRPM response
* sequence (CSI ? Ps1 ; Ps2 $ y).
*/
typedef enum {
typedef enum GHOSTTY_ENUM_TYPED {
/** Mode is not recognized */
GHOSTTY_MODE_REPORT_NOT_RECOGNIZED = 0,
/** Mode is set (enabled) */

View File

@@ -30,7 +30,7 @@ typedef struct GhosttyMouseEncoderImpl *GhosttyMouseEncoder;
*
* @ingroup mouse
*/
typedef enum {
typedef enum GHOSTTY_ENUM_TYPED {
/** Mouse reporting disabled. */
GHOSTTY_MOUSE_TRACKING_NONE = 0,
@@ -53,7 +53,7 @@ typedef enum {
*
* @ingroup mouse
*/
typedef enum {
typedef enum GHOSTTY_ENUM_TYPED {
GHOSTTY_MOUSE_FORMAT_X10 = 0,
GHOSTTY_MOUSE_FORMAT_UTF8 = 1,
GHOSTTY_MOUSE_FORMAT_SGR = 2,
@@ -107,7 +107,7 @@ typedef struct {
*
* @ingroup mouse
*/
typedef enum {
typedef enum GHOSTTY_ENUM_TYPED {
/** Mouse tracking mode (value: GhosttyMouseTrackingMode). */
GHOSTTY_MOUSE_ENCODER_OPT_EVENT = 0,

View File

@@ -27,7 +27,7 @@ typedef struct GhosttyMouseEventImpl *GhosttyMouseEvent;
*
* @ingroup mouse
*/
typedef enum {
typedef enum GHOSTTY_ENUM_TYPED {
/** Mouse button was pressed. */
GHOSTTY_MOUSE_ACTION_PRESS = 0,
@@ -44,7 +44,7 @@ typedef enum {
*
* @ingroup mouse
*/
typedef enum {
typedef enum GHOSTTY_ENUM_TYPED {
GHOSTTY_MOUSE_BUTTON_UNKNOWN = 0,
GHOSTTY_MOUSE_BUTTON_LEFT = 1,
GHOSTTY_MOUSE_BUTTON_RIGHT = 2,

View File

@@ -39,7 +39,7 @@
*
* @ingroup osc
*/
typedef enum {
typedef enum GHOSTTY_ENUM_TYPED {
GHOSTTY_OSC_COMMAND_INVALID = 0,
GHOSTTY_OSC_COMMAND_CHANGE_WINDOW_TITLE = 1,
GHOSTTY_OSC_COMMAND_CHANGE_WINDOW_ICON = 2,
@@ -74,7 +74,7 @@ typedef enum {
*
* @ingroup osc
*/
typedef enum {
typedef enum GHOSTTY_ENUM_TYPED {
/** Invalid data type. Never results in any data extraction. */
GHOSTTY_OSC_DATA_INVALID = 0,

View File

@@ -42,7 +42,7 @@ typedef struct {
*
* @ingroup point
*/
typedef enum {
typedef enum GHOSTTY_ENUM_TYPED {
/** Active area where the cursor can move. */
GHOSTTY_POINT_TAG_ACTIVE = 0,

View File

@@ -86,7 +86,7 @@ extern "C" {
*
* @ingroup render
*/
typedef enum {
typedef enum GHOSTTY_ENUM_TYPED {
/** Not dirty at all; rendering can be skipped. */
GHOSTTY_RENDER_STATE_DIRTY_FALSE = 0,
@@ -103,7 +103,7 @@ typedef enum {
*
* @ingroup render
*/
typedef enum {
typedef enum GHOSTTY_ENUM_TYPED {
/** Bar cursor (DECSCUSR 5, 6). */
GHOSTTY_RENDER_STATE_CURSOR_VISUAL_STYLE_BAR = 0,
@@ -123,7 +123,7 @@ typedef enum {
*
* @ingroup render
*/
typedef enum {
typedef enum GHOSTTY_ENUM_TYPED {
/** Invalid / sentinel value. */
GHOSTTY_RENDER_STATE_DATA_INVALID = 0,
@@ -195,7 +195,7 @@ typedef enum {
*
* @ingroup render
*/
typedef enum {
typedef enum GHOSTTY_ENUM_TYPED {
/** Set dirty state (GhosttyRenderStateDirty). */
GHOSTTY_RENDER_STATE_OPTION_DIRTY = 0,
GHOSTTY_RENDER_STATE_OPTION_MAX_VALUE = GHOSTTY_ENUM_MAX_VALUE,
@@ -206,7 +206,7 @@ typedef enum {
*
* @ingroup render
*/
typedef enum {
typedef enum GHOSTTY_ENUM_TYPED {
/** Invalid / sentinel value. */
GHOSTTY_RENDER_STATE_ROW_DATA_INVALID = 0,
@@ -229,7 +229,7 @@ typedef enum {
*
* @ingroup render
*/
typedef enum {
typedef enum GHOSTTY_ENUM_TYPED {
/** Set dirty state for the current row (bool). */
GHOSTTY_RENDER_STATE_ROW_OPTION_DIRTY = 0,
GHOSTTY_RENDER_STATE_ROW_OPTION_MAX_VALUE = GHOSTTY_ENUM_MAX_VALUE,
@@ -481,7 +481,7 @@ GHOSTTY_API GhosttyResult ghostty_render_state_row_cells_new(
*
* @ingroup render
*/
typedef enum {
typedef enum GHOSTTY_ENUM_TYPED {
/** Invalid / sentinel value. */
GHOSTTY_RENDER_STATE_ROW_CELLS_DATA_INVALID = 0,

View File

@@ -57,7 +57,7 @@ typedef uint64_t GhosttyRow;
*
* @ingroup screen
*/
typedef enum {
typedef enum GHOSTTY_ENUM_TYPED {
/** A single codepoint (may be zero for empty). */
GHOSTTY_CELL_CONTENT_CODEPOINT = 0,
@@ -79,7 +79,7 @@ typedef enum {
*
* @ingroup screen
*/
typedef enum {
typedef enum GHOSTTY_ENUM_TYPED {
/** Not a wide character, cell width 1. */
GHOSTTY_CELL_WIDE_NARROW = 0,
@@ -102,7 +102,7 @@ typedef enum {
*
* @ingroup screen
*/
typedef enum {
typedef enum GHOSTTY_ENUM_TYPED {
/** Regular output content, such as command output. */
GHOSTTY_CELL_SEMANTIC_OUTPUT = 0,
@@ -122,7 +122,7 @@ typedef enum {
*
* @ingroup screen
*/
typedef enum {
typedef enum GHOSTTY_ENUM_TYPED {
/** Invalid data type. Never results in any data extraction. */
GHOSTTY_CELL_DATA_INVALID = 0,
@@ -215,7 +215,7 @@ typedef enum {
*
* @ingroup screen
*/
typedef enum {
typedef enum GHOSTTY_ENUM_TYPED {
/** No prompt cells in this row. */
GHOSTTY_ROW_SEMANTIC_NONE = 0,
@@ -235,7 +235,7 @@ typedef enum {
*
* @ingroup screen
*/
typedef enum {
typedef enum GHOSTTY_ENUM_TYPED {
/** Invalid data type. Never results in any data extraction. */
GHOSTTY_ROW_DATA_INVALID = 0,

View File

@@ -55,7 +55,7 @@ extern "C" {
*
* @ingroup sgr
*/
typedef enum {
typedef enum GHOSTTY_ENUM_TYPED {
GHOSTTY_SGR_ATTR_UNSET = 0,
GHOSTTY_SGR_ATTR_UNKNOWN = 1,
GHOSTTY_SGR_ATTR_BOLD = 2,
@@ -95,7 +95,7 @@ typedef enum {
*
* @ingroup sgr
*/
typedef enum {
typedef enum GHOSTTY_ENUM_TYPED {
GHOSTTY_SGR_UNDERLINE_NONE = 0,
GHOSTTY_SGR_UNDERLINE_SINGLE = 1,
GHOSTTY_SGR_UNDERLINE_DOUBLE = 2,

View File

@@ -40,7 +40,7 @@ extern "C" {
*
* Determines the output format for the terminal size report.
*/
typedef enum {
typedef enum GHOSTTY_ENUM_TYPED {
/** In-band size report (mode 2048): ESC [ 48 ; rows ; cols ; height ; width t */
GHOSTTY_SIZE_REPORT_MODE_2048 = 0,
/** XTWINOPS text area size in pixels: ESC [ 4 ; height ; width t */

View File

@@ -46,7 +46,7 @@ typedef uint16_t GhosttyStyleId;
*
* @ingroup style
*/
typedef enum {
typedef enum GHOSTTY_ENUM_TYPED {
GHOSTTY_STYLE_COLOR_NONE = 0,
GHOSTTY_STYLE_COLOR_PALETTE = 1,
GHOSTTY_STYLE_COLOR_RGB = 2,

View File

@@ -88,7 +88,7 @@ typedef bool (*GhosttySysDecodePngFn)(
/**
* System option identifiers for ghostty_sys_set().
*/
typedef enum {
typedef enum GHOSTTY_ENUM_TYPED {
/**
* Set the userdata pointer passed to all sys callbacks.
*

View File

@@ -180,7 +180,7 @@ typedef struct {
*
* @ingroup terminal
*/
typedef enum {
typedef enum GHOSTTY_ENUM_TYPED {
/** Scroll to the top of the scrollback. */
GHOSTTY_SCROLL_VIEWPORT_TOP,
@@ -222,7 +222,7 @@ typedef struct {
*
* @ingroup terminal
*/
typedef enum {
typedef enum GHOSTTY_ENUM_TYPED {
/** The primary (normal) screen. */
GHOSTTY_TERMINAL_SCREEN_PRIMARY = 0,
@@ -396,7 +396,7 @@ typedef GhosttyString (*GhosttyTerminalXtversionFn)(GhosttyTerminal terminal,
*
* @ingroup terminal
*/
typedef enum {
typedef enum GHOSTTY_ENUM_TYPED {
/**
* Opaque userdata pointer passed to all callbacks.
*
@@ -584,7 +584,7 @@ typedef enum {
*
* @ingroup terminal
*/
typedef enum {
typedef enum GHOSTTY_ENUM_TYPED {
/** Invalid data type. Never results in any data extraction. */
GHOSTTY_TERMINAL_DATA_INVALID = 0,

View File

@@ -34,29 +34,44 @@
#endif
/**
* Sentinel value for enum definitions to force max int width sizing.
* Enum int-sizing helpers.
*
* Pre-C23, the C standard allows compilers to choose any integer type
* that can represent all enum values (C11 §6.7.2.2), so small enums
* could be backed by char or short. Adding this value as the last
* entry in every enum forces the compiler to use at an `int`
* type, ensuring ABI stability across compilers and platforms.
* The Zig side backs all C enums with c_int, so the C declarations
* must use int as their underlying type to maintain ABI compatibility.
*
* We use INT_MAX rather than a fixed constant like 0xFFFFFFFF because
* enum constants must have type int (which is signed). Values above
* INT_MAX overflow signed int and are a constraint violation in
* standard C; compilers that accept them interpret them as negative
* values via two's complement, which can collide with legitimate
* negative enum values. Using INT_MAX also ensures the enum matches
* the target's int size, which is important because the Zig side
* backs these enums with c_int for ABI compatibility.
* C23 (detected via __STDC_VERSION__ >= 202311L) supports explicit
* enum underlying types with `enum : int { ... }`. For pre-C23
* compilers, which are free to choose any type that can represent
* all values (C11 §6.7.2.2), we add an INT_MAX sentinel as the last
* entry to force the compiler to use int.
*
* INT_MAX is used rather than a fixed constant like 0xFFFFFFFF
* because enum constants must have type int (which is signed).
* Values above INT_MAX overflow signed int and are a constraint
* violation in standard C; compilers that accept them interpret them
* as negative values via two's complement, which can collide with
* legitimate negative enum values.
*
* Usage:
* @code
* typedef enum GHOSTTY_ENUM_TYPED {
* FOO_A = 0,
* FOO_B = 1,
* FOO_MAX_VALUE = GHOSTTY_ENUM_MAX_VALUE,
* } Foo;
* @endcode
*/
#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 202311L
#define GHOSTTY_ENUM_TYPED : int
#else
#define GHOSTTY_ENUM_TYPED
#endif
#define GHOSTTY_ENUM_MAX_VALUE INT_MAX
/**
* Result codes for libghostty-vt operations.
*/
typedef enum {
typedef enum GHOSTTY_ENUM_TYPED {
/** Operation completed successfully */
GHOSTTY_SUCCESS = 0,
/** Operation failed due to failed allocation */