+(define-public (interval-sane? i)
+ (not (or (nan? (car i))
+ (inf? (car i))
+ (nan? (cdr i))
+ (inf? (cdr i))
+ (> (car i) (cdr i)))))
+
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; string
+
+(define-public (string-endswith s suffix)
+ (equal? suffix (substring s
+ (max 0 (- (string-length s) (string-length suffix)))
+ (string-length s))))
+
+(define-public (string-startswith s prefix)
+ (equal? prefix (substring s 0 (min (string-length s) (string-length prefix)))))
+
+(define-public (string-encode-integer i)
+ (cond
+ ((= i 0) "o")
+ ((< i 0) (string-append "n" (string-encode-integer (- i))))
+ (else (string-append
+ (make-string 1 (integer->char (+ 65 (modulo i 26))))
+ (string-encode-integer (quotient i 26))))))
+
+(define (number->octal-string x)
+ (let* ((n (inexact->exact x))
+ (n64 (quotient n 64))
+ (n8 (quotient (- n (* n64 64)) 8)))
+ (string-append
+ (number->string n64)
+ (number->string n8)
+ (number->string (remainder (- n (+ (* n64 64) (* n8 8))) 8)))))
+
+(define-public (ly:inexact->string x radix)
+ (let ((n (inexact->exact x)))
+ (number->string n radix)))
+
+(define-public (ly:number-pair->string c)
+ (string-append (ly:number->string (car c)) " "
+ (ly:number->string (cdr c))))
+
+(define-public (dir-basename file . rest)
+ "Strip suffixes in REST, but leave directory component for FILE."
+ (define (inverse-basename x y) (basename y x))
+ (simple-format #f "~a/~a" (dirname file)
+ (fold inverse-basename file rest)))
+