I have a macro and a function which uses it:
(defmacro oauth2-auto--query-case (&rest cases)
"Handle HTTP queries based on the keys present in ‘query-alist’.
‘query-alist’ is a free variable, bound by the caller of this macro. Each
element of CASES has the format ‘(symbols msg body)'. For each element of CASES:
- ‘symbols' is a list of at least one symbol, which should be keys in
‘query-alist’.
- Extract and bind keys `symbols' from `query-alist'.
- If all of them are present, respond with `msg' and runs `body'.
For example of usage see ‘oauth2-auto--httpd-filter’."
(declare
(debug (&rest ((symbolp &rest symbolp) form &rest form))))
`(cond
,@(mapcar (lambda (case)
(let ((symbols (car case))
(msg (cadr case))
(body (cddr case)))
`((and ,@(--map `(cdr (assoc ',it query-alist)) symbols))
(let* (,@(--map `(,it (cdr (assoc ',it query-alist))) symbols)
(msg ,msg))
(oauth2-auto--httpd-respond process msg)
,@body))))
cases)))
(defun oauth2-auto--httpd-filter (process input)
"The HTTP handler for the OAuth2 challenge-response server.
PROCESS is the server process created in ‘oauth2-auto--browser-request’.
INPUT is the raw HTTP request."
(let ((query-alist
(with-temp-buffer
(insert input)
(goto-char (point-min))
(re-search-forward
"^[[:space:]]*GET[[:space:]]+[/?]+\\([[:graph:]]*\\)[[:space:]]+HTTP/[0-9.]+[[:space:]]*$")
(mapcar
(lambda (it) (cons (intern (car it)) (cadr it)))
(url-parse-query-string (match-string 1))))))
(oauth2-auto--query-case
((error error_description)
(format "Error %s: %s" error error_description)
(error msg)
nil)
((code state)
"Authentication token successfully obtained by Emacs! You may close this page now."
query-alist)
((favicon.ico)
""
nil) ; just return empty list if favicon.ico is requested
(()
(format "Could not parse query string %s" (pp-to-string query-alist))
(error msg)
nil))))
Despite my declare
declaration in the macro, however, I still get byte compilation errors when I try to use the macro:
In oauth2-auto--httpd-filter:
oauth2-auto.el:358:13: Warning: Unused lexical variable `code'
oauth2-auto.el:358:13: Warning: Unused lexical variable `state'
oauth2-auto.el:361:8: Warning: Unused lexical variable `favicon\.ico'
What is the right way to declare the macro to get rid of the byte compilation errors?
EDIT: I'm running Emacs 28.1. Here is the first macroexpand-step
of oauth2-auto--query-case
in oauth2-auto--httpd-filter
:
(defun oauth2-auto--httpd-filter (process input)
"The HTTP handler for the OAuth2 challenge-response server.
PROCESS is the server process created in ‘oauth2-auto--browser-request’.
INPUT is the raw HTTP request."
(let ((query-alist
(with-temp-buffer
(insert input)
(goto-char (point-min))
(re-search-forward
"^[[:space:]]*GET[[:space:]]+[/?]+\\([[:graph:]]*\\)[[:space:]]+HTTP/[0-9.]+[[:space:]]*$")
(mapcar
(lambda (it) (cons (intern (car it)) (cadr it)))
(url-parse-query-string (match-string 1))))))
(cond
((and
(cdr
(assoc 'error query-alist))
(cdr
(assoc 'error_description query-alist)))
(let*
((error
(cdr
(assoc 'error query-alist)))
(error_description
(cdr
(assoc 'error_description query-alist)))
(msg
(format "Error %s: %s" error error_description)))
(oauth2-auto--httpd-respond process msg)
(error msg)
nil))
((and
(cdr
(assoc 'code query-alist))
(cdr
(assoc 'state query-alist)))
(let*
((code
(cdr
(assoc 'code query-alist)))
(state
(cdr
(assoc 'state query-alist)))
(msg "Authentication token successfully obtained by Emacs! You may close this page now."))
(oauth2-auto--httpd-respond process msg)
query-alist))
((and
(cdr
(assoc 'favicon\.ico query-alist)))
(let*
((favicon\.ico
(cdr
(assoc 'favicon\.ico query-alist)))
(msg ""))
(oauth2-auto--httpd-respond process msg)
nil))
((and)
(let*
((msg
(format "Could not parse query string %s"
(pp-to-string query-alist))))
(oauth2-auto--httpd-respond process msg)
(error msg)
nil)))))