commit 22994735af588be9c2d6d438155b73328aaa0cf3 (HEAD, refs/remotes/origin/master) Author: Aaron S. Hawley Date: Fri Feb 26 16:18:58 2016 +1030 Add forward-sexp (and related) tests * test/lisp/emacs-lisp/lisp-tests.el: New file for testing forward-sexp and related functions (bug#22800). diff --git a/test/lisp/emacs-lisp/lisp-tests.el b/test/lisp/emacs-lisp/lisp-tests.el new file mode 100644 index 0000000..4fe20f0 --- /dev/null +++ b/test/lisp/emacs-lisp/lisp-tests.el @@ -0,0 +1,211 @@ +;;; lisp-tests.el --- Test Lisp editing commands -*- lexical-binding: t; -*- + +;; Copyright (C) 2013-2016 Free Software Foundation, Inc. + +;; Author: Aaron S. Hawley +;; Keywords: internal + +;; GNU Emacs is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; GNU Emacs is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs. If not, see . + +;;; Commentary: + +;; Testing of `forward-sexp' and related functions. + +;;; Code: + +(require 'ert) +(require 'python) + +(ert-deftest lisp-forward-sexp-1-empty-parens () + "Test basics of \\[forward-sexp]." + (with-temp-buffer + (insert "()") + (goto-char (point-min)) + (should (null + (forward-sexp 1))))) + +(ert-deftest lisp-forward-sexp-1-error-mismatch () + "Test basics of \\[forward-sexp]." + (with-temp-buffer + (insert "(") + (goto-char (point-min)) + (should-error + (forward-sexp 1)))) + +(ert-deftest lisp-backward-sexp-1-empty-parens () + "Test basics of \\[backward-sexp]." + (with-temp-buffer + (insert "()") + (should (null + (forward-sexp -1))))) + +(ert-deftest lisp-backward-sexp-1-error-mismatch () + "Test mismatched parens with \\[backward-sexp]." + (with-temp-buffer + (insert "(") + (should-error + (forward-sexp -1)))) + +(ert-deftest lisp-forward-sexp-1-eobp () + "Test \\[forward-sexp] at `eobp'." + (with-temp-buffer + (insert "()") + (should (null ;; (should-error ;; No, per #13994 + (forward-sexp 1))))) + +(ert-deftest lisp-backward-sexp-1-eobp () + "Test \\[backward-sexp] at `bobp'." + (with-temp-buffer + (insert "()") + (goto-char (point-min)) + (should (null ;; (should-error ;; No, per #13994 + (forward-sexp -1))))) + +(ert-deftest lisp-forward-sexp-2-eobp () + "Test \\[forward-sexp] beyond `eobp'." + (with-temp-buffer + (insert "()") + (goto-char (point-min)) + (should (null ;; (should-error ;; No, per #13994 + (forward-sexp 2))) + (should (eobp)))) + +(ert-deftest lisp-backward-sexp-2-bobp () + "Test \\[backward-sexp] beyond `bobp'." + (with-temp-buffer + (insert "()") + (should (null ;; (should-error ;; No, per #13994 + (forward-sexp -2))) + (should (bobp)))) + +(ert-deftest lisp-forward-sexp-2-eobp-and-subsequent () + "Test \\[forward-sexp] beyond `eobp' and again." + (with-temp-buffer + (insert "()") + (goto-char (point-min)) + (should (null ;; (should-error ;; No, per #13994 + (forward-sexp 2))) + (should (eobp)) + (should (null ;; (should-error ;; No, per #13994 + (forward-sexp 1))))) + +(ert-deftest lisp-backward-sexp-2-bobp-and-subsequent () + "Test \\[backward-sexp] ahead of `bobp' and again." + (with-temp-buffer + (insert "()") + (should (null ;; (should-error ;; No, per #13994 + (forward-sexp -2))) + (should (bobp)) + (should (null ;; (should-error ;; No, per #13994 + (forward-sexp -1))))) + +(ert-deftest lisp-delete-pair-parens () + "Test \\[delete-pair] with parens." + (with-temp-buffer + (insert "(foo)") + (goto-char (point-min)) + (delete-pair) + (should (string-equal "foo" (buffer-string))))) + +(ert-deftest lisp-delete-pair-quotation-marks () + "Test \\[delete-pair] with quotation marks." + (with-temp-buffer + (insert "\"foo\"") + (goto-char (point-min)) + (delete-pair) + (should (string-equal "foo" (buffer-string))))) + +(ert-deftest lisp-delete-pair-quotes-in-text-mode () + "Test \\[delete-pair] against string in Text Mode for #15014." + (with-temp-buffer + (text-mode) + (insert "\"foo\"") + (goto-char (point-min)) + (delete-pair) + (should (string-equal "fo\"" (buffer-string))))) + +(ert-deftest lisp-delete-pair-quotes-text-mode-syntax-table () + "Test \\[delete-pair] with modified Text Mode syntax for #15014." + (with-temp-buffer + (text-mode) + (let ((st (copy-syntax-table text-mode-syntax-table))) + (with-syntax-table st + ;; (modify-syntax-entry ?\" "." text-mode-syntax-table) + (modify-syntax-entry ?\" "$" st) + (insert "\"foo\"") + (goto-char (point-min)) + (delete-pair) + (should (string-equal "foo" (buffer-string))))))) + +(ert-deftest lisp-forward-sexp-elisp-inside-symbol () + "Test \\[forward-sexp] on symbol in Emacs Lisp Mode for #20492." + (with-temp-buffer + (emacs-lisp-mode) + (insert "hide-ifdef-env ") + (insert (concat (number-sequence 32 126))) + (goto-char (point-min)) + (re-search-forward "hide" nil t) ;; (forward-char 4) + (should (looking-at "-")) + (forward-sexp) + (should (looking-at " ")))) + +(ert-deftest lisp-forward-sexp-elisp-quoted-symbol () + "Test \\[forward-sexp] on symbol in Emacs Lisp Mode for #20492." + (with-temp-buffer + (emacs-lisp-mode) + (insert "`hide-ifdef-env'.") + (goto-char (point-min)) + (re-search-forward "hide" nil t) ;; (forward-char 5) + (should (= ?- (char-after))) + (forward-sexp) + (should (= ?. (char-before))))) + +(ert-deftest lisp-forward-sexp-python-triple-quoted-string () + "Test \\[forward-sexp] on Python doc strings for #11321." + (with-temp-buffer + (insert "\"\"\"Triple-quoted string\"\"\"") + (goto-char (point-min)) + (let ((python-indent-guess-indent-offset nil)) + (python-mode)) + (forward-sexp) + (should (eobp)))) + +(ert-deftest lisp-forward-sexp-python-triple-quotes-string () + "Test \\[forward-sexp] on Python doc strings for #11321." + (with-temp-buffer + (insert "'''Triple-quoted string'''") + (goto-char (point-min)) + (let ((python-indent-guess-indent-offset nil)) + (python-mode)) + (forward-sexp) + (should (eobp)))) + +(ert-deftest lisp-forward-sexp-emacs-lisp-semi-char-error () + "Test \\[forward-sexp] on expression with unquoted semicolon per #4030." + (with-temp-buffer + (emacs-lisp-mode) + (insert "(insert ?;)") + (goto-char (point-min)) + (should-error (forward-sexp)))) ;; FIXME: Shouldn't be an error. + +(ert-deftest lisp-forward-sexp-emacs-lisp-quote-char () + "Test \\[forward-sexp] on expression with unquoted quote per #4030." + (with-temp-buffer + (emacs-lisp-mode) + (insert "(insert ?\")") + (goto-char (point-min)) + (should-error (forward-sexp)))) ;; FIXME: Shouldn't be an error. + +(provide 'lisp-tests) +;;; lisp-tests.el ends here commit 10b040814eaf72775c26ff3df9aa3719798e6429 Author: Jan Tatarik Date: Fri Feb 26 16:06:43 2016 +1030 Don't use (localised) week days in dates * lisp/gnus/gnus-icalendar.el (gnus-icalendar-event:org-timestamp): Don't use (localised) week days in the dates, because that messes up things later. diff --git a/lisp/gnus/gnus-icalendar.el b/lisp/gnus/gnus-icalendar.el index f635d99..96697b2 100644 --- a/lisp/gnus/gnus-icalendar.el +++ b/lisp/gnus/gnus-icalendar.el @@ -406,10 +406,10 @@ Return nil for non-recurring EVENT." "Build `org-mode' timestamp from EVENT start/end dates and recurrence info." (let* ((start (gnus-icalendar-event:start-time event)) (end (gnus-icalendar-event:end-time event)) - (start-date (format-time-string "%Y-%m-%d %a" start)) + (start-date (format-time-string "%Y-%m-%d" start)) (start-time (format-time-string "%H:%M" start)) (start-at-midnight (string= start-time "00:00")) - (end-date (format-time-string "%Y-%m-%d %a" end)) + (end-date (format-time-string "%Y-%m-%d" end)) (end-time (format-time-string "%H:%M" end)) (end-at-midnight (string= end-time "00:00")) (start-end-date-diff (/ (float-time (time-subtract @@ -428,7 +428,7 @@ Return nil for non-recurring EVENT." ;; A 0:0 - A+1 0:0 -> A ;; A 0:0 - A+n 0:0 -> A - A+n-1 ((and start-at-midnight end-at-midnight) (if (> start-end-date-diff 1) - (let ((end-ts (format-time-string "%Y-%m-%d %a" (time-subtract end time-1-day)))) + (let ((end-ts (format-time-string "%Y-%m-%d" (time-subtract end time-1-day)))) (format "<%s>--<%s>" start-date end-ts)) (format "<%s%s>" start-date repeat))) ;; end midnight @@ -436,7 +436,7 @@ Return nil for non-recurring EVENT." ;; A .:. - A+n 0:0 -> A .:. - A_n-1 (end-at-midnight (if (= start-end-date-diff 1) (format "<%s %s-23:59%s>" start-date start-time repeat) - (let ((end-ts (format-time-string "%Y-%m-%d %a" (time-subtract end time-1-day)))) + (let ((end-ts (format-time-string "%Y-%m-%d" (time-subtract end time-1-day)))) (format "<%s %s>--<%s>" start-date start-time end-ts)))) ;; start midnight ;; A 0:0 - A .:. -> A 0:0-.:. (default 1) commit eea55f4f4af311bbd4b197564d1cecbc949616bf Author: Thierry Volpiatto Date: Fri Feb 26 16:01:46 2016 +1030 Update pcomplete/find * lisp/pcmpl-gnu.el (pcomplete/find): Update to newest version (bug#10487). diff --git a/lisp/pcmpl-gnu.el b/lisp/pcmpl-gnu.el index 84e42ae..e4e8f3a 100644 --- a/lisp/pcmpl-gnu.el +++ b/lisp/pcmpl-gnu.el @@ -329,8 +329,9 @@ nil 'identity)))) ;;;###autoload + (defun pcomplete/find () - "Completion for GNU find utility." + "Completion for the GNU find utility." (let ((prec (pcomplete-arg 'last -1))) (cond ((and (pcomplete-match "^-" 'last) (string= "find" prec)) @@ -361,7 +362,7 @@ (string= prec "-execdir")) (while (pcomplete-here* (funcall pcomplete-command-completion-function) (pcomplete-arg 'last) t)))) - (while (pcomplete-here (pcomplete-entries) nil 'identity)))) + (while (pcomplete-here (pcomplete-dirs) nil 'identity)))) ;;;###autoload (defalias 'pcomplete/gdb 'pcomplete/xargs) commit 4861b50e439443a1ba8a867c88faf28ae3737706 Author: Lars Ingebrigtsen Date: Fri Feb 26 14:00:06 2016 +1030 Make parse-time-string-chars more efficient * lisp/calendar/parse-time.el (parse-time-string-chars): The string has already been downcase, so don't care about case (bug#18522). diff --git a/lisp/calendar/parse-time.el b/lisp/calendar/parse-time.el index 4086d23..fd26e77 100644 --- a/lisp/calendar/parse-time.el +++ b/lisp/calendar/parse-time.el @@ -42,12 +42,11 @@ (defsubst parse-time-string-chars (char) (save-match-data - (let (case-fold-search str) + (let (str) (cond ((eq char ?+) 1) ((eq char ?-) -1) ((eq char ?:) ?d) - ((string-match "[[:upper:]]" (setq str (string char))) ?A) - ((string-match "[[:lower:]]" str) ?a) + ((string-match "[[:lower:]]" (setq str (string char))) ?a) ((string-match "[[:digit:]]" str) ?0))))) (defun parse-time-tokenize (string) commit a1e7304fc45ed356f35459697ea8415d52008fd8 Author: Lars Ingebrigtsen Date: Fri Feb 26 13:54:41 2016 +1030 Remove killed buffers from the list of Gnus buffers * lisp/gnus/gnus.el (gnus-prune-buffers): Remove killed buffers from the list of Gnus buffers (bug#18522). diff --git a/lisp/gnus/gnus.el b/lisp/gnus/gnus.el index f839325..edf46f1 100644 --- a/lisp/gnus/gnus.el +++ b/lisp/gnus/gnus.el @@ -903,14 +903,20 @@ be set in `.emacs' instead." (defun gnus-add-buffer () "Add the current buffer to the list of Gnus buffers." + (gnus-prune-buffers) (push (current-buffer) gnus-buffers)) (defmacro gnus-kill-buffer (buffer) "Kill BUFFER and remove from the list of Gnus buffers." `(let ((buf ,buffer)) (when (gnus-buffer-exists-p buf) - (setq gnus-buffers (delete (get-buffer buf) gnus-buffers)) - (kill-buffer buf)))) + (kill-buffer buf) + (gnus-prune-buffers)))) + +(defun gnus-prune-buffers () + (dolist (buf gnus-buffers) + (unless (buffer-live-p buf) + (setq gnus-buffers (delete buf gnus-buffers))))) (defun gnus-buffers () "Return a list of live Gnus buffers." commit c1415cc98c4bba699f870277b5311ed320df22cc Author: Paul Eggert Date: Thu Feb 25 11:57:10 2016 -0800 Integer overflow cleanups for ports and socklen * src/process.c (struct sockaddr_and_len, conv_sockaddr_to_lisp) (get_lisp_to_sockaddr_size, Fset_process_datagram_address) (connect_network_socket): Use ptrdiff_t, not int, for signed object sizes. This addresses only a theoretical problem, as in practice these object sizes are less than 2**31, but we might as well use the same style here as elsewhere in Emacs. (string_integer_p): Remove; all uses removed. (Fmake_network_process): Check that port number is in range. When converting an integer-string service, rely on strtol rather than rechecking the string by hand. * src/process.h, src/w32.c (conv_sockaddr_to_lisp): Adjust prototypes to match. diff --git a/src/process.c b/src/process.c index 62a26c3..a321244 100644 --- a/src/process.c +++ b/src/process.c @@ -302,7 +302,7 @@ static struct coding_system *proc_encode_coding_system[FD_SETSIZE]; /* Table of `partner address' for datagram sockets. */ static struct sockaddr_and_len { struct sockaddr *sa; - int len; + ptrdiff_t len; } datagram_address[FD_SETSIZE]; #define DATAGRAM_CHAN_P(chan) (datagram_address[chan].sa != 0) #define DATAGRAM_CONN_P(proc) \ @@ -2245,12 +2245,12 @@ usage: (make-pipe-process &rest ARGS) */) The address family of sa is not included in the result. */ Lisp_Object -conv_sockaddr_to_lisp (struct sockaddr *sa, int len) +conv_sockaddr_to_lisp (struct sockaddr *sa, ptrdiff_t len) { Lisp_Object address; - int i; + ptrdiff_t i; unsigned char *cp; - register struct Lisp_Vector *p; + struct Lisp_Vector *p; /* Workaround for a bug in getsockname on BSD: Names bound to sockets in the UNIX domain are inaccessible; getsockname returns @@ -2325,10 +2325,10 @@ conv_sockaddr_to_lisp (struct sockaddr *sa, int len) /* Get family and required size for sockaddr structure to hold ADDRESS. */ -static int +static ptrdiff_t get_lisp_to_sockaddr_size (Lisp_Object address, int *familyp) { - register struct Lisp_Vector *p; + struct Lisp_Vector *p; if (VECTORP (address)) { @@ -2474,7 +2474,8 @@ set up yet, this function will block until socket setup has completed. */) (Lisp_Object process, Lisp_Object address) { int channel; - int family, len; + int family; + ptrdiff_t len; CHECK_PROCESS (process); @@ -3085,7 +3086,7 @@ connect_network_socket (Lisp_Object proc, Lisp_Object ip_addresses) int family; struct sockaddr *sa = NULL; int ret; - int addrlen; + ptrdiff_t addrlen; struct Lisp_Process *p = XPROCESS (proc); Lisp_Object contact = p->childp; int optbits = 0; @@ -3283,8 +3284,8 @@ connect_network_socket (Lisp_Object proc, Lisp_Object ip_addresses) memset (datagram_address[s].sa, 0, addrlen); if (remote = Fplist_get (contact, QCremote), !NILP (remote)) { - int rfamily, rlen; - rlen = get_lisp_to_sockaddr_size (remote, &rfamily); + int rfamily; + ptrdiff_t rlen = get_lisp_to_sockaddr_size (remote, &rfamily); if (rlen != 0 && rfamily == family && rlen == addrlen) conv_lisp_to_sockaddr (rfamily, remote, @@ -3428,17 +3429,6 @@ conv_numerical_to_lisp (unsigned char *number, int length, int port) } #endif -/* Return true if STRING consists only of numerical characters. */ -static bool -string_integer_p (Lisp_Object string) -{ - char *s = SSDATA (string), c; - while ((c = *s++)) - if (c < '0' || c > '9') - return false; - return true; -} - /* Create a network stream/datagram client/server process. Treated exactly like a normal process when reading and writing. Primary differences are in status display and process deletion. A network @@ -3617,7 +3607,7 @@ usage: (make-network-process &rest ARGS) */) #ifdef HAVE_LOCAL_SOCKETS struct sockaddr_un address_un; #endif - int port = 0; + EMACS_INT port = 0; Lisp_Object tem; Lisp_Object name, buffer, host, service, address; Lisp_Object filter, sentinel; @@ -3807,7 +3797,7 @@ usage: (make-network-process &rest ARGS) */) error ("%s/%s getaddrinfo_a error %d", SSDATA (host), portstring, ret); goto open_socket; - } + } #endif /* HAVE_GETADDRINFO_A */ #ifdef HAVE_GETADDRINFO @@ -3862,20 +3852,35 @@ usage: (make-network-process &rest ARGS) */) if (EQ (service, Qt)) port = 0; else if (INTEGERP (service)) - port = (unsigned short) XINT (service); - /* Allow the service to be a string containing the port number, - because that's allowed if you have getaddrbyname. */ - else if (string_integer_p (service)) - port = strtol (SSDATA (service), NULL, 10); + port = XINT (service); else { - struct servent *svc_info; CHECK_STRING (service); - svc_info = getservbyname (SSDATA (service), - (socktype == SOCK_DGRAM ? "udp" : "tcp")); - if (svc_info == 0) - error ("Unknown service: %s", SDATA (service)); - port = ntohs (svc_info->s_port); + + port = -1; + if (SBYTES (service) != 0) + { + /* Allow the service to be a string containing the port number, + because that's allowed if you have getaddrbyname. */ + char *service_end; + long int lport = strtol (SSDATA (service), &service_end, 10); + if (service_end == SSDATA (service) + SBYTES (service)) + port = lport; + else + { + struct servent *svc_info + = getservbyname (SSDATA (service), + socktype == SOCK_DGRAM ? "udp" : "tcp"); + if (svc_info) + port = ntohs (svc_info->s_port); + } + } + } + + if (! (0 <= port && port < 1 << 16)) + { + AUTO_STRING (unknown_service, "Unknown service: %s"); + xsignal1 (Qerror, CALLN (Fformat, unknown_service, service)); } #ifndef HAVE_GETADDRINFO diff --git a/src/process.h b/src/process.h index 884c304..038d58b 100644 --- a/src/process.h +++ b/src/process.h @@ -250,7 +250,7 @@ extern Lisp_Object system_process_attributes (Lisp_Object); extern void record_deleted_pid (pid_t, Lisp_Object); struct sockaddr; -extern Lisp_Object conv_sockaddr_to_lisp (struct sockaddr *, int); +extern Lisp_Object conv_sockaddr_to_lisp (struct sockaddr *, ptrdiff_t); extern void hold_keyboard_input (void); extern void unhold_keyboard_input (void); extern bool kbd_on_hold_p (void); diff --git a/src/w32.c b/src/w32.c index fbcfb97..d298f47 100644 --- a/src/w32.c +++ b/src/w32.c @@ -8740,7 +8740,7 @@ sys_write (int fd, const void * buffer, unsigned int count) /* Emulation of SIOCGIFCONF and getifaddrs, see process.c. */ -extern Lisp_Object conv_sockaddr_to_lisp (struct sockaddr *, int); +extern Lisp_Object conv_sockaddr_to_lisp (struct sockaddr *, ptrdiff_t); /* Return information about network interface IFNAME, or about all interfaces (if IFNAME is nil). */