lisp-scripts/sync-music/libcue/libcue.lisp

79 lines
2.6 KiB
Common Lisp
Raw Permalink Normal View History

(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+)))
(freopen "/dev/null" "w" +stderr+)
(unwind-protect
(progn ,@body)
(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)
`(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))))))
(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))