Fix R6RS import conflicts for Gerbil porting compatibility
ober
1d9e13e1d00be794ce847c04758748ff08c82b5a
--- a/lib/std/misc/string.sls +++ b/lib/std/misc/string.sls @@ -1,5 +1,14 @@ #!chezscheme ;;; :std/misc/string -- String utilities +;;; +;;; NOTE: This module exports several symbols that overlap with (std srfi srfi-13): +;;; string-join, string-trim, string-prefix?, string-suffix?, string-contains, string-index +;;; If you need both modules, use (only (std misc string) string-split string-empty?) +;;; to import only the unique symbols from this module. +;;; +;;; Semantic differences from srfi-13: +;;; - string-trim: trims BOTH sides (srfi-13 trims leading only; use string-trim-both there) +;;; - string-index: takes a char (srfi-13 takes a predicate or char) (library (std misc string) (export string-split string-join string-trim --- a/lib/std/srfi/srfi-19.sls +++ b/lib/std/srfi/srfi-19.sls @@ -25,7 +25,11 @@ time-difference add-duration time-utc - make-time) + make-time + ;; Chez built-ins re-exported for Gerbil API compatibility + time-second + time-nanosecond + date-week-day) (import (chezscheme)) new file mode 100644 --- /dev/null +++ b/lib/std/string.sls @@ -0,0 +1,38 @@ +#!chezscheme +;;; :std/string -- Unified string utilities +;;; +;;; Convenience module that re-exports (std srfi srfi-13) plus the unique +;;; additions from (std misc string): string-split and string-empty?. +;;; +;;; This avoids R6RS import conflicts when you need both modules. +;;; For the full (std misc string) API or full (std srfi srfi-13) API, +;;; import them individually with (only ...) to resolve overlaps. + +(library (std string) + (export + ;; From (std srfi srfi-13) + string-index string-index-right + string-contains + string-prefix? string-suffix? + string-trim string-trim-right string-trim-both + string-pad string-pad-right + string-join string-concatenate + string-take string-take-right + string-drop string-drop-right + string-count + string-filter string-delete + string-reverse + string-null? + string-every string-any + string-fold string-fold-right + string-for-each-index + string-map! + string-tokenize + string-replace + ;; From (std misc string) — unique additions + string-split + string-empty?) + (import (std srfi srfi-13) + (only (std misc string) string-split string-empty?)) + + ) ;; end library new file mode 100644 --- /dev/null +++ b/tests/test-string-compat.ss @@ -0,0 +1,113 @@ +#!chezscheme +;;; test-string-compat.ss -- Tests for string module compatibility +;;; +;;; Verifies that (std string), (std srfi srfi-13), and (std misc string) +;;; can be used together without R6RS import conflicts. + +(import (except (chezscheme) sort sort!) + (std string) ;; unified module + (std srfi srfi-19)) ;; test new re-exports + +(define pass-count 0) +(define fail-count 0) + +(define-syntax check + (syntax-rules (=>) + ((_ name expr => expected) + (let ((result (guard (exn [else (list 'error exn)]) + expr))) + (cond + ((equal? result expected) + (set! pass-count (+ pass-count 1))) + (else + (set! fail-count (+ fail-count 1)) + (display "FAIL: ") + (display name) + (display " => ") + (write result) + (display " expected ") + (write expected) + (newline))))))) + +;;; ======================================================================== +;;; (std string) — unified string module +;;; ======================================================================== + +(display "--- std/string (unified) ---\n") + +;; string-split from (std misc string) +(check "string-split-char" (string-split "a,b,c" #\,) => '("a" "b" "c")) +(check "string-split-default" (string-split "hello world") => '("hello" "world")) +(check "string-empty?" (string-empty? "") => #t) +(check "string-not-empty?" (string-empty? "hi") => #f) + +;; string operations from (std srfi srfi-13) +(check "string-trim-leading" (string-trim " hi ") => "hi ") +(check "string-trim-both" (string-trim-both " hi ") => "hi") +(check "string-trim-right" (string-trim-right " hi ") => " hi") +(check "string-prefix?" (string-prefix? "hel" "hello") => #t) +(check "string-suffix?" (string-suffix? "lo" "hello") => #t) +(check "string-contains" (string-contains "hello world" "world") => 6) +(check "string-index-pred" (string-index "hello" char-upper-case?) => #f) +(check "string-join" (string-join '("a" "b" "c") ",") => "a,b,c") +(check "string-take" (string-take "hello" 3) => "hel") +(check "string-drop" (string-drop "hello" 3) => "lo") +(check "string-null?" (string-null? "") => #t) +(check "string-count" (string-count "hello" char-alphabetic?) => 5) +(check "string-reverse" (string-reverse "abc") => "cba") + +;;; ======================================================================== +;;; (std srfi srfi-19) — new re-exports +;;; ======================================================================== + +(display "--- std/srfi/srfi-19 (re-exports) ---\n") + +;; time-second (Chez built-in, now re-exported from srfi-19) +(let ((t (make-time 'time-utc 0 42))) + (check "time-second" (time-second t) => 42)) + +;; time-nanosecond (Chez built-in, now re-exported from srfi-19) +(let ((t (make-time 'time-utc 123456789 0))) + (check "time-nanosecond" (time-nanosecond t) => 123456789)) + +;; date-week-day (Chez built-in, now re-exported from srfi-19) +;; 2024-01-15 is a Monday = 1 +(let ((d (make-date 0 0 0 0 15 1 2024 0))) + (check "date-week-day" (date-week-day d) => 1)) + +;; time-difference still works +(let* ((t1 (make-time 'time-utc 0 100)) + (t2 (make-time 'time-utc 0 200)) + (diff (time-difference t2 t1))) + (check "time-difference" (time-second diff) => 100)) + +;; date->time-utc + time-second round-trip +(let* ((d (make-date 0 0 30 10 15 1 2024 0)) + (t (date->time-utc d))) + (check "date->time-utc" (> (time-second t) 0) => #t)) + +;;; ======================================================================== +;;; Verify no import conflict: (std srfi srfi-13) + (only (std misc string) ...) +;;; ======================================================================== + +(display "--- import compatibility ---\n") + +;; This test file already proves compatibility by importing (std string) +;; which combines both modules. If it compiled, they're compatible. +(check "import-compat" #t => #t) + +;;; ======================================================================== +;;; Summary +;;; ======================================================================== + +(newline) +(display "========================================\n") +(display "String compat tests: ") +(display pass-count) +(display " passed, ") +(display fail-count) +(display " failed\n") +(display "========================================\n") + +(when (> fail-count 0) + (exit 1))