+(defmacro org-define-lookup-function (mode)
+ (let ((mode-str (symbol-name mode))
+ (first-p (equal mode 'first))
+ (all-p (equal mode 'all)))
+ (let ((plural-str (if all-p "s" "")))
+ `(defun ,(intern (format "org-lookup-%s" mode-str)) (val s-list r-list &optional predicate)
+ ,(format "Find %s occurrence%s of VAL in S-LIST; return corresponding element%s of R-LIST.
+If R-LIST is nil, return matching element%s of S-LIST.
+If PREDICATE is not nil, use it instead of `equal' to match VAL.
+Matching is done by (PREDICATE VAL S), where S is an element of S-LIST.
+This function is generated by a call to the macro `org-define-lookup-function'."
+ mode-str plural-str plural-str plural-str)
+ (let ,(let ((lvars '((p (or predicate 'equal))
+ (sl s-list)
+ (rl (or r-list s-list))
+ (ret nil))))
+ (if first-p (add-to-list 'lvars '(match-p nil)))
+ lvars)
+ (while ,(if first-p '(and (not match-p) sl) 'sl)
+ (progn
+ (if (funcall p val (car sl))
+ (progn
+ ,(if first-p '(setq match-p t))
+ (let ((rval (car rl)))
+ (setq ret ,(if all-p '(append ret (list rval)) 'rval)))))
+ (setq sl (cdr sl) rl (cdr rl))))
+ ret)))))
+
+(org-define-lookup-function first)
+(org-define-lookup-function last)
+(org-define-lookup-function all)
+