From 9897d6caba05c0cbf256f86bec2e2935f164a9c7 Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Wed, 8 Apr 2026 10:08:43 -0700 Subject: [PATCH] libghostty: add GHOSTTY_ENUM_MAX_VALUE sentinel to all C enums Pre-C23, the C standard allows compilers to choose any integer type that can represent all enum values, so small enums could be backed by char or short. This breaks ABI compatibility with the Zig side, which backs these enums with c_int. Define GHOSTTY_ENUM_MAX_VALUE as INT_MAX in types.h and add it as the last entry in every enum in include/ghostty/vt/. This forces the compiler to use int as the backing type, matching c_int on all targets. INT_MAX is used rather than a fixed constant because enum constants must be representable as int; values above INT_MAX are a constraint violation in standard C. Document this convention in AGENTS.md. --- AGENTS.md | 2 ++ include/ghostty/vt/build_info.h | 2 ++ include/ghostty/vt/device.h | 1 + include/ghostty/vt/focus.h | 1 + include/ghostty/vt/formatter.h | 1 + include/ghostty/vt/key/encoder.h | 2 ++ include/ghostty/vt/key/event.h | 2 ++ include/ghostty/vt/kitty_graphics.h | 7 +++++++ include/ghostty/vt/modes.h | 1 + include/ghostty/vt/mouse/encoder.h | 3 +++ include/ghostty/vt/mouse/event.h | 2 ++ include/ghostty/vt/osc.h | 2 ++ include/ghostty/vt/point.h | 3 ++- include/ghostty/vt/render.h | 7 +++++++ include/ghostty/vt/screen.h | 6 ++++++ include/ghostty/vt/sgr.h | 2 ++ include/ghostty/vt/size_report.h | 1 + include/ghostty/vt/style.h | 3 ++- include/ghostty/vt/sys.h | 1 + include/ghostty/vt/terminal.h | 4 ++++ include/ghostty/vt/types.h | 22 ++++++++++++++++++++++ 21 files changed, 73 insertions(+), 2 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index 7098007f5..8a5254889 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -22,6 +22,8 @@ A file for [guiding coding agents](https://agents.md/). - Build WASM: `zig build -Demit-lib-vt -Dtarget=wasm32-freestanding -Doptimize=ReleaseSmall` - Test: `zig build test-lib-vt -Dtest-filter=` - Prefer this when the change is in a libghostty-vt file +- All C enums in `include/ghostty/vt/` must have a `_MAX_VALUE = GHOSTTY_ENUM_MAX_VALUE` + sentinel as the last entry to force int enum sizing (pre-C23 portability). ## Directory Structure diff --git a/include/ghostty/vt/build_info.h b/include/ghostty/vt/build_info.h index 19999e77f..d0aedfdc1 100644 --- a/include/ghostty/vt/build_info.h +++ b/include/ghostty/vt/build_info.h @@ -40,6 +40,7 @@ typedef enum { GHOSTTY_OPTIMIZE_RELEASE_SAFE = 1, GHOSTTY_OPTIMIZE_RELEASE_SMALL = 2, GHOSTTY_OPTIMIZE_RELEASE_FAST = 3, + GHOSTTY_OPTIMIZE_MODE_MAX_VALUE = GHOSTTY_ENUM_MAX_VALUE, } GhosttyOptimizeMode; /** @@ -122,6 +123,7 @@ typedef enum { * Output type: GhosttyString * */ GHOSTTY_BUILD_INFO_VERSION_BUILD = 10, + GHOSTTY_BUILD_INFO_MAX_VALUE = GHOSTTY_ENUM_MAX_VALUE, } GhosttyBuildInfo; /** diff --git a/include/ghostty/vt/device.h b/include/ghostty/vt/device.h index fdf6bca7d..3b6ba3d7c 100644 --- a/include/ghostty/vt/device.h +++ b/include/ghostty/vt/device.h @@ -74,6 +74,7 @@ extern "C" { typedef enum { GHOSTTY_COLOR_SCHEME_LIGHT = 0, GHOSTTY_COLOR_SCHEME_DARK = 1, + GHOSTTY_COLOR_SCHEME_MAX_VALUE = GHOSTTY_ENUM_MAX_VALUE, } GhosttyColorScheme; /** diff --git a/include/ghostty/vt/focus.h b/include/ghostty/vt/focus.h index 6e4c9502c..2f4954965 100644 --- a/include/ghostty/vt/focus.h +++ b/include/ghostty/vt/focus.h @@ -40,6 +40,7 @@ typedef enum { GHOSTTY_FOCUS_GAINED = 0, /** Terminal window lost focus */ GHOSTTY_FOCUS_LOST = 1, + GHOSTTY_FOCUS_MAX_VALUE = GHOSTTY_ENUM_MAX_VALUE, } GhosttyFocusEvent; /** diff --git a/include/ghostty/vt/formatter.h b/include/ghostty/vt/formatter.h index 9eacc6409..f0fc1447d 100644 --- a/include/ghostty/vt/formatter.h +++ b/include/ghostty/vt/formatter.h @@ -46,6 +46,7 @@ typedef enum { /** HTML with inline styles. */ GHOSTTY_FORMATTER_FORMAT_HTML, + GHOSTTY_FORMATTER_FORMAT_MAX_VALUE = GHOSTTY_ENUM_MAX_VALUE, } GhosttyFormatterFormat; /** diff --git a/include/ghostty/vt/key/encoder.h b/include/ghostty/vt/key/encoder.h index 9d8282cec..5d1200741 100644 --- a/include/ghostty/vt/key/encoder.h +++ b/include/ghostty/vt/key/encoder.h @@ -73,6 +73,7 @@ typedef enum { GHOSTTY_OPTION_AS_ALT_LEFT = 2, /** Only right option key is treated as alt */ GHOSTTY_OPTION_AS_ALT_RIGHT = 3, + GHOSTTY_OPTION_AS_ALT_MAX_VALUE = GHOSTTY_ENUM_MAX_VALUE, } GhosttyOptionAsAlt; /** @@ -104,6 +105,7 @@ typedef enum { /** macOS option-as-alt setting (value: GhosttyOptionAsAlt) */ GHOSTTY_KEY_ENCODER_OPT_MACOS_OPTION_AS_ALT = 6, + GHOSTTY_KEY_ENCODER_OPT_MAX_VALUE = GHOSTTY_ENUM_MAX_VALUE, } GhosttyKeyEncoderOption; /** diff --git a/include/ghostty/vt/key/event.h b/include/ghostty/vt/key/event.h index bcc9d8dec..39f23d7e4 100644 --- a/include/ghostty/vt/key/event.h +++ b/include/ghostty/vt/key/event.h @@ -35,6 +35,7 @@ typedef enum { GHOSTTY_KEY_ACTION_PRESS = 1, /** Key is being repeated (held down) */ GHOSTTY_KEY_ACTION_REPEAT = 2, + GHOSTTY_KEY_ACTION_MAX_VALUE = GHOSTTY_ENUM_MAX_VALUE, } GhosttyKeyAction; /** @@ -296,6 +297,7 @@ typedef enum { GHOSTTY_KEY_COPY, GHOSTTY_KEY_CUT, GHOSTTY_KEY_PASTE, + GHOSTTY_KEY_MAX_VALUE = GHOSTTY_ENUM_MAX_VALUE, } GhosttyKey; /** diff --git a/include/ghostty/vt/kitty_graphics.h b/include/ghostty/vt/kitty_graphics.h index 1f6884348..b9ea64eb3 100644 --- a/include/ghostty/vt/kitty_graphics.h +++ b/include/ghostty/vt/kitty_graphics.h @@ -119,6 +119,7 @@ typedef enum { * Output type: GhosttyKittyGraphicsPlacementIterator * */ GHOSTTY_KITTY_GRAPHICS_DATA_PLACEMENT_ITERATOR = 1, + GHOSTTY_KITTY_GRAPHICS_DATA_MAX_VALUE = GHOSTTY_ENUM_MAX_VALUE, } GhosttyKittyGraphicsData; /** @@ -213,6 +214,7 @@ typedef enum { * Output type: int32_t * */ GHOSTTY_KITTY_GRAPHICS_PLACEMENT_DATA_Z = 12, + GHOSTTY_KITTY_GRAPHICS_PLACEMENT_DATA_MAX_VALUE = GHOSTTY_ENUM_MAX_VALUE, } GhosttyKittyGraphicsPlacementData; /** @@ -231,6 +233,7 @@ typedef enum { GHOSTTY_KITTY_PLACEMENT_LAYER_BELOW_BG = 1, GHOSTTY_KITTY_PLACEMENT_LAYER_BELOW_TEXT = 2, GHOSTTY_KITTY_PLACEMENT_LAYER_ABOVE_TEXT = 3, + GHOSTTY_KITTY_PLACEMENT_LAYER_MAX_VALUE = GHOSTTY_ENUM_MAX_VALUE, } GhosttyKittyPlacementLayer; /** @@ -245,6 +248,7 @@ typedef enum { * Input type: GhosttyKittyPlacementLayer * */ GHOSTTY_KITTY_GRAPHICS_PLACEMENT_ITERATOR_OPTION_LAYER = 0, + GHOSTTY_KITTY_GRAPHICS_PLACEMENT_ITERATOR_OPTION_MAX_VALUE = GHOSTTY_ENUM_MAX_VALUE, } GhosttyKittyGraphicsPlacementIteratorOption; /** @@ -258,6 +262,7 @@ typedef enum { GHOSTTY_KITTY_IMAGE_FORMAT_PNG = 2, GHOSTTY_KITTY_IMAGE_FORMAT_GRAY_ALPHA = 3, GHOSTTY_KITTY_IMAGE_FORMAT_GRAY = 4, + GHOSTTY_KITTY_IMAGE_FORMAT_MAX_VALUE = GHOSTTY_ENUM_MAX_VALUE, } GhosttyKittyImageFormat; /** @@ -268,6 +273,7 @@ typedef enum { typedef enum { GHOSTTY_KITTY_IMAGE_COMPRESSION_NONE = 0, GHOSTTY_KITTY_IMAGE_COMPRESSION_ZLIB_DEFLATE = 1, + GHOSTTY_KITTY_IMAGE_COMPRESSION_MAX_VALUE = GHOSTTY_ENUM_MAX_VALUE, } GhosttyKittyImageCompression; /** @@ -335,6 +341,7 @@ typedef enum { * Output type: size_t * */ GHOSTTY_KITTY_IMAGE_DATA_DATA_LEN = 8, + GHOSTTY_KITTY_IMAGE_DATA_MAX_VALUE = GHOSTTY_ENUM_MAX_VALUE, } GhosttyKittyGraphicsImageData; /** diff --git a/include/ghostty/vt/modes.h b/include/ghostty/vt/modes.h index 513aaf5a5..f8fa7c009 100644 --- a/include/ghostty/vt/modes.h +++ b/include/ghostty/vt/modes.h @@ -157,6 +157,7 @@ typedef enum { GHOSTTY_MODE_REPORT_PERMANENTLY_SET = 3, /** Mode is permanently reset */ GHOSTTY_MODE_REPORT_PERMANENTLY_RESET = 4, + GHOSTTY_MODE_REPORT_MAX_VALUE = GHOSTTY_ENUM_MAX_VALUE, } GhosttyModeReportState; /** diff --git a/include/ghostty/vt/mouse/encoder.h b/include/ghostty/vt/mouse/encoder.h index 744b99303..a82dda089 100644 --- a/include/ghostty/vt/mouse/encoder.h +++ b/include/ghostty/vt/mouse/encoder.h @@ -45,6 +45,7 @@ typedef enum { /** Any-event tracking mode. */ GHOSTTY_MOUSE_TRACKING_ANY = 4, + GHOSTTY_MOUSE_TRACKING_MAX_VALUE = GHOSTTY_ENUM_MAX_VALUE, } GhosttyMouseTrackingMode; /** @@ -58,6 +59,7 @@ typedef enum { GHOSTTY_MOUSE_FORMAT_SGR = 2, GHOSTTY_MOUSE_FORMAT_URXVT = 3, GHOSTTY_MOUSE_FORMAT_SGR_PIXELS = 4, + GHOSTTY_MOUSE_FORMAT_MAX_VALUE = GHOSTTY_ENUM_MAX_VALUE, } GhosttyMouseFormat; /** @@ -120,6 +122,7 @@ typedef enum { /** Whether to enable motion deduplication by last cell (value: bool). */ GHOSTTY_MOUSE_ENCODER_OPT_TRACK_LAST_CELL = 4, + GHOSTTY_MOUSE_ENCODER_OPT_MAX_VALUE = GHOSTTY_ENUM_MAX_VALUE, } GhosttyMouseEncoderOption; /** diff --git a/include/ghostty/vt/mouse/event.h b/include/ghostty/vt/mouse/event.h index 5b72735fc..ac71881f2 100644 --- a/include/ghostty/vt/mouse/event.h +++ b/include/ghostty/vt/mouse/event.h @@ -36,6 +36,7 @@ typedef enum { /** Mouse moved. */ GHOSTTY_MOUSE_ACTION_MOTION = 2, + GHOSTTY_MOUSE_ACTION_MAX_VALUE = GHOSTTY_ENUM_MAX_VALUE, } GhosttyMouseAction; /** @@ -56,6 +57,7 @@ typedef enum { GHOSTTY_MOUSE_BUTTON_NINE = 9, GHOSTTY_MOUSE_BUTTON_TEN = 10, GHOSTTY_MOUSE_BUTTON_ELEVEN = 11, + GHOSTTY_MOUSE_BUTTON_MAX_VALUE = GHOSTTY_ENUM_MAX_VALUE, } GhosttyMouseButton; /** diff --git a/include/ghostty/vt/osc.h b/include/ghostty/vt/osc.h index e17a8a182..43d137061 100644 --- a/include/ghostty/vt/osc.h +++ b/include/ghostty/vt/osc.h @@ -63,6 +63,7 @@ typedef enum { GHOSTTY_OSC_COMMAND_CONEMU_XTERM_EMULATION = 20, GHOSTTY_OSC_COMMAND_CONEMU_COMMENT = 21, GHOSTTY_OSC_COMMAND_KITTY_TEXT_SIZING = 22, + GHOSTTY_OSC_COMMAND_TYPE_MAX_VALUE = GHOSTTY_ENUM_MAX_VALUE, } GhosttyOscCommandType; /** @@ -88,6 +89,7 @@ typedef enum { * the same parser instance. Memory is owned by the parser. */ GHOSTTY_OSC_DATA_CHANGE_WINDOW_TITLE_STR = 1, + GHOSTTY_OSC_DATA_MAX_VALUE = GHOSTTY_ENUM_MAX_VALUE, } GhosttyOscCommandData; /** diff --git a/include/ghostty/vt/point.h b/include/ghostty/vt/point.h index f152a5c46..c1ade0f96 100644 --- a/include/ghostty/vt/point.h +++ b/include/ghostty/vt/point.h @@ -54,7 +54,8 @@ typedef enum { /** Scrollback history only (before active area). */ GHOSTTY_POINT_TAG_HISTORY = 3, -} GhosttyPointTag; + GHOSTTY_POINT_TAG_MAX_VALUE = GHOSTTY_ENUM_MAX_VALUE, + } GhosttyPointTag; /** * Point value union. diff --git a/include/ghostty/vt/render.h b/include/ghostty/vt/render.h index b15be4902..759c9354c 100644 --- a/include/ghostty/vt/render.h +++ b/include/ghostty/vt/render.h @@ -95,6 +95,7 @@ typedef enum { /** Global state changed; renderer should redraw everything. */ GHOSTTY_RENDER_STATE_DIRTY_FULL = 2, + GHOSTTY_RENDER_STATE_DIRTY_MAX_VALUE = GHOSTTY_ENUM_MAX_VALUE, } GhosttyRenderStateDirty; /** @@ -114,6 +115,7 @@ typedef enum { /** Hollow block cursor. */ GHOSTTY_RENDER_STATE_CURSOR_VISUAL_STYLE_BLOCK_HOLLOW = 3, + GHOSTTY_RENDER_STATE_CURSOR_VISUAL_STYLE_MAX_VALUE = GHOSTTY_ENUM_MAX_VALUE, } GhosttyRenderStateCursorVisualStyle; /** @@ -185,6 +187,7 @@ typedef enum { /** Whether the cursor is on the tail of a wide character (bool). * Only valid when CURSOR_VIEWPORT_HAS_VALUE is true. */ GHOSTTY_RENDER_STATE_DATA_CURSOR_VIEWPORT_WIDE_TAIL = 17, + GHOSTTY_RENDER_STATE_DATA_MAX_VALUE = GHOSTTY_ENUM_MAX_VALUE, } GhosttyRenderStateData; /** @@ -195,6 +198,7 @@ typedef enum { typedef enum { /** Set dirty state (GhosttyRenderStateDirty). */ GHOSTTY_RENDER_STATE_OPTION_DIRTY = 0, + GHOSTTY_RENDER_STATE_OPTION_MAX_VALUE = GHOSTTY_ENUM_MAX_VALUE, } GhosttyRenderStateOption; /** @@ -217,6 +221,7 @@ typedef enum { * valid as long as the underlying render state is not updated. * It is unsafe to use cell data after updating the render state. */ GHOSTTY_RENDER_STATE_ROW_DATA_CELLS = 3, + GHOSTTY_RENDER_STATE_ROW_DATA_MAX_VALUE = GHOSTTY_ENUM_MAX_VALUE, } GhosttyRenderStateRowData; /** @@ -227,6 +232,7 @@ typedef enum { typedef enum { /** 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, } GhosttyRenderStateRowOption; /** @@ -509,6 +515,7 @@ typedef enum { * color, in which case the caller should use whatever default foreground * color it wants (e.g. the terminal foreground). */ GHOSTTY_RENDER_STATE_ROW_CELLS_DATA_FG_COLOR = 6, + GHOSTTY_RENDER_STATE_ROW_CELLS_DATA_MAX_VALUE = GHOSTTY_ENUM_MAX_VALUE, } GhosttyRenderStateRowCellsData; /** diff --git a/include/ghostty/vt/screen.h b/include/ghostty/vt/screen.h index 89b4825fe..13bb8e43b 100644 --- a/include/ghostty/vt/screen.h +++ b/include/ghostty/vt/screen.h @@ -69,6 +69,7 @@ typedef enum { /** No text; background color as RGB. */ GHOSTTY_CELL_CONTENT_BG_COLOR_RGB = 3, + GHOSTTY_CELL_CONTENT_TAG_MAX_VALUE = GHOSTTY_ENUM_MAX_VALUE, } GhosttyCellContentTag; /** @@ -90,6 +91,7 @@ typedef enum { /** Spacer at end of soft-wrapped line for a wide character. */ GHOSTTY_CELL_WIDE_SPACER_HEAD = 3, + GHOSTTY_CELL_WIDE_MAX_VALUE = GHOSTTY_ENUM_MAX_VALUE, } GhosttyCellWide; /** @@ -109,6 +111,7 @@ typedef enum { /** Content that is part of a shell prompt. */ GHOSTTY_CELL_SEMANTIC_PROMPT = 2, + GHOSTTY_CELL_SEMANTIC_MAX_VALUE = GHOSTTY_ENUM_MAX_VALUE, } GhosttyCellSemanticContent; /** @@ -201,6 +204,7 @@ typedef enum { * Output type: GhosttyColorRgb * */ GHOSTTY_CELL_DATA_COLOR_RGB = 11, + GHOSTTY_CELL_DATA_MAX_VALUE = GHOSTTY_ENUM_MAX_VALUE, } GhosttyCellData; /** @@ -220,6 +224,7 @@ typedef enum { /** Prompt cells exist and this is a continuation line. */ GHOSTTY_ROW_SEMANTIC_PROMPT_CONTINUATION = 2, + GHOSTTY_ROW_SEMANTIC_MAX_VALUE = GHOSTTY_ENUM_MAX_VALUE, } GhosttyRowSemanticPrompt; /** @@ -289,6 +294,7 @@ typedef enum { * Output type: bool * */ GHOSTTY_ROW_DATA_DIRTY = 8, + GHOSTTY_ROW_DATA_MAX_VALUE = GHOSTTY_ENUM_MAX_VALUE, } GhosttyRowData; /** diff --git a/include/ghostty/vt/sgr.h b/include/ghostty/vt/sgr.h index b093bc9ff..00849283d 100644 --- a/include/ghostty/vt/sgr.h +++ b/include/ghostty/vt/sgr.h @@ -87,6 +87,7 @@ typedef enum { GHOSTTY_SGR_ATTR_BRIGHT_FG_8 = 28, GHOSTTY_SGR_ATTR_BG_256 = 29, GHOSTTY_SGR_ATTR_FG_256 = 30, + GHOSTTY_SGR_ATTR_MAX_VALUE = GHOSTTY_ENUM_MAX_VALUE, } GhosttySgrAttributeTag; /** @@ -101,6 +102,7 @@ typedef enum { GHOSTTY_SGR_UNDERLINE_CURLY = 3, GHOSTTY_SGR_UNDERLINE_DOTTED = 4, GHOSTTY_SGR_UNDERLINE_DASHED = 5, + GHOSTTY_SGR_UNDERLINE_MAX_VALUE = GHOSTTY_ENUM_MAX_VALUE, } GhosttySgrUnderline; /** diff --git a/include/ghostty/vt/size_report.h b/include/ghostty/vt/size_report.h index 98c67c5ed..d65fa95f6 100644 --- a/include/ghostty/vt/size_report.h +++ b/include/ghostty/vt/size_report.h @@ -49,6 +49,7 @@ typedef enum { GHOSTTY_SIZE_REPORT_CSI_16_T = 2, /** XTWINOPS text area size in characters: ESC [ 8 ; rows ; cols t */ GHOSTTY_SIZE_REPORT_CSI_18_T = 3, + GHOSTTY_SIZE_REPORT_STYLE_MAX_VALUE = GHOSTTY_ENUM_MAX_VALUE, } GhosttySizeReportStyle; /** diff --git a/include/ghostty/vt/style.h b/include/ghostty/vt/style.h index ac0495600..ea1750395 100644 --- a/include/ghostty/vt/style.h +++ b/include/ghostty/vt/style.h @@ -50,7 +50,8 @@ typedef enum { GHOSTTY_STYLE_COLOR_NONE = 0, GHOSTTY_STYLE_COLOR_PALETTE = 1, GHOSTTY_STYLE_COLOR_RGB = 2, -} GhosttyStyleColorTag; + GHOSTTY_STYLE_COLOR_TAG_MAX_VALUE = GHOSTTY_ENUM_MAX_VALUE, + } GhosttyStyleColorTag; /** * Style color value union. diff --git a/include/ghostty/vt/sys.h b/include/ghostty/vt/sys.h index 0634f5ac8..56e60b237 100644 --- a/include/ghostty/vt/sys.h +++ b/include/ghostty/vt/sys.h @@ -106,6 +106,7 @@ typedef enum { * Input type: GhosttySysDecodePngFn (function pointer, or NULL) */ GHOSTTY_SYS_OPT_DECODE_PNG = 1, + GHOSTTY_SYS_OPT_MAX_VALUE = GHOSTTY_ENUM_MAX_VALUE, } GhosttySysOption; /** diff --git a/include/ghostty/vt/terminal.h b/include/ghostty/vt/terminal.h index a229dd700..c57ba27b5 100644 --- a/include/ghostty/vt/terminal.h +++ b/include/ghostty/vt/terminal.h @@ -189,6 +189,7 @@ typedef enum { /** Scroll by a delta amount (up is negative). */ GHOSTTY_SCROLL_VIEWPORT_DELTA, + GHOSTTY_SCROLL_VIEWPORT_MAX_VALUE = GHOSTTY_ENUM_MAX_VALUE, } GhosttyTerminalScrollViewportTag; /** @@ -227,6 +228,7 @@ typedef enum { /** The alternate screen. */ GHOSTTY_TERMINAL_SCREEN_ALTERNATE = 1, + GHOSTTY_TERMINAL_SCREEN_MAX_VALUE = GHOSTTY_ENUM_MAX_VALUE, } GhosttyTerminalScreen; /** @@ -571,6 +573,7 @@ typedef enum { * Input type: bool* */ GHOSTTY_TERMINAL_OPT_KITTY_IMAGE_MEDIUM_SHARED_MEM = 18, + GHOSTTY_TERMINAL_OPT_MAX_VALUE = GHOSTTY_ENUM_MAX_VALUE, } GhosttyTerminalOption; /** @@ -846,6 +849,7 @@ typedef enum { * Output type: GhosttyKittyGraphics * */ GHOSTTY_TERMINAL_DATA_KITTY_GRAPHICS = 30, + GHOSTTY_TERMINAL_DATA_MAX_VALUE = GHOSTTY_ENUM_MAX_VALUE, } GhosttyTerminalData; /** diff --git a/include/ghostty/vt/types.h b/include/ghostty/vt/types.h index 0fe37e3b2..70ac11d57 100644 --- a/include/ghostty/vt/types.h +++ b/include/ghostty/vt/types.h @@ -7,6 +7,7 @@ #ifndef GHOSTTY_VT_TYPES_H #define GHOSTTY_VT_TYPES_H +#include #include #include @@ -32,6 +33,26 @@ #endif #endif +/** + * Sentinel value for enum definitions to force max int width sizing. + * + * 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. + * + * 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. + */ +#define GHOSTTY_ENUM_MAX_VALUE INT_MAX + /** * Result codes for libghostty-vt operations. */ @@ -46,6 +67,7 @@ typedef enum { GHOSTTY_OUT_OF_SPACE = -3, /** The requested value has no value */ GHOSTTY_NO_VALUE = -4, + GHOSTTY_RESULT_MAX_VALUE = GHOSTTY_ENUM_MAX_VALUE, } GhosttyResult; /* ---- Opaque handles ---- */