------------------------------------------------------------ revno: 114617 committer: Stefan Monnier branch nick: trunk timestamp: Thu 2013-10-10 17:43:47 -0400 message: * test/automated/ruby-mode-tests.el (ruby-with-temp-buffer): Move before first use. (ruby-should-indent): Use indent-according-to-mode. (ruby-deftest-move-to-block): Use `declare'. diff: === modified file 'test/ChangeLog' --- test/ChangeLog 2013-10-10 02:33:35 +0000 +++ test/ChangeLog 2013-10-10 21:43:47 +0000 @@ -1,3 +1,10 @@ +2013-10-10 Stefan Monnier + + * automated/ruby-mode-tests.el (ruby-with-temp-buffer): Move before + first use. + (ruby-should-indent): Use indent-according-to-mode. + (ruby-deftest-move-to-block): Use `declare'. + 2013-10-07 Dmitry Gutov * indent/ruby.rb: Fix a spurious change, add more failing examples. === modified file 'test/automated/ruby-mode-tests.el' --- test/automated/ruby-mode-tests.el 2013-10-09 03:18:01 +0000 +++ test/automated/ruby-mode-tests.el 2013-10-10 21:43:47 +0000 @@ -24,10 +24,17 @@ (require 'ert) (require 'ruby-mode) +(defmacro ruby-with-temp-buffer (contents &rest body) + (declare (indent 1) (debug t)) + `(with-temp-buffer + (insert ,contents) + (ruby-mode) + ,@body)) + (defun ruby-should-indent (content column) "Assert indentation COLUMN on the last line of CONTENT." (ruby-with-temp-buffer content - (ruby-indent-line) + (indent-according-to-mode) (should (= (current-indentation) column)))) (defun ruby-should-indent-buffer (expected content) @@ -38,13 +45,6 @@ (indent-region (point-min) (point-max)) (should (string= (ruby-test-string expected) (buffer-string))))) -(defmacro ruby-with-temp-buffer (contents &rest body) - (declare (indent 1) (debug t)) - `(with-temp-buffer - (insert ,contents) - (ruby-mode) - ,@body)) - (defun ruby-test-string (s &rest args) (apply 'format (replace-regexp-in-string "^[ \t]*|" "" s) args)) @@ -471,6 +471,7 @@ |end")) (defmacro ruby-deftest-move-to-block (name &rest body) + (declare (indent defun)) `(ert-deftest ,(intern (format "ruby-move-to-block-%s" name)) () (with-temp-buffer (insert ruby-block-test-example) @@ -478,8 +479,6 @@ (goto-char (point-min)) ,@body))) -(put 'ruby-deftest-move-to-block 'lisp-indent-function 'defun) - (ruby-deftest-move-to-block works-on-do (forward-line 10) (ruby-end-of-block) ------------------------------------------------------------ revno: 114616 committer: Stefan Monnier branch nick: trunk timestamp: Thu 2013-10-10 17:42:38 -0400 message: * src/fileio.c (Fsubstitute_in_file_name): Use substitute-env-in-file-name. (Qsubstitute_env_in_file_name): New var. (syms_of_fileio): Define it. * lisp/env.el (substitute-env-in-file-name): New function. (substitute-env-vars): Extend the meaning of the optional arg. diff: === modified file 'lisp/ChangeLog' --- lisp/ChangeLog 2013-10-10 15:30:21 +0000 +++ lisp/ChangeLog 2013-10-10 21:42:38 +0000 @@ -1,3 +1,8 @@ +2013-10-10 Stefan Monnier + + * env.el (substitute-env-in-file-name): New function. + (substitute-env-vars): Extend the meaning of the optional arg. + 2013-10-10 Eli Zaretskii * term/w32-win.el (dynamic-library-alist): Define separate lists === modified file 'lisp/env.el' --- lisp/env.el 2013-01-02 16:13:04 +0000 +++ lisp/env.el 2013-10-10 21:42:38 +0000 @@ -1,4 +1,4 @@ -;;; env.el --- functions to manipulate environment variables +;;; env.el --- functions to manipulate environment variables -*- lexical-binding:t -*- ;; Copyright (C) 1991, 1994, 2000-2013 Free Software Foundation, Inc. @@ -60,30 +60,46 @@ (defconst env--substitute-vars-regexp "\\$\\(?:\\(?1:[[:alnum:]_]+\\)\\|{\\(?1:[^{}]+\\)}\\|\\$\\)") -(defun substitute-env-vars (string &optional only-defined) +(defun substitute-env-vars (string &optional when-undefined) "Substitute environment variables referred to in STRING. `$FOO' where FOO is an environment variable name means to substitute the value of that variable. The variable name should be terminated with a character not a letter, digit or underscore; otherwise, enclose the entire variable name in braces. For instance, in `ab$cd-x', `$cd' is treated as an environment variable. -If ONLY-DEFINED is nil, references to undefined environment variables -are replaced by the empty string; if it is non-nil, they are left unchanged. + +If WHEN-DEFINED is nil, references to undefined environment variables +are replaced by the empty string; if it is a function, the function is called +with the variable name as argument and should return the text with which +to replace it or nil to leave it unchanged. +If it is non-nil and not a function, references to undefined variables are +left unchanged. Use `$$' to insert a single dollar sign." (let ((start 0)) (while (string-match env--substitute-vars-regexp string start) (cond ((match-beginning 1) - (let ((value (getenv (match-string 1 string)))) - (if (and (null value) only-defined) + (let* ((var (match-string 1 string)) + (value (getenv var))) + (if (and (null value) + (if (functionp when-undefined) + (null (setq value (funcall when-undefined var))) + when-undefined)) (setq start (match-end 0)) - (setq string (replace-match (or value "") t t string) + (setq string (replace-match (or value "") t t string) start (+ (match-beginning 0) (length value)))))) (t (setq string (replace-match "$" t t string) start (+ (match-beginning 0) 1))))) string)) +(defun substitute-env-in-file-name (filename) + (substitute-env-vars filename + ;; How 'bout we lookup other tables than the env? + ;; E.g. we could accept bookmark names as well! + (if (memq system-type '(windows-nt ms-dos)) + (lambda (var) (getenv (upcase var))) + t))) (defun setenv-internal (env variable value keep-empty) "Set VARIABLE to VALUE in ENV, adding empty entries if KEEP-EMPTY. === modified file 'src/ChangeLog' --- src/ChangeLog 2013-10-10 19:26:13 +0000 +++ src/ChangeLog 2013-10-10 21:42:38 +0000 @@ -1,3 +1,9 @@ +2013-10-10 Stefan Monnier + + * fileio.c (Fsubstitute_in_file_name): Use substitute-env-in-file-name. + (Qsubstitute_env_in_file_name): New var. + (syms_of_fileio): Define it. + 2013-10-10 Eli Zaretskii * xdisp.c (deep_copy_glyph_row): Assert that the 'used' counts of === modified file 'src/fileio.c' --- src/fileio.c 2013-10-08 06:40:09 +0000 +++ src/fileio.c 2013-10-10 21:42:38 +0000 @@ -143,6 +143,8 @@ /* Lisp function for recursively deleting directories. */ static Lisp_Object Qdelete_directory; +static Lisp_Object Qsubstitute_env_in_file_name; + #ifdef WINDOWSNT #endif @@ -1664,10 +1666,8 @@ those `/' is discarded. */) (Lisp_Object filename) { - char *nm, *s, *p, *o, *x, *endp; - char *target = NULL; - ptrdiff_t total = 0; - bool substituted = 0; + char *nm, *p, *x, *endp; + bool substituted = false; bool multibyte; char *xnm; Lisp_Object handler; @@ -1708,66 +1708,19 @@ return Fsubstitute_in_file_name (make_specified_string (p, -1, endp - p, multibyte)); - /* See if any variables are substituted into the string - and find the total length of their values in `total'. */ - - for (p = nm; p != endp;) - if (*p != '$') - p++; - else - { - p++; - if (p == endp) - goto badsubst; - else if (*p == '$') - { - /* "$$" means a single "$". */ - p++; - total -= 1; - substituted = 1; - continue; - } - else if (*p == '{') - { - o = ++p; - p = memchr (p, '}', endp - p); - if (! p) - goto missingclose; - s = p; - } - else - { - o = p; - while (p != endp && (c_isalnum (*p) || *p == '_')) p++; - s = p; - } - - /* Copy out the variable name. */ - target = alloca (s - o + 1); - memcpy (target, o, s - o); - target[s - o] = 0; -#ifdef DOS_NT - strupr (target); /* $home == $HOME etc. */ -#endif /* DOS_NT */ - - /* Get variable value. */ - o = egetenv (target); - if (o) - { - /* Don't try to guess a maximum length - UTF8 can use up to - four bytes per character. This code is unlikely to run - in a situation that requires performance, so decoding the - env variables twice should be acceptable. Note that - decoding may cause a garbage collect. */ - Lisp_Object orig, decoded; - orig = build_unibyte_string (o); - decoded = DECODE_FILE (orig); - total += SBYTES (decoded); - substituted = 1; - } - else if (*p == '}') - goto badvar; - } + /* See if any variables are substituted into the string. */ + + if (!NILP (Ffboundp (Qsubstitute_env_in_file_name))) + { + Lisp_Object name + = (!substituted ? filename + : make_specified_string (nm, -1, endp - nm, multibyte)); + Lisp_Object tmp = call1 (Qsubstitute_env_in_file_name, name); + CHECK_STRING (tmp); + if (!EQ (tmp, name)) + substituted = true; + filename = tmp; + } if (!substituted) { @@ -1778,73 +1731,9 @@ return filename; } - /* If substitution required, recopy the string and do it. */ - /* Make space in stack frame for the new copy. */ - xnm = alloca (SBYTES (filename) + total + 1); - x = xnm; - - /* Copy the rest of the name through, replacing $ constructs with values. */ - for (p = nm; *p;) - if (*p != '$') - *x++ = *p++; - else - { - p++; - if (p == endp) - goto badsubst; - else if (*p == '$') - { - *x++ = *p++; - continue; - } - else if (*p == '{') - { - o = ++p; - p = memchr (p, '}', endp - p); - if (! p) - goto missingclose; - s = p++; - } - else - { - o = p; - while (p != endp && (c_isalnum (*p) || *p == '_')) p++; - s = p; - } - - /* Copy out the variable name. */ - target = alloca (s - o + 1); - memcpy (target, o, s - o); - target[s - o] = 0; - - /* Get variable value. */ - o = egetenv (target); - if (!o) - { - *x++ = '$'; - strcpy (x, target); x+= strlen (target); - } - else - { - Lisp_Object orig, decoded; - ptrdiff_t orig_length, decoded_length; - orig_length = strlen (o); - orig = make_unibyte_string (o, orig_length); - decoded = DECODE_FILE (orig); - decoded_length = SBYTES (decoded); - memcpy (x, SDATA (decoded), decoded_length); - x += decoded_length; - - /* If environment variable needed decoding, return value - needs to be multibyte. */ - if (decoded_length != orig_length - || memcmp (SDATA (decoded), o, orig_length)) - multibyte = 1; - } - } - - *x = 0; - + xnm = SSDATA (filename); + x = xnm + SBYTES (filename); + /* If /~ or // appears, discard everything through first slash. */ while ((p = search_embedded_absfilename (xnm, x)) != NULL) /* This time we do not start over because we've already expanded envvars @@ -1862,14 +1751,9 @@ } else #endif - return make_specified_string (xnm, -1, x - xnm, multibyte); - - badsubst: - error ("Bad format environment-variable substitution"); - missingclose: - error ("Missing \"}\" in environment-variable substitution"); - badvar: - error ("Substituting nonexistent environment variable \"%s\"", target); + return (xnm == SSDATA (filename) + ? filename + : make_specified_string (xnm, -1, x - xnm, multibyte)); } /* A slightly faster and more convenient way to get @@ -6108,6 +5992,7 @@ DEFSYM (Qmove_file_to_trash, "move-file-to-trash"); DEFSYM (Qcopy_directory, "copy-directory"); DEFSYM (Qdelete_directory, "delete-directory"); + DEFSYM (Qsubstitute_env_in_file_name, "substitute-env-in-file-name"); defsubr (&Sfind_file_name_handler); defsubr (&Sfile_name_directory); ------------------------------------------------------------ revno: 114615 fixes bug: http://debbugs.gnu.org/15575 committer: Eli Zaretskii branch nick: trunk timestamp: Thu 2013-10-10 22:26:13 +0300 message: Attempt to fix crashes per bug #15575. src/xdisp.c (deep_copy_glyph_row): Assert that the 'used' counts of FROM and TO are identical. Copy only the glyphs of TEXT_AREA. src/term.c (save_and_enable_current_matrix): Don't allocate and don't save margin areas. (restore_desired_matrix): Don't restore margin areas. (free_saved_screen): Don't free margin areas. diff: === modified file 'src/ChangeLog' --- src/ChangeLog 2013-10-10 19:15:33 +0000 +++ src/ChangeLog 2013-10-10 19:26:13 +0000 @@ -1,3 +1,14 @@ +2013-10-10 Eli Zaretskii + + * xdisp.c (deep_copy_glyph_row): Assert that the 'used' counts of + FROM and TO are identical. Copy only the glyphs of TEXT_AREA. + (Bug#15575) + + * term.c (save_and_enable_current_matrix): Don't allocate and + don't save margin areas. + (restore_desired_matrix): Don't restore margin areas. + (free_saved_screen): Don't free margin areas. + 2013-10-10 Paul Eggert * image.c: Pacify --enable-gcc-warnings. === modified file 'src/term.c' --- src/term.c 2013-10-10 06:48:42 +0000 +++ src/term.c 2013-10-10 19:26:13 +0000 @@ -3066,22 +3066,6 @@ screen will not be redrawn anyway.) */ to->enabled_p = 1; to->hash = from->hash; - if (from->used[LEFT_MARGIN_AREA]) - { - nbytes = from->used[LEFT_MARGIN_AREA] * sizeof (struct glyph); - to->glyphs[LEFT_MARGIN_AREA] = xmalloc (nbytes); - memcpy (to->glyphs[LEFT_MARGIN_AREA], - from->glyphs[LEFT_MARGIN_AREA], nbytes); - to->used[LEFT_MARGIN_AREA] = from->used[LEFT_MARGIN_AREA]; - } - if (from->used[RIGHT_MARGIN_AREA]) - { - nbytes = from->used[RIGHT_MARGIN_AREA] * sizeof (struct glyph); - to->glyphs[RIGHT_MARGIN_AREA] = xmalloc (nbytes); - memcpy (to->glyphs[RIGHT_MARGIN_AREA], - from->glyphs[RIGHT_MARGIN_AREA], nbytes); - to->used[RIGHT_MARGIN_AREA] = from->used[RIGHT_MARGIN_AREA]; - } } return saved; @@ -3106,26 +3090,6 @@ to->used[TEXT_AREA] = from->used[TEXT_AREA]; to->enabled_p = from->enabled_p; to->hash = from->hash; - nbytes = from->used[LEFT_MARGIN_AREA] * sizeof (struct glyph); - if (nbytes) - { - eassert (to->glyphs[LEFT_MARGIN_AREA] != from->glyphs[LEFT_MARGIN_AREA]); - memcpy (to->glyphs[LEFT_MARGIN_AREA], - from->glyphs[LEFT_MARGIN_AREA], nbytes); - to->used[LEFT_MARGIN_AREA] = from->used[LEFT_MARGIN_AREA]; - } - else - to->used[LEFT_MARGIN_AREA] = 0; - nbytes = from->used[RIGHT_MARGIN_AREA] * sizeof (struct glyph); - if (nbytes) - { - eassert (to->glyphs[RIGHT_MARGIN_AREA] != from->glyphs[RIGHT_MARGIN_AREA]); - memcpy (to->glyphs[RIGHT_MARGIN_AREA], - from->glyphs[RIGHT_MARGIN_AREA], nbytes); - to->used[RIGHT_MARGIN_AREA] = from->used[RIGHT_MARGIN_AREA]; - } - else - to->used[RIGHT_MARGIN_AREA] = 0; } } @@ -3142,10 +3106,6 @@ struct glyph_row *from = saved->rows + i; xfree (from->glyphs[TEXT_AREA]); - if (from->used[LEFT_MARGIN_AREA]) - xfree (from->glyphs[LEFT_MARGIN_AREA]); - if (from->used[RIGHT_MARGIN_AREA]) - xfree (from->glyphs[RIGHT_MARGIN_AREA]); } xfree (saved->rows); === modified file 'src/xdisp.c' --- src/xdisp.c 2013-10-08 17:49:20 +0000 +++ src/xdisp.c 2013-10-10 19:26:13 +0000 @@ -20589,34 +20589,22 @@ static void deep_copy_glyph_row (struct glyph_row *to, struct glyph_row *from) { - int area, i, sum_used = 0; + int area, i; struct glyph *pointers[1 + LAST_AREA]; /* Save glyph pointers of TO. */ memcpy (pointers, to->glyphs, sizeof to->glyphs); + eassert (to->used[TEXT_AREA] == from->used[TEXT_AREA]); /* Do a structure assignment. */ *to = *from; - /* Restore original pointers of TO. */ + /* Restore original glyph pointers of TO. */ memcpy (to->glyphs, pointers, sizeof to->glyphs); - /* Count how many glyphs to copy and update glyph pointers. */ - for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area) - { - if (area > LEFT_MARGIN_AREA) - { - eassert (from->glyphs[area] - from->glyphs[area - 1] - == from->used[area - 1]); - to->glyphs[area] = to->glyphs[area - 1] + to->used[area - 1]; - } - sum_used += from->used[area]; - } - /* Copy the glyphs. */ - eassert (sum_used <= to->glyphs[LAST_AREA] - to->glyphs[LEFT_MARGIN_AREA]); - for (i = 0; i < sum_used; i++) - to->glyphs[LEFT_MARGIN_AREA][i] = from->glyphs[LEFT_MARGIN_AREA][i]; + memcpy (to->glyphs[TEXT_AREA], from->glyphs[TEXT_AREA], + from->used[TEXT_AREA] * sizeof (struct glyph)); } /* Display one menu item on a TTY, by overwriting the glyphs in the