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)))))
declare
form is(debug...)
which is relevant only when stepping through the macro with edebug, so your references todeclare
are also confusing.(setq foo "bar")
does not require quotingfoo
.foo
in(setq foo "bar")
. I suggest you macroexpand your call to your macro to see what you've actually ended up with, and (again) fix the question so that it aligns with the code being shown.