commit 1ed769a3cb753a86badba8a2878fa788a6fdc1f8 (HEAD, refs/remotes/origin/master) Author: Paul Eggert Date: Sun Jan 26 23:04:21 2025 -0800 Pacify -Wanalyzer-use-of-uninitialized-value With ‘configure --enable-gcc-warnings’, gcc (GCC) 14.2.1 20250110 (Red Hat 14.2.1-7) on x86-64 complained, as it apparently did not want to assume that enum variables have one of the listed values. Work around the problem by using tables rather than switch statements. This gives up a little static checking but I don’t see any other easy way to pacify GCC without disabling the warnings entirely. * src/pdumper.c (dump_fwd_int, dump_fwd_bool, dump_fwd_obj) (dump_fwd_buffer_obj, dump_fwd_kboard_obj): Last arg is now void const * so that these functions’ addresses can all be put into the same array. (dump_fwd, dump_anonymous_allocate_posix, dump_map_file_posix): Use an array rather than a switch. (mem_prot_posix_table): New static constant table. diff --git a/src/pdumper.c b/src/pdumper.c index 45a44db0243..9f0447eb5aa 100644 --- a/src/pdumper.c +++ b/src/pdumper.c @@ -2292,11 +2292,12 @@ dump_float (struct dump_context *ctx, const struct Lisp_Float *lfloat) } static dump_off -dump_fwd_int (struct dump_context *ctx, const struct Lisp_Intfwd *intfwd) +dump_fwd_int (struct dump_context *ctx, void const *fwdptr) { #if CHECK_STRUCTS && !defined HASH_Lisp_Intfwd_4D887A7387 # error "Lisp_Intfwd changed. See CHECK_STRUCTS comment in config.h." #endif + struct Lisp_Intfwd const *intfwd = fwdptr; dump_emacs_reloc_immediate_intmax_t (ctx, intfwd->intvar, *intfwd->intvar); struct Lisp_Intfwd out; dump_object_start (ctx, &out, sizeof (out)); @@ -2306,11 +2307,12 @@ dump_fwd_int (struct dump_context *ctx, const struct Lisp_Intfwd *intfwd) } static dump_off -dump_fwd_bool (struct dump_context *ctx, const struct Lisp_Boolfwd *boolfwd) +dump_fwd_bool (struct dump_context *ctx, void const *fwdptr) { #if CHECK_STRUCTS && !defined (HASH_Lisp_Boolfwd_0EA1C7ADCC) # error "Lisp_Boolfwd changed. See CHECK_STRUCTS comment in config.h." #endif + struct Lisp_Boolfwd const *boolfwd = fwdptr; dump_emacs_reloc_immediate_bool (ctx, boolfwd->boolvar, *boolfwd->boolvar); struct Lisp_Boolfwd out; dump_object_start (ctx, &out, sizeof (out)); @@ -2320,11 +2322,12 @@ dump_fwd_bool (struct dump_context *ctx, const struct Lisp_Boolfwd *boolfwd) } static dump_off -dump_fwd_obj (struct dump_context *ctx, const struct Lisp_Objfwd *objfwd) +dump_fwd_obj (struct dump_context *ctx, void const *fwdptr) { #if CHECK_STRUCTS && !defined (HASH_Lisp_Objfwd_45D3E513DC) # error "Lisp_Objfwd changed. See CHECK_STRUCTS comment in config.h." #endif + struct Lisp_Objfwd const *objfwd = fwdptr; if (NILP (Fgethash (dump_off_to_lisp (emacs_offset (objfwd->objvar)), ctx->staticpro_table, Qnil))) @@ -2337,12 +2340,12 @@ dump_fwd_obj (struct dump_context *ctx, const struct Lisp_Objfwd *objfwd) } static dump_off -dump_fwd_buffer_obj (struct dump_context *ctx, - const struct Lisp_Buffer_Objfwd *buffer_objfwd) +dump_fwd_buffer_obj (struct dump_context *ctx, void const *fwdptr) { #if CHECK_STRUCTS && !defined (HASH_Lisp_Buffer_Objfwd_611EBD13FF) # error "Lisp_Buffer_Objfwd changed. See CHECK_STRUCTS comment in config.h." #endif + struct Lisp_Buffer_Objfwd const *buffer_objfwd = fwdptr; struct Lisp_Buffer_Objfwd out; dump_object_start (ctx, &out, sizeof (out)); DUMP_FIELD_COPY (&out, buffer_objfwd, type); @@ -2353,12 +2356,12 @@ dump_fwd_buffer_obj (struct dump_context *ctx, } static dump_off -dump_fwd_kboard_obj (struct dump_context *ctx, - const struct Lisp_Kboard_Objfwd *kboard_objfwd) +dump_fwd_kboard_obj (struct dump_context *ctx, void const *fwdptr) { #if CHECK_STRUCTS && !defined (HASH_Lisp_Kboard_Objfwd_CAA7E71069) # error "Lisp_Intfwd changed. See CHECK_STRUCTS comment in config.h." #endif + struct Lisp_Kboard_Objfwd const *kboard_objfwd = fwdptr; struct Lisp_Kboard_Objfwd out; dump_object_start (ctx, &out, sizeof (out)); DUMP_FIELD_COPY (&out, kboard_objfwd, type); @@ -2372,29 +2375,16 @@ dump_fwd (struct dump_context *ctx, lispfwd fwd) #if CHECK_STRUCTS && !defined (HASH_Lisp_Fwd_Type_9CBA6EE55E) # error "Lisp_Fwd_Type changed. See CHECK_STRUCTS comment in config.h." #endif - void const *p = fwd.fwdptr; - dump_off offset; - - switch (XFWDTYPE (fwd)) - { - case Lisp_Fwd_Int: - offset = dump_fwd_int (ctx, p); - break; - case Lisp_Fwd_Bool: - offset = dump_fwd_bool (ctx, p); - break; - case Lisp_Fwd_Obj: - offset = dump_fwd_obj (ctx, p); - break; - case Lisp_Fwd_Buffer_Obj: - offset = dump_fwd_buffer_obj (ctx, p); - break; - case Lisp_Fwd_Kboard_Obj: - offset = dump_fwd_kboard_obj (ctx, p); - break; - } + typedef dump_off (*dump_fwd_fnptr) (struct dump_context *, void const *); + static dump_fwd_fnptr const dump_fwd_table[] = { + [Lisp_Fwd_Int] = dump_fwd_int, + [Lisp_Fwd_Bool] = dump_fwd_bool, + [Lisp_Fwd_Obj] = dump_fwd_obj, + [Lisp_Fwd_Buffer_Obj] = dump_fwd_buffer_obj, + [Lisp_Fwd_Kboard_Obj] = dump_fwd_kboard_obj, + }; - return offset; + return dump_fwd_table[XFWDTYPE (fwd)] (ctx, fwd.fwdptr); } static dump_off @@ -4544,26 +4534,19 @@ dump_anonymous_allocate_w32 (void *base, # define MAP_ANONYMOUS MAP_ANON # endif +static int const mem_prot_posix_table[] = { + [DUMP_MEMORY_ACCESS_NONE] = PROT_NONE, + [DUMP_MEMORY_ACCESS_READ] = PROT_READ, + [DUMP_MEMORY_ACCESS_READWRITE] = PROT_READ | PROT_WRITE, +}; + static void * dump_anonymous_allocate_posix (void *base, size_t size, enum dump_memory_protection protection) { void *ret; - int mem_prot; - - switch (protection) - { - case DUMP_MEMORY_ACCESS_NONE: - mem_prot = PROT_NONE; - break; - case DUMP_MEMORY_ACCESS_READ: - mem_prot = PROT_READ; - break; - case DUMP_MEMORY_ACCESS_READWRITE: - mem_prot = PROT_READ | PROT_WRITE; - break; - } + int mem_prot = mem_prot_posix_table[protection]; int mem_flags = MAP_PRIVATE | MAP_ANONYMOUS; if (mem_prot != PROT_NONE) @@ -4707,25 +4690,9 @@ dump_map_file_posix (void *base, int fd, off_t offset, size_t size, enum dump_memory_protection protection) { void *ret; - int mem_prot; - int mem_flags; - - switch (protection) - { - case DUMP_MEMORY_ACCESS_NONE: - mem_prot = PROT_NONE; - mem_flags = MAP_SHARED; - break; - case DUMP_MEMORY_ACCESS_READ: - mem_prot = PROT_READ; - mem_flags = MAP_SHARED; - break; - case DUMP_MEMORY_ACCESS_READWRITE: - mem_prot = PROT_READ | PROT_WRITE; - mem_flags = MAP_PRIVATE; - break; - } - + int mem_prot = mem_prot_posix_table[protection]; + int mem_flags = (protection == DUMP_MEMORY_ACCESS_READWRITE + ? MAP_PRIVATE : MAP_SHARED); if (base) mem_flags |= MAP_FIXED; commit a5c47258ffe6d037e3e3c3665ca82a18661cc82c Author: Paul Eggert Date: Sun Jan 26 22:15:50 2025 -0800 Fix unlikely eassert failure in invalid_radix_integer * src/lread.c (invalid_radix_integer): Simplify by using sprintf with a big-enough buffer. diff --git a/src/lread.c b/src/lread.c index e5d1ba0e6bb..de1b0ae2d06 100644 --- a/src/lread.c +++ b/src/lread.c @@ -3109,9 +3109,9 @@ digit_to_number (int character, int base) static void invalid_radix_integer (EMACS_INT radix, Lisp_Object readcharfun) { - char buf[64]; - int n = snprintf (buf, sizeof buf, "integer, radix %"pI"d", radix); - eassert (n < sizeof buf); + static char const format[] = "integer, radix %"pI"d"; + char buf[sizeof format - sizeof "%"pI"d" + INT_BUFSIZE_BOUND (radix)]; + sprintf (buf, format, radix); invalid_syntax (buf, readcharfun); } commit f809302fe5543e20ff7f06a81c263fd29f3ff995 Author: Paul Eggert Date: Sun Jan 26 22:15:50 2025 -0800 Fix unlikely eassert failure in xg_set_widget_bg * src/gtkutil.c (xg_set_widget_bg): Simplify by using sprintf with a big-enough buffer. diff --git a/src/gtkutil.c b/src/gtkutil.c index a1a2c6cbd20..0770874eb40 100644 --- a/src/gtkutil.c +++ b/src/gtkutil.c @@ -1424,13 +1424,9 @@ xg_set_widget_bg (struct frame *f, GtkWidget *w, unsigned long pixel) xbg.blue |= xbg.blue << 8; #endif { - const char format[] = "* { background-color: #%02x%02x%02x; }"; - /* The format is always longer than the resulting string. */ - char buffer[sizeof format]; - int n = snprintf(buffer, sizeof buffer, format, - xbg.red >> 8, xbg.green >> 8, xbg.blue >> 8); - eassert (n > 0); - eassert (n < sizeof buffer); + static char const format[] = "* { background-color: #%02x%02x%02x; }"; + char buffer[sizeof format + 3 * INT_STRLEN_BOUND (xbg.red)]; + sprintf (buffer, format, xbg.red >> 8, xbg.green >> 8, xbg.blue >> 8); GtkCssProvider *provider = gtk_css_provider_new (); gtk_css_provider_load_from_data (provider, buffer, -1, NULL); gtk_style_context_add_provider (gtk_widget_get_style_context(w), commit 901659bb7046bef4ca10490cf47644fb2bc6d753 Author: Paul Eggert Date: Sun Jan 26 22:15:50 2025 -0800 Fix unlikely eassert failure in pgtk_enumerate_devices * src/pgtkterm.c (pgtk_enumerate_devices): Prefer make_formatted_string to snprintf + build_string + eassert, as it’s simpler and won’t crash Emacs if the eassert fails. diff --git a/src/pgtkterm.c b/src/pgtkterm.c index 1f468300deb..dd85d622a62 100644 --- a/src/pgtkterm.c +++ b/src/pgtkterm.c @@ -158,8 +158,6 @@ pgtk_enumerate_devices (struct pgtk_display_info *dpyinfo, struct pgtk_device_t *rec; GList *all_seats, *devices_on_seat, *tem, *t1; GdkSeat *seat; - char printbuf[1026]; /* Believe it or not, some device names are - actually almost this long. */ block_input (); all_seats = gdk_display_list_seats (dpyinfo->gdpy); @@ -187,13 +185,10 @@ pgtk_enumerate_devices (struct pgtk_display_info *dpyinfo, rec = xmalloc (sizeof *rec); rec->seat = g_object_ref (seat); rec->device = GDK_DEVICE (t1->data); - - int len = snprintf (printbuf, sizeof printbuf, "%u:%s", - gdk_device_get_source (rec->device), - gdk_device_get_name (rec->device)); - eassert (len < sizeof printbuf); - - rec->name = build_string (printbuf); + rec->name = (make_formatted_string + ("%u:%s", + gdk_device_get_source (rec->device), + gdk_device_get_name (rec->device))); rec->next = dpyinfo->devices; dpyinfo->devices = rec; } commit f8b8dddce90f5cbf6ca0be2e72b4e11cdcf581fe Author: Paul Eggert Date: Sun Jan 26 22:15:50 2025 -0800 Minor format_string tuneup * src/comp.c (format_string): Prefer strcpy to doing things by hand in a place where strcpy is easier to read, generates more-efficient code, and similar parts of Emacs do strcpy. diff --git a/src/comp.c b/src/comp.c index 2603a2f4334..ce59fdd80e3 100644 --- a/src/comp.c +++ b/src/comp.c @@ -720,11 +720,7 @@ format_string (const char *format, ...) va_start (va, format); int res = vsnprintf (scratch_area, sizeof (scratch_area), format, va); if (res >= sizeof (scratch_area)) - { - scratch_area[sizeof (scratch_area) - 4] = '.'; - scratch_area[sizeof (scratch_area) - 3] = '.'; - scratch_area[sizeof (scratch_area) - 2] = '.'; - } + strcpy (scratch_area + sizeof scratch_area - 4, "..."); va_end (va); return scratch_area; } commit 8d8272d02e38ee3624cd3f16767f3c60fb3383ea Author: Paul Eggert Date: Sun Jan 26 22:15:49 2025 -0800 Ignore -fanalyzer-null-argument in pgtkterm.c * src/pgtkterm.c: Ignore -Wanalyzer-null-dereference. I don’t have time to look into all the diagnostics, but the ones I checked seemed to be false alarms with gcc -std=gnu23 on x86-64, and we are ignoring this diagnostic in other modules. This is GCC 14.2.1 20250110 (Red Hat 14.2.1-7). diff --git a/src/pgtkterm.c b/src/pgtkterm.c index 1d679f0cf57..1f468300deb 100644 --- a/src/pgtkterm.c +++ b/src/pgtkterm.c @@ -22,6 +22,11 @@ along with GNU Emacs. If not, see . */ interpretation of even the system includes. */ #include +/* Work around GCC bug 102671. */ +#if 10 <= __GNUC__ +# pragma GCC diagnostic ignored "-Wanalyzer-null-dereference" +#endif + #include #include #include commit 728c7904fef23059524eeab3193e1634a98d1d35 Author: Paul Eggert Date: Sun Jan 26 22:15:49 2025 -0800 Pacify -fanalyzer-null-argument on pgtk_term_init * src/pgtkterm.c (pgtk_term_init): Use xstrdup, not g_strdup. The value is never freed so the allocator shouldn’t matter. diff --git a/src/pgtkterm.c b/src/pgtkterm.c index 0f272bbeac8..1d679f0cf57 100644 --- a/src/pgtkterm.c +++ b/src/pgtkterm.c @@ -7080,7 +7080,7 @@ pgtk_term_init (Lisp_Object display_name, char *resource_name) dpy = DEFAULT_GDK_DISPLAY (); - initial_display = g_strdup (gdk_display_get_name (dpy)); + initial_display = xstrdup (gdk_display_get_name (dpy)); dpy_name = initial_display; lisp_dpy_name = build_string (dpy_name); } commit 2e8ef0910412aef8f9f1beba7c942473ad8602bb Author: Paul Eggert Date: Sun Jan 26 22:15:49 2025 -0800 Protect against GCing of last_mouse_window * src/window.c (last_mouse_window): New global var. All static instances removed, and all their uses replaced with this global var. This fixes a very unlikely bug where last_mouse_window was GC’ed and a new window created in its place. It also fixes several places that assumed NIL_IS_ZERO without static_asserting it. (init_window_once): Initialize the new var. diff --git a/src/androidterm.c b/src/androidterm.c index 688f254ee23..e0f66652300 100644 --- a/src/androidterm.c +++ b/src/androidterm.c @@ -1179,7 +1179,6 @@ handle_one_android_event (struct android_display_info *dpyinfo, && (f == XFRAME (selected_frame) || !NILP (focus_follows_mouse))) { - static Lisp_Object last_mouse_window; Lisp_Object window = window_from_coordinates (f, event->xmotion.x, event->xmotion.y, 0, diff --git a/src/haikuterm.c b/src/haikuterm.c index 7f02de2ca15..4a217c9e0e2 100644 --- a/src/haikuterm.c +++ b/src/haikuterm.c @@ -3562,7 +3562,6 @@ haiku_read_socket (struct terminal *terminal, struct input_event *hold_quit) if (!NILP (Vmouse_autoselect_window)) { - static Lisp_Object last_mouse_window; Lisp_Object window = window_from_coordinates (f, b->x, b->y, 0, 0, 0, 0); if (WINDOWP (window) diff --git a/src/msdos.c b/src/msdos.c index 95eb6453040..49403ba72f4 100644 --- a/src/msdos.c +++ b/src/msdos.c @@ -2677,8 +2677,6 @@ dos_rawgetc (void) /* Generate SELECT_WINDOW_EVENTs when needed. */ if (!NILP (Vmouse_autoselect_window)) { - static Lisp_Object last_mouse_window; - mouse_window = window_from_coordinates (SELECTED_FRAME (), mouse_last_x, mouse_last_y, 0, 0, 0, 0); /* A window will be selected only when it is not diff --git a/src/pgtkterm.c b/src/pgtkterm.c index 2da1006b6f7..0f272bbeac8 100644 --- a/src/pgtkterm.c +++ b/src/pgtkterm.c @@ -5938,7 +5938,6 @@ motion_notify_event (GtkWidget *widget, GdkEvent *event, also when the target window is on another frame. */ && (f == XFRAME (selected_frame) || !NILP (focus_follows_mouse))) { - static Lisp_Object last_mouse_window; Lisp_Object window = window_from_coordinates (f, event->motion.x, event->motion.y, 0, false, false, false); diff --git a/src/w32inevt.c b/src/w32inevt.c index 1c80f7c6db7..b0e6b5a9286 100644 --- a/src/w32inevt.c +++ b/src/w32inevt.c @@ -467,7 +467,6 @@ do_mouse_event (MOUSE_EVENT_RECORD *event, struct input_event *emacs_ev) { static DWORD button_state = 0; - static Lisp_Object last_mouse_window; DWORD but_change, mask, flags = event->dwEventFlags; int i; diff --git a/src/w32term.c b/src/w32term.c index cb7bc7e4540..5613ade01ce 100644 --- a/src/w32term.c +++ b/src/w32term.c @@ -5444,7 +5444,6 @@ w32_read_socket (struct terminal *terminal, || (!NILP (focus_follows_mouse) && !FRAME_NO_ACCEPT_FOCUS (f)))) { - static Lisp_Object last_mouse_window; Lisp_Object window = window_from_coordinates (f, LOWORD (msg.msg.lParam), HIWORD (msg.msg.lParam), 0, 0, 0, 0); diff --git a/src/window.c b/src/window.c index 0ed1b53d866..330a95a716f 100644 --- a/src/window.c +++ b/src/window.c @@ -106,6 +106,9 @@ Lisp_Object minibuf_window; shown as the selected window when the minibuffer is selected. */ Lisp_Object minibuf_selected_window; +/* Non-nil means it is the window containing the last mouse movement. */ +Lisp_Object last_mouse_window; + /* Incremented for each window created. */ static EMACS_INT sequence_number; @@ -8778,6 +8781,8 @@ init_window_once (void) minibuf_selected_window = Qnil; staticpro (&minibuf_selected_window); + last_mouse_window = Qnil; + staticpro (&last_mouse_window); old_selected_window = Qnil; staticpro (&old_selected_window); @@ -8796,6 +8801,7 @@ static void init_window_once_for_pdumper (void) PDUMPER_RESET_LV (selected_window, Qnil); PDUMPER_RESET_LV (Vwindow_list, Qnil); PDUMPER_RESET_LV (minibuf_selected_window, Qnil); + PDUMPER_RESET_LV (last_mouse_window, Qnil); /* Hack: if mode_line_in_non_selected_windows is true (which it may be, if we're restoring from a dump) the guts of diff --git a/src/window.h b/src/window.h index a48c370b198..2266fc7814c 100644 --- a/src/window.h +++ b/src/window.h @@ -1116,6 +1116,10 @@ extern Lisp_Object minibuf_window; extern Lisp_Object minibuf_selected_window; +/* Non-nil means it is the window containing the last mouse movement. */ + +extern Lisp_Object last_mouse_window; + extern Lisp_Object make_window (void); extern Lisp_Object window_from_coordinates (struct frame *, int, int, enum window_part *, bool, bool, bool); diff --git a/src/xterm.c b/src/xterm.c index fd61d5df91c..e024b36daf5 100644 --- a/src/xterm.c +++ b/src/xterm.c @@ -21291,8 +21291,6 @@ handle_one_xevent (struct x_display_info *dpyinfo, && (f == XFRAME (selected_frame) || !NILP (focus_follows_mouse))) { - static Lisp_Object last_mouse_window; - if (xmotion.window != FRAME_X_WINDOW (f)) { x_translate_coordinates (f, xmotion.x_root, xmotion.y_root, @@ -23231,7 +23229,6 @@ handle_one_xevent (struct x_display_info *dpyinfo, && (f == XFRAME (selected_frame) || !NILP (focus_follows_mouse))) { - static Lisp_Object last_mouse_window; Lisp_Object window = window_from_coordinates (f, ev.x, ev.y, 0, false, false, false); commit ff65cc9944dc0b37986d512ee8b9817c6913db36 Author: Paul Eggert Date: Sun Jan 26 22:15:49 2025 -0800 Pacify GCC in pgtkselect malloc alignment * src/pgtkselect.c (pgtk_size_for_format): Remove. (pgtk_get_window_property): Third arg is now void **, not unsigned char **. Omit last arg. All callers changed. Simplify allocation to pacify GCC 14.2.1 complaint about malloc size mismatching size of array: there’s no need for an extra byte when converting from ldata to idata. (selection_data_to_lisp_data): Third arg is now void const *, not unsigned char const *. All callers changed. Omit unnecessary casts. Make some locals more local. diff --git a/src/pgtkselect.c b/src/pgtkselect.c index c05594d7366..7e6c457d15b 100644 --- a/src/pgtkselect.c +++ b/src/pgtkselect.c @@ -50,7 +50,7 @@ static Lisp_Object pgtk_get_window_property_as_lisp_data (struct pgtk_display_in GdkWindow *, GdkAtom, Lisp_Object, GdkAtom, bool); static Lisp_Object selection_data_to_lisp_data (struct pgtk_display_info *, - const unsigned char *, + void const *, ptrdiff_t, GdkAtom, int); static void lisp_data_to_selection_data (struct pgtk_display_info *, Lisp_Object, struct selection_data *); @@ -148,7 +148,7 @@ pgtk_own_selection (Lisp_Object selection_name, Lisp_Object selection_value, guint32 timestamp = gtk_get_current_event_time (); GdkAtom selection_atom = symbol_to_gdk_atom (selection_name); Lisp_Object targets; - ptrdiff_t i, ntargets; + ptrdiff_t ntargets; GtkTargetEntry *gtargets; if (timestamp == GDK_CURRENT_TIME) @@ -207,7 +207,7 @@ pgtk_own_selection (Lisp_Object selection_name, Lisp_Object selection_value, gtargets = xzalloc (sizeof *gtargets * ASIZE (targets)); ntargets = 0; - for (i = 0; i < ASIZE (targets); ++i) + for (ptrdiff_t i = 0; i < ASIZE (targets); i++) { if (SYMBOLP (AREF (targets, i))) gtargets[ntargets++].target @@ -1072,38 +1072,17 @@ pgtk_get_foreign_selection (Lisp_Object selection_symbol, Lisp_Object target_typ /* Subroutines of pgtk_get_window_property_as_lisp_data */ -static ptrdiff_t -pgtk_size_for_format (gint format) -{ - switch (format) - { - case 8: - return sizeof (unsigned char); - case 16: - return sizeof (unsigned short); - case 32: - return sizeof (unsigned long); - - default: - emacs_abort (); - } -} - /* Use xfree, not g_free, to free the data obtained with this function. */ static void -pgtk_get_window_property (GdkWindow *window, unsigned char **data_ret, +pgtk_get_window_property (GdkWindow *window, void **data_ret, ptrdiff_t *bytes_ret, GdkAtom *actual_type_ret, - int *actual_format_ret, unsigned long *actual_size_ret) + int *actual_format_ret) { gint length, actual_format; unsigned char *data; - ptrdiff_t element_size; void *xdata; GdkAtom actual_type; - unsigned long i; - unsigned int *idata; - unsigned long *ldata; data = NULL; @@ -1117,63 +1096,39 @@ pgtk_get_window_property (GdkWindow *window, unsigned char **data_ret, *actual_type_ret = GDK_NONE; *bytes_ret = 0; *actual_format_ret = 8; - *actual_size_ret = 0; return; } - if (actual_type == GDK_SELECTION_TYPE_ATOM - || actual_type == gdk_atom_intern_static_string ("ATOM_PAIR")) - { - /* GDK should not allow anything else. */ - eassert (actual_format == 32); - - length = length / sizeof (GdkAtom); - xdata = xmalloc (sizeof (GdkAtom) * length + 1); - memcpy (xdata, data, 1 + length * sizeof (GdkAtom)); - - g_free (data); + if (! (actual_type == GDK_SELECTION_TYPE_ATOM + || actual_type == gdk_atom_intern_static_string ("ATOM_PAIR"))) + actual_type = GDK_NONE; - *data_ret = xdata; - *actual_type_ret = actual_type; - *bytes_ret = length * sizeof (GdkAtom); - *actual_format_ret = 32; - *actual_size_ret = length; - - return; - } - - element_size = pgtk_size_for_format (actual_format); - length = length / element_size; - - /* Add an extra byte on the end. GDK guarantees that it is - NULL. */ - xdata = xmalloc (1 + element_size * length); - memcpy (xdata, data, 1 + element_size * length); - - if (actual_format == 32 && LONG_WIDTH > 32) + if (ULONG_WIDTH > 32 && actual_format == 32) { - ldata = (typeof (ldata)) data; - idata = xdata; - - for (i = 0; i < length; ++i) + unsigned long int *ldata = (unsigned long int *) data; + gint n = length / sizeof *ldata; + unsigned int *idata; + length = n * sizeof *idata; + idata = xdata = xmalloc (length); + for (gint i = 0; i < n; i++) idata[i] = ldata[i]; - - /* There is always enough space in idata. */ - idata[length] = 0; - *bytes_ret = sizeof *idata * length; } else - /* I think GDK itself prevents element_size from exceeding the - length at which this computation fails. */ - *bytes_ret = element_size * length; + { + /* Add an extra byte on the end. GDK guarantees that it is + NULL. */ + xdata = xmalloc (length + 1); + memcpy (xdata, data, length + 1); + } + + *bytes_ret = length; /* Now free the original `data' allocated by GDK. */ g_free (data); *data_ret = xdata; *actual_type_ret = GDK_NONE; - *actual_size_ret = length; *actual_format_ret = actual_format; *actual_type_ret = actual_type; } @@ -1186,15 +1141,13 @@ pgtk_get_window_property_as_lisp_data (struct pgtk_display_info *dpyinfo, { GdkAtom actual_type; int actual_format; - unsigned long actual_size; - unsigned char *data = 0; + void *data; ptrdiff_t bytes = 0; Lisp_Object val; GdkDisplay *display = dpyinfo->display; pgtk_get_window_property (window, &data, &bytes, - &actual_type, &actual_format, - &actual_size); + &actual_type, &actual_format); if (!data) { @@ -1261,7 +1214,7 @@ pgtk_get_window_property_as_lisp_data (struct pgtk_display_info *dpyinfo, static Lisp_Object selection_data_to_lisp_data (struct pgtk_display_info *dpyinfo, - const unsigned char *data, + void const *data, ptrdiff_t size, GdkAtom type, int format) { if (type == gdk_atom_intern_static_string ("NULL")) @@ -1271,7 +1224,7 @@ selection_data_to_lisp_data (struct pgtk_display_info *dpyinfo, { Lisp_Object str, lispy_type; - str = make_unibyte_string ((char *) data, size); + str = make_unibyte_string (data, size); /* Indicate that this string is from foreign selection by a text property `foreign-selection' so that the caller of x-get-selection-internal (usually x-get-selection) can know @@ -1294,8 +1247,7 @@ selection_data_to_lisp_data (struct pgtk_display_info *dpyinfo, /* Treat ATOM_PAIR type similar to list of atoms. */ || type == gdk_atom_intern_static_string ("ATOM_PAIR"))) { - ptrdiff_t i; - GdkAtom *idata = (GdkAtom *) data; + GdkAtom const *idata = data; if (size == sizeof (GdkAtom)) return gdk_atom_to_symbol (idata[0]); @@ -1303,7 +1255,7 @@ selection_data_to_lisp_data (struct pgtk_display_info *dpyinfo, { Lisp_Object v = make_nil_vector (size / sizeof (GdkAtom)); - for (i = 0; i < size / sizeof (GdkAtom); i++) + for (ptrdiff_t i = 0; i < size / sizeof (GdkAtom); i++) ASET (v, i, gdk_atom_to_symbol (idata[i])); return v; } @@ -1335,12 +1287,11 @@ selection_data_to_lisp_data (struct pgtk_display_info *dpyinfo, */ else if (format == 16) { - ptrdiff_t i; Lisp_Object v = make_uninit_vector (size / 2); if (type == GDK_SELECTION_TYPE_INTEGER) { - for (i = 0; i < size / 2; i++) + for (ptrdiff_t i = 0; i < size / 2; i++) { short j = ((short *) data) [i]; ASET (v, i, make_fixnum (j)); @@ -1348,7 +1299,7 @@ selection_data_to_lisp_data (struct pgtk_display_info *dpyinfo, } else { - for (i = 0; i < size / 2; i++) + for (ptrdiff_t i = 0; i < size / 2; i++) { unsigned short j = ((unsigned short *) data) [i]; ASET (v, i, make_fixnum (j)); @@ -1358,12 +1309,11 @@ selection_data_to_lisp_data (struct pgtk_display_info *dpyinfo, } else { - ptrdiff_t i; Lisp_Object v = make_nil_vector (size / sizeof (gint)); if (type == GDK_SELECTION_TYPE_INTEGER) { - for (i = 0; i < size / sizeof (gint); i++) + for (ptrdiff_t i = 0; i < size / sizeof (gint); i++) { int j = ((gint *) data) [i]; ASET (v, i, INT_TO_INTEGER (j)); @@ -1371,7 +1321,7 @@ selection_data_to_lisp_data (struct pgtk_display_info *dpyinfo, } else { - for (i = 0; i < size / sizeof (gint); i++) + for (ptrdiff_t i = 0; i < size / sizeof (gint); i++) { unsigned int j = ((unsigned int *) data) [i]; ASET (v, i, INT_TO_INTEGER (j)); @@ -1478,7 +1428,6 @@ lisp_data_to_selection_data (struct pgtk_display_info *dpyinfo, a set of 16 or 32 bit INTEGERs; or a set of ATOM_PAIRs (represented as [[A1 A2] [A3 A4] ...] */ - ptrdiff_t i; ptrdiff_t size = ASIZE (obj); if (SYMBOLP (AREF (obj, 0))) @@ -1487,7 +1436,7 @@ lisp_data_to_selection_data (struct pgtk_display_info *dpyinfo, void *data; GdkAtom *x_atoms; if (NILP (type)) type = QATOM; - for (i = 0; i < size; i++) + for (ptrdiff_t i = 0; i < size; i++) if (!SYMBOLP (AREF (obj, i))) signal_error ("All elements of selection vector must have same type", obj); @@ -1495,7 +1444,7 @@ lisp_data_to_selection_data (struct pgtk_display_info *dpyinfo, x_atoms = data; cs->format = 32; cs->size = size; - for (i = 0; i < size; i++) + for (ptrdiff_t i = 0; i < size; i++) x_atoms[i] = symbol_to_gdk_atom (AREF (obj, i)); } else @@ -1507,7 +1456,7 @@ lisp_data_to_selection_data (struct pgtk_display_info *dpyinfo, unsigned long *x_atoms; short *shorts; if (NILP (type)) type = QINTEGER; - for (i = 0; i < size; i++) + for (ptrdiff_t i = 0; i < size; i++) { if (! RANGED_FIXNUMP (SHRT_MIN, AREF (obj, i), SHRT_MAX)) { @@ -1524,7 +1473,7 @@ lisp_data_to_selection_data (struct pgtk_display_info *dpyinfo, shorts = data; cs->format = format; cs->size = size; - for (i = 0; i < size; i++) + for (ptrdiff_t i = 0; i < size; i++) { if (format == 32) x_atoms[i] = cons_to_gdk_long (AREF (obj, i)); @@ -1560,13 +1509,11 @@ clean_local_selection_data (Lisp_Object obj) } if (VECTORP (obj)) { - ptrdiff_t i; ptrdiff_t size = ASIZE (obj); - Lisp_Object copy; if (size == 1) return clean_local_selection_data (AREF (obj, 0)); - copy = make_nil_vector (size); - for (i = 0; i < size; i++) + Lisp_Object copy = make_nil_vector (size); + for (ptrdiff_t i = 0; i < size; i++) ASET (copy, i, clean_local_selection_data (AREF (obj, i))); return copy; } commit c0d83876f18cb21abae299d3b4a2a2bd7f117252 Author: Paul Eggert Date: Sun Jan 26 22:15:49 2025 -0800 Avoid undefined behavior with botched pgtk menu * src/pgtkmenu.c (pgtk_menu_show): Do not dereference save_wv if null. Problem found by gcc 20250110 (Red Hat 14.2.1-7) -Wanalyzer-null-dereference. diff --git a/src/pgtkmenu.c b/src/pgtkmenu.c index 54e1c3739cf..e7a862b0c18 100644 --- a/src/pgtkmenu.c +++ b/src/pgtkmenu.c @@ -725,7 +725,7 @@ pgtk_menu_show (struct frame *f, int x, int y, int menuflags, STRINGP (help) ? help : Qnil); if (prev_wv) prev_wv->next = wv; - else + else if (save_wv) save_wv->contents = wv; if (!NILP (descrip)) wv->key = SSDATA (descrip); commit 06fd3f4e98d683b6595899861e47e931724e7020 Author: Paul Eggert Date: Sun Jan 26 22:15:49 2025 -0800 Use gtk_disable_setlocale * src/pgtkterm.c (pgtk_term_init): * src/xterm.c (x_term_init): Use gtk_disable_setlocale rather than fixup_locale. diff --git a/src/pgtkterm.c b/src/pgtkterm.c index 41bec344799..2da1006b6f7 100644 --- a/src/pgtkterm.c +++ b/src/pgtkterm.c @@ -7070,13 +7070,10 @@ pgtk_term_init (Lisp_Object display_name, char *resource_name) id = g_log_set_handler ("GLib", G_LOG_LEVEL_WARNING | G_LOG_FLAG_FATAL | G_LOG_FLAG_RECURSION, my_log_handler, NULL); - /* gtk_init does set_locale. Fix locale before and after. */ - fixup_locale (); + gtk_disable_setlocale (); unrequest_sigio (); /* See comment in x_display_ok. */ gtk_init (&argc, &argv2); request_sigio (); - fixup_locale (); - g_log_remove_handler ("GLib", id); diff --git a/src/xterm.c b/src/xterm.c index 00c61c486ed..fd61d5df91c 100644 --- a/src/xterm.c +++ b/src/xterm.c @@ -30651,8 +30651,7 @@ x_term_init (Lisp_Object display_name, char *xrm_option, char *resource_name) Call before gtk_init so Gtk+ event filters comes after our. */ gdk_window_add_filter (NULL, event_handler_gdk, NULL); - /* gtk_init does set_locale. Fix locale before and after. */ - fixup_locale (); + gtk_disable_setlocale (); unrequest_sigio (); /* See comment in x_display_ok. */ gtk_init (&argc, &argv2); request_sigio (); @@ -30661,8 +30660,7 @@ x_term_init (Lisp_Object display_name, char *xrm_option, char *resource_name) xg_initialize (); - /* Do this after the call to xg_initialize, because when - Fontconfig is used, xg_initialize calls its initialization + /* When Fontconfig is used, xg_initialize calls its initialization function which in some versions of Fontconfig calls setlocale. */ fixup_locale (); commit a1e4f6a35c70cf265c77b445288f4e0ab6ffc19f Author: Paul Eggert Date: Sun Jan 26 22:15:49 2025 -0800 Avoid unlikely int overflow. * src/pgtkterm.c (pgtk_term_init): * src/xterm.c (x_term_init): Use a bool, not an int that keeps incrementing, to record whether initialization has occurred. diff --git a/src/pgtkterm.c b/src/pgtkterm.c index 30679353c1b..41bec344799 100644 --- a/src/pgtkterm.c +++ b/src/pgtkterm.c @@ -7004,7 +7004,7 @@ pgtk_term_init (Lisp_Object display_name, char *resource_name) GdkDisplay *dpy; struct terminal *terminal; struct pgtk_display_info *dpyinfo; - static int x_initialized = 0; + static bool x_initialized; static unsigned x_display_id = 0; static char *initial_display = NULL; char *dpy_name; @@ -7015,6 +7015,7 @@ pgtk_term_init (Lisp_Object display_name, char *resource_name) block_input (); + bool was_initialized = x_initialized; if (!x_initialized) { any_help_event_p = false; @@ -7025,8 +7026,7 @@ pgtk_term_init (Lisp_Object display_name, char *resource_name) #ifdef USE_CAIRO gui_init_fringe (&pgtk_redisplay_interface); #endif - - ++x_initialized; + x_initialized = true; } dpy_name = SSDATA (display_name); @@ -7041,7 +7041,7 @@ pgtk_term_init (Lisp_Object display_name, char *resource_name) char **argv2 = argv; guint id; - if (x_initialized++ > 1) + if (was_initialized) { xg_display_open (dpy_name, &dpy); } diff --git a/src/xterm.c b/src/xterm.c index 21968b38e78..00c61c486ed 100644 --- a/src/xterm.c +++ b/src/xterm.c @@ -30382,7 +30382,7 @@ static bool x_timeout_atimer_activated_flag; #endif /* USE_X_TOOLKIT */ -static int x_initialized; +static bool x_initialized; /* Test whether two display-name strings agree up to the dot that separates the screen number from the server number. */ @@ -30594,10 +30594,11 @@ x_term_init (Lisp_Object display_name, char *xrm_option, char *resource_name) block_input (); + bool was_initialized = x_initialized; if (!x_initialized) { x_initialize (); - ++x_initialized; + x_initialized = true; } #if defined USE_X_TOOLKIT || defined USE_GTK @@ -30615,7 +30616,7 @@ x_term_init (Lisp_Object display_name, char *xrm_option, char *resource_name) char **argv2 = argv; guint id; - if (x_initialized++ > 1) + if (was_initialized) { xg_display_open (SSDATA (display_name), &dpy); } commit 6ff06ff738ead96d7b4cb59eda15a1c72e2b5776 Author: Paul Eggert Date: Sun Jan 26 22:15:49 2025 -0800 Beware large stack growth in pgtk_menu_show * src/pgtkmenu.c (pgtk_menu_show): USE_SAFE_ALLOCA instead of alloca. Problem found with --enable-gcc-warnings. diff --git a/src/pgtkmenu.c b/src/pgtkmenu.c index a2e09b6cb58..54e1c3739cf 100644 --- a/src/pgtkmenu.c +++ b/src/pgtkmenu.c @@ -596,14 +596,10 @@ pgtk_menu_show (struct frame *f, int x, int y, int menuflags, { int i; widget_value *wv, *save_wv = 0, *first_wv = 0, *prev_wv = 0; - widget_value **submenu_stack - = alloca (menu_items_used * sizeof *submenu_stack); - Lisp_Object *subprefix_stack - = alloca (menu_items_used * sizeof *subprefix_stack); + widget_value **submenu_stack; + Lisp_Object *subprefix_stack; int submenu_depth = 0; - specpdl_ref specpdl_count = SPECPDL_INDEX (); - eassert (FRAME_PGTK_P (f)); *error_name = NULL; @@ -614,6 +610,11 @@ pgtk_menu_show (struct frame *f, int x, int y, int menuflags, return Qnil; } + USE_SAFE_ALLOCA; + SAFE_NALLOCA (submenu_stack, 1, menu_items_used); + SAFE_NALLOCA (subprefix_stack, 1, menu_items_used); + specpdl_ref specpdl_count = SPECPDL_INDEX (); + block_input (); /* Create a tree of widget_value objects @@ -830,6 +831,7 @@ pgtk_menu_show (struct frame *f, int x, int y, int menuflags, entry = Fcons (subprefix_stack[j], entry); } unblock_input (); + SAFE_FREE (); return entry; } i += MENU_ITEMS_ITEM_LENGTH; @@ -844,6 +846,7 @@ pgtk_menu_show (struct frame *f, int x, int y, int menuflags, } unblock_input (); + SAFE_FREE (); return Qnil; } diff --git a/src/xmenu.c b/src/xmenu.c index ce5cdbcfc0b..f95c50b1833 100644 --- a/src/xmenu.c +++ b/src/xmenu.c @@ -1898,14 +1898,10 @@ x_menu_show (struct frame *f, int x, int y, int menuflags, widget_value **submenu_stack; Lisp_Object *subprefix_stack; int submenu_depth = 0; - specpdl_ref specpdl_count; - USE_SAFE_ALLOCA; - SAFE_NALLOCA (submenu_stack, 1, menu_items_used); SAFE_NALLOCA (subprefix_stack, 1, menu_items_used); - - specpdl_count = SPECPDL_INDEX (); + specpdl_ref specpdl_count = SPECPDL_INDEX (); eassert (FRAME_X_P (f)); commit 17a8bf53f390718756e397cc0b31c1ef2c7de5f0 Author: Paul Eggert Date: Sun Jan 26 22:15:49 2025 -0800 Fix x-show-tip bignum crash * src/pgtkfns.c (compute_tip_xy): Fix crash if user specifies bignums. Bug found with --enable-gcc-warnings. diff --git a/src/pgtkfns.c b/src/pgtkfns.c index 21456f4f489..2c87ba8e326 100644 --- a/src/pgtkfns.c +++ b/src/pgtkfns.c @@ -2905,8 +2905,8 @@ compute_tip_xy (struct frame *f, Lisp_Object parms, Lisp_Object dx, /* Move the tooltip window where the mouse pointer is. Resize and show it. */ - if ((!INTEGERP (left) && !INTEGERP (right)) - || (!INTEGERP (top) && !INTEGERP (bottom))) + if ((!FIXNUMP (left) && !FIXNUMP (right)) + || (!FIXNUMP (top) && !FIXNUMP (bottom))) { Lisp_Object frame, attributes, monitor, geometry; GdkSeat *seat = @@ -2955,9 +2955,9 @@ compute_tip_xy (struct frame *f, Lisp_Object parms, Lisp_Object dx, max_y = pgtk_display_pixel_height (FRAME_DISPLAY_INFO (f)); } - if (INTEGERP (top)) + if (FIXNUMP (top)) *root_y = XFIXNUM (top); - else if (INTEGERP (bottom)) + else if (FIXNUMP (bottom)) *root_y = XFIXNUM (bottom) - height; else if (*root_y + XFIXNUM (dy) <= min_y) *root_y = min_y; /* Can happen for negative dy */ @@ -2971,9 +2971,9 @@ compute_tip_xy (struct frame *f, Lisp_Object parms, Lisp_Object dx, /* Put it on the top. */ *root_y = min_y; - if (INTEGERP (left)) + if (FIXNUMP (left)) *root_x = XFIXNUM (left); - else if (INTEGERP (right)) + else if (FIXNUMP (right)) *root_x = XFIXNUM (right) - width; else if (*root_x + XFIXNUM (dx) <= min_x) *root_x = 0; /* Can happen for negative dx */ commit c50e8c24247eb69d85b004a72197e710c8e1e32a Author: Paul Eggert Date: Sun Jan 26 22:15:49 2025 -0800 Prefer make_formatted_string in svg_load_image * src/image.c (svg_load_image): Prefer make_formatted_string to snprintf, as this simplifies the code and does not truncate the resulting string arbitrarily. diff --git a/src/image.c b/src/image.c index 901063c9bde..0d7e77164b6 100644 --- a/src/image.c +++ b/src/image.c @@ -12048,17 +12048,11 @@ svg_load_image (struct frame *f, struct image *img, char *contents, int height; const guint8 *pixels; int rowstride; - char *wrapped_contents = NULL; - ptrdiff_t wrapped_size; - + Lisp_Object wrapped_contents; bool empty_errmsg = true; const char *errmsg = ""; ptrdiff_t errlen = 0; -#if LIBRSVG_CHECK_VERSION (2, 48, 0) - char *css = NULL; -#endif - #if ! GLIB_CHECK_VERSION (2, 36, 0) /* g_type_init is a glib function that must be called prior to using gnome type library functions (obsolete since 2.36.0). */ @@ -12096,23 +12090,11 @@ svg_load_image (struct frame *f, struct image *img, char *contents, SVG supports, however it's only available in librsvg 2.48 and above so some things we could set here are handled in the wrapper below. */ - /* FIXME: The below calculations leave enough space for a font - size up to 9999, if it overflows we just throw an error but - should probably increase the buffer size. */ - const char *css_spec = "svg{font-family:\"%s\";font-size:%dpx}"; - int css_len = strlen (css_spec) + strlen (img->face_font_family) + 1; - css = xmalloc (css_len); - if (css_len <= snprintf (css, css_len, css_spec, - img->face_font_family, img->face_font_size)) - goto rsvg_error; - - rsvg_handle_set_stylesheet (rsvg_handle, (guint8 *)css, strlen (css), NULL); - } - else - { - css = xmalloc (SBYTES (lcss) + 1); - strncpy (css, SSDATA (lcss), SBYTES (lcss)); - *(css + SBYTES (lcss) + 1) = 0; + lcss = make_formatted_string ("svg{font-family:\"%s\";font-size:%dpx}", + img->face_font_family, + img->face_font_size); + rsvg_handle_set_stylesheet (rsvg_handle, (guint8 *) SDATA (lcss), + SBYTES (lcss), NULL); } #endif @@ -12280,7 +12262,7 @@ svg_load_image (struct frame *f, struct image *img, char *contents, background color, before including the original image. This acts to set the background color, instead of leaving it transparent. */ - const char *wrapper = + static char const wrapper[] = "" ""; - /* FIXME: I've added 64 in the hope it will cover the size of the - width and height strings and things. */ - int buffer_size = SBYTES (encoded_contents) + strlen (wrapper) + 64; - value = image_spec_value (img->spec, QCforeground, NULL); if (!NILP (value)) foreground = image_alloc_image_color (f, img, value, img->face_foreground); @@ -12317,22 +12295,18 @@ svg_load_image (struct frame *f, struct image *img, char *contents, | (background & 0x00FF00); #endif - wrapped_contents = xmalloc (buffer_size); - - if (buffer_size <= snprintf (wrapped_contents, buffer_size, wrapper, - foreground & 0xFFFFFF, width, height, - viewbox_width, viewbox_height, - background & 0xFFFFFF, - SSDATA (encoded_contents))) - goto rsvg_error; - - wrapped_size = strlen (wrapped_contents); + unsigned int color = foreground & 0xFFFFFF, fill = background & 0xFFFFFF; + wrapped_contents + = make_formatted_string (wrapper, color, width, height, + viewbox_width, viewbox_height, + fill, SSDATA (encoded_contents)); } /* Now we parse the wrapped version. */ #if LIBRSVG_CHECK_VERSION (2, 32, 0) - input_stream = g_memory_input_stream_new_from_data (wrapped_contents, wrapped_size, NULL); + input_stream = g_memory_input_stream_new_from_data + (SDATA (wrapped_contents), SBYTES (wrapped_contents), NULL); base_file = filename ? g_file_new_for_path (filename) : NULL; rsvg_handle = rsvg_handle_new_from_stream_sync (input_stream, base_file, RSVG_HANDLE_FLAGS_NONE, @@ -12351,7 +12325,8 @@ svg_load_image (struct frame *f, struct image *img, char *contents, #if LIBRSVG_CHECK_VERSION (2, 48, 0) /* Set the CSS for the wrapped SVG. See the comment above the previous use of 'css'. */ - rsvg_handle_set_stylesheet (rsvg_handle, (guint8 *)css, strlen (css), NULL); + rsvg_handle_set_stylesheet (rsvg_handle, (guint8 *) SDATA (lcss), + SBYTES (lcss), NULL); #endif #else /* Make a handle to a new rsvg object. */ @@ -12369,7 +12344,8 @@ svg_load_image (struct frame *f, struct image *img, char *contents, rsvg_handle_set_base_uri (rsvg_handle, filename); /* Parse the contents argument and fill in the rsvg_handle. */ - rsvg_handle_write (rsvg_handle, (unsigned char *) wrapped_contents, wrapped_size, &err); + rsvg_handle_write (rsvg_handle, SDATA (wrapped_contents), + SBYTES (wrapped_contents), &err); if (err) goto rsvg_error; /* The parsing is complete, rsvg_handle is ready to used, close it @@ -12389,12 +12365,6 @@ svg_load_image (struct frame *f, struct image *img, char *contents, if (!pixbuf) goto rsvg_error; #endif g_object_unref (rsvg_handle); - xfree (wrapped_contents); - -#if LIBRSVG_CHECK_VERSION (2, 48, 0) - if (!STRINGP (lcss)) - xfree (css); -#endif /* Extract some meta data from the svg handle. */ width = gdk_pixbuf_get_width (pixbuf); @@ -12485,12 +12455,6 @@ svg_load_image (struct frame *f, struct image *img, char *contents, done_error: if (rsvg_handle) g_object_unref (rsvg_handle); - if (wrapped_contents) - xfree (wrapped_contents); -#if LIBRSVG_CHECK_VERSION (2, 48, 0) - if (css && !STRINGP (lcss)) - xfree (css); -#endif return false; } commit 028fae966142b6e2330b9250fb4cdf2cbd8e1446 Author: Paul Eggert Date: Sun Jan 26 22:15:48 2025 -0800 Simplify building of color names in image.c * src/image.c (make_color_name): New function. (image_background, image_build_heuristic_mask, png_load_body): Use it. diff --git a/src/image.c b/src/image.c index 4350c415d9c..901063c9bde 100644 --- a/src/image.c +++ b/src/image.c @@ -1971,6 +1971,12 @@ four_corners_best (Emacs_Pix_Context pimg, int *corners, return best; } +static Lisp_Object +make_color_name (unsigned int red, unsigned int green, unsigned int blue) +{ + return make_formatted_string ("#%04x%04x%04x", red, green, blue); +} + /* Return the `background' field of IMG. If IMG doesn't have one yet, it is guessed heuristically. If non-zero, XIMG is an existing Emacs_Pix_Context object (device context with the image selected on @@ -1993,14 +1999,10 @@ image_background (struct image *img, struct frame *f, Emacs_Pix_Context pimg) RGB_PIXEL_COLOR bg = four_corners_best (pimg, img->corners, img->width, img->height); #ifdef USE_CAIRO - { - char color_name[30]; - snprintf (color_name, sizeof color_name, "#%04x%04x%04x", - (unsigned int) RED16_FROM_ULONG (bg), - (unsigned int) GREEN16_FROM_ULONG (bg), - (unsigned int) BLUE16_FROM_ULONG (bg)); - bg = image_alloc_image_color (f, img, build_string (color_name), 0); - } + Lisp_Object color_name = make_color_name (RED16_FROM_ULONG (bg), + GREEN16_FROM_ULONG (bg), + BLUE16_FROM_ULONG (bg)); + bg = image_alloc_image_color (f, img, color_name, 0); #endif img->background = bg; @@ -7383,15 +7385,11 @@ image_build_heuristic_mask (struct frame *f, struct image *img, if (i == 3 && NILP (how)) { #ifndef USE_CAIRO - char color_name[30]; - int len = snprintf (color_name, sizeof color_name, "#%04x%04x%04x", - rgb[0] + 0u, rgb[1] + 0u, rgb[2] + 0u); - eassert (len < sizeof color_name); - bg = ( -#ifdef HAVE_NTGUI - 0x00ffffff & /* Filter out palette info. */ -#endif /* HAVE_NTGUI */ - image_alloc_image_color (f, img, build_string (color_name), 0)); + Lisp_Object color_name = make_color_name (rgb[0], rgb[1], rgb[2]); + bg = image_alloc_image_color (f, img, color_name, 0); +# ifdef HAVE_NTGUI + bg &= 0x00ffffff; /* Filter out palette info. */ +# endif #else /* USE_CAIRO */ bg = lookup_rgb_color (f, rgb[0], rgb[1], rgb[2]); #endif /* USE_CAIRO */ @@ -8535,12 +8533,9 @@ png_load_body (struct frame *f, struct image *img, struct png_load_context *c) #ifndef USE_CAIRO img->background = lookup_rgb_color (f, bg->red, bg->green, bg->blue); #else /* USE_CAIRO */ - char color_name[30]; - int len = snprintf (color_name, sizeof color_name, "#%04x%04x%04x", - bg->red, bg->green, bg->blue); - eassert (len < sizeof color_name); - img->background - = image_alloc_image_color (f, img, build_string (color_name), 0); + Lisp_Object color_name + = make_color_name (bg->red, bg->green, bg->blue); + img->background = image_alloc_image_color (f, img, color_name, 0); #endif /* USE_CAIRO */ img->background_valid = 1; } commit f885806fdf1aa862ad55d124e9795794fed0b964 Author: Paul Eggert Date: Sun Jan 26 22:15:48 2025 -0800 Simplify make_formatted_string API From a suggestion by Pip Cet. * src/alloc.c (make_formatted_string): Omit first argument, to simplify the calling convention. All callers changed. * src/doprnt.c (doprnt): Also support %u. Update doc. diff --git a/src/alloc.c b/src/alloc.c index c4e2ff52015..2c0ccc9dd62 100644 --- a/src/alloc.c +++ b/src/alloc.c @@ -2542,19 +2542,23 @@ make_uninit_multibyte_string (EMACS_INT nchars, EMACS_INT nbytes) return make_clear_multibyte_string (nchars, nbytes, false); } -/* Print arguments to BUF according to a FORMAT, then return - a Lisp_String initialized with the data from BUF. */ +/* Return a Lisp_String according to a doprnt-style FORMAT and args. */ Lisp_Object -make_formatted_string (char *buf, const char *format, ...) +make_formatted_string (const char *format, ...) { + char buf[64]; + char *cstr = buf; + ptrdiff_t bufsize = sizeof buf; va_list ap; - int length; va_start (ap, format); - length = vsprintf (buf, format, ap); + ptrdiff_t length = evxprintf (&cstr, &bufsize, buf, -1, format, ap); va_end (ap); - return make_string (buf, length); + Lisp_Object ret = make_string (cstr, length); + if (cstr != buf) + xfree (cstr); + return ret; } /* Pin a unibyte string in place so that it won't move during GC. */ diff --git a/src/dbusbind.c b/src/dbusbind.c index b590a40c4a9..d98009f68b4 100644 --- a/src/dbusbind.c +++ b/src/dbusbind.c @@ -1970,10 +1970,9 @@ syms_of_dbusbind (void) { #ifdef DBUS_VERSION int major, minor, micro; - char s[sizeof ".." + 3 * INT_STRLEN_BOUND (int)]; dbus_get_version (&major, &minor, µ); Vdbus_runtime_version - = make_formatted_string (s, "%d.%d.%d", major, minor, micro); + = make_formatted_string ("%d.%d.%d", major, minor, micro); #else Vdbus_runtime_version = Qnil; #endif diff --git a/src/doprnt.c b/src/doprnt.c index 640349cfec4..335223f972a 100644 --- a/src/doprnt.c +++ b/src/doprnt.c @@ -23,7 +23,7 @@ along with GNU Emacs. If not, see . */ supports the following Emacs-specific features: . For %c conversions, it produces a string with the multibyte representation - of the (`int') argument, suitable for display in an Emacs buffer. + of the ('int') argument, suitable for display in an Emacs buffer. . For %s and %c, when field width is specified (e.g., %25s), it accounts for the display width of each character, according to char-width-table. That @@ -42,8 +42,8 @@ along with GNU Emacs. If not, see . */ overflow ptrdiff_t or size_t, to avoid producing strings longer than what Emacs can handle. - OTOH, this function supports only a small subset of the standard C formatted - output facilities. E.g., %u is not supported, precision is ignored + On the other hand, this function supports only a small subset of the + standard C formatted output facilities. E.g., precision is ignored in %s and %c conversions, and %lld does not necessarily work and code should use something like %"pM"d with intmax_t instead. (See below for the detailed documentation of what is supported.) @@ -57,16 +57,17 @@ along with GNU Emacs. If not, see . */ also supports the following %-sequences: %s means print a string argument. - %S is treated as %s, for loose compatibility with `Fformat_message'. - %d means print a `signed int' argument in decimal. - %o means print an `unsigned int' argument in octal. - %x means print an `unsigned int' argument in hex. - %e means print a `double' argument in exponential notation. - %f means print a `double' argument in decimal-point notation. - %g means print a `double' argument in exponential notation + %S is treated as %s, for loose compatibility with 'Fformat_message'. + %d means print a 'signed int' argument in decimal. + %o means print an 'unsigned int' argument in octal. + %u means print an 'unsigned int' argument in decimal. + %x means print an 'unsigned int' argument in hex. + %e means print a 'double' argument in exponential notation. + %f means print a 'double' argument in decimal-point notation. + %g means print a 'double' argument in exponential notation or in decimal-point notation, depending on the value; this is often (though not always) the shorter of the two notations. - %c means print a `signed int' argument as a single character. + %c means print a 'signed int' argument as a single character. %% means produce a literal % character. A %-sequence other than %% may contain optional flags, width, precision, @@ -82,18 +83,18 @@ along with GNU Emacs. If not, see . */ The + flag character inserts a + before any positive number, while a space inserts a space before any positive number; these flags only affect %d, %o, %x, %e, %f, and %g sequences. The - and 0 flags affect the width specifier, - as described below. For signed numerical arguments only, the ` ' (space) + as described below. For signed numerical arguments only, the ' ' (space) flag causes the result to be prefixed with a space character if it does not start with a sign (+ or -). - The l (lower-case letter ell) length modifier is a `long' data type + The l (lower-case letter ell) length modifier is a 'long' data type modifier: it is supported for %d, %o, and %x conversions of integral arguments, must immediately precede the conversion specifier, and means that - the respective argument is to be treated as `long int' or `unsigned long + the respective argument is to be treated as 'long int' or 'unsigned long int'. Similarly, the value of the pD macro means to use ptrdiff_t, the value of the pI macro means to use EMACS_INT or EMACS_UINT, the value of the PRIdMAX etc. macros means to use intmax_t or uintmax_t, - and the empty length modifier means `int' or `unsigned int'. + and the empty length modifier means 'int' or 'unsigned int'. The width specifier supplies a lower limit for the length of the printed representation. The padding, if any, normally goes on the left, but it goes @@ -162,16 +163,15 @@ doprnt_non_null_end (char *buffer, ptrdiff_t bufsize, char const *format, return nbytes; } -/* Generate output from a format-spec FORMAT, +/* Format to BUFFER (of positive size BUFSIZE) data formated by FORMAT, terminated at either the first NUL or (if FORMAT_END is non-null and there are no NUL bytes between FORMAT and FORMAT_END) - terminated at position FORMAT_END. + terminated at position FORMAT_END. AP specifies format arguments. (*FORMAT_END is not part of the format, but must exist and be readable.) - Output goes in BUFFER, which has room for BUFSIZE chars. - BUFSIZE must be positive. If the output does not fit, truncate it - to fit and return BUFSIZE - 1; if this truncates a multibyte - sequence, store '\0' into the sequence's first byte. - Returns the number of bytes stored into BUFFER, excluding + If the output does not fit, truncate it to fit and return BUFSIZE - 1; + if this truncates a multibyte sequence, + store '\0' into the sequence's first byte. + Return the number of bytes stored into BUFFER, excluding the terminating null byte. Output is always null-terminated. String arguments are passed as C strings. Integers are passed as C integers. @@ -349,6 +349,7 @@ doprnt (char *buffer, ptrdiff_t bufsize, const char *format, goto doit; case 'o': + case 'u': case 'x': switch (length_modifier) { diff --git a/src/frame.c b/src/frame.c index 904b7984420..dbed3f940fb 100644 --- a/src/frame.c +++ b/src/frame.c @@ -1283,8 +1283,6 @@ static struct frame * make_terminal_frame (struct terminal *terminal, Lisp_Object parent, Lisp_Object params) { - char name[sizeof "F" + INT_STRLEN_BOUND (tty_frame_count)]; - if (!terminal->name) error ("Terminal is not live, can't create new frames on it"); @@ -1364,7 +1362,7 @@ make_terminal_frame (struct terminal *terminal, Lisp_Object parent, XSETFRAME (frame, f); Vframe_list = Fcons (frame, Vframe_list); - fset_name (f, make_formatted_string (name, "F%"PRIdMAX, ++tty_frame_count)); + fset_name (f, make_formatted_string ("F%"PRIdMAX, ++tty_frame_count)); SET_FRAME_VISIBLE (f, true); @@ -3504,14 +3502,12 @@ set_term_frame_name (struct frame *f, Lisp_Object name) /* If NAME is nil, set the name to F. */ if (NILP (name)) { - char namebuf[sizeof "F" + INT_STRLEN_BOUND (tty_frame_count)]; - /* Check for no change needed in this very common case before we do any consing. */ if (frame_name_fnn_p (SSDATA (f->name), SBYTES (f->name))) return; - name = make_formatted_string (namebuf, "F%"PRIdMAX, ++tty_frame_count); + name = make_formatted_string ("F%"PRIdMAX, ++tty_frame_count); } else { @@ -4938,7 +4934,6 @@ gui_report_frame_params (struct frame *f, Lisp_Object *alistptr) { Lisp_Object tem; uintmax_t w; - char buf[INT_BUFSIZE_BOUND (w)]; /* Represent negative positions (off the top or left screen edge) in a way that Fmodify_frame_parameters will understand correctly. */ @@ -4989,7 +4984,7 @@ gui_report_frame_params (struct frame *f, Lisp_Object *alistptr) warnings. */ w = (uintptr_t) FRAME_NATIVE_WINDOW (f); store_in_alist (alistptr, Qwindow_id, - make_formatted_string (buf, "%"PRIuMAX, w)); + make_formatted_string ("%"PRIuMAX, w)); #ifdef HAVE_X_WINDOWS #ifdef USE_X_TOOLKIT /* Tooltip frame may not have this widget. */ @@ -4997,7 +4992,7 @@ gui_report_frame_params (struct frame *f, Lisp_Object *alistptr) #endif w = (uintptr_t) FRAME_OUTER_WINDOW (f); store_in_alist (alistptr, Qouter_window_id, - make_formatted_string (buf, "%"PRIuMAX, w)); + make_formatted_string ("%"PRIuMAX, w)); #endif store_in_alist (alistptr, Qicon_name, f->icon_name); store_in_alist (alistptr, Qvisibility, diff --git a/src/image.c b/src/image.c index de6955c2a47..4350c415d9c 100644 --- a/src/image.c +++ b/src/image.c @@ -12601,7 +12601,6 @@ static bool gs_load (struct frame *f, struct image *img) { uintmax_t printnum1, printnum2; - char buffer[sizeof " " + 2 * INT_STRLEN_BOUND (intmax_t)]; Lisp_Object window_and_pixmap_id = Qnil, loader, pt_height, pt_width; Lisp_Object frame; double in_width, in_height; @@ -12653,13 +12652,13 @@ gs_load (struct frame *f, struct image *img) printnum1 = FRAME_X_DRAWABLE (f); printnum2 = img->pixmap; window_and_pixmap_id - = make_formatted_string (buffer, "%"PRIuMAX" %"PRIuMAX, + = make_formatted_string ("%"PRIuMAX" %"PRIuMAX, printnum1, printnum2); printnum1 = FRAME_FOREGROUND_PIXEL (f); printnum2 = FRAME_BACKGROUND_PIXEL (f); pixel_colors - = make_formatted_string (buffer, "%"PRIuMAX" %"PRIuMAX, + = make_formatted_string ("%"PRIuMAX" %"PRIuMAX, printnum1, printnum2); XSETFRAME (frame, f); diff --git a/src/lisp.h b/src/lisp.h index 28fa4c8037e..2faad895133 100644 --- a/src/lisp.h +++ b/src/lisp.h @@ -4592,8 +4592,8 @@ extern Lisp_Object make_uninit_bool_vector (EMACS_INT); extern Lisp_Object bool_vector_fill (Lisp_Object, Lisp_Object); extern AVOID string_overflow (void); extern Lisp_Object make_string (const char *, ptrdiff_t); -extern Lisp_Object make_formatted_string (char *, const char *, ...) - ATTRIBUTE_FORMAT_PRINTF (2, 3); +extern Lisp_Object make_formatted_string (const char *, ...) + ATTRIBUTE_FORMAT_PRINTF (1, 2); extern Lisp_Object make_unibyte_string (const char *, ptrdiff_t); extern ptrdiff_t vectorlike_nbytes (const union vectorlike_header *hdr); diff --git a/src/msdos.c b/src/msdos.c index 63a5400bc7d..95eb6453040 100644 --- a/src/msdos.c +++ b/src/msdos.c @@ -531,7 +531,6 @@ vga_installed (void) void dos_set_window_size (int *rows, int *cols) { - char video_name[30]; union REGS regs; Lisp_Object video_mode; int video_mode_value, have_vga = 0; @@ -547,7 +546,7 @@ dos_set_window_size (int *rows, int *cols) use that mode. */ video_mode = Fsymbol_value (Fintern_soft (make_formatted_string - (video_name, "screen-dimensions-%dx%d", + ("screen-dimensions-%dx%d", *rows, *cols), Qnil)); if (FIXNUMP (video_mode) diff --git a/src/xsettings.c b/src/xsettings.c index 76f9fae62fe..30b5ed258ae 100644 --- a/src/xsettings.c +++ b/src/xsettings.c @@ -927,17 +927,6 @@ apply_xft_settings (Display_Info *dpyinfo, static char const format[] = "Antialias: %d, Hinting: %d, RGBA: %d, LCDFilter: %d, " "Hintstyle: %d, DPI: %f"; - enum - { - d_formats = 5, - d_growth = INT_BUFSIZE_BOUND (int) - sizeof "%d", - lf_formats = 1, - max_f_integer_digits = DBL_MAX_10_EXP + 1, - f_precision = 6, - lf_growth = (sizeof "-." + max_f_integer_digits + f_precision - - sizeof "%f") - }; - char buf[sizeof format + d_formats * d_growth + lf_formats * lf_growth]; #ifdef HAVE_XFT XftDefaultSet (dpyinfo->display, pat); #else @@ -946,7 +935,7 @@ apply_xft_settings (Display_Info *dpyinfo, store_config_changed_event (Qfont_render, XCAR (dpyinfo->name_list_element)); Vxft_settings - = make_formatted_string (buf, format, + = make_formatted_string (format, oldsettings.aa, oldsettings.hinting, oldsettings.rgba, oldsettings.lcdfilter, oldsettings.hintstyle, oldsettings.dpi); commit bcfd4d21b0a62c5c15b919fa28673066c493775a Author: Paul Eggert Date: Sun Jan 26 22:15:48 2025 -0800 Fix unlikely time zone abbreviation bug * src/timefns.c (Fcurrent_time_zone): Fix double-"-" bug when time zone name is not known and time zone offset is -3600 or less. Also, stop assuming that make_formatted_string works with "*" precisions; this might ease future changes. diff --git a/src/timefns.c b/src/timefns.c index 4fb142f2f1b..590d84c4d65 100644 --- a/src/timefns.c +++ b/src/timefns.c @@ -1950,15 +1950,24 @@ the data it can't find. */) /* No local time zone name is available; use numeric zone instead. */ long int hour = offset / 3600; int min_sec = offset % 3600; - int amin_sec = eabs (min_sec); - int min = amin_sec / 60; - int sec = amin_sec % 60; - int min_prec = min_sec ? 2 : 0; - int sec_prec = sec ? 2 : 0; - char buf[sizeof "+0000" + INT_STRLEN_BOUND (long int)]; - zone_name = make_formatted_string (buf, "%c%.2ld%.*d%.*d", - (offset < 0 ? '-' : '+'), - hour, min_prec, min, sec_prec, sec); + char buf[INT_STRLEN_BOUND (long int) + sizeof "5959"]; + int buflen = 0; + buf[buflen++] = offset < 0 ? '-' : '+'; + buflen += sprintf (buf + buflen, "%.2ld", eabs (hour)); + if (min_sec) + { + int amin_sec = eabs (min_sec); + int min = amin_sec / 60; + int sec = amin_sec % 60; + buf[buflen++] = '0' + min / 10; + buf[buflen++] = '0' + min % 10; + if (sec) + { + buf[buflen++] = '0' + sec / 10; + buf[buflen++] = '0' + sec % 10; + } + } + zone_name = make_string (buf, buflen); } } commit b06364f1b667e7960d1724293398179f280e910b Author: Stefan Kangas Date: Mon Jan 27 07:47:29 2025 +0100 Don't use obsolete face alias in themes * etc/themes/leuven-dark-theme.el: * etc/themes/leuven-theme.el: * etc/themes/manoj-dark-theme.el: * etc/themes/tango-dark-theme.el: * etc/themes/tango-theme.el: Don't use obsolete face alias 'smerge-refined-change', preferring instead 'smerge-refined-changed'. diff --git a/etc/themes/leuven-dark-theme.el b/etc/themes/leuven-dark-theme.el index 29aa7b224f3..4cf30fc6e1e 100644 --- a/etc/themes/leuven-dark-theme.el +++ b/etc/themes/leuven-dark-theme.el @@ -333,7 +333,7 @@ more..." `(smerge-other ((,class ,diff-added))) `(smerge-base ((,class ,diff-removed))) `(smerge-markers ((,class (:background "#253859")))) - `(smerge-refined-change ((,class (:background "#5a550b")))) + `(smerge-refined-changed ((,class (:background "#5a550b")))) ;; Ediff. `(ediff-current-diff-A ((,class (:background "#253f49")))) diff --git a/etc/themes/leuven-theme.el b/etc/themes/leuven-theme.el index f5bf9c5179e..71704c4b01e 100644 --- a/etc/themes/leuven-theme.el +++ b/etc/themes/leuven-theme.el @@ -359,7 +359,7 @@ more..." `(smerge-other ((,class ,diff-added))) `(smerge-base ((,class ,diff-removed))) `(smerge-markers ((,class (:background "#FFE5CC")))) - `(smerge-refined-change ((,class (:background "#AAAAFF")))) + `(smerge-refined-changed ((,class (:background "#AAAAFF")))) ;; Ediff. `(ediff-current-diff-A ((,class (:background "#FFDDDD")))) diff --git a/etc/themes/manoj-dark-theme.el b/etc/themes/manoj-dark-theme.el index 5612a4de3fa..9c6798ab324 100644 --- a/etc/themes/manoj-dark-theme.el +++ b/etc/themes/manoj-dark-theme.el @@ -639,7 +639,7 @@ jarring angry fruit salad look to reduce eye fatigue." '(smerge-markers ((t (:background "grey30")))) '(smerge-mine ((t (:foreground "cyan")))) '(smerge-other ((t (:foreground "lightgreen")))) - '(smerge-refined-change ((t (:background "blue4")))) + '(smerge-refined-changed ((t (:background "blue4")))) '(speedbar-button-face ((t (:foreground "green3")))) '(speedbar-directory-face ((t (:foreground "light blue")))) '(speedbar-file-face ((t (:foreground "cyan")))) diff --git a/etc/themes/tango-dark-theme.el b/etc/themes/tango-dark-theme.el index 0119eba3d78..d0fa2dff49f 100644 --- a/etc/themes/tango-dark-theme.el +++ b/etc/themes/tango-dark-theme.el @@ -135,7 +135,7 @@ Semantic, and Ansi-Color faces are included." `(message-cited-text ((,class (:foreground ,cham-1)))) `(message-separator ((,class (:foreground ,plum-1)))) ;; SMerge faces - `(smerge-refined-change ((,class (:background ,blue-3)))) + `(smerge-refined-changed ((,class (:background ,blue-3)))) ;; Ediff faces `(ediff-current-diff-A ((,class (:background ,alum-5)))) `(ediff-fine-diff-A ((,class (:background ,blue-3)))) diff --git a/etc/themes/tango-theme.el b/etc/themes/tango-theme.el index 498f3bbb07c..9b276466d95 100644 --- a/etc/themes/tango-theme.el +++ b/etc/themes/tango-theme.el @@ -121,7 +121,7 @@ Semantic, and Ansi-Color faces are included." `(message-cited-text ((,class (:slant italic :foreground ,alum-5)))) `(message-separator ((,class (:weight bold :foreground ,cham-3)))) ;; SMerge - `(smerge-refined-change ((,class (:background ,plum-1)))) + `(smerge-refined-changed ((,class (:background ,plum-1)))) ;; Ediff `(ediff-current-diff-A ((,class (:background ,blue-1)))) `(ediff-fine-diff-A ((,class (:background ,plum-1)))) commit 52c41a66bad451dd43940cb313c62a95f464db1e Author: Stefan Kangas Date: Mon Jan 27 06:22:39 2025 +0100 Don't use obsolete variable in semantic/grammar.el * lisp/cedet/semantic/grammar.el (semantic-grammar-mode-keywords-2): (semantic-grammar-mode-keywords-3): Don't use obsolete variables. diff --git a/lisp/cedet/semantic/grammar.el b/lisp/cedet/semantic/grammar.el index fddeb20ace1..c38d585b833 100644 --- a/lisp/cedet/semantic/grammar.el +++ b/lisp/cedet/semantic/grammar.el @@ -1174,16 +1174,12 @@ END is the limit of the search." (defvar semantic-grammar-mode-keywords-2 (append semantic-grammar-mode-keywords-1 - (if (boundp 'lisp-font-lock-keywords-1) - lisp-font-lock-keywords-1 - lisp-el-font-lock-keywords-1)) + lisp-el-font-lock-keywords-1) "Font Lock keywords used to highlight Semantic grammar buffers.") (defvar semantic-grammar-mode-keywords-3 (append semantic-grammar-mode-keywords-1 - (if (boundp 'lisp-font-lock-keywords-2) - lisp-font-lock-keywords-2 - lisp-el-font-lock-keywords-2)) + lisp-el-font-lock-keywords-2) "Font Lock keywords used to highlight Semantic grammar buffers.") (defvar semantic-grammar-mode-keywords commit 2b3599bb08e8ccfe49bbaa28693fed8dca62440b Author: Stefan Kangas Date: Mon Jan 27 06:19:34 2025 +0100 Don't use obsolete variables in semantic/idle.el * lisp/cedet/semantic/idle.el (semantic-idle-symbol-maybe-highlight) (semantic-idle-local-symbol-highlight): Don't use obsolete variable 'semantic-idle-symbol-highlight-face'. diff --git a/lisp/cedet/semantic/idle.el b/lisp/cedet/semantic/idle.el index addd94690e7..515a6b439bb 100644 --- a/lisp/cedet/semantic/idle.el +++ b/lisp/cedet/semantic/idle.el @@ -820,13 +820,12 @@ visible, then highlight it." (point) (get-buffer-window (current-buffer) 'visible)) (if (< (overlay-end region) (line-end-position)) (pulse-momentary-highlight-overlay - region semantic-idle-symbol-highlight-face) + region semantic-idle-symbol-highlight) ;; Not the same (pulse-momentary-highlight-region (overlay-start region) (line-end-position) - semantic-idle-symbol-highlight-face)))) - )) + semantic-idle-symbol-highlight)))))) ((vectorp region) (let ((start (aref region 0)) (end (aref region 1))) @@ -845,8 +844,7 @@ visible, then highlight it." (pulse-momentary-highlight-region start (if (<= end (line-end-position)) end (line-end-position)) - semantic-idle-symbol-highlight-face))) - )))) + semantic-idle-symbol-highlight))))))) nil)) (define-semantic-idle-service semantic-idle-local-symbol-highlight @@ -876,12 +874,10 @@ Call `semantic-symref-hits-in-region' to identify local references." target (lambda (start end _prefix) (when (/= start (car Hbounds)) (pulse-momentary-highlight-region - start end semantic-idle-symbol-highlight-face)) - (semantic-throw-on-input 'symref-highlight) - ) + start end semantic-idle-symbol-highlight)) + (semantic-throw-on-input 'symref-highlight)) (semantic-tag-start tag) - (semantic-tag-end tag))) - )))) + (semantic-tag-end tag))))))) ;;;###autoload commit 8d11871c63e65459fd14f1cbe08bf0460c452ac6 Author: Po Lu Date: Mon Jan 27 09:11:21 2025 +0800 Fix the Android port * src/term.c (tty_frame_at) [HAVE_ANDROID]: Always return nil. * src/terminal.c (cursor_to, raw_cursor_to) [HAVE_ANDROID]: Don't call root_xy. diff --git a/src/term.c b/src/term.c index 777ab5f918c..e519813c7ac 100644 --- a/src/term.c +++ b/src/term.c @@ -2597,6 +2597,7 @@ tty_draw_row_with_mouse_face (struct window *w, struct glyph_row *row, static Lisp_Object tty_frame_at (int x, int y, int *cx, int *cy) { +#ifndef HAVE_ANDROID for (Lisp_Object frames = Ftty_frame_list_z_order (Qnil); !NILP (frames); frames = Fcdr (frames)) @@ -2613,6 +2614,7 @@ tty_frame_at (int x, int y, int *cx, int *cy) return frame; } } +#endif /* !HAVE_ANDROID */ return Qnil; } diff --git a/src/terminal.c b/src/terminal.c index 17dc4770ef7..668b8845029 100644 --- a/src/terminal.c +++ b/src/terminal.c @@ -114,7 +114,11 @@ cursor_to (struct frame *f, int vpos, int hpos) if (term->cursor_to_hook) { int x, y; +#ifndef HAVE_ANDROID root_xy (f, hpos, vpos, &x, &y); +#else /* HAVE_ANDROID */ + x = hpos, y = vpos; +#endif /* !HAVE_ANDROID */ term->cursor_to_hook (f, y, x); } } @@ -128,7 +132,11 @@ raw_cursor_to (struct frame *f, int row, int col) if (term->raw_cursor_to_hook) { int x, y; +#ifndef HAVE_ANDROID root_xy (f, col, row, &x, &y); +#else /* HAVE_ANDROID */ + x = col, y = row; +#endif /* !HAVE_ANDROID */ term->raw_cursor_to_hook (f, y, x); } } commit aec9e66178793e631f0583768315a6371054c907 Author: Stefan Kangas Date: Sun Jan 26 21:17:31 2025 +0100 Fix compilation warnings in pdumper with !HAVE_NATIVECOMP * src/pdumper.c [!HAVE_NATIVECOMP] (cold_op, dump_subr): Fix compilation warnings. Ref: https://lists.gnu.org/r/emacs-devel/2025-01/msg01003.html diff --git a/src/pdumper.c b/src/pdumper.c index 77d4407935e..45a44db0243 100644 --- a/src/pdumper.c +++ b/src/pdumper.c @@ -446,7 +446,9 @@ enum cold_op COLD_OP_CHARSET, COLD_OP_BUFFER, COLD_OP_BIGNUM, +#ifdef HAVE_NATIVE_COMP COLD_OP_NATIVE_SUBR, +#endif }; /* This structure controls what operations we perform inside @@ -2972,15 +2974,14 @@ dump_subr (struct dump_context *ctx, const struct Lisp_Subr *subr) DUMP_FIELD_COPY (&out, subr, header.size); #ifdef HAVE_NATIVE_COMP bool non_primitive = !NILP (subr->native_comp_u); -#else - bool non_primitive = false; -#endif if (non_primitive) out.function.a0 = NULL; else +#endif dump_field_emacs_ptr (ctx, &out, subr, &subr->function.a0); DUMP_FIELD_COPY (&out, subr, min_args); DUMP_FIELD_COPY (&out, subr, max_args); +#ifdef HAVE_NATIVE_COMP if (non_primitive) { dump_field_fixup_later (ctx, &out, subr, &subr->symbol_name); @@ -2991,6 +2992,7 @@ dump_subr (struct dump_context *ctx, const struct Lisp_Subr *subr) dump_field_lv (ctx, &out, subr, &subr->command_modes, WEIGHT_NORMAL); } else +#endif { dump_field_emacs_ptr (ctx, &out, subr, &subr->symbol_name); dump_field_emacs_ptr (ctx, &out, subr, &subr->intspec.string); @@ -3006,12 +3008,14 @@ dump_subr (struct dump_context *ctx, const struct Lisp_Subr *subr) dump_field_lv (ctx, &out, subr, &subr->type, WEIGHT_NORMAL); #endif dump_off subr_off = dump_object_finish (ctx, &out, sizeof (out)); +#ifdef HAVE_NATIVE_COMP if (non_primitive && ctx->flags.dump_object_contents) /* We'll do the final addr relocation during VERY_LATE_RELOCS time after the compilation units has been loaded. */ dump_push (&ctx->dump_relocs[VERY_LATE_RELOCS], list2 (make_fixnum (RELOC_NATIVE_SUBR), dump_off_to_lisp (subr_off))); +#endif return subr_off; } commit 6e2e7265a04f63f482db7fbdfd8e2519d8bfe03e Author: Stefan Kangas Date: Sun Jan 26 20:04:07 2025 +0100 Prefer static switch-case checking in pdumper * src/pdumper.c (dump_fwd, dump_symbol, dump_drain_cold_data) (dump_do_fixup, dump_anonymous_allocate_w32) (dump_anonymous_allocate_posix, dump_map_file_w32, dump_map_file_posix) (dump_do_emacs_relocation): Remove default clauses to allow static checking using -Wswitch. diff --git a/src/pdumper.c b/src/pdumper.c index e7e6e2c392c..77d4407935e 100644 --- a/src/pdumper.c +++ b/src/pdumper.c @@ -2390,8 +2390,6 @@ dump_fwd (struct dump_context *ctx, lispfwd fwd) case Lisp_Fwd_Kboard_Obj: offset = dump_fwd_kboard_obj (ctx, p); break; - default: - emacs_abort (); } return offset; @@ -2523,8 +2521,6 @@ dump_symbol (struct dump_context *ctx, case SYMBOL_FORWARDED: dump_field_fixup_later (ctx, &out, symbol, &symbol->u.s.val.fwd); break; - default: - emacs_abort (); } dump_field_lv (ctx, &out, symbol, &symbol->u.s.function, WEIGHT_NORMAL); dump_field_lv (ctx, &out, symbol, &symbol->u.s.plist, WEIGHT_NORMAL); @@ -3603,8 +3599,6 @@ dump_drain_cold_data (struct dump_context *ctx) dump_cold_native_subr (ctx, data); break; #endif - default: - emacs_abort (); } } @@ -4069,8 +4063,6 @@ dump_do_fixup (struct dump_context *ctx, do_write = false; break; } - default: - emacs_abort (); } if (do_write) dump_write (ctx, &dump_value, sizeof (dump_value)); @@ -4529,8 +4521,6 @@ dump_anonymous_allocate_w32 (void *base, mem_type = MEM_COMMIT; mem_prot = PAGE_READWRITE; break; - default: - emacs_abort (); } ret = VirtualAlloc (base, size, mem_type, mem_prot); @@ -4569,8 +4559,6 @@ dump_anonymous_allocate_posix (void *base, case DUMP_MEMORY_ACCESS_READWRITE: mem_prot = PROT_READ | PROT_WRITE; break; - default: - emacs_abort (); } int mem_flags = MAP_PRIVATE | MAP_ANONYMOUS; @@ -4663,7 +4651,6 @@ dump_map_file_w32 (void *base, int fd, off_t offset, size_t size, case DUMP_MEMORY_ACCESS_READWRITE: protect = PAGE_WRITECOPY; /* for Windows 9X */ break; - default: case DUMP_MEMORY_ACCESS_NONE: case DUMP_MEMORY_ACCESS_READ: protect = PAGE_READONLY; @@ -4691,8 +4678,6 @@ dump_map_file_w32 (void *base, int fd, off_t offset, size_t size, case DUMP_MEMORY_ACCESS_READWRITE: map_access = FILE_MAP_COPY; break; - default: - emacs_abort (); } ret = MapViewOfFileEx (section, @@ -4735,8 +4720,6 @@ dump_map_file_posix (void *base, int fd, off_t offset, size_t size, mem_prot = PROT_READ | PROT_WRITE; mem_flags = MAP_PRIVATE; break; - default: - emacs_abort (); } if (base) @@ -5603,8 +5586,6 @@ dump_do_emacs_relocation (const uintptr_t dump_base, memcpy (emacs_ptr_at (reloc.emacs_offset), &lv, sizeof (lv)); break; } - default: - fatal ("unrecognied relocation type %d", (int) reloc.type); } } commit b07c12ce59c96db753a1f8f3a829f9ab5514e35f Author: Pip Cet Date: Sun Jan 26 14:34:45 2025 +0000 Avoid crashes in Fdocumentation caused by incorrect data types Note that this can only change things when function-documentation is defined or overloaded incorrectly. * src/doc.c (Fdocumentation): Check that the cdr of a docstring cons is a fixnum. diff --git a/src/doc.c b/src/doc.c index 6f4ce79f1f1..09e099efcdb 100644 --- a/src/doc.c +++ b/src/doc.c @@ -362,7 +362,7 @@ string is passed through `substitute-command-keys'. */) from the DOC file (bug in src/Makefile.in). */ if (BASE_EQ (doc, make_fixnum (0))) doc = Qnil; - if (FIXNUMP (doc) || CONSP (doc)) + if (FIXNUMP (doc) || (CONSP (doc) && FIXNUMP (XCDR (doc)))) { Lisp_Object tem = get_doc_string (doc, 0); if (NILP (tem) && try_reload) commit 8cfb4e35da4b7ffa84c521e28fd592c40209d04e Author: Eli Zaretskii Date: Sun Jan 26 17:50:34 2025 +0200 ; Fix last change * lisp/disp-table.el (display-table-slot) (set-display-table-slot): * etc/NEWS: * doc/lispref/display.texi (Display Tables): Fix punctuation and typos. diff --git a/doc/lispref/display.texi b/doc/lispref/display.texi index 39f182995c0..3bf9f3bd2ac 100644 --- a/doc/lispref/display.texi +++ b/doc/lispref/display.texi @@ -8727,7 +8727,7 @@ the single-line tty menu separator. The glyphs for a double-line border, in the order of vertical, horizontal, down-right edge, down-left edge, up-right, and up-left edge -glyphs. The horizontal glyph is also used for the single-line tty menu +glyphs. The horizontal glyph is also used for the single-line TTY menu separator, the other glyphs are not yet used. @end table @@ -8766,7 +8766,7 @@ Valid slot name symbols are @code{truncation}, @code{wrap}, @code{box-down-right}, @code{box-down-left}, @code{box-up-right}, @code{box-up-left}, @code{box-double-vertical}, @code{box-double-horizontal}, @code{box-double-down-right}, -@code{box-double-down-left}, @code{box-double-down-left}, +@code{box-double-down-left}, @code{box-double-up-right}, @code{box-double-up-left}. @defun describe-display-table display-table diff --git a/etc/NEWS b/etc/NEWS index 1bea343d079..249fcafd5cd 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -48,16 +48,15 @@ init file. * Changes in Emacs 31.1 +++ -** standard-display-table now has more extra slots - -standard-display-table has been extended to allow specifying glyphs that -are used for borders around child frames and menu separators on TTY +** 'standard-display-table' now has more extra slots. +'standard-display-table' has been extended to allow specifying glyphs +that are used for borders around child frames and menu separators on TTY frames. -Call function standard-display-unicode-special-glyphs to set up the -standard-display-table's extra slots with Unicode characters. Please -see the documentation of that function to see which slots of the display -table it changes. +Call the function 'standard-display-unicode-special-glyphs' to set up +the 'standard-display-table's extra slots with Unicode characters. +Please see the documentation of that function to see which slots of the +display table it changes. ** Child frames are now supported on TTY frames. This supports use-cases like Posframe, Corfu, and child frames acting diff --git a/lisp/disp-table.el b/lisp/disp-table.el index 738887d0d00..afce22deb85 100644 --- a/lisp/disp-table.el +++ b/lisp/disp-table.el @@ -70,7 +70,7 @@ Valid symbols are `truncation', `wrap', `escape', `control', `box-horizontal', `box-down-right', `box-down-left', `box-up-right', `box-up-left',`box-double-vertical', `box-double-horizontal', `box-double-down-right', `box-double-down-left', -`box-double-up-left', `box-double-up-left'," +`box-double-up-right', `box-double-up-left'," (let ((slot-number (if (numberp slot) slot (or (get slot 'display-table-slot) @@ -86,7 +86,7 @@ Valid symbols are `truncation', `wrap', `escape', `control', `box-horizontal', `box-down-right', `box-down-left', `box-up-right', `box-up-left',`box-double-vertical', `box-double-horizontal', `box-double-down-right', `box-double-down-left', -`box-double-up-left', `box-double-up-left'," +`box-double-up-right', `box-double-up-left'," (let ((slot-number (if (numberp slot) slot (or (get slot 'display-table-slot) commit 4e78a3e117f4ca0b6b9f3b7a2d7919cb5b2e0295 Author: Gerd Möllmann Date: Sun Jan 26 11:31:32 2025 +0100 Display separators on tty menus with display table entries * src/xdisp.c (display_tty_menu_separator): Lookup separator char in standard-display-table, make a string, and display that using display_string. * src/xdisp.c (display_tty_menu_separator_char): New function. (display_tty_menu_separator): Use it. * lisp/disp-table.el (display-table): Increase from 12 to 18. (box-double-vertical, box-double-horizontal, box-double-down-right) (box-double-down-left, box-double-up-right, box-double-up-left): New symbols for extra slots. (display-table-slot, set-display-table-slot): Change doc string. (describe-display-table): Describe new slots. (standard-display-unicode-special-glyphs): Define new slots. * src/disptab.h (DISP_TABLE_P): Add enumerators. (DISP_TABLE_EXTRA_SLOTS): Define based on enum box. * src/dispnew.c (produce_box_glyphs): Add new enumerators to switch to make it exhaustive. * src/xdisp.c (display_tty_menu_separator): Use BOX_DOUBLE_HORIZONTAL for '=' if present. * doc/lispref/display.texi: Add documentation. * etc/NEWS: Mention in NEWS. diff --git a/doc/lispref/display.texi b/doc/lispref/display.texi index b17ee2e96a1..39f182995c0 100644 --- a/doc/lispref/display.texi +++ b/doc/lispref/display.texi @@ -8715,6 +8715,20 @@ scroll bars are supported and in use, a scroll bar separates the two windows, and if there are no vertical scroll bars and no dividers (@pxref{Window Dividers}), Emacs uses a thin line to indicate the border. + +@item 6 to 11 + +The glyphs for a single-line border around child frames on a terminal, +in the order of vertical, horizontal, down-right edge, down-left edge, +up-right, and up-left edge glyphs. The horizontal glyph is also used for +the single-line tty menu separator. + +@item 12 to 17 + +The glyphs for a double-line border, in the order of vertical, +horizontal, down-right edge, down-left edge, up-right, and up-left edge +glyphs. The horizontal glyph is also used for the single-line tty menu +separator, the other glyphs are not yet used. @end table For example, here is how to construct a display table that mimics @@ -8737,24 +8751,34 @@ the effect of setting @code{ctl-arrow} to a non-@code{nil} value @defun display-table-slot display-table slot This function returns the value of the extra slot @var{slot} of @var{display-table}. The argument @var{slot} may be a number from 0 to -5 inclusive, or a slot name (symbol). Valid symbols are -@code{truncation}, @code{wrap}, @code{escape}, @code{control}, -@code{selective-display}, and @code{vertical-border}. +17 inclusive, or a slot name, a symbol. @end defun @defun set-display-table-slot display-table slot value This function stores @var{value} in the extra slot @var{slot} of @var{display-table}. The argument @var{slot} may be a number from 0 to -5 inclusive, or a slot name (symbol). Valid symbols are -@code{truncation}, @code{wrap}, @code{escape}, @code{control}, -@code{selective-display}, and @code{vertical-border}. +17 inclusive, or a slot name, a symbol. @end defun +Valid slot name symbols are @code{truncation}, @code{wrap}, +@code{escape}, @code{control}, @code{selective-display}, +@code{vertical-border}, @code{box-vertical}, @code{box-horizontal}, +@code{box-down-right}, @code{box-down-left}, @code{box-up-right}, +@code{box-up-left}, @code{box-double-vertical}, +@code{box-double-horizontal}, @code{box-double-down-right}, +@code{box-double-down-left}, @code{box-double-down-left}, +@code{box-double-up-left}. + @defun describe-display-table display-table This function displays a description of the display table @var{display-table} in a help buffer. @end defun +@defun standard-display-unicode-special-glyphs +This function sets the extra slots of @var{standard-display-table} with +suitable Unicode characters. +@end defun + @deffn Command describe-current-display-table This command displays a description of the current display table in a help buffer. diff --git a/etc/NEWS b/etc/NEWS index af5c320a19b..1bea343d079 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -47,7 +47,18 @@ init file. * Changes in Emacs 31.1 ---- ++++ +** standard-display-table now has more extra slots + +standard-display-table has been extended to allow specifying glyphs that +are used for borders around child frames and menu separators on TTY +frames. + +Call function standard-display-unicode-special-glyphs to set up the +standard-display-table's extra slots with Unicode characters. Please +see the documentation of that function to see which slots of the display +table it changes. + ** Child frames are now supported on TTY frames. This supports use-cases like Posframe, Corfu, and child frames acting like tooltips. Other use-cases of child frames are not supported yet. diff --git a/lisp/disp-table.el b/lisp/disp-table.el index 38d45a0c336..738887d0d00 100644 --- a/lisp/disp-table.el +++ b/lisp/disp-table.el @@ -28,7 +28,7 @@ ;;; Code: -(put 'display-table 'char-table-extra-slots 12) +(put 'display-table 'char-table-extra-slots 18) ;;;###autoload (defun make-display-table () @@ -46,6 +46,7 @@ (put 'control 'display-table-slot 3) (put 'selective-display 'display-table-slot 4) (put 'vertical-border 'display-table-slot 5) + (put 'box-vertical 'display-table-slot 6) (put 'box-horizontal 'display-table-slot 7) (put 'box-down-right 'display-table-slot 8) @@ -53,14 +54,23 @@ (put 'box-up-right 'display-table-slot 10) (put 'box-up-left 'display-table-slot 11) +(put 'box-double-vertical 'display-table-slot 12) +(put 'box-double-horizontal 'display-table-slot 13) +(put 'box-double-down-right 'display-table-slot 14) +(put 'box-double-down-left 'display-table-slot 15) +(put 'box-double-up-right 'display-table-slot 16) +(put 'box-double-up-left 'display-table-slot 17) + ;;;###autoload (defun display-table-slot (display-table slot) "Return the value of the extra slot in DISPLAY-TABLE named SLOT. -SLOT may be a number from 0 to 11 inclusive, or a slot name (symbol). +SLOT may be a number from 0 to 17 inclusive, or a slot name (symbol). Valid symbols are `truncation', `wrap', `escape', `control', `selective-display', `vertical-border', `box-vertical', `box-horizontal', `box-down-right', `box-down-left', `box-up-right', -and `box-up-left'." +`box-up-left',`box-double-vertical', `box-double-horizontal', +`box-double-down-right', `box-double-down-left', +`box-double-up-left', `box-double-up-left'," (let ((slot-number (if (numberp slot) slot (or (get slot 'display-table-slot) @@ -70,11 +80,13 @@ and `box-up-left'." ;;;###autoload (defun set-display-table-slot (display-table slot value) "Set the value of the extra slot in DISPLAY-TABLE named SLOT to VALUE. -SLOT may be a number from 0 to 11 inclusive, or a name (symbol). +SLOT may be a number from 0 to 17 inclusive, or a name (symbol). Valid symbols are `truncation', `wrap', `escape', `control', -`selective-display', `vertical-border', `box-vertical', +`selective-display', `vertical-border', `box-vertical', `box-horizontal', `box-down-right', `box-down-left', `box-up-right', -and `box-up-left'." +`box-up-left',`box-double-vertical', `box-double-horizontal', +`box-double-down-right', `box-double-down-left', +`box-double-up-left', `box-double-up-left'," (let ((slot-number (if (numberp slot) slot (or (get slot 'display-table-slot) @@ -97,6 +109,7 @@ and `box-up-left'." (prin1 (display-table-slot dt 'selective-display)) (princ "\nVertical window border glyph: ") (prin1 (display-table-slot dt 'vertical-border)) + (princ "\nBox vertical line glyph: ") (prin1 (display-table-slot dt 'box-vertical)) (princ "\nBox horizonal line glyph: ") @@ -109,6 +122,20 @@ and `box-up-left'." (prin1 (display-table-slot dt 'box-up-right)) (princ "\nBox lower right corner glyph: ") (prin1 (display-table-slot dt 'box-up-left)) + + (princ "\nBox double vertical line glyph: ") + (prin1 (display-table-slot dt 'box-double-vertical)) + (princ "\nBox double horizonal line glyph: ") + (prin1 (display-table-slot dt 'box-double-horizontal)) + (princ "\nBox double upper left corner glyph: ") + (prin1 (display-table-slot dt 'box-double-down-right)) + (princ "\nBox double upper right corner glyph: ") + (prin1 (display-table-slot dt 'box-double-down-left)) + (princ "\nBox double lower left corner glyph: ") + (prin1 (display-table-slot dt 'box-double-up-right)) + (princ "\nBox double lower right corner glyph: ") + (prin1 (display-table-slot dt 'box-double-up-left)) + (princ "\nCharacter display glyph sequences:\n") (with-current-buffer standard-output (let ((vector (make-vector 256 nil)) @@ -152,11 +179,14 @@ and `box-up-left'." (defun standard-display-unicode-special-glyphs () "Display some glyps using Unicode characters. The glyphs being changed by this function are `vertical-border', -`box-vertical', `box-horizontal', `box-down-right', `box-down-left', -`box-up-right', and `box-up-left'." +`box-vertical',`box-horizontal', `box-down-right', `box-down-left', +`box-up-right', `box-up-left',`box-double-vertical', +`box-double-horizontal', `box-double-down-right', +`box-double-down-left', `box-double-up-right', `box-double-up-left'," (interactive) (set-display-table-slot standard-display-table 'vertical-border (make-glyph-code #x2502)) + (set-display-table-slot standard-display-table 'box-vertical (make-glyph-code #x2502)) (set-display-table-slot standard-display-table @@ -168,7 +198,20 @@ The glyphs being changed by this function are `vertical-border', (set-display-table-slot standard-display-table 'box-up-right (make-glyph-code #x2514)) (set-display-table-slot standard-display-table - 'box-up-left (make-glyph-code #x2518))) + 'box-up-left (make-glyph-code #x2518)) + + (set-display-table-slot standard-display-table + 'box-double-vertical (make-glyph-code #x2551)) + (set-display-table-slot standard-display-table + 'box-double-horizontal (make-glyph-code #x2550)) + (set-display-table-slot standard-display-table + 'box-double-down-right (make-glyph-code #x2554)) + (set-display-table-slot standard-display-table + 'box-double-down-left (make-glyph-code #x2557)) + (set-display-table-slot standard-display-table + 'box-double-up-right (make-glyph-code #x255a)) + (set-display-table-slot standard-display-table + 'box-double-up-left (make-glyph-code #x255d))) ;;;###autoload (defun standard-display-8bit (l h) diff --git a/src/dispnew.c b/src/dispnew.c index d28dc3d54fa..d1e731e69f8 100644 --- a/src/dispnew.c +++ b/src/dispnew.c @@ -3614,6 +3614,13 @@ produce_box_glyphs (enum box box, struct glyph_row *row, int x, int n, case BOX_UP_LEFT: dflt = '+'; break; + case BOX_DOUBLE_VERTICAL: + case BOX_DOUBLE_HORIZONTAL: + case BOX_DOUBLE_DOWN_RIGHT: + case BOX_DOUBLE_DOWN_LEFT: + case BOX_DOUBLE_UP_RIGHT: + case BOX_DOUBLE_UP_LEFT: + emacs_abort (); } /* FIXME/tty: some face for the border. */ diff --git a/src/disptab.h b/src/disptab.h index 8db9a06d2f4..5ab73715e6c 100644 --- a/src/disptab.h +++ b/src/disptab.h @@ -28,7 +28,6 @@ along with GNU Emacs. If not, see . */ && EQ (XCHAR_TABLE (obj)->purpose, Qdisplay_table) \ && CHAR_TABLE_EXTRA_SLOTS (XCHAR_TABLE (obj)) == DISP_TABLE_EXTRA_SLOTS) -#define DISP_TABLE_EXTRA_SLOTS 12 #define DISP_TRUNC_GLYPH(dp) ((dp)->extras[0]) #define DISP_CONTINUE_GLYPH(dp) ((dp)->extras[1]) #define DISP_ESCAPE_GLYPH(dp) ((dp)->extras[2]) @@ -43,7 +42,14 @@ enum box BOX_DOWN_RIGHT, BOX_DOWN_LEFT, BOX_UP_RIGHT, - BOX_UP_LEFT + BOX_UP_LEFT, + BOX_DOUBLE_VERTICAL, + BOX_DOUBLE_HORIZONTAL, + BOX_DOUBLE_DOWN_RIGHT, + BOX_DOUBLE_DOWN_LEFT, + BOX_DOUBLE_UP_RIGHT, + BOX_DOUBLE_UP_LEFT +#define DISP_TABLE_EXTRA_SLOTS (BOX_DOUBLE_UP_LEFT + 1) }; extern Lisp_Object disp_char_vector (struct Lisp_Char_Table *, int); diff --git a/src/xdisp.c b/src/xdisp.c index 2676e982c9e..5b5cb3849fc 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -27272,33 +27272,42 @@ deep_copy_glyph_row (struct frame *f, struct glyph_row *to, struct glyph_row *fr fill_up_frame_row_with_spaces (f, to, to_used); } +/* Return the character to be used for displaying a tty menu separator. + C is the character to be used by default. BOX is the display table + entry for the character to be used instead. It is looked up in + standard-display-table. Value is the character to use. */ + +static int +display_tty_menu_separator_char (int c, enum box box) +{ + if (DISP_TABLE_P (Vstandard_display_table)) + { + struct Lisp_Char_Table *dp = XCHAR_TABLE (Vstandard_display_table); + Lisp_Object gc = dp->extras[box]; + if (GLYPH_CODE_P (gc)) + c = GLYPH_CODE_CHAR (gc); + } + return c; +} + /* Produce glyphs for a menu separator on a tty. FIXME: This is only a "good enough for now" implementation of menu separators as described in the Elisp info manual. We should probably - ignore menu separators when computing the width of a menu. Secondly, - optionally using Unicode characters via display table entries would - be nice. Patches very welcome. */ + ignore menu separators when computing the width of a menu. */ static void display_tty_menu_separator (struct it *it, const char *label, int width) { - USE_SAFE_ALLOCA; - char c; + int c; if (strcmp (label, "--space") == 0) c = ' '; else if (strcmp (label, "--double-line") == 0) - c = '='; + c = display_tty_menu_separator_char ('=', BOX_DOUBLE_HORIZONTAL); else - c = '-'; - char *sep = SAFE_ALLOCA (width); - memset (sep, c, width - 1); - sep[width - 1] = 0; - display_string (sep, Qnil, Qnil, 0, 0, it, width - 1, width - 1, - FRAME_COLS (it->f) - 1, -1); - display_string (" ", Qnil, Qnil, 0, 0, it, 1, 0, - FRAME_COLS (it->f) - 1, -1); - SAFE_FREE (); + c = display_tty_menu_separator_char ('-', BOX_HORIZONTAL); + Lisp_Object sep = Fmake_string (make_fixnum (width - 1), make_fixnum (c), Qt); + display_string ((char *) SDATA (sep), Qnil, Qnil, 0, 0, it, width, -1, -1, 1); } /* Display one menu item on a TTY, by overwriting the glyphs in the commit 01d93d56cd469ddb45d142da948caef9f2dc1a3f Author: Tassilo Horn Date: Sun Jan 26 09:44:59 2025 +0100 Use dired--inhibit-auto-revert for fixing bug#71264 The original fix bound auto-revert-mode to nil which had the side-effect of disabling auto-revert forever in this buffer because auto-revert-handler removes the buffer from auto-revert-buffer-list when it's called but auto-revert-mode is nil. * lisp/dired.el (dired-internal-do-deletions): Bind dired--inhibit-auto-revert during deletion (bug#71264). diff --git a/lisp/dired.el b/lisp/dired.el index d2071d80bf3..94865808d73 100644 --- a/lisp/dired.el +++ b/lisp/dired.el @@ -4089,13 +4089,12 @@ non-empty directories is allowed." (while l (goto-char (marker-position (cdr (car l)))) (dired-move-to-filename) - (let ((inhibit-read-only t)) + (let ((inhibit-read-only t) + ;; Temporarily prevent auto-revert while deleting + ;; entry in the dired buffer (bug#71264). + (dired--inhibit-auto-revert t)) (condition-case err - (let ((fn (car (car l))) - ;; Temporarily prevent auto-revert while - ;; deleting entry in the dired buffer - ;; (bug#71264). - (auto-revert-mode nil)) + (let ((fn (car (car l)))) (dired-delete-file fn dired-recursive-deletes trash) ;; if we get here, removing worked (setq succ (1+ succ))