(defun match (pattern string)
  (let ((i 0)
        (len (length string))
        star)
    (loop
       for c across pattern
       while (< i len)
       do
         (case c
           (#\* (setf star t))
           (#\? (incf i))
           (otherwise (if star
                          (loop while (and (< i len) (not (eql c (elt string i))))
                             do (incf i)
                             finally (incf i) (setf star nil))
                          (if (eql c (elt string i))
                              (incf i)
                              (return))))))
     (and (= i len) (>= len (length pattern)))))

(format t "~a ==> ~a ~%" "abcd" (match "a*?b*c*d" "abcd"))

(loop :for (s r) :on '("abcd" nil
                       "aabcd" t
                       "a?bcd" t
                       "aa?bxcxd" t
                       "aa?bxcd" t) :by #'cddr
    :for x := (match "a*?b*c*d" s) :do
    (format t "~:[FAIL~;OK~] ~:S: expected ~:[false~;true~]~%" (eq r x) s r))