macOS port: graceful FFI loading with foreign-entry? guards
ober
52f15d4eb5935164cb71c3eadfa71d9fcfb6d7d5
--- a/src/chez-scintilla/ffi.sls +++ b/src/chez-scintilla/ffi.sls @@ -80,184 +80,310 @@ (or (getenv "CHEZ_SCINTILLA_LIB") ".")) + (define shlib-ext + (let ((mt (symbol->string (machine-type)))) + (if (and (>= (string-length mt) 3) + (string=? (substring mt (- (string-length mt) 3) (string-length mt)) "osx")) + "dylib" + "so"))) + (define _shim-loaded - (load-shared-object - (format "~a/chez_scintilla_shim.so" shim-dir))) + (guard (e [#t #f]) ;; gracefully skip if shim not available (e.g. macOS Qt-only build) + (load-shared-object + (format "~a/chez_scintilla_shim.~a" shim-dir shlib-ext)))) + + ;; Optional FFI — returns error-raising thunk if symbol not present. + ;; Used when the termbox shim may not be available (e.g. macOS Qt builds). + (define-syntax define-scintilla-ffi + (syntax-rules () + [(_ name c-name (arg-type ...) ret-type) + (define name + (if (foreign-entry? c-name) + (foreign-procedure c-name (arg-type ...) ret-type) + (lambda _ (error 'chez-scintilla "termbox shim not loaded" c-name))))])) ;; ==================================================================== ;; Instance lifecycle ;; ==================================================================== (define ffi-scintilla-new - (foreign-procedure "chez_scintilla_new" () void*)) + (if (foreign-entry? "chez_scintilla_new") + (foreign-procedure "chez_scintilla_new" () void*) + (lambda () (error 'chez-scintilla "termbox shim not loaded" "chez_scintilla_new")))) (define ffi-scintilla-delete - (foreign-procedure "chez_scintilla_delete" (void*) void)) + (if (foreign-entry? "chez_scintilla_delete") + (foreign-procedure "chez_scintilla_delete" (void*) void) + (lambda _ (error 'chez-scintilla "termbox shim not loaded" "chez_scintilla_delete")))) ;; ==================================================================== ;; Message passing ;; ==================================================================== (define ffi-scintilla-send-message - (foreign-procedure "chez_scintilla_send_message" - (void* unsigned int unsigned-long long) long)) + (if (foreign-entry? "chez_scintilla_send_message") + (foreign-procedure "chez_scintilla_send_message" + (void* unsigned int unsigned-long long) long) + (lambda _ (error 'chez-scintilla "termbox shim not loaded" "chez_scintilla_send_message")))) (define ffi-scintilla-send-message-string - (foreign-procedure "chez_scintilla_send_message_string" - (void* unsigned-int unsigned-long string) long)) + (if (foreign-entry? "chez_scintilla_send_message_string") + (foreign-procedure "chez_scintilla_send_message_string" + (void* unsigned-int unsigned-long string) long) + (lambda _ (error 'chez-scintilla "termbox shim not loaded" "chez_scintilla_send_message_string")))) (define ffi-scintilla-receive-string - (foreign-procedure "chez_scintilla_receive_string" - (void* unsigned-int unsigned-long) string)) + (if (foreign-entry? "chez_scintilla_receive_string") + (foreign-procedure "chez_scintilla_receive_string" + (void* unsigned-int unsigned-long) string) + (lambda _ (error 'chez-scintilla "termbox shim not loaded" "chez_scintilla_receive_string")))) (define ffi-scintilla-set-property - (foreign-procedure "chez_scintilla_set_property" - (void* unsigned-int string string) long)) + (if (foreign-entry? "chez_scintilla_set_property") + (foreign-procedure "chez_scintilla_set_property" + (void* unsigned-int string string) long) + (lambda _ (error 'chez-scintilla "termbox shim not loaded" "chez_scintilla_set_property")))) ;; ==================================================================== ;; Input ;; ==================================================================== (define ffi-scintilla-send-key - (foreign-procedure "chez_scintilla_send_key" - (void* int int int int) void)) + (if (foreign-entry? "chez_scintilla_send_key") + (foreign-procedure "chez_scintilla_send_key" + (void* int int int int) void) + (lambda _ (error 'chez-scintilla "termbox shim not loaded" "chez_scintilla_send_key")))) (define ffi-scintilla-send-mouse - (foreign-procedure "chez_scintilla_send_mouse" - (void* int int int int int int int) int)) + (if (foreign-entry? "chez_scintilla_send_mouse") + (foreign-procedure "chez_scintilla_send_mouse" + (void* int int int int int int int) int) + (lambda _ (error 'chez-scintilla "termbox shim not loaded" "chez_scintilla_send_mouse")))) ;; ==================================================================== ;; Display ;; ==================================================================== (define ffi-scintilla-refresh - (foreign-procedure "chez_scintilla_refresh" (void*) void)) + (if (foreign-entry? "chez_scintilla_refresh") + (foreign-procedure "chez_scintilla_refresh" (void*) void) + (lambda _ (error 'chez-scintilla "termbox shim not loaded" "chez_scintilla_refresh")))) (define ffi-scintilla-resize - (foreign-procedure "chez_scintilla_resize" (void* int int) void)) + (if (foreign-entry? "chez_scintilla_resize") + (foreign-procedure "chez_scintilla_resize" (void* int int) void) + (lambda _ (error 'chez-scintilla "termbox shim not loaded" "chez_scintilla_resize")))) (define ffi-scintilla-move - (foreign-procedure "chez_scintilla_move" (void* int int) void)) + (if (foreign-entry? "chez_scintilla_move") + (foreign-procedure "chez_scintilla_move" (void* int int) void) + (lambda _ (error 'chez-scintilla "termbox shim not loaded" "chez_scintilla_move")))) ;; ==================================================================== ;; Clipboard ;; ==================================================================== (define ffi-scintilla-get-clipboard - (foreign-procedure "chez_scintilla_get_clipboard" (void*) string)) + (if (foreign-entry? "chez_scintilla_get_clipboard") + (foreign-procedure "chez_scintilla_get_clipboard" (void*) string) + (lambda _ (error 'chez-scintilla "termbox shim not loaded" "chez_scintilla_get_clipboard")))) ;; ==================================================================== ;; Lexer ;; ==================================================================== (define ffi-scintilla-set-lexer-language - (foreign-procedure "chez_scintilla_set_lexer_language" (void* string) void)) + (if (foreign-entry? "chez_scintilla_set_lexer_language") + (foreign-procedure "chez_scintilla_set_lexer_language" (void* string) void) + (lambda _ (error 'chez-scintilla "termbox shim not loaded" "chez_scintilla_set_lexer_language")))) ;; ==================================================================== ;; Notification queue ;; ==================================================================== (define ffi-scintilla-drain-one - (foreign-procedure "chez_scintilla_drain_one" (void*) int)) + (if (foreign-entry? "chez_scintilla_drain_one") + (foreign-procedure "chez_scintilla_drain_one" (void*) int) + (lambda _ (error 'chez-scintilla "termbox shim not loaded" "chez_scintilla_drain_one")))) (define ffi-scn-code - (foreign-procedure "chez_scn_code" () int)) + (if (foreign-entry? "chez_scn_code") + (foreign-procedure "chez_scn_code" () int) + (lambda _ (error 'chez-scintilla "termbox shim not loaded" "chez_scn_code")))) (define ffi-scn-position - (foreign-procedure "chez_scn_position" () long)) + (if (foreign-entry? "chez_scn_position") + (foreign-procedure "chez_scn_position" () long) + (lambda _ (error 'chez-scintilla "termbox shim not loaded" "chez_scn_position")))) (define ffi-scn-ch - (foreign-procedure "chez_scn_ch" () int)) + (if (foreign-entry? "chez_scn_ch") + (foreign-procedure "chez_scn_ch" () int) + (lambda _ (error 'chez-scintilla "termbox shim not loaded" "chez_scn_ch")))) (define ffi-scn-modifiers - (foreign-procedure "chez_scn_modifiers" () int)) + (if (foreign-entry? "chez_scn_modifiers") + (foreign-procedure "chez_scn_modifiers" () int) + (lambda _ (error 'chez-scintilla "termbox shim not loaded" "chez_scn_modifiers")))) (define ffi-scn-modification-type - (foreign-procedure "chez_scn_modification_type" () int)) + (if (foreign-entry? "chez_scn_modification_type") + (foreign-procedure "chez_scn_modification_type" () int) + (lambda _ (error 'chez-scintilla "termbox shim not loaded" "chez_scn_modification_type")))) (define ffi-scn-text - (foreign-procedure "chez_scn_text" () string)) + (if (foreign-entry? "chez_scn_text") + (foreign-procedure "chez_scn_text" () string) + (lambda _ (error 'chez-scintilla "termbox shim not loaded" "chez_scn_text")))) (define ffi-scn-length - (foreign-procedure "chez_scn_length" () long)) + (if (foreign-entry? "chez_scn_length") + (foreign-procedure "chez_scn_length" () long) + (lambda _ (error 'chez-scintilla "termbox shim not loaded" "chez_scn_length")))) (define ffi-scn-lines-added - (foreign-procedure "chez_scn_lines_added" () long)) + (if (foreign-entry? "chez_scn_lines_added") + (foreign-procedure "chez_scn_lines_added" () long) + (lambda _ (error 'chez-scintilla "termbox shim not loaded" "chez_scn_lines_added")))) (define ffi-scn-message - (foreign-procedure "chez_scn_message" () int)) + (if (foreign-entry? "chez_scn_message") + (foreign-procedure "chez_scn_message" () int) + (lambda _ (error 'chez-scintilla "termbox shim not loaded" "chez_scn_message")))) (define ffi-scn-line - (foreign-procedure "chez_scn_line" () long)) + (if (foreign-entry? "chez_scn_line") + (foreign-procedure "chez_scn_line" () long) + (lambda _ (error 'chez-scintilla "termbox shim not loaded" "chez_scn_line")))) (define ffi-scn-fold-level-now - (foreign-procedure "chez_scn_fold_level_now" () int)) + (if (foreign-entry? "chez_scn_fold_level_now") + (foreign-procedure "chez_scn_fold_level_now" () int) + (lambda _ (error 'chez-scintilla "termbox shim not loaded" "chez_scn_fold_level_now")))) (define ffi-scn-fold-level-prev - (foreign-procedure "chez_scn_fold_level_prev" () int)) + (if (foreign-entry? "chez_scn_fold_level_prev") + (foreign-procedure "chez_scn_fold_level_prev" () int) + (lambda _ (error 'chez-scintilla "termbox shim not loaded" "chez_scn_fold_level_prev")))) (define ffi-scn-margin - (foreign-procedure "chez_scn_margin" () int)) + (if (foreign-entry? "chez_scn_margin") + (foreign-procedure "chez_scn_margin" () int) + (lambda _ (error 'chez-scintilla "termbox shim not loaded" "chez_scn_margin")))) (define ffi-scn-list-type - (foreign-procedure "chez_scn_list_type" () int)) + (if (foreign-entry? "chez_scn_list_type") + (foreign-procedure "chez_scn_list_type" () int) + (lambda _ (error 'chez-scintilla "termbox shim not loaded" "chez_scn_list_type")))) (define ffi-scn-x - (foreign-procedure "chez_scn_x" () int)) + (if (foreign-entry? "chez_scn_x") + (foreign-procedure "chez_scn_x" () int) + (lambda _ (error 'chez-scintilla "termbox shim not loaded" "chez_scn_x")))) (define ffi-scn-y - (foreign-procedure "chez_scn_y" () int)) + (if (foreign-entry? "chez_scn_y") + (foreign-procedure "chez_scn_y" () int) + (lambda _ (error 'chez-scintilla "termbox shim not loaded" "chez_scn_y")))) (define ffi-scn-token - (foreign-procedure "chez_scn_token" () int)) + (if (foreign-entry? "chez_scn_token") + (foreign-procedure "chez_scn_token" () int) + (lambda _ (error 'chez-scintilla "termbox shim not loaded" "chez_scn_token")))) (define ffi-scn-updated - (foreign-procedure "chez_scn_updated" () int)) + (if (foreign-entry? "chez_scn_updated") + (foreign-procedure "chez_scn_updated" () int) + (lambda _ (error 'chez-scintilla "termbox shim not loaded" "chez_scn_updated")))) ;; ==================================================================== ;; Termbox ;; ==================================================================== (define ffi-tb-init - (foreign-procedure "chez_tb_init" () int)) + (if (foreign-entry? "chez_tb_init") + (foreign-procedure "chez_tb_init" () int) + (lambda _ (error 'chez-scintilla "termbox shim not loaded" "chez_tb_init")))) (define ffi-tb-shutdown - (foreign-procedure "chez_tb_shutdown" () void)) + (if (foreign-entry? "chez_tb_shutdown") + (foreign-procedure "chez_tb_shutdown" () void) + (lambda _ (error 'chez-scintilla "termbox shim not loaded" "chez_tb_shutdown")))) (define ffi-tb-width - (foreign-procedure "chez_tb_width" () int)) + (if (foreign-entry? "chez_tb_width") + (foreign-procedure "chez_tb_width" () int) + (lambda _ (error 'chez-scintilla "termbox shim not loaded" "chez_tb_width")))) (define ffi-tb-height - (foreign-procedure "chez_tb_height" () int)) + (if (foreign-entry? "chez_tb_height") + (foreign-procedure "chez_tb_height" () int) + (lambda _ (error 'chez-scintilla "termbox shim not loaded" "chez_tb_height")))) (define ffi-tb-clear - (foreign-procedure "chez_tb_clear" () void)) + (if (foreign-entry? "chez_tb_clear") + (foreign-procedure "chez_tb_clear" () void) + (lambda _ (error 'chez-scintilla "termbox shim not loaded" "chez_tb_clear")))) (define ffi-tb-present - (foreign-procedure "chez_tb_present" () void)) + (if (foreign-entry? "chez_tb_present") + (foreign-procedure "chez_tb_present" () void) + (lambda _ (error 'chez-scintilla "termbox shim not loaded" "chez_tb_present")))) (define ffi-tb-set-cursor - (foreign-procedure "chez_tb_set_cursor" (int int) void)) + (if (foreign-entry? "chez_tb_set_cursor") + (foreign-procedure "chez_tb_set_cursor" (int int) void) + (lambda _ (error 'chez-scintilla "termbox shim not loaded" "chez_tb_set_cursor")))) (define ffi-tb-poll-event - (foreign-procedure "chez_tb_poll_event" () int)) + (if (foreign-entry? "chez_tb_poll_event") + (foreign-procedure "chez_tb_poll_event" () int) + (lambda _ (error 'chez-scintilla "termbox shim not loaded" "chez_tb_poll_event")))) (define ffi-tb-peek-event - (foreign-procedure "chez_tb_peek_event" (int) int)) + (if (foreign-entry? "chez_tb_peek_event") + (foreign-procedure "chez_tb_peek_event" (int) int) + (lambda _ (error 'chez-scintilla "termbox shim not loaded" "chez_tb_peek_event")))) (define ffi-tb-event-type - (foreign-procedure "chez_tb_event_type" () int)) + (if (foreign-entry? "chez_tb_event_type") + (foreign-procedure "chez_tb_event_type" () int) + (lambda _ (error 'chez-scintilla "termbox shim not loaded" "chez_tb_event_type")))) (define ffi-tb-event-mod - (foreign-procedure "chez_tb_event_mod" () int)) + (if (foreign-entry? "chez_tb_event_mod") + (foreign-procedure "chez_tb_event_mod" () int) + (lambda _ (error 'chez-scintilla "termbox shim not loaded" "chez_tb_event_mod")))) (define ffi-tb-event-key - (foreign-procedure "chez_tb_event_key" () int)) + (if (foreign-entry? "chez_tb_event_key") + (foreign-procedure "chez_tb_event_key" () int) + (lambda _ (error 'chez-scintilla "termbox shim not loaded" "chez_tb_event_key")))) (define ffi-tb-event-ch - (foreign-procedure "chez_tb_event_ch" () unsigned-int)) + (if (foreign-entry? "chez_tb_event_ch") + (foreign-procedure "chez_tb_event_ch" () unsigned-int) + (lambda _ (error 'chez-scintilla "termbox shim not loaded" "chez_tb_event_ch")))) (define ffi-tb-event-w - (foreign-procedure "chez_tb_event_w" () int)) + (if (foreign-entry? "chez_tb_event_w") + (foreign-procedure "chez_tb_event_w" () int) + (lambda _ (error 'chez-scintilla "termbox shim not loaded" "chez_tb_event_w")))) (define ffi-tb-event-h - (foreign-procedure "chez_tb_event_h" () int)) + (if (foreign-entry? "chez_tb_event_h") + (foreign-procedure "chez_tb_event_h" () int) + (lambda _ (error 'chez-scintilla "termbox shim not loaded" "chez_tb_event_h")))) (define ffi-tb-event-x - (foreign-procedure "chez_tb_event_x" () int)) + (if (foreign-entry? "chez_tb_event_x") + (foreign-procedure "chez_tb_event_x" () int) + (lambda _ (error 'chez-scintilla "termbox shim not loaded" "chez_tb_event_x")))) (define ffi-tb-event-y - (foreign-procedure "chez_tb_event_y" () int)) + (if (foreign-entry? "chez_tb_event_y") + (foreign-procedure "chez_tb_event_y" () int) + (lambda _ (error 'chez-scintilla "termbox shim not loaded" "chez_tb_event_y")))) ;; ==================================================================== ;; Termbox extended ;; ==================================================================== (define ffi-tb-change-cell - (foreign-procedure "chez_tb_change_cell" - (int int unsigned-32 unsigned-32 unsigned-32) void)) + (if (foreign-entry? "chez_tb_change_cell") + (foreign-procedure "chez_tb_change_cell" + (int int unsigned-32 unsigned-32 unsigned-32) void) + (lambda _ (error 'chez-scintilla "termbox shim not loaded" "chez_tb_change_cell")))) (define ffi-tb-set-clear-attributes - (foreign-procedure "chez_tb_set_clear_attributes" - (unsigned-32 unsigned-32) void)) + (if (foreign-entry? "chez_tb_set_clear_attributes") + (foreign-procedure "chez_tb_set_clear_attributes" + (unsigned-32 unsigned-32) void) + (lambda _ (error 'chez-scintilla "termbox shim not loaded" "chez_tb_set_clear_attributes")))) (define ffi-tb-select-input-mode - (foreign-procedure "chez_tb_select_input_mode" (int) int)) + (if (foreign-entry? "chez_tb_select_input_mode") + (foreign-procedure "chez_tb_select_input_mode" (int) int) + (lambda _ (error 'chez-scintilla "termbox shim not loaded" "chez_tb_select_input_mode")))) (define ffi-tb-select-output-mode - (foreign-procedure "chez_tb_select_output_mode" (int) int)) + (if (foreign-entry? "chez_tb_select_output_mode") + (foreign-procedure "chez_tb_select_output_mode" (int) int) + (lambda _ (error 'chez-scintilla "termbox shim not loaded" "chez_tb_select_output_mode")))) (define ffi-tb-print-string - (foreign-procedure "chez_tb_print_string" - (int int unsigned-32 unsigned-32 string) void)) + (if (foreign-entry? "chez_tb_print_string") + (foreign-procedure "chez_tb_print_string" + (int int unsigned-32 unsigned-32 string) void) + (lambda _ (error 'chez-scintilla "termbox shim not loaded" "chez_tb_print_string")))) ) ;; end library