Now on revision 113467. ------------------------------------------------------------ revno: 113467 author: Paul Eggert committer: Paul Eggert branch nick: trunk timestamp: Fri 2013-07-19 11:09:23 -0700 message: Fix some minor file descriptor leaks and related glitches. * filelock.c (create_lock_file) [!O_CLOEXEC]: Use fcntl with FD_CLOEXEC. (create_lock_file): Use write, not emacs_write. * image.c (slurp_file, png_load_body): * process.c (Fnetwork_interface_list, Fnetwork_interface_info) (server_accept_connection): Don't leak an fd on memory allocation failure. * image.c (slurp_file): Add a cheap heuristic for growing files. * xfaces.c (Fx_load_color_file): Block input around the fopen too, as that's what the other routines do. Maybe input need not be blocked at all, but it's better to be consistent. Avoid undefined behavior when strlen is zero. diff: === modified file 'src/ChangeLog' --- src/ChangeLog 2013-07-19 17:54:26 +0000 +++ src/ChangeLog 2013-07-19 18:09:23 +0000 @@ -1,5 +1,18 @@ 2013-07-19 Paul Eggert + Fix some minor file descriptor leaks and related glitches. + * filelock.c (create_lock_file) [!O_CLOEXEC]: Use fcntl with FD_CLOEXEC. + (create_lock_file): Use write, not emacs_write. + * image.c (slurp_file, png_load_body): + * process.c (Fnetwork_interface_list, Fnetwork_interface_info) + (server_accept_connection): + Don't leak an fd on memory allocation failure. + * image.c (slurp_file): Add a cheap heuristic for growing files. + * xfaces.c (Fx_load_color_file): Block input around the fopen too, + as that's what the other routines do. Maybe input need not be + blocked at all, but it's better to be consistent. + Avoid undefined behavior when strlen is zero. + * alloc.c (staticpro): Avoid buffer overrun on repeated calls. (NSTATICS): Now a constant; doesn't need to be a macro. === modified file 'src/filelock.c' --- src/filelock.c 2013-07-18 10:24:26 +0000 +++ src/filelock.c 2013-07-19 18:09:23 +0000 @@ -430,12 +430,14 @@ else { ptrdiff_t lock_info_len; -#if ! HAVE_MKOSTEMP +#if ! (HAVE_MKOSTEMP && O_CLOEXEC) fcntl (fd, F_SETFD, FD_CLOEXEC); #endif lock_info_len = strlen (lock_info_str); err = 0; - if (emacs_write (fd, lock_info_str, lock_info_len) != lock_info_len + /* Use 'write', not 'emacs_write', as garbage collection + might signal an error, which would leak FD. */ + if (write (fd, lock_info_str, lock_info_len) != lock_info_len || fchmod (fd, S_IRUSR | S_IRGRP | S_IROTH) != 0) err = errno; /* There is no need to call fsync here, as the contents of === modified file 'src/image.c' --- src/image.c 2013-07-16 06:39:49 +0000 +++ src/image.c 2013-07-19 18:09:23 +0000 @@ -2276,23 +2276,28 @@ unsigned char *buf = NULL; struct stat st; - if (fp && fstat (fileno (fp), &st) == 0 - && 0 <= st.st_size && st.st_size <= min (PTRDIFF_MAX, SIZE_MAX) - && (buf = xmalloc (st.st_size), - fread (buf, 1, st.st_size, fp) == st.st_size)) - { - *size = st.st_size; - fclose (fp); - } - else - { - if (fp) - fclose (fp); - if (buf) + if (fp) + { + ptrdiff_t count = SPECPDL_INDEX (); + record_unwind_protect_ptr (fclose_unwind, fp); + + if (fstat (fileno (fp), &st) == 0 + && 0 <= st.st_size && st.st_size < min (PTRDIFF_MAX, SIZE_MAX)) { - xfree (buf); - buf = NULL; + /* Report an error if we read past the purported EOF. + This can happen if the file grows as we read it. */ + ptrdiff_t buflen = st.st_size; + buf = xmalloc (buflen + 1); + if (fread (buf, 1, buflen + 1, fp) == buflen) + *size = buflen; + else + { + xfree (buf); + buf = NULL; + } } + + unbind_to (count, Qnil); } return buf; @@ -5732,8 +5737,8 @@ if (fread (sig, 1, sizeof sig, fp) != sizeof sig || fn_png_sig_cmp (sig, 0, sizeof sig)) { + fclose (fp); image_error ("Not a PNG file: `%s'", file, Qnil); - fclose (fp); return 0; } } === modified file 'src/process.c' --- src/process.c 2013-07-17 04:37:27 +0000 +++ src/process.c 2013-07-19 18:09:23 +0000 @@ -3526,10 +3526,13 @@ ptrdiff_t buf_size = 512; int s; Lisp_Object res; + ptrdiff_t count; s = socket (AF_INET, SOCK_STREAM | SOCK_CLOEXEC, 0); if (s < 0) return Qnil; + count = SPECPDL_INDEX (); + record_unwind_protect_int (close_file_unwind, s); do { @@ -3545,9 +3548,7 @@ } while (ifconf.ifc_len == buf_size); - emacs_close (s); - - res = Qnil; + res = unbind_to (count, Qnil); ifreq = ifconf.ifc_req; while ((char *) ifreq < (char *) ifconf.ifc_req + ifconf.ifc_len) { @@ -3672,6 +3673,7 @@ Lisp_Object elt; int s; bool any = 0; + ptrdiff_t count; #if (! (defined SIOCGIFHWADDR && defined HAVE_STRUCT_IFREQ_IFR_HWADDR) \ && defined HAVE_GETIFADDRS && defined LLADDR) struct ifaddrs *ifap; @@ -3686,6 +3688,8 @@ s = socket (AF_INET, SOCK_STREAM | SOCK_CLOEXEC, 0); if (s < 0) return Qnil; + count = SPECPDL_INDEX (); + record_unwind_protect_int (close_file_unwind, s); elt = Qnil; #if defined (SIOCGIFFLAGS) && defined (HAVE_STRUCT_IFREQ_IFR_FLAGS) @@ -3802,9 +3806,7 @@ #endif res = Fcons (elt, res); - emacs_close (s); - - return any ? res : Qnil; + return unbind_to (count, any ? res : Qnil); } #endif #endif /* defined (HAVE_NET_IF_H) */ @@ -3978,6 +3980,7 @@ #endif } saddr; socklen_t len = sizeof saddr; + ptrdiff_t count; s = accept4 (channel, &saddr.sa, &len, SOCK_CLOEXEC); @@ -4000,6 +4003,9 @@ return; } + count = SPECPDL_INDEX (); + record_unwind_protect_int (close_file_unwind, s); + connect_counter++; /* Setup a new process to handle the connection. */ @@ -4116,6 +4122,10 @@ pset_filter (p, ps->filter); pset_command (p, Qnil); p->pid = 0; + + /* Discard the unwind protect for closing S. */ + specpdl_ptr = specpdl + count; + p->infd = s; p->outfd = s; pset_status (p, Qrun); === modified file 'src/xfaces.c' --- src/xfaces.c 2013-07-16 06:39:49 +0000 +++ src/xfaces.c 2013-07-19 18:09:23 +0000 @@ -6283,6 +6283,7 @@ CHECK_STRING (filename); abspath = Fexpand_file_name (filename, Qnil); + block_input (); fp = emacs_fopen (SSDATA (abspath), "rt"); if (fp) { @@ -6290,29 +6291,24 @@ int red, green, blue; int num; - block_input (); - while (fgets (buf, sizeof (buf), fp) != NULL) { if (sscanf (buf, "%u %u %u %n", &red, &green, &blue, &num) == 3) { +#ifdef HAVE_NTGUI + int color = RGB (red, green, blue); +#else + int color = (red << 16) | (green << 8) | blue; +#endif char *name = buf + num; - num = strlen (name) - 1; - if (num >= 0 && name[num] == '\n') - name[num] = 0; - cmap = Fcons (Fcons (build_string (name), -#ifdef HAVE_NTGUI - make_number (RGB (red, green, blue))), -#else - make_number ((red << 16) | (green << 8) | blue)), -#endif + ptrdiff_t len = strlen (name); + len -= 0 < len && name[len - 1] == '\n'; + cmap = Fcons (Fcons (make_string (name, len), make_number (color)), cmap); } } fclose (fp); - - unblock_input (); } - + unblock_input (); return cmap; } #endif ------------------------------------------------------------ revno: 113466 committer: Paul Eggert branch nick: trunk timestamp: Fri 2013-07-19 10:54:26 -0700 message: * alloc.c (staticpro): Avoid buffer overrun on repeated calls. (NSTATICS): Now a constant; doesn't need to be a macro. diff: === modified file 'src/ChangeLog' --- src/ChangeLog 2013-07-19 16:15:51 +0000 +++ src/ChangeLog 2013-07-19 17:54:26 +0000 @@ -1,3 +1,8 @@ +2013-07-19 Paul Eggert + + * alloc.c (staticpro): Avoid buffer overrun on repeated calls. + (NSTATICS): Now a constant; doesn't need to be a macro. + 2013-07-19 Richard Stallman * coding.c (decode_coding_utf_8): Add simple loop for fast === modified file 'src/alloc.c' --- src/alloc.c 2013-07-19 01:24:35 +0000 +++ src/alloc.c 2013-07-19 17:54:26 +0000 @@ -341,7 +341,7 @@ /* Addresses of staticpro'd variables. Initialize it to a nonzero value; otherwise some compilers put it into BSS. */ -#define NSTATICS 0x800 +enum { NSTATICS = 2048 }; static Lisp_Object *staticvec[NSTATICS] = {&Vpurify_flag}; /* Index of next unused slot in staticvec. */ @@ -5136,9 +5136,9 @@ void staticpro (Lisp_Object *varaddress) { - staticvec[staticidx++] = varaddress; if (staticidx >= NSTATICS) fatal ("NSTATICS too small; try increasing and recompiling Emacs."); + staticvec[staticidx++] = varaddress; } ------------------------------------------------------------ revno: 113465 committer: Richard Stallman branch nick: trunk timestamp: Fri 2013-07-19 12:15:51 -0400 message: (decode_coding_utf_8): Add simple loop for fast processing of ASCII characters. diff: === modified file 'src/ChangeLog' --- src/ChangeLog 2013-07-19 14:34:56 +0000 +++ src/ChangeLog 2013-07-19 16:15:51 +0000 @@ -1,3 +1,8 @@ +2013-07-19 Richard Stallman + + * coding.c (decode_coding_utf_8): Add simple loop for fast + processing of ASCII characters. + 2013-07-19 Paul Eggert * conf_post.h (RE_TRANSLATE_P) [emacs]: Remove obsolete optimization. === modified file 'src/coding.c' --- src/coding.c 2013-07-16 21:35:45 +0000 +++ src/coding.c 2013-07-19 16:15:51 +0000 @@ -1363,6 +1363,45 @@ break; } + /* In the simple case, rapidly handle ordinary characters */ + if (multibytep && ! eol_dos + && charbuf < charbuf_end - 6 && src < src_end - 6) + { + while (charbuf < charbuf_end - 6 && src < src_end - 6) + { + c1 = *src; + if (c1 & 0x80) + break; + src++; + consumed_chars++; + *charbuf++ = c1; + + c1 = *src; + if (c1 & 0x80) + break; + src++; + consumed_chars++; + *charbuf++ = c1; + + c1 = *src; + if (c1 & 0x80) + break; + src++; + consumed_chars++; + *charbuf++ = c1; + + c1 = *src; + if (c1 & 0x80) + break; + src++; + consumed_chars++; + *charbuf++ = c1; + } + /* If we handled at least one character, restart the main loop. */ + if (src != src_base) + continue; + } + if (byte_after_cr >= 0) c1 = byte_after_cr, byte_after_cr = -1; else ------------------------------------------------------------ revno: 113464 fixes bug: http://debbugs.gnu.org/14815 committer: Lars Magne Ingebrigtsen branch nick: trunk timestamp: Fri 2013-07-19 16:57:28 +0200 message: * net/shr.el (shr-mouse-browse-url): New command and keystroke. diff: === modified file 'lisp/ChangeLog' --- lisp/ChangeLog 2013-07-19 14:44:16 +0000 +++ lisp/ChangeLog 2013-07-19 14:57:28 +0000 @@ -1,5 +1,8 @@ 2013-07-19 Lars Magne Ingebrigtsen + * net/shr.el (shr-mouse-browse-url): New command and keystroke + (bug#14815). + * net/eww.el (eww-process-text-input): Allow inputting when the point is at the start of the line, as the properties aren't front-sticky. === modified file 'lisp/net/shr.el' --- lisp/net/shr.el 2013-07-19 14:07:43 +0000 +++ lisp/net/shr.el 2013-07-19 14:57:28 +0000 @@ -143,6 +143,7 @@ (define-key map [tab] 'shr-next-link) (define-key map [backtab] 'shr-previous-link) (define-key map [follow-link] 'mouse-face) + (define-key map [mouse-2] 'shr-mouse-browse-url) (define-key map "I" 'shr-insert-image) (define-key map "w" 'shr-copy-url) (define-key map "u" 'shr-copy-url) @@ -657,6 +658,12 @@ (forward-line 1) (goto-char end)))))) +(defun shr-mouse-browse-url (ev) + "Browse the URL under the mouse cursor." + (interactive "e") + (mouse-set-point ev) + (shr-browse-url)) + (defun shr-browse-url (&optional external) "Browse the URL under point. If EXTERNAL, browse the URL using `shr-external-browser'." ------------------------------------------------------------ revno: 113463 author: Gnus developers committer: Katsumi Yamaoka branch nick: trunk timestamp: Fri 2013-07-19 14:50:21 +0000 message: Merge Changes made in Gnus master 2013-07-19 Geoff Kuenning (tiny change) * gnus.texi (Customizing Articles): Document function predicates. 2013-07-19 Geoff Kuenning (tiny change) * gnus-art.el (gnus-treat-predicate): Allow functions as predicates (bug#13384). 2013-07-18 Lars Magne Ingebrigtsen * gnus-start.el (gnus-clean-old-newsrc): Remove the newsrc cleanups that were only relevant in a development version a long time ago. diff: === modified file 'doc/misc/ChangeLog' --- doc/misc/ChangeLog 2013-07-08 23:51:26 +0000 +++ doc/misc/ChangeLog 2013-07-19 14:50:21 +0000 @@ -1,3 +1,7 @@ +2013-07-19 Geoff Kuenning (tiny change) + + * gnus.texi (Customizing Articles): Document function predicates. + 2013-07-08 Tassilo Horn * gnus.texi (lines): Correct description of === modified file 'doc/misc/gnus.texi' --- doc/misc/gnus.texi 2013-07-08 23:51:26 +0000 +++ doc/misc/gnus.texi 2013-07-19 14:50:21 +0000 @@ -11858,6 +11858,11 @@ (typep "text/x-vcard")) @end lisp +@item +A function: the function is called with no arguments and should return +@code{nil} or non-@code{nil}. The current article is available in the +buffer named by @code{gnus-article-buffer}. + @end enumerate You may have noticed that the word @dfn{part} is used here. This refers === modified file 'lisp/gnus/ChangeLog' --- lisp/gnus/ChangeLog 2013-07-18 11:26:04 +0000 +++ lisp/gnus/ChangeLog 2013-07-19 14:50:21 +0000 @@ -1,3 +1,13 @@ +2013-07-19 Geoff Kuenning (tiny change) + + * gnus-art.el (gnus-treat-predicate): Allow functions as predicates + (bug#13384). + +2013-07-18 Lars Magne Ingebrigtsen + + * gnus-start.el (gnus-clean-old-newsrc): Remove the newsrc cleanups + that were only relevant in a development version a long time ago. + 2013-07-18 Katsumi Yamaoka * gnus-art.el (gnus-shr-put-image): Make it work as well for shr.el's === modified file 'lisp/gnus/gnus-art.el' --- lisp/gnus/gnus-art.el 2013-07-18 11:26:04 +0000 +++ lisp/gnus/gnus-art.el 2013-07-19 14:50:21 +0000 @@ -8419,6 +8419,8 @@ (not (gnus-treat-predicate (car val)))) ((eq pred 'typep) (equal (car val) gnus-treat-type)) + ((functionp pred) + (funcall pred)) (t (error "%S is not a valid predicate" pred))))) ((eq val t) === modified file 'lisp/gnus/gnus-start.el' --- lisp/gnus/gnus-start.el 2013-07-10 22:17:07 +0000 +++ lisp/gnus/gnus-start.el 2013-07-19 14:50:21 +0000 @@ -2305,24 +2305,8 @@ (gnus-clean-old-newsrc)))) (defun gnus-clean-old-newsrc (&optional force) - (when gnus-newsrc-file-version - ;; Remove totally bogus `unexists' entries. The name is - ;; `unexist'. - (dolist (info (cdr gnus-newsrc-alist)) - (let ((exist (assoc 'unexists (gnus-info-marks info)))) - (when exist - (gnus-info-set-marks - info (delete exist (gnus-info-marks info)))))) - (when (or force - (not (string= gnus-newsrc-file-version gnus-version))) - (message (concat "Removing unexist marks because newsrc " - "version does not match Gnus version.")) - ;; Remove old `exist' marks from old nnimap groups. - (dolist (info (cdr gnus-newsrc-alist)) - (let ((exist (assoc 'unexist (gnus-info-marks info)))) - (when exist - (gnus-info-set-marks - info (delete exist (gnus-info-marks info))))))))) + ;; Currently no cleanups. + ) (defun gnus-convert-old-newsrc () "Convert old newsrc formats into the current format, if needed." ------------------------------------------------------------ revno: 113462 committer: Lars Magne Ingebrigtsen branch nick: trunk timestamp: Fri 2013-07-19 16:44:16 +0200 message: eww textarea input fixup * net/eww.el (eww-process-text-input): Allow inputting when the point is at the start of the line, as the properties aren't front-sticky. diff: === modified file 'lisp/ChangeLog' --- lisp/ChangeLog 2013-07-19 14:07:43 +0000 +++ lisp/ChangeLog 2013-07-19 14:44:16 +0000 @@ -1,5 +1,9 @@ 2013-07-19 Lars Magne Ingebrigtsen + * net/eww.el (eww-process-text-input): Allow inputting when the + point is at the start of the line, as the properties aren't + front-sticky. + * net/shr.el (shr-make-table-1): Ensure that we don't infloop on degenerate widths. === modified file 'lisp/net/eww.el' --- lisp/net/eww.el 2013-06-28 07:54:42 +0000 +++ lisp/net/eww.el 2013-07-19 14:44:16 +0000 @@ -603,7 +603,7 @@ (insert " "))) (defun eww-process-text-input (beg end length) - (let* ((form (get-text-property end 'eww-form)) + (let* ((form (get-text-property (min (1+ end) (point-max)) 'eww-form)) (properties (text-properties-at end)) (type (plist-get form :type))) (when (and form ------------------------------------------------------------ revno: 113461 committer: Paul Eggert branch nick: trunk timestamp: Fri 2013-07-19 07:34:56 -0700 message: * conf_post.h (RE_TRANSLATE_P) [emacs]: Remove obsolete optimization. diff: === modified file 'src/ChangeLog' --- src/ChangeLog 2013-07-19 10:55:36 +0000 +++ src/ChangeLog 2013-07-19 14:34:56 +0000 @@ -1,3 +1,7 @@ +2013-07-19 Paul Eggert + + * conf_post.h (RE_TRANSLATE_P) [emacs]: Remove obsolete optimization. + 2013-07-19 Eli Zaretskii * keyboard.c (kbd_buffer_get_event): Use Display_Info instead of === modified file 'src/conf_post.h' --- src/conf_post.h 2013-06-30 15:10:33 +0000 +++ src/conf_post.h 2013-07-19 14:34:56 +0000 @@ -160,13 +160,7 @@ /* Tell regex.c to use a type compatible with Emacs. */ #define RE_TRANSLATE_TYPE Lisp_Object #define RE_TRANSLATE(TBL, C) char_table_translate (TBL, C) -#ifdef make_number -/* If make_number is a macro, use it. */ #define RE_TRANSLATE_P(TBL) (!EQ (TBL, make_number (0))) -#else -/* If make_number is a function, avoid it. */ -#define RE_TRANSLATE_P(TBL) (!(INTEGERP (TBL) && XINT (TBL) == 0)) -#endif #endif #include ------------------------------------------------------------ revno: 113460 committer: Lars Magne Ingebrigtsen branch nick: trunk timestamp: Fri 2013-07-19 16:07:43 +0200 message: (shr-make-table-1): Ensure that we don't infloop on degenerate widths. diff: === modified file 'lisp/ChangeLog' --- lisp/ChangeLog 2013-07-19 13:30:58 +0000 +++ lisp/ChangeLog 2013-07-19 14:07:43 +0000 @@ -1,3 +1,8 @@ +2013-07-19 Lars Magne Ingebrigtsen + + * net/shr.el (shr-make-table-1): Ensure that we don't infloop on + degenerate widths. + 2013-07-19 Richard Stallman * epa.el (epa-popup-info-window): Doc fix. === modified file 'lisp/net/shr.el' --- lisp/net/shr.el 2013-07-08 11:19:51 +0000 +++ lisp/net/shr.el 2013-07-19 14:07:43 +0000 @@ -1476,9 +1476,6 @@ (if column (aref widths width-column) 10)) - ;; Sanity check for degenerate tables. - (when (zerop width) - (setq width 10)) (when (and fill (setq colspan (cdr (assq :colspan (cdr column))))) (setq colspan (string-to-number colspan)) @@ -1491,6 +1488,9 @@ (setq width-column (+ width-column (1- colspan)))) (when (or column (not fill)) + ;; Sanity check for degenerate tables. + (when (zerop width) + (setq width 10)) (push (shr-render-td (cdr column) width fill) tds)) (setq i (1+ i) @@ -1499,6 +1499,7 @@ (nreverse trs))) (defun shr-render-td (cont width fill) + (when (= width 0) (debug)) (with-temp-buffer (let ((bgcolor (cdr (assq :bgcolor cont))) (fgcolor (cdr (assq :fgcolor cont))) ------------------------------------------------------------ revno: 113459 committer: Richard Stallman branch nick: trunk timestamp: Fri 2013-07-19 09:30:58 -0400 message: * epa.el (epa-popup-info-window): Doc fix. diff: === modified file 'lisp/ChangeLog' --- lisp/ChangeLog 2013-07-19 12:18:16 +0000 +++ lisp/ChangeLog 2013-07-19 13:30:58 +0000 @@ -1,5 +1,7 @@ 2013-07-19 Richard Stallman + * epa.el (epa-popup-info-window): Doc fix. + * subr.el (split-string): New arg TRIM. 2013-07-18 Juanma Barranquero === modified file 'lisp/epa.el' --- lisp/epa.el 2013-06-10 00:32:49 +0000 +++ lisp/epa.el 2013-07-19 13:30:58 +0000 @@ -34,8 +34,7 @@ :group 'epg) (defcustom epa-popup-info-window t - "If non-nil, status information from epa commands is displayed on -the separate window." + "If non-nil, display status information from epa commands in another window." :type 'boolean :group 'epa) ------------------------------------------------------------ revno: 113458 committer: Richard Stallman branch nick: trunk timestamp: Fri 2013-07-19 09:09:03 -0400 message: Add a comment. diff: === modified file 'lisp/mail/mailalias.el' --- lisp/mail/mailalias.el 2013-01-01 09:11:05 +0000 +++ lisp/mail/mailalias.el 2013-07-19 13:09:03 +0000 @@ -209,7 +209,9 @@ (if (re-search-forward "[ \t]*[\n,][ \t]*" end1 t) (setq epos (match-beginning 0) seplen (- (point) epos)) - (setq epos (marker-position end1) seplen 0)) + ;; Handle the last name in this header field. + ;; We already moved END1 back across whitespace after it. + (setq epos (marker-position end1) seplen 0)) (let ((string (buffer-substring-no-properties pos epos)) translation) (if (and (not (assoc string disabled-aliases)) ------------------------------------------------------------ revno: 113457 committer: Richard Stallman branch nick: trunk timestamp: Fri 2013-07-19 08:18:16 -0400 message: split-string takes a new arg TRIM that's a regexp saying what to trim from the start and end of each substring. * subr.el (split-string): New arg TRIM. diff: === modified file 'etc/NEWS' --- etc/NEWS 2013-07-16 11:41:06 +0000 +++ etc/NEWS 2013-07-19 12:18:16 +0000 @@ -561,6 +561,9 @@ *** `completion-in-region-function' obsoletes `completion-in-region-functions'. *** `filter-buffer-substring-function' obsoletes `filter-buffer-substring-functions'. +** `split-string' now takes an optional argument TRIM. +The value, if non-nil, is a regexp that specifies what to trim from +the start and end of each substring. ** `get-upcase-table' is obsoleted by the new `case-table-get-table'. === modified file 'lisp/ChangeLog' --- lisp/ChangeLog 2013-07-19 00:38:19 +0000 +++ lisp/ChangeLog 2013-07-19 12:18:16 +0000 @@ -1,3 +1,7 @@ +2013-07-19 Richard Stallman + + * subr.el (split-string): New arg TRIM. + 2013-07-18 Juanma Barranquero * frame.el (blink-cursor-timer-function, blink-cursor-suspend): === modified file 'lisp/subr.el' --- lisp/subr.el 2013-07-11 01:49:17 +0000 +++ lisp/subr.el 2013-07-19 12:18:16 +0000 @@ -3529,7 +3529,7 @@ ;; defaulted, OMIT-NULLS should be treated as t. Simplifying the logical ;; expression leads to the equivalent implementation that if SEPARATORS ;; is defaulted, OMIT-NULLS is treated as t. -(defun split-string (string &optional separators omit-nulls) +(defun split-string (string &optional separators omit-nulls trim) "Split STRING into substrings bounded by matches for SEPARATORS. The beginning and end of STRING, and each match for SEPARATORS, are @@ -3547,17 +3547,50 @@ are effectively trimmed). If nil, all zero-length substrings are retained, which correctly parses CSV format, for example. +If TRIM is non-nil, it should be a regular expression to match +text to trim from the beginning and end of each substring. If trimming +makes the substring empty, it is treated as null. + +If you want to trim whitespace from the substrings, the reliably correct +way is using TRIM. Making SEPARATORS match that whitespace gives incorrect +results when there is whitespace at the start or end of STRING. If you +see such calls to `split-string', please fix them. + Note that the effect of `(split-string STRING)' is the same as `(split-string STRING split-string-default-separators t)'. In the rare case that you wish to retain zero-length substrings when splitting on whitespace, use `(split-string STRING split-string-default-separators)'. Modifies the match data; use `save-match-data' if necessary." - (let ((keep-nulls (not (if separators omit-nulls t))) - (rexp (or separators split-string-default-separators)) - (start 0) - notfirst - (list nil)) + (let* ((keep-nulls (not (if separators omit-nulls t))) + (rexp (or separators split-string-default-separators)) + (start 0) + this-start this-end + notfirst + (list nil) + (push-one + ;; Push the substring in range THIS-START to THIS-END + ;; onto LIST, trimming it and perhaps discarding it. + (lambda () + (when trim + ;; Discard the trim from start of this substring. + (let ((tem (string-match trim string this-start))) + (and (eq tem this-start) + (setq this-start (match-end 0))))) + + (when (or keep-nulls (< this-start this-end)) + (let ((this (substring string this-start this-end))) + + ;; Discard the trim from end of this substring. + (when trim + (let ((tem (string-match (concat trim "\\'") this 0))) + (and tem (< tem (length this)) + (setq this (substring this 0 tem))))) + + ;; Trimming could make it empty; check again. + (when (or keep-nulls (> (length this) 0)) + (push this list))))))) + (while (and (string-match rexp string (if (and notfirst (= start (match-beginning 0)) @@ -3565,15 +3598,15 @@ (1+ start) start)) (< start (length string))) (setq notfirst t) - (if (or keep-nulls (< start (match-beginning 0))) - (setq list - (cons (substring string start (match-beginning 0)) - list))) - (setq start (match-end 0))) - (if (or keep-nulls (< start (length string))) - (setq list - (cons (substring string start) - list))) + (setq this-start start this-end (match-beginning 0) + start (match-end 0)) + + (funcall push-one)) + + ;; Handle the substring at the end of STRING. + (setq this-start start this-end (length string)) + (funcall push-one) + (nreverse list))) (defun combine-and-quote-strings (strings &optional separator) ------------------------------------------------------------ revno: 113456 fixes bug: http://debbugs.gnu.org/14901 committer: Eli Zaretskii branch nick: trunk timestamp: Fri 2013-07-19 13:55:36 +0300 message: Fix the fix for bug #14901. src/keyboard.c (kbd_buffer_get_event): Use Display_Info instead of unportable 'struct x_display_info'. (DISPLAY_LIST_INFO): Delete macro: not needed, since Display_Info is a portable type. diff: === modified file 'src/ChangeLog' --- src/ChangeLog 2013-07-19 05:36:50 +0000 +++ src/ChangeLog 2013-07-19 10:55:36 +0000 @@ -1,3 +1,10 @@ +2013-07-19 Eli Zaretskii + + * keyboard.c (kbd_buffer_get_event): Use Display_Info instead of + unportable 'struct x_display_info'. + (DISPLAY_LIST_INFO): Delete macro: not needed, since Display_Info + is a portable type. + 2013-07-19 Paul Eggert * sysdep.c [GNU_LINUX]: Fix fd and memory leaks and similar issues. === modified file 'src/keyboard.c' --- src/keyboard.c 2013-07-18 21:16:33 +0000 +++ src/keyboard.c 2013-07-19 10:55:36 +0000 @@ -4066,28 +4066,19 @@ } else if (event->kind == FOCUS_OUT_EVENT) { -#if defined HAVE_X11 || defined HAVE_NS -# define DISPLAY_LIST_INFO(di) (di) -#elif defined WINDOWSNT -# define DISPLAY_LIST_INFO(di) FRAME_X_DISPLAY_INFO (di) -#endif -#ifdef DISPLAY_LIST_INFO +#ifdef HAVE_WINDOW_SYSTEM -#ifdef HAVE_NS - struct ns_display_info *di; -#else - struct x_display_info *di; -#endif + Display_Info *di; Lisp_Object frame = event->frame_or_window; bool focused = false; - for (di = x_display_list; - di && ! focused; - di = DISPLAY_LIST_INFO (di)->next) - focused = DISPLAY_LIST_INFO (di)->x_highlight_frame != 0; - - if (! focused) obj = make_lispy_focus_out (frame); -#endif /* DISPLAY_LIST_INFO */ + for (di = x_display_list; di && ! focused; di = di->next) + focused = di->x_highlight_frame != 0; + + if (!focused) + obj = make_lispy_focus_out (frame); + +#endif /* HAVE_WINDOW_SYSTEM */ kbd_fetch_ptr = event + 1; } ------------------------------------------------------------ revno: 113455 committer: Xue Fuqiao branch nick: trunk timestamp: Fri 2013-07-19 14:31:17 +0800 message: * doc/lispref/windows.texi (Display Action Functions): Mention next-window. diff: === modified file 'doc/lispref/ChangeLog' --- doc/lispref/ChangeLog 2013-07-16 06:45:01 +0000 +++ doc/lispref/ChangeLog 2013-07-19 06:31:17 +0000 @@ -1,3 +1,7 @@ +2013-07-19 Xue Fuqiao + + * windows.texi (Display Action Functions): Mention next-window. + 2013-07-16 Xue Fuqiao * windows.texi (Selecting Windows): Fix the introduction of === modified file 'doc/lispref/windows.texi' --- doc/lispref/windows.texi 2013-07-16 06:45:01 +0000 +++ doc/lispref/windows.texi 2013-07-19 06:31:17 +0000 @@ -1924,6 +1924,10 @@ A frame means consider windows on that frame only. @end itemize +Note that these meanings differ slightly from those of the +@var{all-frames} argument to @code{next-window} (@pxref{Cyclic Window +Ordering}). + If @var{alist} contains no @code{reusable-frames} entry, this function normally searches just the selected frame; however, if the variable @code{pop-up-frames} is non-@code{nil}, it searches all frames on the