GNU bug report logs -
#8706
24.0.50; [PATCH] Function to build a URL query-string
Previous Next
Reported by: Ian Eure <ian <at> simplegeo.com>
Date: Fri, 20 May 2011 18:40:02 UTC
Severity: wishlist
Tags: patch
Found in version 24.0.50
Done: Chong Yidong <cyd <at> gnu.org>
Bug is archived. No further changes may be made.
Full log
Message #35 received at 8706 <at> debbugs.gnu.org (full text, mbox):
[Message part 1 (text/plain, inline)]
(second try for this, the first one I posted through Gmane disappeared)
Attached is a patch which:
- adds optional SEMICOLONS and KEEP-EMPTY to `url-build-query-string' to
separate parameters with semicolons and to keep empty values
- fixes `url-parse-query-string' to understand the '=' is not required
in a parameter
- adds ERT tests for `url-build-query-string' and
`url-parse-query-string'
Ian, if you could look it over, I'd appreciate it. In particular if you
think KEEP-EMPTY should be the default or if you see any other problems...
Thanks
Ted
[url-build-and-parse.patch (text/x-diff, inline)]
=== modified file 'lisp/url/url-util.el'
--- lisp/url/url-util.el 2011-01-25 04:08:28 +0000
+++ lisp/url/url-util.el 2011-06-09 16:43:39 +0000
@@ -26,7 +26,8 @@
(require 'url-parse)
(require 'url-vars)
-(eval-when-compile (require 'cl))
+(eval-when-compile (require 'cl)
+ (require 'ert))
(autoload 'timezone-parse-date "timezone")
(autoload 'timezone-make-date-arpa-standard "timezone")
(autoload 'mail-header-extract "mailheader")
@@ -263,24 +264,65 @@
;;;###autoload
(defun url-parse-query-string (query &optional downcase allow-newlines)
(let (retval pairs cur key val)
- (setq pairs (split-string query "&"))
+ (setq pairs (split-string query "[;&]"))
(while pairs
(setq cur (car pairs)
pairs (cdr pairs))
- (if (not (string-match "=" cur))
- nil ; Grace
- (setq key (url-unhex-string (substring cur 0 (match-beginning 0))
- allow-newlines))
- (setq val (url-unhex-string (substring cur (match-end 0) nil)
- allow-newlines))
- (if downcase
- (setq key (downcase key)))
- (setq cur (assoc key retval))
- (if cur
- (setcdr cur (cons val (cdr cur)))
- (setq retval (cons (list key val) retval)))))
+ (unless (string-match "=" cur)
+ (setq cur (concat cur "=")))
+
+ (when (string-match "=" cur)
+ (setq key (url-unhex-string (substring cur 0 (match-beginning 0))
+ allow-newlines))
+ (setq val (url-unhex-string (substring cur (match-end 0) nil)
+ allow-newlines))
+ (if downcase
+ (setq key (downcase key)))
+ (setq cur (assoc key retval))
+ (if cur
+ (setcdr cur (cons val (cdr cur)))
+ (setq retval (cons (list key val) retval)))))
retval))
+;;;###autoload
+(defun url-build-query-string (query &optional semicolons keep-empty)
+ "Build a query-string.
+
+Given a QUERY in the form:
+'((key1 val1)
+ (key2 val2)
+ (key3 val1 val2)
+ (key4)
+ (key5 ""))
+
+\(This is the same format as produced by `url-parse-query-string')
+
+This will return a string
+\"key1=val1&key2=val2&key3=val1&key3=val2&key4&key5\". Keys may
+be strings or symbols; if they are symbols, the symbol name will
+be used.
+
+When SEMICOLONS is given, the separator will be \";\".
+
+When KEEP-EMPTY is given, empty values will show as \"key=\"
+instead of just \"key\" as in the example above."
+ (mapconcat
+ (lambda (key-vals)
+ (let ((escaped
+ (mapcar (lambda (sym)
+ (url-hexify-string (format "%s" sym))) key-vals)))
+ (mapconcat (lambda (val)
+ (let ((vprint (format "%s" val))
+ (eprint (format "%s" (car escaped))))
+ (concat eprint
+ (if (or keep-empty
+ (and val (not (zerop (length vprint)))))
+ "="
+ "")
+ vprint)))
+ (or (cdr escaped) '("")) (if semicolons ";" "&"))))
+ query (if semicolons ";" "&")))
+
(defun url-unhex (x)
(if (> x ?9)
(if (>= x ?a)
@@ -529,6 +571,27 @@
(error "Danger: `%s' is a symbolic link" file))
(set-file-modes file #o0600))))
+(ert-deftest url-build-and-parse-query-string ()
+ (let ((tests
+ '(("key1=val1&key2=val2&key3=val1&key3=val2&key4&key5"
+ ((key1 val1) (key2 "val2") (key3 val1 val2) (key4) (key5 "")))
+ ("key1=val1;key2=val2;key3=val1;key3=val2;key4;key5"
+ ((key1 "val1") (key2 val2) (key3 val1 val2) ("key4") (key5 "")) t)
+ ("key1=val1;key2=val2;key3=val1;key3=val2;key4=;key5="
+ ((key1 val1) (key2 val2) ("key3" val1 val2) (key4) (key5 "")) t t)))
+ test)
+ (while tests
+ (setq test (car tests)
+ tests (cdr tests))
+ (should (equal (apply 'url-build-query-string (cdr test)) (car test)))))
+ (should (equal (url-parse-query-string
+ "key1=val1&key2=val2&key3=val1&key3=val2&key4=&key5")
+ '(("key5" "")
+ ("key4" "")
+ ("key3" "val2" "val1")
+ ("key2" "val2")
+ ("key1" "val1")))))
+
(provide 'url-util)
;;; url-util.el ends here
This bug report was last modified 13 years and 13 days ago.
Previous Next
GNU bug tracking system
Copyright (C) 1999 Darren O. Benham,
1997,2003 nCipher Corporation Ltd,
1994-97 Ian Jackson.