2024-11-11 18:34:27 -08:00
|
|
|
(in-package #:sync-music/libcue)
|
|
|
|
|
|
|
|
(defmacro with-read-file ((var path) &body body)
|
|
|
|
"Bind VAR to the result of an fopen on PATH while executing BODY."
|
|
|
|
(once-only (path)
|
|
|
|
`(let ((,var (fopen (uiop:native-namestring ,path) "r")))
|
|
|
|
(declare (dynamic-extent ,var))
|
|
|
|
(when (cffi:null-pointer-p ,var)
|
|
|
|
(error "Failed to open file `~A` with errno ~A." ,path +errno+))
|
|
|
|
(unwind-protect
|
|
|
|
(progn ,@body)
|
|
|
|
(fclose ,var)))))
|
|
|
|
|
|
|
|
(defmacro with-ignore-stderr (&body body)
|
|
|
|
"Execute BODY without printing anything into stderr.
|
|
|
|
|
|
|
|
Only works on Unix systems with a /dev/fd/ filesystem."
|
|
|
|
#+unix
|
|
|
|
(with-gensyms (old-stderr)
|
|
|
|
`(progn
|
|
|
|
(finish-output *error-output*)
|
|
|
|
(let ((,old-stderr (dup +stderr-fileno+)))
|
2024-11-11 19:57:16 -08:00
|
|
|
(freopen "/dev/null" "w" +stderr+)
|
|
|
|
(unwind-protect
|
|
|
|
(progn ,@body)
|
2024-11-11 18:34:27 -08:00
|
|
|
(freopen (format nil "/dev/fd/~D" ,old-stderr) "a" +stderr+)))))
|
|
|
|
#-unix
|
|
|
|
`(progn ,@body))
|
|
|
|
|
|
|
|
(defmacro with-cue ((var type data) &body body)
|
|
|
|
"Bind VAR to the result of a cue_parse_* while executing BODY.
|
|
|
|
|
|
|
|
If TYPE is :FILE, use cue_parse_file with fopen on DATA. If TYPE is :STRING,
|
|
|
|
use cue_parse_string directly."
|
|
|
|
(once-only (data)
|
2024-12-19 15:51:00 -08:00
|
|
|
`(let ((,var (with-ignore-stderr
|
|
|
|
,(ecase type
|
|
|
|
(:file
|
|
|
|
(with-gensyms (file)
|
|
|
|
`(with-read-file (,file ,data)
|
|
|
|
(cue-parse-file ,file))))
|
|
|
|
(:string
|
|
|
|
`(cue-parse-string ,data))))))
|
2024-11-11 18:34:27 -08:00
|
|
|
(declare (dynamic-extent ,var))
|
|
|
|
(unless (cffi:null-pointer-p ,var)
|
|
|
|
(unwind-protect
|
|
|
|
(progn ,@body)
|
|
|
|
(cd-delete ,var))))))
|
|
|
|
|
|
|
|
(defun get-rem (type data)
|
|
|
|
(rem-get (cffi:foreign-enum-value 'rem-type type) data))
|
|
|
|
|
|
|
|
(defun get-cd-text (type data)
|
|
|
|
(cd-text-get (cffi:foreign-enum-value 'pti type) data))
|
|
|
|
|
|
|
|
(defun cd-get-mode (cd)
|
|
|
|
(cffi:foreign-enum-keyword 'disc-mode
|
|
|
|
(%cd-get-mode cd)))
|
|
|
|
|
|
|
|
(defun track-get-mode (track)
|
|
|
|
(cffi:foreign-enum-keyword 'track-mode
|
|
|
|
(%track-get-mode track)))
|
|
|
|
|
|
|
|
(defun track-get-sub-mode (track)
|
|
|
|
(cffi:foreign-enum-keyword 'track-sub-mode
|
|
|
|
(%track-get-sub-mode track)))
|
|
|
|
|
|
|
|
(defun track-flag-set-p (track flag)
|
|
|
|
(%track-flag-set-p track
|
|
|
|
(cffi:foreign-enum-keyword 'track-flag flag)))
|
|
|
|
|
|
|
|
(defun ensure-nonempty (val)
|
|
|
|
"Ensure a null value returned by a libcue function is NIL."
|
|
|
|
(unless (etypecase val
|
|
|
|
(null t)
|
|
|
|
(string (emptyp val))
|
|
|
|
(integer (minusp val)))
|
|
|
|
val))
|