123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127 |
- (in-package :hurd)
- (defclass translator-options ()
- ((table :initform nil
- :accessor table
- :documentation "Alist mapping option names and values."))
- (:documentation "Class to manage translator options."))
- (defun %get-symbol-name (symbol)
- (string-downcase (symbol-name symbol)))
- (defun make-translator-options (&optional option-list)
- "Create a new translator options object based on an option list.
- Example: '(:readonly (:update 30))."
- (let ((obj (make-instance 'translator-options)))
- (when option-list
- (set-translator-options obj option-list nil))
- obj))
- (defun %obj-to-string (obj)
- "Transforms a lisp object into a string."
- (cond
- ((null obj) "")
- ((eq t obj) "yes")
- (t (prin1-to-string obj))))
- (defun %get-string-keyword (keyword)
- "Return an option string. Example: :readonly -> --readonly."
- (concatenate-string "--"
- (string-downcase (symbol-name keyword))))
- (defun %build-option-string (base value)
- "Construct an option string."
- (if (null value)
- base
- (concatenate-string base "="
- (%obj-to-string value))))
- (defmethod get-translator-options ((options translator-options))
- "Build a list of string option assignments nearly ready to be passed down a foreign pointer, also good for printing."
- (iterate-options
- options
- (lambda (key value)
- (%build-option-string (%get-string-keyword key) value))))
- (defmethod set-translator-options ((options translator-options)
- option-list &optional (clear-old t))
- "Change the current options."
- ; Clear old options.
- (when clear-old
- (setf (table options) nil))
- (loop for option in option-list
- do (cond
- ((listp option)
- (push (cons (first option) (second option))
- (table options)))
- (t
- (push (cons option nil) (table options)))))
- t)
- (defmethod has-translator-option-p ((options translator-options) option)
- "Check if 'option' is enabled in this option set."
- (if (assoc option (table options) :test #'equal)
- t
- nil))
- (defmethod get-translator-option ((options translator-options) option)
- "Returns the value assigned to 'option' if it exists."
- (let ((found (assoc option (table options) :test #'equal)))
- (when found
- (if (cdr found)
- (cdr found)
- t))))
- (defmethod add-option ((options translator-options) option &optional value)
- "Add a new option to a set of translator options."
- (push (cons option value)
- (table options))
- options)
- (defmethod iterate-options ((options translator-options) (fn function))
- "For each option/value in options call 'fn'."
- (loop for (key . value) in (table options)
- collect (funcall fn key value)))
- (defun %get-keyword (str)
- "Return the keyword associated with string 'str'."
- (intern (string-upcase str) "KEYWORD"))
- (defun %split-options (item)
- "Split options, examples:
- 'readonly' -> :readonly
- 'max-files=5' -> (:max-files 5)"
- (let ((pos (position #\= item)))
- (cond
- ((null pos) (%get-keyword item))
- (t
- (list (%get-keyword (subseq item 0 pos))
- (let* ((value (subseq item (1+ pos)))
- (converted (read-from-string value)))
- (if (symbolp converted)
- value
- converted)))))))
- (defun get-foreign-options (ptr len)
- "From a foreign pointer 'ptr' with size 'len', return a translator options object."
- (let* ((options-list (foreign-string-zero-separated-to-list
- ptr len))
- (filtered-list ; Remove options without "--"
- (remove-if-not (lambda (item)
- (and (> (length item) 2)
- (string= "--"
- (subseq item 0 2))))
- options-list))
- (final-list ; Remove initial --
- (mapcar (lambda (item)
- (%split-options (subseq item 2)))
- filtered-list)))
- (make-translator-options final-list)))
- (defmethod print-object ((options translator-options) stream)
- "Print to 'stream' a translator options object."
- (format stream "#<translator-options ~a>"
- (get-translator-options options)))
|