From: Mark Oteiza Date: Sat, 9 Sep 2017 15:55:09 +0000 (-0400) Subject: Add function to read all entries in a group X-Git-Tag: emacs-26.0.90~216 X-Git-Url: http://git.eshelyaron.com/gitweb/?a=commitdiff_plain;h=4131f9785e30f2a31745125c714e922892113c62;p=emacs.git Add function to read all entries in a group Use that to extend xdg-desktop-read-file. Also fix a bug where all entries in all groups were read and returned by xdg-desktop-read-file. * lisp/xdg.el (xdg-desktop-read-group): New function. (xdg-desktop-read-file): Use it. * test/data/xdg/malformed.desktop: New file. * test/data/xdg/test.desktop: Add another section. * test/lisp/xdg-tests.el (xdg-desktop-parsing): Test presence of a key in another group. Test reading a prescribed group. Test detecting a malformed key=value. --- diff --git a/lisp/xdg.el b/lisp/xdg.el index c7000219487..102e34cb0ce 100644 --- a/lisp/xdg.el +++ b/lisp/xdg.el @@ -167,33 +167,41 @@ This should be called at the beginning of a line." (group-n 2 (* nonl))) "Regexp matching desktop file entry key-value pairs.") -(defun xdg--desktop-parse-line () - (skip-chars-forward "[:blank:]") - (when (/= (following-char) ?#) - (cond - ((looking-at xdg-desktop-entry-regexp) - (cons (match-string 1) (match-string 2))) - ((looking-at xdg-desktop-group-regexp) - (match-string 1))))) - -(defun xdg-desktop-read-file (filename) - "Return \"Desktop Entry\" contents of desktop file FILENAME as a hash table." - (let ((res (make-hash-table :test #'equal)) - elt group) - (with-temp-buffer - (insert-file-contents-literally filename) - (goto-char (point-min)) - (while (or (= (following-char) ?#) - (string-blank-p (buffer-substring (point) (point-at-eol)))) - (forward-line)) - (unless (equal (setq group (xdg--desktop-parse-line)) "Desktop Entry") - (error "Wrong first section: %s" group)) - (while (not (eobp)) - (when (consp (setq elt (xdg--desktop-parse-line))) - (puthash (car elt) (cdr elt) res)) - (forward-line))) +(defun xdg-desktop-read-group () + "Return hash table of group of desktop entries in the current buffer." + (let ((res (make-hash-table :test #'equal))) + (while (not (or (eobp) (looking-at xdg-desktop-group-regexp))) + (skip-chars-forward "[:blank:]") + (cond + ((eolp)) + ((= (following-char) ?#)) + ((looking-at xdg-desktop-entry-regexp) + (puthash (match-string 1) (match-string 2) res)) + (t (error "Malformed line: %s" + (buffer-substring (point) (point-at-eol))))) + (forward-line)) res)) +(defun xdg-desktop-read-file (filename &optional group) + "Return group contents of desktop file FILENAME as a hash table. +Optional argument GROUP defaults to the string \"Desktop Entry\"." + (with-temp-buffer + (insert-file-contents-literally filename) + (goto-char (point-min)) + (while (and (skip-chars-forward "[:blank:]" (line-end-position)) + (or (eolp) (= (following-char) ?#))) + (forward-line)) + (unless (looking-at xdg-desktop-group-regexp) + (error "Expected group name! Instead saw: %s" + (buffer-substring (point) (point-at-eol)))) + (unless (equal (match-string 1) "Desktop Entry") + (error "Wrong first group: %s" (match-string 1))) + (when group + (while (and (re-search-forward xdg-desktop-group-regexp nil t) + (not (equal (match-string 1) group))))) + (forward-line) + (xdg-desktop-read-group))) + (defun xdg-desktop-strings (value) "Partition VALUE into elements delimited by unescaped semicolons." (let (res) diff --git a/test/data/xdg/malformed.desktop b/test/data/xdg/malformed.desktop new file mode 100644 index 00000000000..144a3f719d5 --- /dev/null +++ b/test/data/xdg/malformed.desktop @@ -0,0 +1,4 @@ +# unacceptable key=value format +[Desktop Entry] +Key=value +aowef faoweif of diff --git a/test/data/xdg/test.desktop b/test/data/xdg/test.desktop index b6dda62774a..b848cef5b0f 100644 --- a/test/data/xdg/test.desktop +++ b/test/data/xdg/test.desktop @@ -1,3 +1,5 @@ # this is a comment [Desktop Entry] Name=Test +[Another Section] +Exec=frobnicate diff --git a/test/lisp/xdg-tests.el b/test/lisp/xdg-tests.el index 59c850b07af..4822a05c1e4 100644 --- a/test/lisp/xdg-tests.el +++ b/test/lisp/xdg-tests.el @@ -32,12 +32,20 @@ (ert-deftest xdg-desktop-parsing () "Test `xdg-desktop-read-file' parsing of .desktop files." - (let ((tab (xdg-desktop-read-file - (expand-file-name "test.desktop" xdg-tests-data-dir)))) - (should (equal (gethash "Name" tab) "Test"))) + (let ((tab1 (xdg-desktop-read-file + (expand-file-name "test.desktop" xdg-tests-data-dir))) + (tab2 (xdg-desktop-read-file + (expand-file-name "test.desktop" xdg-tests-data-dir) + "Another Section"))) + (should (equal (gethash "Name" tab1) "Test")) + (should (eq 'default (gethash "Exec" tab1 'default))) + (should (equal "frobnicate" (gethash "Exec" tab2)))) (should-error (xdg-desktop-read-file - (expand-file-name "wrong.desktop" xdg-tests-data-dir)))) + (expand-file-name "wrong.desktop" xdg-tests-data-dir))) + (should-error + (xdg-desktop-read-file + (expand-file-name "malformed.desktop" xdg-tests-data-dir)))) (ert-deftest xdg-desktop-strings-type () "Test desktop \"string(s)\" type: strings delimited by \";\"."