ambrevar/shell: Use magicffi and replace slow file-type function with fast ones.

master
Pierre Neidhardt 2021-01-12 12:35:44 +01:00
parent a9e7cb7b7d
commit c2ee48be16
2 changed files with 34 additions and 11 deletions

View File

@ -18,6 +18,7 @@
(:import-from #:iolib)
(:import-from #:local-time)
(:import-from #:log4cl)
(:import-from #:magicffi)
(:import-from #:mk-string-metrics)
(:import-from #:moptilities)
(:import-from #:osicat)

View File

@ -14,14 +14,37 @@
(delete-if #'sera:resolve-executable (cons program more-programs))))
(error "Missing programs: ~{~a~,^, ~}" missing-programs)))
(export-always 'file-type)
(defun file-type (file)
"Return the file type, as per the `file' program."
;; TODO: This is too slow, is there a pure Common Lisp equivalent?
(let ((type-string (second (str:split ": "
(run* "file" file)
:limit 2))))
(str:split ", " type-string)))
(defvar %magic-cookie-mime-type (magicffi:magic-open '(:symlink :mime-type))
"Internal, persistent cookie for `magicffi' calls.
Benchmark on thousands of files shows that
keeping the same cookie saves about 15% of time.")
(magicffi:magic-load %magic-cookie-mime-type)
(defvar %magic-cookie-mime (magicffi:magic-open '(:symlink :mime))
"See `%magic-cookie-mime-type'. ")
(magicffi:magic-load %magic-cookie-mime)
(defvar %magic-cookie-description (magicffi:magic-open '(:symlink))
"See `%magic-cookie-mime-type'. ")
(magicffi:magic-load %magic-cookie-description)
(export-always 'file-mime-type)
(defun file-mime-type (file)
"Return the FILE MIME type."
(magicffi:magic-file %magic-cookie-mime-type file))
(export-always 'file-mime)
(defun file-mime (file)
"Return a pair of MIME type and MIME encoding for FILE."
(str:split "; "
(magicffi:magic-file %magic-cookie-mime file)))
(export-always 'file-description)
(defun file-description (file)
"Return the FILE description as per the `file' UNIX command."
(magicffi:magic-file %magic-cookie-description file))
(export-always 'file-extension)
(defun file-extension (file)
@ -81,13 +104,12 @@ Useful for `walk'."
(export-always 'match-elf-binary)
(defun match-elf-binary ()
(lambda (file)
;; (ppcre:scan "ELF.*executable" (first (file-type file)))
(string= "ELF 64-bit LSB executable" (first (file-type file)))))
(string= "application/x-executable" (file-mime-type file))))
(export-always 'match-elf-library)
(defun match-elf-library ()
(lambda (file)
(ppcre:scan "ELF.*shared object" (first (file-type file)))))
(ppcre:scan "application/x-sharedlib" (first (file-type file)))))
(export-always '*finder-include-directories*)
(defvar *finder-include-directories* t