commit 076ed98ff6d7debff3929beab048c8a90e48dbb8 (HEAD, refs/remotes/origin/master) Author: Paul Eggert Date: Tue Apr 2 00:17:37 2019 -0700 More regexp advice and clarifications * doc/lispref/searching.texi (Regexp Special): Simplify style advice for order of ], ^, and - in character alternatives. Stick with saying that it’s not a good idea to put ‘-’ after a range. Remove the special case about raw 8-bit bytes and unibyte characters, as this documentation is confusing and seems to be incorrect in some cases. Say that z-a is the preferred style for reversed ranges, since it’s clearer and is typically what’s used in practice. Mention some bad styles: duplicates in character alternatives, ranges that denote <=3 characters, and ‘-’ as the first character. diff --git a/doc/lispref/searching.texi b/doc/lispref/searching.texi index 748ab586af..72ee9233a3 100644 --- a/doc/lispref/searching.texi +++ b/doc/lispref/searching.texi @@ -398,17 +398,11 @@ range should not be the starting point of another one; for example, The usual regexp special characters are not special inside a character alternative. A completely different set of characters is special inside character alternatives: @samp{]}, @samp{-} and @samp{^}. - -To include a @samp{]} in a character alternative, you must make it the first -character. For example, @samp{[]a]} matches @samp{]} or @samp{a}. To include -a @samp{-}, write @samp{-} as the last character of the character alternative, -tho you can also put it first or after a range. Thus, @samp{[]-]} matches both -@samp{]} and @samp{-}. (As explained below, you cannot use @samp{\]} to -include a @samp{]} inside a character alternative, since @samp{\} is not -special there.) - -To include @samp{^} in a character alternative, put it anywhere but at -the beginning. +To include @samp{]} in a character alternative, put it at the +beginning. To include @samp{^}, put it anywhere but at the beginning. +To include @samp{-}, put it at the end. Thus, @samp{[]^-]} matches +all three of these special characters. You cannot use @samp{\} to +escape these three characters, since @samp{\} is not special here. The following aspects of ranges are specific to Emacs, in that POSIX allows but does not require this behavior and programs other than @@ -426,17 +420,33 @@ of its bounds, so that @samp{[a-z]} matches only ASCII letters, even outside the C or POSIX locale. @item -As a special case, if either bound of a range is a raw 8-bit byte, the -other bound should be a unibyte character, and the range matches only -unibyte characters. +If the lower bound of a range is greater than its upper bound, the +range is empty and represents no characters. Thus, @samp{[z-a]} +always fails to match, and @samp{[^z-a]} matches any character, +including newline. However, a reversed range should always be from +the letter @samp{z} to the letter @samp{a} to make it clear that it is +not a typo; for example, @samp{[+-*/]} should be avoided, because it +matches only @samp{/} rather than the likely-intended four characters. +@end enumerate + +Some kinds of character alternatives are not the best style even +though they are standardized by POSIX and are portable. They include: +@enumerate @item -If the lower bound of a range is greater than its upper bound, the -range is empty and represents no characters. Thus, @samp{[b-a]} -always fails to match, and @samp{[^b-a]} matches any character, -including newline. However, the lower bound should be at most one -greater than the upper bound; for example, @samp{[c-a]} should be -avoided. +A character alternative can include duplicates. For example, +@samp{[XYa-yYb-zX]} is less clear than @samp{[XYa-z]}. + +@item +A range can denote just one, two, or three characters. For example, +@samp{[(-(]} is less clear than @samp{[(]}, @samp{[*-+]} is less clear +than @samp{[*+]}, and @samp{[*-,]} is less clear than @samp{[*+,]}. + +@item +A @samp{-} also appear at the beginning of a character alternative, or +as the upper bound of a range. For example, although @samp{[-a-z]} is +valid, @samp{[a-z-]} is better style; and although @samp{[!--/]} is +valid, @samp{[!-,/-]} is clearer. @end enumerate A character alternative can also specify named character classes @@ -452,7 +462,7 @@ of a range. @cindex @samp{^} in regexp @samp{[^} begins a @dfn{complemented character alternative}. This matches any character except the ones specified. Thus, -@samp{[^a-z0-9A-Z]} matches all characters @emph{except} letters and +@samp{[^a-z0-9A-Z]} matches all characters @emph{except} ASCII letters and digits. @samp{^} is not special in a character alternative unless it is the first commit f81ec28f4fc122658e59c0ec99ca4d92a1fe439f Merge: f5d3449612 0924b27bca Author: Paul Eggert Date: Mon Apr 1 23:43:57 2019 -0700 Merge from origin/emacs-26 0924b27bca Say which regexp ranges should be avoided # Conflicts: # doc/lispref/searching.texi commit f5d34496123ce6df53d50082159280da54f052c4 Merge: 03ceee0e64 297a141ca3 Author: Paul Eggert Date: Mon Apr 1 23:40:21 2019 -0700 ; Merge from origin/emacs-26 The following commit was skipped: 297a141ca3 ; * lisp/ldefs-boot.el: Update. commit 03ceee0e6403052f7367efe1159e3663402c8c1e Author: Eric Abrahamsen Date: Sun Mar 31 09:18:43 2019 -0700 Refactor Gnus group name extraction in group completing read * lisp/gnus/gnus-group.el (gnus-group-completing-read): Only do the unibyte check once; make sure it applies to hash table keys as well. diff --git a/lisp/gnus/gnus-group.el b/lisp/gnus/gnus-group.el index bd24c3f8da..0be3854174 100644 --- a/lisp/gnus/gnus-group.el +++ b/lisp/gnus/gnus-group.el @@ -2173,30 +2173,23 @@ Non-ASCII group names are allowed. The arguments are the same as they are omitted. Can handle COLLECTION as a list, hash table, or vector." (or collection (setq collection gnus-active-hashtb)) - (let (choices group) - (cond ((listp collection) - (if (symbolp (car collection)) - (dolist (symbol collection) - (setq group (symbol-name symbol)) - (push (if (string-match "[^\000-\177]" group) - (gnus-group-decoded-name group) - group) - choices)) - (setq choices collection))) - ((vectorp collection) - (mapatoms (lambda (symbol) - (setq group (symbol-name symbol)) - (push (if (string-match "[^\000-\177]" group) - (gnus-group-decoded-name group) - group) - choices)) - collection)) - ((hash-table-p collection) - (setq choices (hash-table-keys collection)))) - (setq group (gnus-completing-read (or prompt "Group") (reverse choices) - require-match initial-input - (or hist 'gnus-group-history) - def)) + (let* ((choices + (mapcar + (lambda (g) + (if (string-match "[^\000-\177]" g) + (gnus-group-decoded-name g) + g)) + (cond ((listp collection) + collection) + ((vectorp collection) + (mapatoms #'symbol-name collection)) + ((hash-table-p collection) + (hash-table-keys collection))))) + (group + (gnus-completing-read (or prompt "Group") (reverse choices) + require-match initial-input + (or hist 'gnus-group-history) + def))) (unless (cond ((and (listp collection) (symbolp (car collection))) (member group (mapcar 'symbol-name collection))) commit 74b63d27a629db96b73a83f205d8a256911abc1c Author: Paul Eggert Date: Mon Apr 1 11:54:23 2019 -0700 Make struct Lisp_Objfwd etc. objects read-only Initialize these objects statically, and make them constants. This is a bit safer and more efficient. * src/data.c (XBOOLFWD, XKBOARD_OBJFWD, XFIXNUMFWD, XOBJFWD): * src/lisp.h (XBUFFER_OBJFWD): Return a pointer-to-const instead of an unrestricted pointer. (lispfwd): fwdptr is now a pointer-to-const instead of an unrestricted pointer. All uses changed. (SET_SYMBOL_FWD): Accept pointer-to-const instead of an unrestricted pointer. (DEFVAR_LISP, DEFVAR_LISP_NOPRO, DEFVAR_BOOL, DEFVAR_INT) (DEFVAR_KBOARD): Initialize static structures statically instead of dynamically, and make them const. * src/lread.c (defvar_int, defvar_bool, defvar_lisp_nopro) (defvar_lisp, defvar_kboard): Accept pointer-to-const instead of an unrestricted pointer; it’s now the caller’s responsibility to initialize the pointed-to storage. No need for a separate address argument any more. All callers changed. diff --git a/src/data.c b/src/data.c index 936bb74f69..11cd598ed8 100644 --- a/src/data.c +++ b/src/data.c @@ -62,25 +62,25 @@ OBJFWDP (lispfwd a) return XFWDTYPE (a) == Lisp_Fwd_Obj; } -static struct Lisp_Boolfwd * +static struct Lisp_Boolfwd const * XBOOLFWD (lispfwd a) { eassert (BOOLFWDP (a)); return a.fwdptr; } -static struct Lisp_Kboard_Objfwd * +static struct Lisp_Kboard_Objfwd const * XKBOARD_OBJFWD (lispfwd a) { eassert (KBOARD_OBJFWDP (a)); return a.fwdptr; } -static struct Lisp_Intfwd * +static struct Lisp_Intfwd const * XFIXNUMFWD (lispfwd a) { eassert (INTFWDP (a)); return a.fwdptr; } -static struct Lisp_Objfwd * +static struct Lisp_Objfwd const * XOBJFWD (lispfwd a) { eassert (OBJFWDP (a)); diff --git a/src/lisp.h b/src/lisp.h index 62c3230a14..a0a7cbdf51 100644 --- a/src/lisp.h +++ b/src/lisp.h @@ -803,7 +803,7 @@ INLINE void union of the possible values (struct Lisp_Objfwd, struct Lisp_Intfwd, etc.). The pointer is packaged inside a struct to help static checking. */ -typedef struct { void *fwdptr; } lispfwd; +typedef struct { void const *fwdptr; } lispfwd; /* Interned state of a symbol. */ @@ -2204,7 +2204,7 @@ SET_SYMBOL_BLV (struct Lisp_Symbol *sym, struct Lisp_Buffer_Local_Value *v) sym->u.s.val.blv = v; } INLINE void -SET_SYMBOL_FWD (struct Lisp_Symbol *sym, void *v) +SET_SYMBOL_FWD (struct Lisp_Symbol *sym, void const *v) { eassume (sym->u.s.redirect == SYMBOL_FORWARDED && v); sym->u.s.val.fwd.fwdptr = v; @@ -2759,7 +2759,7 @@ struct Lisp_Kboard_Objfwd INLINE enum Lisp_Fwd_Type XFWDTYPE (lispfwd a) { - enum Lisp_Fwd_Type *p = a.fwdptr; + enum Lisp_Fwd_Type const *p = a.fwdptr; return *p; } @@ -2769,7 +2769,7 @@ BUFFER_OBJFWDP (lispfwd a) return XFWDTYPE (a) == Lisp_Fwd_Buffer_Obj; } -INLINE struct Lisp_Buffer_Objfwd * +INLINE struct Lisp_Buffer_Objfwd const * XBUFFER_OBJFWD (lispfwd a) { eassert (BUFFER_OBJFWDP (a)); @@ -3096,11 +3096,11 @@ enum maxargs CALLN is overkill for simple usages like 'Finsert (1, &text);'. */ #define CALLN(f, ...) CALLMANY (f, ((Lisp_Object []) {__VA_ARGS__})) -extern void defvar_lisp (struct Lisp_Objfwd *, const char *, Lisp_Object *); -extern void defvar_lisp_nopro (struct Lisp_Objfwd *, const char *, Lisp_Object *); -extern void defvar_bool (struct Lisp_Boolfwd *, const char *, bool *); -extern void defvar_int (struct Lisp_Intfwd *, const char *, intmax_t *); -extern void defvar_kboard (struct Lisp_Kboard_Objfwd *, const char *, int); +extern void defvar_lisp (struct Lisp_Objfwd const *, char const *); +extern void defvar_lisp_nopro (struct Lisp_Objfwd const *, char const *); +extern void defvar_bool (struct Lisp_Boolfwd const *, char const *); +extern void defvar_int (struct Lisp_Intfwd const *, char const *); +extern void defvar_kboard (struct Lisp_Kboard_Objfwd const *, char const *); /* Macros we use to define forwarded Lisp variables. These are used in the syms_of_FILENAME functions. @@ -3121,29 +3121,34 @@ extern void defvar_kboard (struct Lisp_Kboard_Objfwd *, const char *, int); #define DEFVAR_LISP(lname, vname, doc) \ do { \ - static struct Lisp_Objfwd o_fwd; \ - defvar_lisp (&o_fwd, lname, &globals.f_ ## vname); \ + static struct Lisp_Objfwd const o_fwd \ + = {Lisp_Fwd_Obj, &globals.f_##vname}; \ + defvar_lisp (&o_fwd, lname); \ } while (false) #define DEFVAR_LISP_NOPRO(lname, vname, doc) \ do { \ - static struct Lisp_Objfwd o_fwd; \ - defvar_lisp_nopro (&o_fwd, lname, &globals.f_ ## vname); \ + static struct Lisp_Objfwd const o_fwd \ + = {Lisp_Fwd_Obj, &globals.f_##vname}; \ + defvar_lisp_nopro (&o_fwd, lname); \ } while (false) #define DEFVAR_BOOL(lname, vname, doc) \ do { \ - static struct Lisp_Boolfwd b_fwd; \ - defvar_bool (&b_fwd, lname, &globals.f_ ## vname); \ + static struct Lisp_Boolfwd const b_fwd \ + = {Lisp_Fwd_Bool, &globals.f_##vname}; \ + defvar_bool (&b_fwd, lname); \ } while (false) #define DEFVAR_INT(lname, vname, doc) \ do { \ - static struct Lisp_Intfwd i_fwd; \ - defvar_int (&i_fwd, lname, &globals.f_ ## vname); \ + static struct Lisp_Intfwd const i_fwd \ + = {Lisp_Fwd_Int, &globals.f_##vname}; \ + defvar_int (&i_fwd, lname); \ } while (false) #define DEFVAR_KBOARD(lname, vname, doc) \ do { \ - static struct Lisp_Kboard_Objfwd ko_fwd; \ - defvar_kboard (&ko_fwd, lname, offsetof (KBOARD, vname ## _)); \ + static struct Lisp_Kboard_Objfwd const ko_fwd \ + = {Lisp_Fwd_Kboard_Obj, offsetof (KBOARD, vname##_)}; \ + defvar_kboard (&ko_fwd, lname); \ } while (false) diff --git a/src/lread.c b/src/lread.c index dd35cf9063..5f33fcd695 100644 --- a/src/lread.c +++ b/src/lread.c @@ -4425,28 +4425,19 @@ defalias (struct Lisp_Subr *sname, char *string) C variable of type intmax_t. Sample call (with "xx" to fool make-docfile): DEFxxVAR_INT ("emacs-priority", &emacs_priority, "Documentation"); */ void -defvar_int (struct Lisp_Intfwd *i_fwd, - const char *namestring, intmax_t *address) +defvar_int (struct Lisp_Intfwd const *i_fwd, char const *namestring) { - Lisp_Object sym; - sym = intern_c_string (namestring); - i_fwd->type = Lisp_Fwd_Int; - i_fwd->intvar = address; + Lisp_Object sym = intern_c_string (namestring); XSYMBOL (sym)->u.s.declared_special = true; XSYMBOL (sym)->u.s.redirect = SYMBOL_FORWARDED; SET_SYMBOL_FWD (XSYMBOL (sym), i_fwd); } -/* Similar but define a variable whose value is t if address contains 1, - nil if address contains 0. */ +/* Similar but define a variable whose value is t if 1, nil if 0. */ void -defvar_bool (struct Lisp_Boolfwd *b_fwd, - const char *namestring, bool *address) +defvar_bool (struct Lisp_Boolfwd const *b_fwd, char const *namestring) { - Lisp_Object sym; - sym = intern_c_string (namestring); - b_fwd->type = Lisp_Fwd_Bool; - b_fwd->boolvar = address; + Lisp_Object sym = intern_c_string (namestring); XSYMBOL (sym)->u.s.declared_special = true; XSYMBOL (sym)->u.s.redirect = SYMBOL_FORWARDED; SET_SYMBOL_FWD (XSYMBOL (sym), b_fwd); @@ -4459,37 +4450,28 @@ defvar_bool (struct Lisp_Boolfwd *b_fwd, gc-marked for some other reason, since marking the same slot twice can cause trouble with strings. */ void -defvar_lisp_nopro (struct Lisp_Objfwd *o_fwd, - const char *namestring, Lisp_Object *address) +defvar_lisp_nopro (struct Lisp_Objfwd const *o_fwd, char const *namestring) { - Lisp_Object sym; - sym = intern_c_string (namestring); - o_fwd->type = Lisp_Fwd_Obj; - o_fwd->objvar = address; + Lisp_Object sym = intern_c_string (namestring); XSYMBOL (sym)->u.s.declared_special = true; XSYMBOL (sym)->u.s.redirect = SYMBOL_FORWARDED; SET_SYMBOL_FWD (XSYMBOL (sym), o_fwd); } void -defvar_lisp (struct Lisp_Objfwd *o_fwd, - const char *namestring, Lisp_Object *address) +defvar_lisp (struct Lisp_Objfwd const *o_fwd, char const *namestring) { - defvar_lisp_nopro (o_fwd, namestring, address); - staticpro (address); + defvar_lisp_nopro (o_fwd, namestring); + staticpro (o_fwd->objvar); } /* Similar but define a variable whose value is the Lisp Object stored at a particular offset in the current kboard object. */ void -defvar_kboard (struct Lisp_Kboard_Objfwd *ko_fwd, - const char *namestring, int offset) +defvar_kboard (struct Lisp_Kboard_Objfwd const *ko_fwd, char const *namestring) { - Lisp_Object sym; - sym = intern_c_string (namestring); - ko_fwd->type = Lisp_Fwd_Kboard_Obj; - ko_fwd->offset = offset; + Lisp_Object sym = intern_c_string (namestring); XSYMBOL (sym)->u.s.declared_special = true; XSYMBOL (sym)->u.s.redirect = SYMBOL_FORWARDED; SET_SYMBOL_FWD (XSYMBOL (sym), ko_fwd); commit 9287813da1ae9076f29be111674d1795bee66447 Author: Paul Eggert Date: Mon Apr 1 11:54:23 2019 -0700 Fix union Lisp_Fwd * alignment bug It's not portable to cast (e.g.) struct Lisp_Objfwd * to union Lisp_Fwd * and then back again, because the compiler can then assume that the pointer is aligned for union Lisp_Fwd * when accessing the struct Lisp_Objfwd * components, and this assumption might be incorrect becase we don't force that alignment. * src/lisp.h (lispfwd): New type, replacing ... (union Lisp_Fwd): ... this type, which was removed. All uses changed. (SET_SYMBOL_FWD): 2nd arg is now void *, not lispfwd. All uses changed (casts no longer needed; they were not portable anyway). diff --git a/src/buffer.c b/src/buffer.c index 7c4691e52c..c0f7521c9e 100644 --- a/src/buffer.c +++ b/src/buffer.c @@ -1207,7 +1207,7 @@ buffer_local_value (Lisp_Object variable, Lisp_Object buffer) result = Fassoc (variable, BVAR (buf, local_var_alist), Qnil); if (!NILP (result)) { - if (blv->fwd) + if (blv->fwd.fwdptr) { /* What binding is loaded right now? */ Lisp_Object current_alist_element = blv->valcell; @@ -1228,7 +1228,7 @@ buffer_local_value (Lisp_Object variable, Lisp_Object buffer) } case SYMBOL_FORWARDED: { - union Lisp_Fwd *fwd = SYMBOL_FWD (sym); + lispfwd fwd = SYMBOL_FWD (sym); if (BUFFER_OBJFWDP (fwd)) result = per_buffer_value (buf, XBUFFER_OBJFWD (fwd)->offset); else @@ -2140,7 +2140,7 @@ void set_buffer_internal_2 (register struct buffer *b) Lisp_Object var = XCAR (XCAR (tail)); struct Lisp_Symbol *sym = XSYMBOL (var); if (sym->u.s.redirect == SYMBOL_LOCALIZED /* Just to be sure. */ - && SYMBOL_BLV (sym)->fwd) + && SYMBOL_BLV (sym)->fwd.fwdptr) /* Just reference the variable to cause it to become set for this buffer. */ Fsymbol_value (var); @@ -5444,7 +5444,7 @@ defvar_per_buffer (struct Lisp_Buffer_Objfwd *bo_fwd, const char *namestring, bo_fwd->predicate = predicate; sym->u.s.declared_special = true; sym->u.s.redirect = SYMBOL_FORWARDED; - SET_SYMBOL_FWD (sym, (union Lisp_Fwd *) bo_fwd); + SET_SYMBOL_FWD (sym, bo_fwd); XSETSYMBOL (PER_BUFFER_SYMBOL (offset), sym); if (PER_BUFFER_IDX (offset) == 0) diff --git a/src/data.c b/src/data.c index 30c578dee9..936bb74f69 100644 --- a/src/data.c +++ b/src/data.c @@ -42,49 +42,49 @@ static void swap_in_symval_forwarding (struct Lisp_Symbol *, struct Lisp_Buffer_Local_Value *); static bool -BOOLFWDP (union Lisp_Fwd *a) +BOOLFWDP (lispfwd a) { return XFWDTYPE (a) == Lisp_Fwd_Bool; } static bool -INTFWDP (union Lisp_Fwd *a) +INTFWDP (lispfwd a) { return XFWDTYPE (a) == Lisp_Fwd_Int; } static bool -KBOARD_OBJFWDP (union Lisp_Fwd *a) +KBOARD_OBJFWDP (lispfwd a) { return XFWDTYPE (a) == Lisp_Fwd_Kboard_Obj; } static bool -OBJFWDP (union Lisp_Fwd *a) +OBJFWDP (lispfwd a) { return XFWDTYPE (a) == Lisp_Fwd_Obj; } static struct Lisp_Boolfwd * -XBOOLFWD (union Lisp_Fwd *a) +XBOOLFWD (lispfwd a) { eassert (BOOLFWDP (a)); - return &a->u_boolfwd; + return a.fwdptr; } static struct Lisp_Kboard_Objfwd * -XKBOARD_OBJFWD (union Lisp_Fwd *a) +XKBOARD_OBJFWD (lispfwd a) { eassert (KBOARD_OBJFWDP (a)); - return &a->u_kboard_objfwd; + return a.fwdptr; } static struct Lisp_Intfwd * -XFIXNUMFWD (union Lisp_Fwd *a) +XFIXNUMFWD (lispfwd a) { eassert (INTFWDP (a)); - return &a->u_intfwd; + return a.fwdptr; } static struct Lisp_Objfwd * -XOBJFWD (union Lisp_Fwd *a) +XOBJFWD (lispfwd a) { eassert (OBJFWDP (a)); - return &a->u_objfwd; + return a.fwdptr; } static void @@ -669,7 +669,7 @@ global value outside of any lexical scope. */) case SYMBOL_LOCALIZED: { struct Lisp_Buffer_Local_Value *blv = SYMBOL_BLV (sym); - if (blv->fwd) + if (blv->fwd.fwdptr) /* In set_internal, we un-forward vars when their value is set to Qunbound. */ return Qt; @@ -980,7 +980,7 @@ chain of aliases, signal a `cyclic-variable-indirection' error. */) swap_in_symval_forwarding for that. */ Lisp_Object -do_symval_forwarding (union Lisp_Fwd *valcontents) +do_symval_forwarding (lispfwd valcontents) { switch (XFWDTYPE (valcontents)) { @@ -1071,7 +1071,8 @@ wrong_range (Lisp_Object min, Lisp_Object max, Lisp_Object wrong) current buffer. This only plays a role for per-buffer variables. */ static void -store_symval_forwarding (union Lisp_Fwd *valcontents, register Lisp_Object newval, struct buffer *buf) +store_symval_forwarding (lispfwd valcontents, Lisp_Object newval, + struct buffer *buf) { switch (XFWDTYPE (valcontents)) { @@ -1178,12 +1179,12 @@ swap_in_global_binding (struct Lisp_Symbol *symbol) struct Lisp_Buffer_Local_Value *blv = SYMBOL_BLV (symbol); /* Unload the previously loaded binding. */ - if (blv->fwd) + if (blv->fwd.fwdptr) set_blv_value (blv, do_symval_forwarding (blv->fwd)); /* Select the global binding in the symbol. */ set_blv_valcell (blv, blv->defcell); - if (blv->fwd) + if (blv->fwd.fwdptr) store_symval_forwarding (blv->fwd, XCDR (blv->defcell), NULL); /* Indicate that the global binding is set up now. */ @@ -1213,7 +1214,7 @@ swap_in_symval_forwarding (struct Lisp_Symbol *symbol, struct Lisp_Buffer_Local_ /* Unload the previously loaded binding. */ tem1 = blv->valcell; - if (blv->fwd) + if (blv->fwd.fwdptr) set_blv_value (blv, do_symval_forwarding (blv->fwd)); /* Choose the new binding. */ { @@ -1227,7 +1228,7 @@ swap_in_symval_forwarding (struct Lisp_Symbol *symbol, struct Lisp_Buffer_Local_ /* Load the new binding. */ set_blv_valcell (blv, tem1); - if (blv->fwd) + if (blv->fwd.fwdptr) store_symval_forwarding (blv->fwd, blv_value (blv), NULL); } } @@ -1255,7 +1256,9 @@ find_symbol_value (Lisp_Object symbol) { struct Lisp_Buffer_Local_Value *blv = SYMBOL_BLV (sym); swap_in_symval_forwarding (sym, blv); - return blv->fwd ? do_symval_forwarding (blv->fwd) : blv_value (blv); + return (blv->fwd.fwdptr + ? do_symval_forwarding (blv->fwd) + : blv_value (blv)); } case SYMBOL_FORWARDED: return do_symval_forwarding (SYMBOL_FWD (sym)); @@ -1357,7 +1360,7 @@ set_internal (Lisp_Object symbol, Lisp_Object newval, Lisp_Object where, We need to unload it, and choose a new binding. */ /* Write out `realvalue' to the old loaded binding. */ - if (blv->fwd) + if (blv->fwd.fwdptr) set_blv_value (blv, do_symval_forwarding (blv->fwd)); /* Find the new binding. */ @@ -1404,12 +1407,12 @@ set_internal (Lisp_Object symbol, Lisp_Object newval, Lisp_Object where, /* Store the new value in the cons cell. */ set_blv_value (blv, newval); - if (blv->fwd) + if (blv->fwd.fwdptr) { if (voide) /* If storing void (making the symbol void), forward only through buffer-local indicator, not through Lisp_Objfwd, etc. */ - blv->fwd = NULL; + blv->fwd.fwdptr = NULL; else store_symval_forwarding (blv->fwd, newval, BUFFERP (where) @@ -1421,7 +1424,7 @@ set_internal (Lisp_Object symbol, Lisp_Object newval, Lisp_Object where, { struct buffer *buf = BUFFERP (where) ? XBUFFER (where) : current_buffer; - union Lisp_Fwd *innercontents = SYMBOL_FWD (sym); + lispfwd innercontents = SYMBOL_FWD (sym); if (BUFFER_OBJFWDP (innercontents)) { int offset = XBUFFER_OBJFWD (innercontents)->offset; @@ -1593,14 +1596,14 @@ default_value (Lisp_Object symbol) But the `realvalue' slot may be more up to date, since ordinary setq stores just that slot. So use that. */ struct Lisp_Buffer_Local_Value *blv = SYMBOL_BLV (sym); - if (blv->fwd && EQ (blv->valcell, blv->defcell)) + if (blv->fwd.fwdptr && EQ (blv->valcell, blv->defcell)) return do_symval_forwarding (blv->fwd); else return XCDR (blv->defcell); } case SYMBOL_FORWARDED: { - union Lisp_Fwd *valcontents = SYMBOL_FWD (sym); + lispfwd valcontents = SYMBOL_FWD (sym); /* For a built-in buffer-local variable, get the default value rather than letting do_symval_forwarding get the current value. */ @@ -1688,13 +1691,13 @@ set_default_internal (Lisp_Object symbol, Lisp_Object value, XSETCDR (blv->defcell, value); /* If the default binding is now loaded, set the REALVALUE slot too. */ - if (blv->fwd && EQ (blv->defcell, blv->valcell)) + if (blv->fwd.fwdptr && EQ (blv->defcell, blv->valcell)) store_symval_forwarding (blv->fwd, value, NULL); return; } case SYMBOL_FORWARDED: { - union Lisp_Fwd *valcontents = SYMBOL_FWD (sym); + lispfwd valcontents = SYMBOL_FWD (sym); /* Handle variables like case-fold-search that have special slots in the buffer. @@ -1750,7 +1753,7 @@ for this variable. */) union Lisp_Val_Fwd { Lisp_Object value; - union Lisp_Fwd *fwd; + lispfwd fwd; }; static struct Lisp_Buffer_Local_Value * @@ -1770,7 +1773,10 @@ make_blv (struct Lisp_Symbol *sym, bool forwarded, or keyboard-local forwarding. */ eassert (!(forwarded && BUFFER_OBJFWDP (valcontents.fwd))); eassert (!(forwarded && KBOARD_OBJFWDP (valcontents.fwd))); - blv->fwd = forwarded ? valcontents.fwd : NULL; + if (forwarded) + blv->fwd = valcontents.fwd; + else + blv->fwd.fwdptr = NULL; set_blv_where (blv, Qnil); blv->local_if_set = 0; set_blv_defcell (blv, tem); @@ -1941,7 +1947,7 @@ Instead, use `add-hook' and specify t for the LOCAL argument. */) Otherwise, if C code modifies the variable before we load the binding in, then that new value would clobber the default binding the next time we unload it. See bug#34318. */ - if (blv->fwd) + if (blv->fwd.fwdptr) swap_in_symval_forwarding (sym, blv); } @@ -1968,7 +1974,7 @@ From now on the default value will apply in this buffer. Return VARIABLE. */) case SYMBOL_PLAINVAL: return variable; case SYMBOL_FORWARDED: { - union Lisp_Fwd *valcontents = SYMBOL_FWD (sym); + lispfwd valcontents = SYMBOL_FWD (sym); if (BUFFER_OBJFWDP (valcontents)) { int offset = XBUFFER_OBJFWD (valcontents)->offset; @@ -2051,7 +2057,7 @@ BUFFER defaults to the current buffer. */) } case SYMBOL_FORWARDED: { - union Lisp_Fwd *valcontents = SYMBOL_FWD (sym); + lispfwd valcontents = SYMBOL_FWD (sym); if (BUFFER_OBJFWDP (valcontents)) { int offset = XBUFFER_OBJFWD (valcontents)->offset; @@ -2122,7 +2128,7 @@ If the current binding is global (the default), the value is nil. */) case SYMBOL_PLAINVAL: return Qnil; case SYMBOL_FORWARDED: { - union Lisp_Fwd *valcontents = SYMBOL_FWD (sym); + lispfwd valcontents = SYMBOL_FWD (sym); if (KBOARD_OBJFWDP (valcontents)) return Fframe_terminal (selected_frame); else if (!BUFFER_OBJFWDP (valcontents)) diff --git a/src/lisp.h b/src/lisp.h index 178eebed2a..62c3230a14 100644 --- a/src/lisp.h +++ b/src/lisp.h @@ -797,6 +797,13 @@ INLINE void #define XUNTAG(a, type, ctype) ((ctype *) \ ((char *) XLP (a) - LISP_WORD_TAG (type))) + +/* A forwarding pointer to a value. It uses a generic pointer to + avoid alignment bugs that could occur if it used a pointer to a + union of the possible values (struct Lisp_Objfwd, struct + Lisp_Intfwd, etc.). The pointer is packaged inside a struct to + help static checking. */ +typedef struct { void *fwdptr; } lispfwd; /* Interned state of a symbol. */ @@ -862,7 +869,7 @@ struct Lisp_Symbol Lisp_Object value; struct Lisp_Symbol *alias; struct Lisp_Buffer_Local_Value *blv; - union Lisp_Fwd *fwd; + lispfwd fwd; } val; /* Function value of the symbol or Qnil if not fboundp. */ @@ -2171,10 +2178,10 @@ SYMBOL_BLV (struct Lisp_Symbol *sym) eassume (sym->u.s.redirect == SYMBOL_LOCALIZED && sym->u.s.val.blv); return sym->u.s.val.blv; } -INLINE union Lisp_Fwd * +INLINE lispfwd SYMBOL_FWD (struct Lisp_Symbol *sym) { - eassume (sym->u.s.redirect == SYMBOL_FORWARDED && sym->u.s.val.fwd); + eassume (sym->u.s.redirect == SYMBOL_FORWARDED && sym->u.s.val.fwd.fwdptr); return sym->u.s.val.fwd; } @@ -2197,10 +2204,10 @@ SET_SYMBOL_BLV (struct Lisp_Symbol *sym, struct Lisp_Buffer_Local_Value *v) sym->u.s.val.blv = v; } INLINE void -SET_SYMBOL_FWD (struct Lisp_Symbol *sym, union Lisp_Fwd *v) +SET_SYMBOL_FWD (struct Lisp_Symbol *sym, void *v) { eassume (sym->u.s.redirect == SYMBOL_FORWARDED && v); - sym->u.s.val.fwd = v; + sym->u.s.val.fwd.fwdptr = v; } INLINE Lisp_Object @@ -2727,7 +2734,7 @@ struct Lisp_Buffer_Local_Value Presumably equivalent to (defcell!=valcell). */ bool_bf found : 1; /* If non-NULL, a forwarding to the C var where it should also be set. */ - union Lisp_Fwd *fwd; /* Should never be (Buffer|Kboard)_Objfwd. */ + lispfwd fwd; /* Should never be (Buffer|Kboard)_Objfwd. */ /* The buffer for which the loaded binding was found. */ Lisp_Object where; /* A cons cell that holds the default value. It has the form @@ -2749,32 +2756,24 @@ struct Lisp_Kboard_Objfwd int offset; }; -union Lisp_Fwd - { - struct Lisp_Intfwd u_intfwd; - struct Lisp_Boolfwd u_boolfwd; - struct Lisp_Objfwd u_objfwd; - struct Lisp_Buffer_Objfwd u_buffer_objfwd; - struct Lisp_Kboard_Objfwd u_kboard_objfwd; - }; - INLINE enum Lisp_Fwd_Type -XFWDTYPE (union Lisp_Fwd *a) +XFWDTYPE (lispfwd a) { - return a->u_intfwd.type; + enum Lisp_Fwd_Type *p = a.fwdptr; + return *p; } INLINE bool -BUFFER_OBJFWDP (union Lisp_Fwd *a) +BUFFER_OBJFWDP (lispfwd a) { return XFWDTYPE (a) == Lisp_Fwd_Buffer_Obj; } INLINE struct Lisp_Buffer_Objfwd * -XBUFFER_OBJFWD (union Lisp_Fwd *a) +XBUFFER_OBJFWD (lispfwd a) { eassert (BUFFER_OBJFWDP (a)); - return &a->u_buffer_objfwd; + return a.fwdptr; } /* Lisp floating point type. */ @@ -3552,7 +3551,7 @@ extern _Noreturn void args_out_of_range (Lisp_Object, Lisp_Object); extern _Noreturn void args_out_of_range_3 (Lisp_Object, Lisp_Object, Lisp_Object); extern _Noreturn void circular_list (Lisp_Object); -extern Lisp_Object do_symval_forwarding (union Lisp_Fwd *); +extern Lisp_Object do_symval_forwarding (lispfwd); enum Set_Internal_Bind { SET_INTERNAL_SET, SET_INTERNAL_BIND, diff --git a/src/lread.c b/src/lread.c index 2d64b638ff..dd35cf9063 100644 --- a/src/lread.c +++ b/src/lread.c @@ -4434,7 +4434,7 @@ defvar_int (struct Lisp_Intfwd *i_fwd, i_fwd->intvar = address; XSYMBOL (sym)->u.s.declared_special = true; XSYMBOL (sym)->u.s.redirect = SYMBOL_FORWARDED; - SET_SYMBOL_FWD (XSYMBOL (sym), (union Lisp_Fwd *)i_fwd); + SET_SYMBOL_FWD (XSYMBOL (sym), i_fwd); } /* Similar but define a variable whose value is t if address contains 1, @@ -4449,7 +4449,7 @@ defvar_bool (struct Lisp_Boolfwd *b_fwd, b_fwd->boolvar = address; XSYMBOL (sym)->u.s.declared_special = true; XSYMBOL (sym)->u.s.redirect = SYMBOL_FORWARDED; - SET_SYMBOL_FWD (XSYMBOL (sym), (union Lisp_Fwd *)b_fwd); + SET_SYMBOL_FWD (XSYMBOL (sym), b_fwd); Vbyte_boolean_vars = Fcons (sym, Vbyte_boolean_vars); } @@ -4468,7 +4468,7 @@ defvar_lisp_nopro (struct Lisp_Objfwd *o_fwd, o_fwd->objvar = address; XSYMBOL (sym)->u.s.declared_special = true; XSYMBOL (sym)->u.s.redirect = SYMBOL_FORWARDED; - SET_SYMBOL_FWD (XSYMBOL (sym), (union Lisp_Fwd *)o_fwd); + SET_SYMBOL_FWD (XSYMBOL (sym), o_fwd); } void @@ -4492,7 +4492,7 @@ defvar_kboard (struct Lisp_Kboard_Objfwd *ko_fwd, ko_fwd->offset = offset; XSYMBOL (sym)->u.s.declared_special = true; XSYMBOL (sym)->u.s.redirect = SYMBOL_FORWARDED; - SET_SYMBOL_FWD (XSYMBOL (sym), (union Lisp_Fwd *)ko_fwd); + SET_SYMBOL_FWD (XSYMBOL (sym), ko_fwd); } /* Check that the elements of lpath exist. */ diff --git a/src/pdumper.c b/src/pdumper.c index a9b3732a2d..53a10b62b3 100644 --- a/src/pdumper.c +++ b/src/pdumper.c @@ -2334,32 +2334,30 @@ dump_fwd_kboard_obj (struct dump_context *ctx, } static dump_off -dump_fwd (struct dump_context *ctx, union Lisp_Fwd *fwd) +dump_fwd (struct dump_context *ctx, lispfwd fwd) { -#if CHECK_STRUCTS && !defined (HASH_Lisp_Fwd_5227B18E87) -# error "Lisp_Fwd changed. See CHECK_STRUCTS comment." -#endif #if CHECK_STRUCTS && !defined (HASH_Lisp_Fwd_Type_9CBA6EE55E) # error "Lisp_Fwd_Type changed. See CHECK_STRUCTS comment." #endif + void const *p = fwd.fwdptr; dump_off offset; switch (XFWDTYPE (fwd)) { case Lisp_Fwd_Int: - offset = dump_fwd_int (ctx, &fwd->u_intfwd); + offset = dump_fwd_int (ctx, p); break; case Lisp_Fwd_Bool: - offset = dump_fwd_bool (ctx, &fwd->u_boolfwd); + offset = dump_fwd_bool (ctx, p); break; case Lisp_Fwd_Obj: - offset = dump_fwd_obj (ctx, &fwd->u_objfwd); + offset = dump_fwd_obj (ctx, p); break; case Lisp_Fwd_Buffer_Obj: - offset = dump_fwd_buffer_obj (ctx, &fwd->u_buffer_objfwd); + offset = dump_fwd_buffer_obj (ctx, p); break; case Lisp_Fwd_Kboard_Obj: - offset = dump_fwd_kboard_obj (ctx, &fwd->u_kboard_objfwd); + offset = dump_fwd_kboard_obj (ctx, p); break; default: emacs_abort (); @@ -2372,20 +2370,20 @@ static dump_off dump_blv (struct dump_context *ctx, const struct Lisp_Buffer_Local_Value *blv) { -#if CHECK_STRUCTS && !defined (HASH_Lisp_Buffer_Local_Value_066F33A92E) +#if CHECK_STRUCTS && !defined HASH_Lisp_Buffer_Local_Value_3C363FAC3C # error "Lisp_Buffer_Local_Value changed. See CHECK_STRUCTS comment." #endif struct Lisp_Buffer_Local_Value out; dump_object_start (ctx, &out, sizeof (out)); DUMP_FIELD_COPY (&out, blv, local_if_set); DUMP_FIELD_COPY (&out, blv, found); - if (blv->fwd) - dump_field_fixup_later (ctx, &out, blv, &blv->fwd); + if (blv->fwd.fwdptr) + dump_field_fixup_later (ctx, &out, blv, &blv->fwd.fwdptr); dump_field_lv (ctx, &out, blv, &blv->where, WEIGHT_NORMAL); dump_field_lv (ctx, &out, blv, &blv->defcell, WEIGHT_STRONG); dump_field_lv (ctx, &out, blv, &blv->valcell, WEIGHT_STRONG); dump_off offset = dump_object_finish (ctx, &out, sizeof (out)); - if (blv->fwd) + if (blv->fwd.fwdptr) dump_remember_fixup_ptr_raw (ctx, offset + dump_offsetof (struct Lisp_Buffer_Local_Value, fwd), @@ -2437,7 +2435,7 @@ dump_symbol (struct dump_context *ctx, Lisp_Object object, dump_off offset) { -#if CHECK_STRUCTS && !defined (HASH_Lisp_Symbol_60EA1E748E) +#if CHECK_STRUCTS && !defined HASH_Lisp_Symbol_999DC26DEC # error "Lisp_Symbol changed. See CHECK_STRUCTS comment." #endif #if CHECK_STRUCTS && !defined (HASH_symbol_redirect_ADB4F5B113) commit 197fbfc71f49b307baa3831a30732c3a0c4c7420 Author: Stefan Monnier Date: Mon Apr 1 12:35:10 2019 -0400 * lisp/subr.el (setq-default): Define as a macro * lisp/emacs-lisp/bytecomp.el (byte-compile-setq-default): Delete. (byte-compile-set-default): Inline the part that it used. * lisp/emacs-lisp/edebug.el (setq-default): Remove the debug spec. * src/data.c (Fsetq_default): Delete. (syms_of_data): Don't register. diff --git a/lisp/abbrev.el b/lisp/abbrev.el index 855d80cbd5..3c88ec661a 100644 --- a/lisp/abbrev.el +++ b/lisp/abbrev.el @@ -940,8 +940,7 @@ If READABLE is nil, an expression is inserted. The expression is a call to `define-abbrev-table' that when evaluated will define the abbrev table NAME exactly as it is currently defined. Abbrevs marked as \"system abbrevs\" are ignored." - (let ((table (symbol-value name)) - (symbols (abbrev--table-symbols name readable))) + (let ((symbols (abbrev--table-symbols name readable))) (setq symbols (sort symbols 'string-lessp)) (let ((standard-output (current-buffer))) (if readable diff --git a/lisp/emacs-lisp/bytecomp.el b/lisp/emacs-lisp/bytecomp.el index 66b40a8a1c..9dd5151963 100644 --- a/lisp/emacs-lisp/bytecomp.el +++ b/lisp/emacs-lisp/bytecomp.el @@ -3910,7 +3910,6 @@ discarding." (byte-defop-compiler-1 setq) -(byte-defop-compiler-1 setq-default) (byte-defop-compiler-1 quote) (defun byte-compile-setq (form) @@ -3935,34 +3934,20 @@ discarding." (byte-compile-form nil byte-compile--for-effect))) (setq byte-compile--for-effect nil))) -(defun byte-compile-setq-default (form) - (setq form (cdr form)) - (if (null form) ; (setq-default), with no arguments - (byte-compile-form nil byte-compile--for-effect) - (if (> (length form) 2) - (let ((setters ())) - (while (consp form) - (push `(setq-default ,(pop form) ,(pop form)) setters)) - (byte-compile-form (cons 'progn (nreverse setters)))) - (let ((var (car form))) - (and (or (not (symbolp var)) - (macroexp--const-symbol-p var t)) - (byte-compile-warning-enabled-p 'constants) - (byte-compile-warn - "variable assignment to %s `%s'" - (if (symbolp var) "constant" "nonvariable") - (prin1-to-string var))) - (byte-compile-normal-call `(set-default ',var ,@(cdr form))))))) - (byte-defop-compiler-1 set-default) (defun byte-compile-set-default (form) (let ((varexp (car-safe (cdr-safe form)))) (if (eq (car-safe varexp) 'quote) - ;; If the varexp is constant, compile it as a setq-default - ;; so we get more warnings. - (byte-compile-setq-default `(setq-default ,(car-safe (cdr varexp)) - ,@(cddr form))) - (byte-compile-normal-call form)))) + ;; If the varexp is constant, check the var's name. + (let ((var (car-safe (cdr varexp)))) + (and (or (not (symbolp var)) + (macroexp--const-symbol-p var t)) + (byte-compile-warning-enabled-p 'constants) + (byte-compile-warn + "variable assignment to %s `%s'" + (if (symbolp var) "constant" "nonvariable") + (prin1-to-string var))))) + (byte-compile-normal-call form))) (defun byte-compile-quote (form) (byte-compile-constant (car (cdr form)))) diff --git a/lisp/emacs-lisp/edebug.el b/lisp/emacs-lisp/edebug.el index 8b4cb1adc7..6dfcc24493 100644 --- a/lisp/emacs-lisp/edebug.el +++ b/lisp/emacs-lisp/edebug.el @@ -2165,7 +2165,6 @@ into `edebug--cl-macrolet-defs' which is checked in `edebug-list-form-args'." (def-edebug-spec let* let) (def-edebug-spec setq (&rest symbolp form)) -(def-edebug-spec setq-default setq) (def-edebug-spec cond (&rest (&rest form))) diff --git a/lisp/subr.el b/lisp/subr.el index f1a1dddd81..6a9492a3a7 100644 --- a/lisp/subr.el +++ b/lisp/subr.el @@ -118,6 +118,26 @@ BODY should be a list of Lisp expressions. ;; depend on backquote.el. (list 'function (cons 'lambda cdr))) +(defmacro setq-default (&rest args) + "Set the default value of variable VAR to VALUE. +VAR, the variable name, is literal (not evaluated); +VALUE is an expression: it is evaluated and its value returned. +The default value of a variable is seen in buffers +that do not have their own values for the variable. + +More generally, you can use multiple variables and values, as in + (setq-default VAR VALUE VAR VALUE...) +This sets each VAR's default value to the corresponding VALUE. +The VALUE for the Nth VAR can refer to the new default values +of previous VARs. + +\(setq-default [VAR VALUE]...)" + (declare (debug setq)) + (let ((exps nil)) + (while args + (push `(set-default ',(pop args) ,(pop args)) exps)) + `(progn . ,(nreverse exps)))) + (defmacro setq-local (var val) "Set variable VAR to value VAL in current buffer." ;; Can't use backquote here, it's too early in the bootstrap. diff --git a/src/data.c b/src/data.c index 15b6106cfe..30c578dee9 100644 --- a/src/data.c +++ b/src/data.c @@ -1744,36 +1744,6 @@ for this variable. */) set_default_internal (symbol, value, SET_INTERNAL_SET); return value; } - -DEFUN ("setq-default", Fsetq_default, Ssetq_default, 0, UNEVALLED, 0, - doc: /* Set the default value of variable VAR to VALUE. -VAR, the variable name, is literal (not evaluated); -VALUE is an expression: it is evaluated and its value returned. -The default value of a variable is seen in buffers -that do not have their own values for the variable. - -More generally, you can use multiple variables and values, as in - (setq-default VAR VALUE VAR VALUE...) -This sets each VAR's default value to the corresponding VALUE. -The VALUE for the Nth VAR can refer to the new default values -of previous VARs. -usage: (setq-default [VAR VALUE]...) */) - (Lisp_Object args) -{ - Lisp_Object args_left, symbol, val; - - args_left = val = args; - - while (CONSP (args_left)) - { - val = eval_sub (Fcar (XCDR (args_left))); - symbol = XCAR (args_left); - Fset_default (symbol, val); - args_left = Fcdr (XCDR (args_left)); - } - - return val; -} /* Lisp functions for creating and removing buffer-local variables. */ @@ -4047,7 +4017,6 @@ syms_of_data (void) defsubr (&Sdefault_boundp); defsubr (&Sdefault_value); defsubr (&Sset_default); - defsubr (&Ssetq_default); defsubr (&Smake_variable_buffer_local); defsubr (&Smake_local_variable); defsubr (&Skill_local_variable); commit 20ef15fbe6d49b0bb8a1841dbe4665cf81a567d7 Author: Eli Zaretskii Date: Mon Apr 1 17:39:30 2019 +0300 Fix a typo in xterm.c and w32term.c * src/xterm.c (x_window_to_scroll_bar): * src/w32term.c (x_window_to_scroll_bar): Fix a typo. diff --git a/src/w32term.c b/src/w32term.c index 4d5f2e7c3c..7dbeda7a71 100644 --- a/src/w32term.c +++ b/src/w32term.c @@ -3690,7 +3690,7 @@ x_window_to_scroll_bar (Window window_id, int type) ! NILP (bar)); bar = XSCROLL_BAR (bar)->next) if (SCROLL_BAR_W32_WINDOW (XSCROLL_BAR (bar)) == window_id - && (type = 2 + && (type == 2 || (type == 1 && XSCROLL_BAR (bar)->horizontal) || (type == 0 && !XSCROLL_BAR (bar)->horizontal))) return XSCROLL_BAR (bar); diff --git a/src/xterm.c b/src/xterm.c index f90d6713b0..2f830afe61 100644 --- a/src/xterm.c +++ b/src/xterm.c @@ -5343,7 +5343,7 @@ x_window_to_scroll_bar (Display *display, Window window_id, int type) bar = XSCROLL_BAR (bar)->next) if (XSCROLL_BAR (bar)->x_window == window_id && FRAME_X_DISPLAY (XFRAME (frame)) == display - && (type = 2 + && (type == 2 || (type == 1 && XSCROLL_BAR (bar)->horizontal) || (type == 0 && !XSCROLL_BAR (bar)->horizontal))) return XSCROLL_BAR (bar); commit d5fdcccacaf0b60a1e4c908fba638ef6e234b5e8 Author: Glenn Morris Date: Mon Apr 1 07:37:57 2019 -0400 ; Auto-commit of loaddefs files. diff --git a/lisp/ldefs-boot.el b/lisp/ldefs-boot.el index 0e8e5f699b..ccf2cdc87e 100644 --- a/lisp/ldefs-boot.el +++ b/lisp/ldefs-boot.el @@ -14224,6 +14224,11 @@ Pop up a frame and enter GROUP. ;;;;;; 0 0 0)) ;;; Generated autoloads from gnus/gnus-icalendar.el +(autoload 'gnus-icalendar-mm-inline "gnus-icalendar" "\ + + +\(fn HANDLE)" nil nil) + (if (fboundp 'register-definition-prefixes) (register-definition-prefixes "gnus-icalendar" '("gnus-icalendar"))) ;;;*** @@ -26849,9 +26854,9 @@ This enforces rescanning the buffer on next use." nil nil) (autoload 'regexp-opt "regexp-opt" "\ Return a regexp to match a string in the list STRINGS. -Each string should be unique in STRINGS and should not contain -any regexps, quoted or not. Optional PAREN specifies how the -returned regexp is surrounded by grouping constructs. +Each member of STRINGS is treated as a fixed string, not as a regexp. +Optional PAREN specifies how the returned regexp is surrounded by +grouping constructs. If STRINGS is the empty list, the return value is a regexp that never matches anything. @@ -27908,6 +27913,7 @@ CHAR matches any character in SET .... SET may be a character or string. Ranges of characters can be specified as `A-Z' in strings. Ranges may also be specified as conses like `(?A . ?Z)'. + Reversed ranges like `Z-A' and `(?Z . ?A)' are not permitted. SET may also be the name of a character class: `digit', `control', `hex-digit', `blank', `graph', `print', `alnum', @@ -34621,16 +34627,16 @@ the arguments that would have been passed to OPERATION. (autoload 'url-copy-file "url-handlers" "\ Copy URL to NEWNAME. Both args must be strings. -Signals a `file-already-exists' error if file NEWNAME already exists, +Signal a `file-already-exists' error if file NEWNAME already exists, unless a third argument OK-IF-ALREADY-EXISTS is supplied and non-nil. A number as third arg means request confirmation if NEWNAME already exists. This is what happens in interactive use with M-x. Fourth arg KEEP-TIME non-nil means give the new file the same last-modified time as the old one. (This works on only some systems.) -Fifth arg PRESERVE-UID-GID is ignored. +Args PRESERVE-UID-GID and PRESERVE-PERMISSIONS are ignored. A prefix arg makes KEEP-TIME non-nil. -\(fn URL NEWNAME &optional OK-IF-ALREADY-EXISTS KEEP-TIME PRESERVE-UID-GID)" nil nil) +\(fn URL NEWNAME &optional OK-IF-ALREADY-EXISTS KEEP-TIME PRESERVE-UID-GID PRESERVE-PERMISSIONS)" nil nil) (autoload 'url-file-local-copy "url-handlers" "\ Copy URL into a temporary file on this machine. @@ -35321,6 +35327,12 @@ saving the buffer. \(fn &optional HISTORIC NOT-URGENT)" t nil) +(autoload 'vc-diff-mergebase "vc" "\ +Report diffs between the merge base of REV1 and REV2 revisions. +The merge base is a common ancestor between REV1 and REV2 revisions. + +\(fn FILES REV1 REV2)" t nil) + (autoload 'vc-version-ediff "vc" "\ Show differences between revisions of the fileset in the repository history using ediff. @@ -35449,6 +35461,12 @@ When called interactively with a prefix argument, prompt for REMOTE-LOCATION. \(fn &optional REMOTE-LOCATION)" t nil) +(autoload 'vc-log-mergebase "vc" "\ +Show a log of changes between the merge base of REV1 and REV2 revisions. +The merge base is a common ancestor between REV1 and REV2 revisions. + +\(fn FILES REV1 REV2)" t nil) + (autoload 'vc-region-history "vc" "\ Show the history of the region between FROM and TO. @@ -38153,37 +38171,36 @@ Zone out, completely." t nil) ;;;;;; "international/uni-digit.el" "international/uni-lowercase.el" ;;;;;; "international/uni-mirrored.el" "international/uni-name.el" ;;;;;; "international/uni-numeric.el" "international/uni-old-name.el" -;;;;;; "international/uni-special-lowercase.el" "international/uni-special-titlecase.el" -;;;;;; "international/uni-special-uppercase.el" "international/uni-titlecase.el" -;;;;;; "international/uni-uppercase.el" "isearch.el" "jit-lock.el" -;;;;;; "jka-cmpr-hook.el" "language/burmese.el" "language/cham.el" -;;;;;; "language/chinese.el" "language/cyrillic.el" "language/czech.el" -;;;;;; "language/english.el" "language/ethiopic.el" "language/european.el" -;;;;;; "language/georgian.el" "language/greek.el" "language/hebrew.el" -;;;;;; "language/indian.el" "language/japanese.el" "language/khmer.el" -;;;;;; "language/korean.el" "language/lao.el" "language/misc-lang.el" -;;;;;; "language/romanian.el" "language/sinhala.el" "language/slovak.el" -;;;;;; "language/tai-viet.el" "language/thai.el" "language/tibetan.el" -;;;;;; "language/utf-8-lang.el" "language/vietnamese.el" "ldefs-boot.el" -;;;;;; "leim/ja-dic/ja-dic.el" "leim/leim-list.el" "leim/quail/4Corner.el" -;;;;;; "leim/quail/ARRAY30.el" "leim/quail/CCDOSPY.el" "leim/quail/CTLau-b5.el" -;;;;;; "leim/quail/CTLau.el" "leim/quail/ECDICT.el" "leim/quail/ETZY.el" -;;;;;; "leim/quail/PY-b5.el" "leim/quail/PY.el" "leim/quail/Punct-b5.el" -;;;;;; "leim/quail/Punct.el" "leim/quail/QJ-b5.el" "leim/quail/QJ.el" -;;;;;; "leim/quail/SW.el" "leim/quail/TONEPY.el" "leim/quail/ZIRANMA.el" -;;;;;; "leim/quail/ZOZY.el" "leim/quail/arabic.el" "leim/quail/croatian.el" -;;;;;; "leim/quail/cyril-jis.el" "leim/quail/cyrillic.el" "leim/quail/czech.el" -;;;;;; "leim/quail/georgian.el" "leim/quail/greek.el" "leim/quail/hanja-jis.el" -;;;;;; "leim/quail/hanja.el" "leim/quail/hanja3.el" "leim/quail/hebrew.el" -;;;;;; "leim/quail/ipa-praat.el" "leim/quail/latin-alt.el" "leim/quail/latin-ltx.el" -;;;;;; "leim/quail/latin-post.el" "leim/quail/latin-pre.el" "leim/quail/persian.el" -;;;;;; "leim/quail/programmer-dvorak.el" "leim/quail/py-punct.el" -;;;;;; "leim/quail/pypunct-b5.el" "leim/quail/quick-b5.el" "leim/quail/quick-cns.el" -;;;;;; "leim/quail/rfc1345.el" "leim/quail/sgml-input.el" "leim/quail/slovak.el" -;;;;;; "leim/quail/symbol-ksc.el" "leim/quail/tamil-dvorak.el" "leim/quail/tsang-b5.el" -;;;;;; "leim/quail/tsang-cns.el" "leim/quail/vntelex.el" "leim/quail/vnvni.el" -;;;;;; "leim/quail/welsh.el" "loadup.el" "mail/blessmail.el" "mail/rmailedit.el" -;;;;;; "mail/rmailkwd.el" "mail/rmailmm.el" "mail/rmailmsc.el" "mail/rmailsort.el" +;;;;;; "international/uni-titlecase.el" "international/uni-uppercase.el" +;;;;;; "isearch.el" "jit-lock.el" "jka-cmpr-hook.el" "language/burmese.el" +;;;;;; "language/cham.el" "language/chinese.el" "language/cyrillic.el" +;;;;;; "language/czech.el" "language/english.el" "language/ethiopic.el" +;;;;;; "language/european.el" "language/georgian.el" "language/greek.el" +;;;;;; "language/hebrew.el" "language/indian.el" "language/japanese.el" +;;;;;; "language/khmer.el" "language/korean.el" "language/lao.el" +;;;;;; "language/misc-lang.el" "language/romanian.el" "language/sinhala.el" +;;;;;; "language/slovak.el" "language/tai-viet.el" "language/thai.el" +;;;;;; "language/tibetan.el" "language/utf-8-lang.el" "language/vietnamese.el" +;;;;;; "ldefs-boot.el" "leim/ja-dic/ja-dic.el" "leim/leim-list.el" +;;;;;; "leim/quail/4Corner.el" "leim/quail/ARRAY30.el" "leim/quail/CCDOSPY.el" +;;;;;; "leim/quail/CTLau-b5.el" "leim/quail/CTLau.el" "leim/quail/ECDICT.el" +;;;;;; "leim/quail/ETZY.el" "leim/quail/PY-b5.el" "leim/quail/PY.el" +;;;;;; "leim/quail/Punct-b5.el" "leim/quail/Punct.el" "leim/quail/QJ-b5.el" +;;;;;; "leim/quail/QJ.el" "leim/quail/SW.el" "leim/quail/TONEPY.el" +;;;;;; "leim/quail/ZIRANMA.el" "leim/quail/ZOZY.el" "leim/quail/arabic.el" +;;;;;; "leim/quail/croatian.el" "leim/quail/cyril-jis.el" "leim/quail/cyrillic.el" +;;;;;; "leim/quail/czech.el" "leim/quail/georgian.el" "leim/quail/greek.el" +;;;;;; "leim/quail/hanja-jis.el" "leim/quail/hanja.el" "leim/quail/hanja3.el" +;;;;;; "leim/quail/hebrew.el" "leim/quail/ipa-praat.el" "leim/quail/latin-alt.el" +;;;;;; "leim/quail/latin-ltx.el" "leim/quail/latin-post.el" "leim/quail/latin-pre.el" +;;;;;; "leim/quail/persian.el" "leim/quail/programmer-dvorak.el" +;;;;;; "leim/quail/py-punct.el" "leim/quail/pypunct-b5.el" "leim/quail/quick-b5.el" +;;;;;; "leim/quail/quick-cns.el" "leim/quail/rfc1345.el" "leim/quail/sami.el" +;;;;;; "leim/quail/sgml-input.el" "leim/quail/slovak.el" "leim/quail/symbol-ksc.el" +;;;;;; "leim/quail/tamil-dvorak.el" "leim/quail/tsang-b5.el" "leim/quail/tsang-cns.el" +;;;;;; "leim/quail/vntelex.el" "leim/quail/vnvni.el" "leim/quail/welsh.el" +;;;;;; "loadup.el" "mail/blessmail.el" "mail/rmailedit.el" "mail/rmailkwd.el" +;;;;;; "mail/rmailmm.el" "mail/rmailmsc.el" "mail/rmailsort.el" ;;;;;; "mail/rmailsum.el" "mail/undigest.el" "menu-bar.el" "mh-e/mh-gnus.el" ;;;;;; "mh-e/mh-loaddefs.el" "minibuffer.el" "mouse.el" "net/tramp-loaddefs.el" ;;;;;; "newcomment.el" "obarray.el" "org/ob-core.el" "org/ob-keys.el" commit 0924b27bca40d219e34529144ea04a581428f1f7 (refs/remotes/origin/emacs-26) Author: Paul Eggert Date: Wed Mar 20 14:43:30 2019 -0700 Say which regexp ranges should be avoided * doc/lispref/searching.texi (Regexp Special): Say that regular expressions like "[a-m-z]" and "[[:alpha:]-~]" should be avoided, for the same reason that regular expressions like "+" and "*" should be avoided: POSIX says their behavior is undefined, and they are confusing anyway. Also, explain better what happens when the bound of a range is a raw 8-bit byte; the old explanation appears to have been obsolete anyway. Finally, say that ranges like "[\u00FF-\xFF]" that mix non-ASCII characters and raw 8-bit bytes should be avoided, since it’s not clear what they should mean. diff --git a/doc/lispref/searching.texi b/doc/lispref/searching.texi index 7546863dde..0cf527b6ac 100644 --- a/doc/lispref/searching.texi +++ b/doc/lispref/searching.texi @@ -391,25 +391,18 @@ writing the starting and ending characters with a @samp{-} between them. Thus, @samp{[a-z]} matches any lower-case @acronym{ASCII} letter. Ranges may be intermixed freely with individual characters, as in @samp{[a-z$%.]}, which matches any lower case @acronym{ASCII} letter -or @samp{$}, @samp{%} or period. +or @samp{$}, @samp{%} or period. However, the ending character of one +range should not be the starting point of another one; for example, +@samp{[a-m-z]} should be avoided. -If @code{case-fold-search} is non-@code{nil}, @samp{[a-z]} also -matches upper-case letters. Note that a range like @samp{[a-z]} is -not affected by the locale's collation sequence, it always represents -a sequence in @acronym{ASCII} order. -@c This wasn't obvious to me, since, e.g., the grep manual "Character -@c Classes and Bracket Expressions" specifically notes the opposite -@c behavior. But by experiment Emacs seems unaffected by LC_COLLATE -@c in this regard. - -Note also that the usual regexp special characters are not special inside a +The usual regexp special characters are not special inside a character alternative. A completely different set of characters is special inside character alternatives: @samp{]}, @samp{-} and @samp{^}. To include a @samp{]} in a character alternative, you must make it the first character. For example, @samp{[]a]} matches @samp{]} or @samp{a}. To include a @samp{-}, write @samp{-} as the first or last character of -the character alternative, or put it after a range. Thus, @samp{[]-]} +the character alternative, or as the upper bound of a range. Thus, @samp{[]-]} matches both @samp{]} and @samp{-}. (As explained below, you cannot use @samp{\]} to include a @samp{]} inside a character alternative, since @samp{\} is not special there.) @@ -417,13 +410,34 @@ since @samp{\} is not special there.) To include @samp{^} in a character alternative, put it anywhere but at the beginning. -@c What if it starts with a multibyte and ends with a unibyte? -@c That doesn't seem to match anything...? -If a range starts with a unibyte character @var{c} and ends with a -multibyte character @var{c2}, the range is divided into two parts: one -spans the unibyte characters @samp{@var{c}..?\377}, the other the -multibyte characters @samp{@var{c1}..@var{c2}}, where @var{c1} is the -first character of the charset to which @var{c2} belongs. +The following aspects of ranges are specific to Emacs, in that POSIX +allows but does not require this behavior and programs other than +Emacs may behave differently: + +@enumerate +@item +If @code{case-fold-search} is non-@code{nil}, @samp{[a-z]} also +matches upper-case letters. + +@item +A range is not affected by the locale's collation sequence: it always +represents the set of characters with codepoints ranging between those +of its bounds, so that @samp{[a-z]} matches only ASCII letters, even +outside the C or POSIX locale. + +@item +As a special case, if either bound of a range is a raw 8-bit byte, the +other bound should be a unibyte character, and the range matches only +unibyte characters. + +@item +If the lower bound of a range is greater than its upper bound, the +range is empty and represents no characters. Thus, @samp{[b-a]} +always fails to match, and @samp{[^b-a]} matches any character, +including newline. However, the lower bound should be at most one +greater than the upper bound; for example, @samp{[c-a]} should be +avoided. +@end enumerate A character alternative can also specify named character classes (@pxref{Char Classes}). This is a POSIX feature. For example, @@ -431,6 +445,8 @@ A character alternative can also specify named character classes Using a character class is equivalent to mentioning each of the characters in that class; but the latter is not feasible in practice, since some classes include thousands of different characters. +A character class should not appear as the lower or upper bound +of a range. @item @samp{[^ @dots{} ]} @cindex @samp{^} in regexp commit 297a141ca33f7fb25c17ba0b6ed7834dfe111c48 Author: Nicolas Petton Date: Wed Mar 20 22:08:46 2019 +0100 ; * lisp/ldefs-boot.el: Update. diff --git a/lisp/ldefs-boot.el b/lisp/ldefs-boot.el index 49578a0465..3903463c8a 100644 --- a/lisp/ldefs-boot.el +++ b/lisp/ldefs-boot.el @@ -35338,16 +35338,16 @@ the arguments that would have been passed to OPERATION. (autoload 'url-copy-file "url-handlers" "\ Copy URL to NEWNAME. Both args must be strings. -Signals a `file-already-exists' error if file NEWNAME already exists, +Signal a `file-already-exists' error if file NEWNAME already exists, unless a third argument OK-IF-ALREADY-EXISTS is supplied and non-nil. A number as third arg means request confirmation if NEWNAME already exists. This is what happens in interactive use with M-x. Fourth arg KEEP-TIME non-nil means give the new file the same last-modified time as the old one. (This works on only some systems.) -Fifth arg PRESERVE-UID-GID is ignored. +Args PRESERVE-UID-GID and PRESERVE-PERMISSIONS are ignored. A prefix arg makes KEEP-TIME non-nil. -\(fn URL NEWNAME &optional OK-IF-ALREADY-EXISTS KEEP-TIME PRESERVE-UID-GID)" nil nil) +\(fn URL NEWNAME &optional OK-IF-ALREADY-EXISTS KEEP-TIME PRESERVE-UID-GID PRESERVE-PERMISSIONS)" nil nil) (autoload 'url-file-local-copy "url-handlers" "\ Copy URL into a temporary file on this machine.