aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorYuuki Harano2021-05-29 18:00:13 +0900
committerYuuki Harano2021-05-29 18:00:13 +0900
commit67ae4b6271233559271f7a7158ba0e059b643ba5 (patch)
tree9ceee3c99afb42b252ac11116cc31163acaaeb40 /src
parent67a4c8b5ad9ebfb3fa2c7fae433aa6b6b5e92154 (diff)
parente3fc16fd71a46990503a71b11a2ad592e99d9edb (diff)
downloademacs-67ae4b6271233559271f7a7158ba0e059b643ba5.tar.gz
emacs-67ae4b6271233559271f7a7158ba0e059b643ba5.zip
Merge branch 'master' of git.sv.gnu.org:/srv/git/emacs into feature/pgtk
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.in2
-rw-r--r--src/buffer.c8
-rw-r--r--src/character.c52
-rw-r--r--src/comp.c22
-rw-r--r--src/composite.c10
-rw-r--r--src/composite.h4
-rw-r--r--src/conf_post.h31
-rw-r--r--src/editfns.c4
-rw-r--r--src/fileio.c16
-rw-r--r--src/fns.c18
-rw-r--r--src/fringe.c5
-rw-r--r--src/gmalloc.c32
-rw-r--r--src/keyboard.c13
-rw-r--r--src/lread.c10
-rw-r--r--src/process.c29
-rw-r--r--src/sysdep.c84
-rw-r--r--src/w32.c39
-rw-r--r--src/w32.h1
18 files changed, 289 insertions, 91 deletions
diff --git a/src/Makefile.in b/src/Makefile.in
index 5da2257ba97..40a423d6a1e 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -345,7 +345,7 @@ DUMPING=@DUMPING@
345CHECK_STRUCTS = @CHECK_STRUCTS@ 345CHECK_STRUCTS = @CHECK_STRUCTS@
346HAVE_PDUMPER = @HAVE_PDUMPER@ 346HAVE_PDUMPER = @HAVE_PDUMPER@
347 347
348## ARM Macs require that all code have a valid signature. Since pump 348## ARM Macs require that all code have a valid signature. Since pdump
349## invalidates the signature, we must re-sign to fix it. 349## invalidates the signature, we must re-sign to fix it.
350DO_CODESIGN=$(patsubst aarch64-apple-darwin%,yes,@configuration@) 350DO_CODESIGN=$(patsubst aarch64-apple-darwin%,yes,@configuration@)
351 351
diff --git a/src/buffer.c b/src/buffer.c
index df302db0e52..565577e75ae 100644
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -5681,10 +5681,10 @@ inserts one or more TAB characters, this variable will affect the
5681indentation step as well, even if `indent-tabs-mode' is non-nil. */); 5681indentation step as well, even if `indent-tabs-mode' is non-nil. */);
5682 5682
5683 DEFVAR_PER_BUFFER ("ctl-arrow", &BVAR (current_buffer, ctl_arrow), Qnil, 5683 DEFVAR_PER_BUFFER ("ctl-arrow", &BVAR (current_buffer, ctl_arrow), Qnil,
5684 doc: /* Non-nil means display control chars with uparrow. 5684 doc: /* Non-nil means display control chars with uparrow `^'.
5685A value of nil means use backslash and octal digits. 5685A value of nil means use backslash `\\' and octal digits.
5686This variable does not apply to characters whose display is specified 5686This variable does not apply to characters whose display is specified in
5687in the current display table (if there is one). */); 5687the current display table (if there is one; see `standard-display-table'). */);
5688 5688
5689 DEFVAR_PER_BUFFER ("enable-multibyte-characters", 5689 DEFVAR_PER_BUFFER ("enable-multibyte-characters",
5690 &BVAR (current_buffer, enable_multibyte_characters), 5690 &BVAR (current_buffer, enable_multibyte_characters),
diff --git a/src/character.c b/src/character.c
index 41abb83a48b..e874cf5e53c 100644
--- a/src/character.c
+++ b/src/character.c
@@ -34,6 +34,7 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
34#include "lisp.h" 34#include "lisp.h"
35#include "character.h" 35#include "character.h"
36#include "buffer.h" 36#include "buffer.h"
37#include "frame.h"
37#include "dispextern.h" 38#include "dispextern.h"
38#include "composite.h" 39#include "composite.h"
39#include "disptab.h" 40#include "disptab.h"
@@ -338,11 +339,18 @@ lisp_string_width (Lisp_Object string, ptrdiff_t from, ptrdiff_t to,
338 contains only ascii and eight-bit-graphic, but that's 339 contains only ascii and eight-bit-graphic, but that's
339 intentional. */ 340 intentional. */
340 bool multibyte = SCHARS (string) < SBYTES (string); 341 bool multibyte = SCHARS (string) < SBYTES (string);
341 unsigned char *str = SDATA (string);
342 ptrdiff_t i = from, i_byte = from ? string_char_to_byte (string, from) : 0; 342 ptrdiff_t i = from, i_byte = from ? string_char_to_byte (string, from) : 0;
343 ptrdiff_t from_byte = i_byte; 343 ptrdiff_t from_byte = i_byte;
344 ptrdiff_t width = 0; 344 ptrdiff_t width = 0;
345 struct Lisp_Char_Table *dp = buffer_display_table (); 345 struct Lisp_Char_Table *dp = buffer_display_table ();
346#ifdef HAVE_WINDOW_SYSTEM
347 struct frame *f =
348 (FRAMEP (selected_frame) && FRAME_LIVE_P (XFRAME (selected_frame)))
349 ? XFRAME (selected_frame)
350 : NULL;
351 int font_width = -1;
352 Lisp_Object default_font, frame_font;
353#endif
346 354
347 eassert (precision <= 0 || (nchars && nbytes)); 355 eassert (precision <= 0 || (nchars && nbytes));
348 356
@@ -361,9 +369,51 @@ lisp_string_width (Lisp_Object string, ptrdiff_t from, ptrdiff_t to,
361 chars = end - i; 369 chars = end - i;
362 bytes = string_char_to_byte (string, end) - i_byte; 370 bytes = string_char_to_byte (string, end) - i_byte;
363 } 371 }
372#ifdef HAVE_WINDOW_SYSTEM
373 else if (f && FRAME_WINDOW_P (f)
374 && multibyte
375 && find_automatic_composition (i, -1, &ignore, &end, &val, string)
376 && end > i)
377 {
378 int j;
379 for (j = 0; j < LGSTRING_GLYPH_LEN (val); j++)
380 if (NILP (LGSTRING_GLYPH (val, j)))
381 break;
382
383 int pixelwidth = composition_gstring_width (val, 0, j, NULL);
384
385 /* The below is somewhat expensive, so compute it only once
386 for the entire loop, and only if needed. */
387 if (font_width < 0)
388 {
389 font_width = FRAME_COLUMN_WIDTH (f);
390 default_font = Fface_font (Qdefault, Qnil, Qnil);
391 frame_font = Fframe_parameter (Qnil, Qfont);
392
393 if (STRINGP (default_font) && STRINGP (frame_font)
394 && (SCHARS (default_font) != SCHARS (frame_font)
395 || SBYTES (default_font) != SBYTES (frame_font)
396 || memcmp (SDATA (default_font), SDATA (frame_font),
397 SBYTES (default_font))))
398 {
399 Lisp_Object font_info = Ffont_info (default_font, Qnil);
400 if (VECTORP (font_info))
401 {
402 font_width = XFIXNUM (AREF (font_info, 11));
403 if (font_width <= 0)
404 font_width = XFIXNUM (AREF (font_info, 10));
405 }
406 }
407 }
408 thiswidth = (double) pixelwidth / font_width + 0.5;
409 chars = end - i;
410 bytes = string_char_to_byte (string, end) - i_byte;
411 }
412#endif /* HAVE_WINDOW_SYSTEM */
364 else 413 else
365 { 414 {
366 int c; 415 int c;
416 unsigned char *str = SDATA (string);
367 417
368 if (multibyte) 418 if (multibyte)
369 { 419 {
diff --git a/src/comp.c b/src/comp.c
index c0445050b71..056d0860d8a 100644
--- a/src/comp.c
+++ b/src/comp.c
@@ -4008,15 +4008,16 @@ DEFUN ("comp-el-to-eln-rel-filename", Fcomp_el_to_eln_rel_filename,
4008{ 4008{
4009 CHECK_STRING (filename); 4009 CHECK_STRING (filename);
4010 4010
4011 /* Use `file-truename' or fall back to `expand-file-name' when the 4011 /* Resolve possible symlinks in FILENAME, so that path_hash below
4012 first is not available (bug#44701). 4012 always compares equal. (Bug#44701). */
4013 4013 filename = Fexpand_file_name (filename, Qnil);
4014 `file-truename' is not available only for a short phases of the 4014 char *file_normalized = realpath (SSDATA (ENCODE_FILE (filename)), NULL);
4015 bootstrap before file.el is loaded, given we do not symlink 4015 if (file_normalized)
4016 inside the build directory this should work. */ 4016 {
4017 filename = NILP (Ffboundp (intern_c_string ("file-truename"))) 4017 filename = DECODE_FILE (make_unibyte_string (file_normalized,
4018 ? Fexpand_file_name (filename, Qnil) 4018 strlen (file_normalized)));
4019 : CALL1I (file-truename, filename); 4019 xfree (file_normalized);
4020 }
4020 4021
4021 if (NILP (Ffile_exists_p (filename))) 4022 if (NILP (Ffile_exists_p (filename)))
4022 xsignal1 (Qfile_missing, filename); 4023 xsignal1 (Qfile_missing, filename);
@@ -4056,7 +4057,8 @@ DEFUN ("comp-el-to-eln-rel-filename", Fcomp_el_to_eln_rel_filename,
4056 Lisp_Object sys_re = 4057 Lisp_Object sys_re =
4057 concat2 (build_string ("\\`[[:ascii:]]+"), 4058 concat2 (build_string ("\\`[[:ascii:]]+"),
4058 Fregexp_quote (build_string ("/" PATH_REL_LOADSEARCH "/"))); 4059 Fregexp_quote (build_string ("/" PATH_REL_LOADSEARCH "/")));
4059 Lisp_Object dump_load_search = build_string (PATH_DUMPLOADSEARCH "/"); 4060 Lisp_Object dump_load_search =
4061 Fexpand_file_name (build_string (PATH_DUMPLOADSEARCH "/"), Qnil);
4060#ifdef WINDOWSNT 4062#ifdef WINDOWSNT
4061 dump_load_search = Fw32_long_file_name (dump_load_search); 4063 dump_load_search = Fw32_long_file_name (dump_load_search);
4062#endif 4064#endif
diff --git a/src/composite.c b/src/composite.c
index f1c011223b2..17d5914e634 100644
--- a/src/composite.c
+++ b/src/composite.c
@@ -953,8 +953,12 @@ char_composable_p (int c)
953 Lisp_Object val; 953 Lisp_Object val;
954 return (c >= ' ' 954 return (c >= ' '
955 && (c == ZERO_WIDTH_NON_JOINER || c == ZERO_WIDTH_JOINER 955 && (c == ZERO_WIDTH_NON_JOINER || c == ZERO_WIDTH_JOINER
956 || (val = CHAR_TABLE_REF (Vunicode_category_table, c), 956 /* unicode-category-table may not be available during
957 (FIXNUMP (val) && (XFIXNUM (val) <= UNICODE_CATEGORY_Zs))))); 957 dumping. */
958 || (CHAR_TABLE_P (Vunicode_category_table)
959 && (val = CHAR_TABLE_REF (Vunicode_category_table, c),
960 (FIXNUMP (val)
961 && (XFIXNUM (val) <= UNICODE_CATEGORY_Zs))))));
958} 962}
959 963
960/* Update cmp_it->stop_pos to the next position after CHARPOS (and 964/* Update cmp_it->stop_pos to the next position after CHARPOS (and
@@ -1475,7 +1479,7 @@ struct position_record
1475 representing the composition, and return true. Otherwise, *GSTRING to 1479 representing the composition, and return true. Otherwise, *GSTRING to
1476 Qnil, and return false. */ 1480 Qnil, and return false. */
1477 1481
1478static bool 1482bool
1479find_automatic_composition (ptrdiff_t pos, ptrdiff_t limit, 1483find_automatic_composition (ptrdiff_t pos, ptrdiff_t limit,
1480 ptrdiff_t *start, ptrdiff_t *end, 1484 ptrdiff_t *start, ptrdiff_t *end,
1481 Lisp_Object *gstring, Lisp_Object string) 1485 Lisp_Object *gstring, Lisp_Object string)
diff --git a/src/composite.h b/src/composite.h
index c5d3c0faabb..75e5f9b9ecb 100644
--- a/src/composite.h
+++ b/src/composite.h
@@ -320,6 +320,10 @@ extern bool composition_gstring_p (Lisp_Object);
320extern int composition_gstring_width (Lisp_Object, ptrdiff_t, ptrdiff_t, 320extern int composition_gstring_width (Lisp_Object, ptrdiff_t, ptrdiff_t,
321 struct font_metrics *); 321 struct font_metrics *);
322 322
323extern bool find_automatic_composition (ptrdiff_t, ptrdiff_t, ptrdiff_t *,
324 ptrdiff_t *, Lisp_Object *,
325 Lisp_Object);
326
323extern void composition_compute_stop_pos (struct composition_it *, 327extern void composition_compute_stop_pos (struct composition_it *,
324 ptrdiff_t, ptrdiff_t, ptrdiff_t, 328 ptrdiff_t, ptrdiff_t, ptrdiff_t,
325 Lisp_Object); 329 Lisp_Object);
diff --git a/src/conf_post.h b/src/conf_post.h
index 176ab28b21a..8558dc466cc 100644
--- a/src/conf_post.h
+++ b/src/conf_post.h
@@ -99,10 +99,28 @@ typedef bool bool_bf;
99# define ADDRESS_SANITIZER false 99# define ADDRESS_SANITIZER false
100#endif 100#endif
101 101
102#ifdef emacs
103/* We include stdlib.h here, because Gnulib's stdlib.h might redirect
104 'free' to its replacement, and we want to avoid that in unexec
105 builds. Inclduing it here will render its inclusion after config.h
106 a no-op. */
107# if (defined DARWIN_OS && defined HAVE_UNEXEC) || defined HYBRID_MALLOC
108# include <stdlib.h>
109# endif
110#endif
111
102#if defined DARWIN_OS && defined emacs && defined HAVE_UNEXEC 112#if defined DARWIN_OS && defined emacs && defined HAVE_UNEXEC
113# undef malloc
103# define malloc unexec_malloc 114# define malloc unexec_malloc
115# undef realloc
104# define realloc unexec_realloc 116# define realloc unexec_realloc
117# undef free
105# define free unexec_free 118# define free unexec_free
119
120extern void *unexec_malloc (size_t);
121extern void *unexec_realloc (void *, size_t);
122extern void unexec_free (void *);
123
106#endif 124#endif
107 125
108/* If HYBRID_MALLOC is defined (e.g., on Cygwin), emacs will use 126/* If HYBRID_MALLOC is defined (e.g., on Cygwin), emacs will use
@@ -111,12 +129,23 @@ typedef bool bool_bf;
111 accomplish this. */ 129 accomplish this. */
112#ifdef HYBRID_MALLOC 130#ifdef HYBRID_MALLOC
113#ifdef emacs 131#ifdef emacs
132#undef malloc
114#define malloc hybrid_malloc 133#define malloc hybrid_malloc
134#undef realloc
115#define realloc hybrid_realloc 135#define realloc hybrid_realloc
136#undef aligned_alloc
116#define aligned_alloc hybrid_aligned_alloc 137#define aligned_alloc hybrid_aligned_alloc
138#undef calloc
117#define calloc hybrid_calloc 139#define calloc hybrid_calloc
140#undef free
118#define free hybrid_free 141#define free hybrid_free
119#endif 142
143extern void *hybrid_malloc (size_t);
144extern void *hybrid_calloc (size_t, size_t);
145extern void hybrid_free (void *);
146extern void *hybrid_aligned_alloc (size_t, size_t);
147extern void *hybrid_realloc (void *, size_t);
148#endif /* emacs */
120#endif /* HYBRID_MALLOC */ 149#endif /* HYBRID_MALLOC */
121 150
122/* We have to go this route, rather than the old hpux9 approach of 151/* We have to go this route, rather than the old hpux9 approach of
diff --git a/src/editfns.c b/src/editfns.c
index 04b8e85d9c6..182d3ba6f2b 100644
--- a/src/editfns.c
+++ b/src/editfns.c
@@ -1452,8 +1452,8 @@ DEFUN ("insert-char", Finsert_char, Sinsert_char, 1, 3,
1452 (prefix-numeric-value current-prefix-arg)\ 1452 (prefix-numeric-value current-prefix-arg)\
1453 t))", 1453 t))",
1454 doc: /* Insert COUNT copies of CHARACTER. 1454 doc: /* Insert COUNT copies of CHARACTER.
1455Interactively, prompt for CHARACTER. You can specify CHARACTER in one 1455Interactively, prompt for CHARACTER using `read-char-by-name'.
1456of these ways: 1456You can specify CHARACTER in one of these ways:
1457 1457
1458 - As its Unicode character name, e.g. \"LATIN SMALL LETTER A\". 1458 - As its Unicode character name, e.g. \"LATIN SMALL LETTER A\".
1459 Completion is available; if you type a substring of the name 1459 Completion is available; if you type a substring of the name
diff --git a/src/fileio.c b/src/fileio.c
index 741e297d29c..caf077e2fbf 100644
--- a/src/fileio.c
+++ b/src/fileio.c
@@ -2987,12 +2987,16 @@ file_directory_p (Lisp_Object file)
2987DEFUN ("file-accessible-directory-p", Ffile_accessible_directory_p, 2987DEFUN ("file-accessible-directory-p", Ffile_accessible_directory_p,
2988 Sfile_accessible_directory_p, 1, 1, 0, 2988 Sfile_accessible_directory_p, 1, 1, 0,
2989 doc: /* Return t if FILENAME names a directory you can open. 2989 doc: /* Return t if FILENAME names a directory you can open.
2990For the value to be t, FILENAME must specify the name of a directory 2990This means that FILENAME must specify the name of a directory, and the
2991as a file, and the directory must allow you to open files in it. In 2991directory must allow you to open files in it. If this isn't the case,
2992order to use a directory as a buffer's current directory, this 2992return nil.
2993predicate must return true. A directory name spec may be given 2993
2994instead; then the value is t if the directory so specified exists and 2994FILENAME can either be a directory name (eg. \"/tmp/foo/\") or the
2995really is a readable and searchable directory. */) 2995file name of a file which is a directory (eg. \"/tmp/foo\", without
2996the final slash).
2997
2998In order to use a directory as a buffer's current directory, this
2999predicate must return true. */)
2996 (Lisp_Object filename) 3000 (Lisp_Object filename)
2997{ 3001{
2998 Lisp_Object absname; 3002 Lisp_Object absname;
diff --git a/src/fns.c b/src/fns.c
index 41429c8863d..40ade578008 100644
--- a/src/fns.c
+++ b/src/fns.c
@@ -5892,12 +5892,14 @@ in OBJECT. */)
5892 5892
5893DEFUN ("line-number-at-pos", Fline_number_at_pos, 5893DEFUN ("line-number-at-pos", Fline_number_at_pos,
5894 Sline_number_at_pos, 0, 2, 0, 5894 Sline_number_at_pos, 0, 2, 0,
5895 doc: /* Return the line number at POSITION. 5895 doc: /* Return the line number at POSITION in the current buffer.
5896If POSITION is nil, use the current buffer location. 5896If POSITION is nil or omitted, it defaults to point's position in the
5897 5897current buffer.
5898If the buffer is narrowed, the position returned is the position in the 5898
5899visible part of the buffer. If ABSOLUTE is non-nil, count the lines 5899If the buffer is narrowed, the return value by default counts the lines
5900from the absolute start of the buffer. */) 5900from the beginning of the accessible portion of the buffer. But if the
5901second optional argument ABSOLUTE is non-nil, the value counts the lines
5902from the absolute start of the buffer, disregarding the narrowing. */)
5901 (register Lisp_Object position, Lisp_Object absolute) 5903 (register Lisp_Object position, Lisp_Object absolute)
5902{ 5904{
5903 ptrdiff_t pos, start = BEGV_BYTE; 5905 ptrdiff_t pos, start = BEGV_BYTE;
@@ -5915,9 +5917,9 @@ from the absolute start of the buffer. */)
5915 if (!NILP (absolute)) 5917 if (!NILP (absolute))
5916 start = BEG_BYTE; 5918 start = BEG_BYTE;
5917 5919
5918 /* Check that POSITION is n the visible range of the buffer. */ 5920 /* Check that POSITION is in the accessible range of the buffer. */
5919 if (pos < BEGV || pos > ZV) 5921 if (pos < BEGV || pos > ZV)
5920 args_out_of_range (make_int (start), make_int (ZV)); 5922 args_out_of_range_3 (make_int (pos), make_int (BEGV), make_int (ZV));
5921 5923
5922 return make_int (count_lines (start, CHAR_TO_BYTE (pos)) + 1); 5924 return make_int (count_lines (start, CHAR_TO_BYTE (pos)) + 1);
5923} 5925}
diff --git a/src/fringe.c b/src/fringe.c
index 0224268c2e6..e67ea9d88fd 100644
--- a/src/fringe.c
+++ b/src/fringe.c
@@ -1797,14 +1797,15 @@ gui_init_fringe (struct redisplay_interface *rif)
1797 for (bt = NO_FRINGE_BITMAP + 1; bt < MAX_STANDARD_FRINGE_BITMAPS; bt++) 1797 for (bt = NO_FRINGE_BITMAP + 1; bt < MAX_STANDARD_FRINGE_BITMAPS; bt++)
1798 { 1798 {
1799 struct fringe_bitmap *fb = &standard_bitmaps[bt]; 1799 struct fringe_bitmap *fb = &standard_bitmaps[bt];
1800 rif->define_fringe_bitmap (bt, fb->bits, fb->height, fb->width); 1800 if (!fringe_bitmaps[bt])
1801 rif->define_fringe_bitmap (bt, fb->bits, fb->height, fb->width);
1801 } 1802 }
1802 1803
1803 /* Set up user-defined fringe bitmaps that might have been defined 1804 /* Set up user-defined fringe bitmaps that might have been defined
1804 before the frame of this kind was initialized. This can happen 1805 before the frame of this kind was initialized. This can happen
1805 if Emacs is started as a daemon and the init files define fringe 1806 if Emacs is started as a daemon and the init files define fringe
1806 bitmaps. */ 1807 bitmaps. */
1807 for ( ; bt < max_used_fringe_bitmap; bt++) 1808 for (bt = NO_FRINGE_BITMAP + 1; bt < max_used_fringe_bitmap; bt++)
1808 { 1809 {
1809 struct fringe_bitmap *fb = fringe_bitmaps[bt]; 1810 struct fringe_bitmap *fb = fringe_bitmaps[bt];
1810 if (fb) 1811 if (fb)
diff --git a/src/gmalloc.c b/src/gmalloc.c
index 66008ea69b2..55ae7365d99 100644
--- a/src/gmalloc.c
+++ b/src/gmalloc.c
@@ -1690,16 +1690,6 @@ valloc (size_t size)
1690#undef free 1690#undef free
1691 1691
1692#ifdef HYBRID_MALLOC 1692#ifdef HYBRID_MALLOC
1693/* Declare system malloc and friends. */
1694extern void *malloc (size_t size);
1695extern void *realloc (void *ptr, size_t size);
1696extern void *calloc (size_t nmemb, size_t size);
1697extern void free (void *ptr);
1698#ifdef HAVE_ALIGNED_ALLOC
1699extern void *aligned_alloc (size_t alignment, size_t size);
1700#elif defined HAVE_POSIX_MEMALIGN
1701extern int posix_memalign (void **memptr, size_t alignment, size_t size);
1702#endif
1703 1693
1704/* Assuming PTR was allocated via the hybrid malloc, return true if 1694/* Assuming PTR was allocated via the hybrid malloc, return true if
1705 PTR was allocated via gmalloc, not the system malloc. Also, return 1695 PTR was allocated via gmalloc, not the system malloc. Also, return
@@ -1736,8 +1726,8 @@ hybrid_calloc (size_t nmemb, size_t size)
1736 return gcalloc (nmemb, size); 1726 return gcalloc (nmemb, size);
1737} 1727}
1738 1728
1739void 1729static void
1740hybrid_free (void *ptr) 1730hybrid_free_1 (void *ptr)
1741{ 1731{
1742 if (allocated_via_gmalloc (ptr)) 1732 if (allocated_via_gmalloc (ptr))
1743 gfree (ptr); 1733 gfree (ptr);
@@ -1745,6 +1735,24 @@ hybrid_free (void *ptr)
1745 free (ptr); 1735 free (ptr);
1746} 1736}
1747 1737
1738void
1739hybrid_free (void *ptr)
1740{
1741 /* Stolen from Gnulib, to make sure we preserve errno. */
1742#if defined __GNUC__ && !defined __clang__
1743 int err[2];
1744 err[0] = errno;
1745 err[1] = errno;
1746 errno = 0;
1747 hybrid_free_1 (ptr);
1748 errno = err[errno == 0];
1749#else
1750 int err = errno;
1751 hybrid_free_1 (ptr);
1752 errno = err;
1753#endif
1754}
1755
1748#if defined HAVE_ALIGNED_ALLOC || defined HAVE_POSIX_MEMALIGN 1756#if defined HAVE_ALIGNED_ALLOC || defined HAVE_POSIX_MEMALIGN
1749void * 1757void *
1750hybrid_aligned_alloc (size_t alignment, size_t size) 1758hybrid_aligned_alloc (size_t alignment, size_t size)
diff --git a/src/keyboard.c b/src/keyboard.c
index c3fce19d881..b2aabdda325 100644
--- a/src/keyboard.c
+++ b/src/keyboard.c
@@ -3233,10 +3233,6 @@ help_char_p (Lisp_Object c)
3233static void 3233static void
3234record_char (Lisp_Object c) 3234record_char (Lisp_Object c)
3235{ 3235{
3236 /* quail.el binds this to avoid recording keys twice. */
3237 if (inhibit_record_char)
3238 return;
3239
3240 int recorded = 0; 3236 int recorded = 0;
3241 3237
3242 if (CONSP (c) && (EQ (XCAR (c), Qhelp_echo) || EQ (XCAR (c), Qmouse_movement))) 3238 if (CONSP (c) && (EQ (XCAR (c), Qhelp_echo) || EQ (XCAR (c), Qmouse_movement)))
@@ -12351,13 +12347,6 @@ If nil, Emacs crashes immediately in response to fatal signals. */);
12351 Vwhile_no_input_ignore_events, 12347 Vwhile_no_input_ignore_events,
12352 doc: /* Ignored events from while-no-input. */); 12348 doc: /* Ignored events from while-no-input. */);
12353 12349
12354 DEFVAR_BOOL ("inhibit--record-char",
12355 inhibit_record_char,
12356 doc: /* If non-nil, don't record input events.
12357This inhibits recording input events for the purposes of keyboard
12358macros, dribble file, and `recent-keys'.
12359Internal use only. */);
12360
12361 pdumper_do_now_and_after_load (syms_of_keyboard_for_pdumper); 12350 pdumper_do_now_and_after_load (syms_of_keyboard_for_pdumper);
12362} 12351}
12363 12352
@@ -12391,8 +12380,6 @@ syms_of_keyboard_for_pdumper (void)
12391 /* Create the initial keyboard. Qt means 'unset'. */ 12380 /* Create the initial keyboard. Qt means 'unset'. */
12392 eassert (initial_kboard == NULL); 12381 eassert (initial_kboard == NULL);
12393 initial_kboard = allocate_kboard (Qt); 12382 initial_kboard = allocate_kboard (Qt);
12394
12395 inhibit_record_char = false;
12396} 12383}
12397 12384
12398void 12385void
diff --git a/src/lread.c b/src/lread.c
index bca53a9a37a..0b33fd0f254 100644
--- a/src/lread.c
+++ b/src/lread.c
@@ -3938,8 +3938,7 @@ string_to_number (char const *string, int base, ptrdiff_t *plen)
3938 bool signedp = negative | positive; 3938 bool signedp = negative | positive;
3939 cp += signedp; 3939 cp += signedp;
3940 3940
3941 enum { INTOVERFLOW = 1, LEAD_INT = 2, DOT_CHAR = 4, TRAIL_INT = 8, 3941 enum { INTOVERFLOW = 1, LEAD_INT = 2, TRAIL_INT = 4, E_EXP = 16 };
3942 E_EXP = 16 };
3943 int state = 0; 3942 int state = 0;
3944 int leading_digit = digit_to_number (*cp, base); 3943 int leading_digit = digit_to_number (*cp, base);
3945 uintmax_t n = leading_digit; 3944 uintmax_t n = leading_digit;
@@ -3959,7 +3958,6 @@ string_to_number (char const *string, int base, ptrdiff_t *plen)
3959 char const *after_digits = cp; 3958 char const *after_digits = cp;
3960 if (*cp == '.') 3959 if (*cp == '.')
3961 { 3960 {
3962 state |= DOT_CHAR;
3963 cp++; 3961 cp++;
3964 } 3962 }
3965 3963
@@ -4008,8 +4006,10 @@ string_to_number (char const *string, int base, ptrdiff_t *plen)
4008 cp = ecp; 4006 cp = ecp;
4009 } 4007 }
4010 4008
4011 float_syntax = ((state & (DOT_CHAR|TRAIL_INT)) == (DOT_CHAR|TRAIL_INT) 4009 /* A float has digits after the dot or an exponent.
4012 || (state & ~INTOVERFLOW) == (LEAD_INT|E_EXP)); 4010 This excludes numbers like "1." which are lexed as integers. */
4011 float_syntax = ((state & TRAIL_INT)
4012 || ((state & LEAD_INT) && (state & E_EXP)));
4013 } 4013 }
4014 4014
4015 if (plen) 4015 if (plen)
diff --git a/src/process.c b/src/process.c
index f3f4f09f740..ce71545c117 100644
--- a/src/process.c
+++ b/src/process.c
@@ -5134,6 +5134,7 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd,
5134 Lisp_Object wait_for_cell, 5134 Lisp_Object wait_for_cell,
5135 struct Lisp_Process *wait_proc, int just_wait_proc) 5135 struct Lisp_Process *wait_proc, int just_wait_proc)
5136{ 5136{
5137 static int last_read_channel = -1;
5137 int channel, nfds; 5138 int channel, nfds;
5138 fd_set Available; 5139 fd_set Available;
5139 fd_set Writeok; 5140 fd_set Writeok;
@@ -5188,6 +5189,8 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd,
5188 while (1) 5189 while (1)
5189 { 5190 {
5190 bool process_skipped = false; 5191 bool process_skipped = false;
5192 bool wrapped;
5193 int channel_start;
5191 5194
5192 /* If calling from keyboard input, do not quit 5195 /* If calling from keyboard input, do not quit
5193 since we want to return C-g as an input character. 5196 since we want to return C-g as an input character.
@@ -5726,8 +5729,21 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd,
5726 d->func (channel, d->data); 5729 d->func (channel, d->data);
5727 } 5730 }
5728 5731
5729 for (channel = 0; channel <= max_desc; channel++) 5732 /* Do round robin if `process-pritoritize-lower-fds' is nil. */
5733 channel_start
5734 = process_prioritize_lower_fds ? 0 : last_read_channel + 1;
5735
5736 for (channel = channel_start, wrapped = false;
5737 !wrapped || (channel < channel_start && channel <= max_desc);
5738 channel++)
5730 { 5739 {
5740 if (channel > max_desc)
5741 {
5742 wrapped = true;
5743 channel = -1;
5744 continue;
5745 }
5746
5731 if (FD_ISSET (channel, &Available) 5747 if (FD_ISSET (channel, &Available)
5732 && ((fd_callback_info[channel].flags & (KEYBOARD_FD | PROCESS_FD)) 5748 && ((fd_callback_info[channel].flags & (KEYBOARD_FD | PROCESS_FD))
5733 == PROCESS_FD)) 5749 == PROCESS_FD))
@@ -5765,6 +5781,7 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd,
5765 don't try to read from any other processes 5781 don't try to read from any other processes
5766 before doing the select again. */ 5782 before doing the select again. */
5767 FD_ZERO (&Available); 5783 FD_ZERO (&Available);
5784 last_read_channel = channel;
5768 5785
5769 if (do_display) 5786 if (do_display)
5770 redisplay_preserve_echo_area (12); 5787 redisplay_preserve_echo_area (12);
@@ -8481,6 +8498,16 @@ non-nil value means that the delay is not reset on write.
8481The variable takes effect when `start-process' is called. */); 8498The variable takes effect when `start-process' is called. */);
8482 Vprocess_adaptive_read_buffering = Qt; 8499 Vprocess_adaptive_read_buffering = Qt;
8483 8500
8501 DEFVAR_BOOL ("process-prioritize-lower-fds", process_prioritize_lower_fds,
8502 doc: /* Whether to start checking for subprocess output from first file descriptor.
8503Emacs loops through file descriptors to check for output from subprocesses.
8504If this variable is nil, the default, then after accepting output from a
8505subprocess, Emacs will continue checking the rest of descriptors, starting
8506from the one following the descriptor it just read. If this variable is
8507non-nil, Emacs will always restart the loop from the first file descriptor,
8508thus favoring processes with lower descriptors. */);
8509 process_prioritize_lower_fds = 0;
8510
8484 DEFVAR_LISP ("interrupt-process-functions", Vinterrupt_process_functions, 8511 DEFVAR_LISP ("interrupt-process-functions", Vinterrupt_process_functions,
8485 doc: /* List of functions to be called for `interrupt-process'. 8512 doc: /* List of functions to be called for `interrupt-process'.
8486The arguments of the functions are the same as for `interrupt-process'. 8513The arguments of the functions are the same as for `interrupt-process'.
diff --git a/src/sysdep.c b/src/sysdep.c
index d940acc4e05..51d8b5eeedc 100644
--- a/src/sysdep.c
+++ b/src/sysdep.c
@@ -3626,7 +3626,7 @@ system_process_attributes (Lisp_Object pid)
3626 ttyname = proc.ki_tdev == NODEV ? NULL : devname (proc.ki_tdev, S_IFCHR); 3626 ttyname = proc.ki_tdev == NODEV ? NULL : devname (proc.ki_tdev, S_IFCHR);
3627 unblock_input (); 3627 unblock_input ();
3628 if (ttyname) 3628 if (ttyname)
3629 attrs = Fcons (Fcons (Qtty, build_string (ttyname)), attrs); 3629 attrs = Fcons (Fcons (Qttname, build_string (ttyname)), attrs);
3630 3630
3631 attrs = Fcons (Fcons (Qtpgid, INT_TO_INTEGER (proc.ki_tpgid)), attrs); 3631 attrs = Fcons (Fcons (Qtpgid, INT_TO_INTEGER (proc.ki_tpgid)), attrs);
3632 attrs = Fcons (Fcons (Qminflt, INT_TO_INTEGER (proc.ki_rusage.ru_minflt)), 3632 attrs = Fcons (Fcons (Qminflt, INT_TO_INTEGER (proc.ki_rusage.ru_minflt)),
@@ -3898,20 +3898,19 @@ system_process_attributes (Lisp_Object pid)
3898Lisp_Object 3898Lisp_Object
3899system_process_attributes (Lisp_Object pid) 3899system_process_attributes (Lisp_Object pid)
3900{ 3900{
3901 int proc_id; 3901 int proc_id, i;
3902 struct passwd *pw; 3902 struct passwd *pw;
3903 struct group *gr; 3903 struct group *gr;
3904 char *ttyname; 3904 char *ttyname;
3905 struct timeval starttime; 3905 struct timeval starttime;
3906 struct timespec t, now; 3906 struct timespec t, now;
3907 struct rusage *rusage;
3908 dev_t tdev; 3907 dev_t tdev;
3909 uid_t uid; 3908 uid_t uid;
3910 gid_t gid; 3909 gid_t gid;
3911 3910
3912 int mib[4] = {CTL_KERN, KERN_PROC, KERN_PROC_PID}; 3911 int mib[4] = {CTL_KERN, KERN_PROC, KERN_PROC_PID};
3913 struct kinfo_proc proc; 3912 struct kinfo_proc proc;
3914 size_t proclen = sizeof proc; 3913 size_t len = sizeof proc;
3915 3914
3916 Lisp_Object attrs = Qnil; 3915 Lisp_Object attrs = Qnil;
3917 Lisp_Object decoded_comm; 3916 Lisp_Object decoded_comm;
@@ -3920,7 +3919,7 @@ system_process_attributes (Lisp_Object pid)
3920 CONS_TO_INTEGER (pid, int, proc_id); 3919 CONS_TO_INTEGER (pid, int, proc_id);
3921 mib[3] = proc_id; 3920 mib[3] = proc_id;
3922 3921
3923 if (sysctl (mib, 4, &proc, &proclen, NULL, 0) != 0 || proclen == 0) 3922 if (sysctl (mib, 4, &proc, &len, NULL, 0) != 0 || len == 0)
3924 return attrs; 3923 return attrs;
3925 3924
3926 uid = proc.kp_eproc.e_ucred.cr_uid; 3925 uid = proc.kp_eproc.e_ucred.cr_uid;
@@ -3957,8 +3956,8 @@ system_process_attributes (Lisp_Object pid)
3957 decoded_comm = (code_convert_string_norecord 3956 decoded_comm = (code_convert_string_norecord
3958 (build_unibyte_string (comm), 3957 (build_unibyte_string (comm),
3959 Vlocale_coding_system, 0)); 3958 Vlocale_coding_system, 0));
3960
3961 attrs = Fcons (Fcons (Qcomm, decoded_comm), attrs); 3959 attrs = Fcons (Fcons (Qcomm, decoded_comm), attrs);
3960
3962 { 3961 {
3963 char state[2] = {'\0', '\0'}; 3962 char state[2] = {'\0', '\0'};
3964 switch (proc.kp_proc.p_stat) 3963 switch (proc.kp_proc.p_stat)
@@ -3994,27 +3993,24 @@ system_process_attributes (Lisp_Object pid)
3994 ttyname = tdev == NODEV ? NULL : devname (tdev, S_IFCHR); 3993 ttyname = tdev == NODEV ? NULL : devname (tdev, S_IFCHR);
3995 unblock_input (); 3994 unblock_input ();
3996 if (ttyname) 3995 if (ttyname)
3997 attrs = Fcons (Fcons (Qtty, build_string (ttyname)), attrs); 3996 attrs = Fcons (Fcons (Qttname, build_string (ttyname)), attrs);
3998 3997
3999 attrs = Fcons (Fcons (Qtpgid, INT_TO_INTEGER (proc.kp_eproc.e_tpgid)), 3998 attrs = Fcons (Fcons (Qtpgid, INT_TO_INTEGER (proc.kp_eproc.e_tpgid)),
4000 attrs); 3999 attrs);
4001 4000
4002 rusage = proc.kp_proc.p_ru; 4001 rusage_info_current ri;
4003 if (rusage) 4002 if (proc_pid_rusage(proc_id, RUSAGE_INFO_CURRENT, (rusage_info_t *) &ri) == 0)
4004 { 4003 {
4005 attrs = Fcons (Fcons (Qminflt, INT_TO_INTEGER (rusage->ru_minflt)), 4004 struct timespec utime = make_timespec (ri.ri_user_time / TIMESPEC_HZ,
4006 attrs); 4005 ri.ri_user_time % TIMESPEC_HZ);
4007 attrs = Fcons (Fcons (Qmajflt, INT_TO_INTEGER (rusage->ru_majflt)), 4006 struct timespec stime = make_timespec (ri.ri_system_time / TIMESPEC_HZ,
4008 attrs); 4007 ri.ri_system_time % TIMESPEC_HZ);
4009 4008 attrs = Fcons (Fcons (Qutime, make_lisp_time (utime)), attrs);
4010 attrs = Fcons (Fcons (Qutime, make_lisp_timeval (rusage->ru_utime)), 4009 attrs = Fcons (Fcons (Qstime, make_lisp_time (stime)), attrs);
4011 attrs); 4010 attrs = Fcons (Fcons (Qtime, make_lisp_time (timespec_add (utime, stime))), attrs);
4012 attrs = Fcons (Fcons (Qstime, make_lisp_timeval (rusage->ru_stime)), 4011
4013 attrs); 4012 attrs = Fcons (Fcons (Qmajflt, INT_TO_INTEGER (ri.ri_pageins)), attrs);
4014 t = timespec_add (timeval_to_timespec (rusage->ru_utime), 4013 }
4015 timeval_to_timespec (rusage->ru_stime));
4016 attrs = Fcons (Fcons (Qtime, make_lisp_time (t)), attrs);
4017 }
4018 4014
4019 starttime = proc.kp_proc.p_starttime; 4015 starttime = proc.kp_proc.p_starttime;
4020 attrs = Fcons (Fcons (Qnice, make_fixnum (proc.kp_proc.p_nice)), attrs); 4016 attrs = Fcons (Fcons (Qnice, make_fixnum (proc.kp_proc.p_nice)), attrs);
@@ -4024,6 +4020,50 @@ system_process_attributes (Lisp_Object pid)
4024 t = timespec_sub (now, timeval_to_timespec (starttime)); 4020 t = timespec_sub (now, timeval_to_timespec (starttime));
4025 attrs = Fcons (Fcons (Qetime, make_lisp_time (t)), attrs); 4021 attrs = Fcons (Fcons (Qetime, make_lisp_time (t)), attrs);
4026 4022
4023 struct proc_taskinfo taskinfo;
4024 if (proc_pidinfo (proc_id, PROC_PIDTASKINFO, 0, &taskinfo, sizeof (taskinfo)) > 0)
4025 {
4026 attrs = Fcons (Fcons (Qvsize, make_fixnum (taskinfo.pti_virtual_size / 1024)), attrs);
4027 attrs = Fcons (Fcons (Qrss, make_fixnum (taskinfo.pti_resident_size / 1024)), attrs);
4028 attrs = Fcons (Fcons (Qthcount, make_fixnum (taskinfo.pti_threadnum)), attrs);
4029 }
4030
4031#ifdef KERN_PROCARGS2
4032 char args[ARG_MAX];
4033 mib[1] = KERN_PROCARGS2;
4034 mib[2] = proc_id;
4035 len = sizeof args;
4036
4037 if (sysctl (mib, 3, &args, &len, NULL, 0) == 0 && len != 0)
4038 {
4039 char *start, *end;
4040
4041 int argc = *(int*)args; /* argc is the first int */
4042 start = args + sizeof (int);
4043
4044 start += strlen (start) + 1; /* skip executable name and any '\0's */
4045 while ((start - args < len) && ! *start) start++;
4046
4047 /* skip argv to find real end */
4048 for (i = 0, end = start; i < argc && (end - args) < len; i++)
4049 {
4050 end += strlen (end) + 1;
4051 }
4052
4053 len = end - start;
4054 for (int i = 0; i < len; i++)
4055 {
4056 if (! start[i] && i < len - 1)
4057 start[i] = ' ';
4058 }
4059
4060 AUTO_STRING (comm, start);
4061 decoded_comm = code_convert_string_norecord (comm,
4062 Vlocale_coding_system, 0);
4063 attrs = Fcons (Fcons (Qargs, decoded_comm), attrs);
4064 }
4065#endif /* KERN_PROCARGS2 */
4066
4027 return attrs; 4067 return attrs;
4028} 4068}
4029 4069
diff --git a/src/w32.c b/src/w32.c
index 26cc28f877c..968b4bbe489 100644
--- a/src/w32.c
+++ b/src/w32.c
@@ -10587,6 +10587,45 @@ w32_my_exename (void)
10587 return exename; 10587 return exename;
10588} 10588}
10589 10589
10590/* Emulate Posix 'realpath'. This is needed in
10591 comp-el-to-eln-rel-filename. */
10592char *
10593realpath (const char *file_name, char *resolved_name)
10594{
10595 char *tgt = chase_symlinks (file_name);
10596 char target[MAX_UTF8_PATH];
10597
10598 if (tgt == file_name)
10599 {
10600 /* If FILE_NAME is not a symlink, chase_symlinks returns its
10601 argument, possibly not in canonical absolute form. Make sure
10602 we return a canonical file name. */
10603 if (w32_unicode_filenames)
10604 {
10605 wchar_t file_w[MAX_PATH], tgt_w[MAX_PATH];
10606
10607 filename_to_utf16 (file_name, file_w);
10608 if (GetFullPathNameW (file_w, MAX_PATH, tgt_w, NULL) == 0)
10609 return NULL;
10610 filename_from_utf16 (tgt_w, target);
10611 }
10612 else
10613 {
10614 char file_a[MAX_PATH], tgt_a[MAX_PATH];
10615
10616 filename_to_ansi (file_name, file_a);
10617 if (GetFullPathNameA (file_a, MAX_PATH, tgt_a, NULL) == 0)
10618 return NULL;
10619 filename_from_ansi (tgt_a, target);
10620 }
10621 tgt = target;
10622 }
10623
10624 if (resolved_name)
10625 return strcpy (resolved_name, tgt);
10626 return xstrdup (tgt);
10627}
10628
10590/* 10629/*
10591 globals_of_w32 is used to initialize those global variables that 10630 globals_of_w32 is used to initialize those global variables that
10592 must always be initialized on startup even when the global variable 10631 must always be initialized on startup even when the global variable
diff --git a/src/w32.h b/src/w32.h
index a382dbe791a..ffa145b1484 100644
--- a/src/w32.h
+++ b/src/w32.h
@@ -187,6 +187,7 @@ extern DWORD multiByteToWideCharFlags;
187 187
188extern char *w32_my_exename (void); 188extern char *w32_my_exename (void);
189extern const char *w32_relocate (const char *); 189extern const char *w32_relocate (const char *);
190extern char *realpath (const char *, char *);
190 191
191extern void init_environment (char **); 192extern void init_environment (char **);
192extern void check_windows_init_file (void); 193extern void check_windows_init_file (void);