commit 07ebcf1bd964ae64446c52fb5481e919ed577358 (HEAD, refs/remotes/origin/master) Author: Paul Eggert Date: Wed May 18 00:48:35 2016 -0700 ‘make check-declare’ now chatters less * etc/NEWS: Document this. * lisp/emacs-lisp/check-declare.el (check-declare-locate): Return relative names, not absolute. (check-declare-scan, check-declare-verify, check-declare-warn) (check-declare-file, check-declare-directory): Generate less chatter. Use relative file names rather than absolute. Don’t give up on computing a good file name for a diagnostic merely because the function name was bad. Make malformed declarations more noticeable. Don’t warn about "ext:..." declarations if check-declare-ext-errors is nil. (check-declare-errmsg): Remove. (check-declare-warn): New optional arg LINE. (check-declare-files): Put status into mode line rather than chattering. diff --git a/etc/NEWS b/etc/NEWS index a910eaf..d74e570 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -370,6 +370,10 @@ of curved quotes in format arguments to functions like 'message' and 'format-message'. In particular, when this variable's value is 'grave', all quotes in formats are output as-is. +** Functions like 'check-declare-file' and 'check-declare-directory' +now generate less chatter and more-compact diagnostics. The auxiliary +function 'check-declare-errmsg' has been removed. + * Lisp Changes in Emacs 25.2 diff --git a/lisp/emacs-lisp/check-declare.el b/lisp/emacs-lisp/check-declare.el index bc7b5ae..e1e756b 100644 --- a/lisp/emacs-lisp/check-declare.el +++ b/lisp/emacs-lisp/check-declare.el @@ -43,7 +43,7 @@ "Name of buffer used to display any `check-declare' warnings.") (defun check-declare-locate (file basefile) - "Return the full path of FILE. + "Return the relative name of FILE. Expands files with a \".c\" or \".m\" extension relative to the Emacs \"src/\" directory. Otherwise, `locate-library' searches for FILE. If that fails, expands FILE relative to BASEFILE's directory part. @@ -70,6 +70,7 @@ the result." (string-match "\\.el\\'" tfile)) tfile (concat tfile ".el"))))) + (setq file (file-relative-name file)) (if ext (concat "ext:" file) file))) @@ -80,49 +81,40 @@ where only the first two elements need be present. This claims that FNFILE defines FN, with ARGLIST. FILEONLY non-nil means only check that FNFILE exists, not that it defines FN. This is for function definitions that we don't know how to recognize (e.g. some macros)." - (let ((m (format "Scanning %s..." file)) - alist form len fn fnfile arglist fileonly) - (message "%s" m) + (let (alist) (with-temp-buffer (insert-file-contents file) ;; FIXME we could theoretically be inside a string. (while (re-search-forward "^[ \t]*\\((declare-function\\)[ \t\n]" nil t) - (goto-char (match-beginning 1)) - (if (and (setq form (ignore-errors (read (current-buffer)))) + (let ((pos (match-beginning 1))) + (goto-char pos) + (let ((form (ignore-errors (read (current-buffer)))) + len fn formfile fnfile arglist fileonly) + (if (and ;; Exclude element of byte-compile-initial-macro-environment. (or (listp (cdr form)) (setq form nil)) (> (setq len (length form)) 2) (< len 6) + (setq formfile (nth 2 form)) (symbolp (setq fn (cadr form))) (setq fn (symbol-name fn)) ; later we use as a search string - (stringp (setq fnfile (nth 2 form))) - (setq fnfile (check-declare-locate fnfile - (expand-file-name file))) + (stringp formfile) + (setq fnfile (check-declare-locate formfile file)) ;; Use t to distinguish unspecified arglist from empty one. (or (eq t (setq arglist (if (> len 3) (nth 3 form) t))) (listp arglist)) (symbolp (setq fileonly (nth 4 form)))) - (setq alist (cons (list fnfile fn arglist fileonly) alist)) - ;; FIXME make this more noticeable. - (if form (message "Malformed declaration for `%s'" (cadr form)))))) - (message "%sdone" m) + (setq alist (cons (list fnfile fn arglist fileonly) alist)) + (when form + (check-declare-warn file (or fn "unknown function") + (if (stringp formfile) formfile + "unknown file") + "Malformed declaration" + (line-number-at-pos pos)))))))) alist)) -(defun check-declare-errmsg (errlist &optional full) - "Return a string with the number of errors in ERRLIST, if any. -Normally just counts the number of elements in ERRLIST. -With optional argument FULL, sums the number of elements in each element." - (if errlist - (let ((l (length errlist))) - (when full - (setq l 0) - (dolist (e errlist) - (setq l (+ l (1- (length e)))))) - (format "%d problem%s found" l (if (= l 1) "" "s"))) - "OK")) - (autoload 'byte-compile-arglist-signature "bytecomp") (defgroup check-declare nil @@ -144,11 +136,9 @@ to only check that FNFILE exists, not that it actually defines FN. Returns nil if all claims are found to be true, otherwise a list of errors with elements of the form \(FILE FN TYPE), where TYPE is a string giving details of the error." - (let ((m (format "Checking %s..." fnfile)) - (cflag (member (file-name-extension fnfile) '("c" "m"))) + (let ((cflag (member (file-name-extension fnfile) '("c" "m"))) (ext (string-match "^ext:" fnfile)) re fn sig siglist arglist type errlist minargs maxargs) - (message "%s" m) (if ext (setq fnfile (substring fnfile 4))) (if (file-regular-p fnfile) @@ -216,7 +206,8 @@ fset\\|\\(?:cl-\\)?defmethod\\)\\>" type) (setq arglist (nth 2 e) type (if (not re) - "file not found" + (when (or check-declare-ext-errors (not ext)) + "file not found") (if (not (setq sig (assoc (cadr e) siglist))) (unless (nth 3 e) ; fileonly "function not found") @@ -235,13 +226,6 @@ fset\\|\\(?:cl-\\)?defmethod\\)\\>" type) "arglist mismatch"))))) (when type (setq errlist (cons (list (car e) (cadr e) type) errlist)))) - (message "%s%s" m - (if (or re (or check-declare-ext-errors - (not ext))) - (check-declare-errmsg errlist) - (progn - (setq errlist nil) - "skipping external file"))) errlist)) (defun check-declare-sort (alist) @@ -258,30 +242,27 @@ Returned list has elements FNFILE (FILE ...)." (setq sort (cons (list fnfile (cons file rest)) sort))))) sort)) -(defun check-declare-warn (file fn fnfile type) +(defun check-declare-warn (file fn fnfile type &optional line) "Warn that FILE made a false claim about FN in FNFILE. -TYPE is a string giving the nature of the error. Warning is displayed in -`check-declare-warning-buffer'." +TYPE is a string giving the nature of the error. +Optional LINE is the claim's line number; otherwise, search for the claim. +Display warning in `check-declare-warning-buffer'." (let ((warning-prefix-function (lambda (level entry) - (let ((line 0) - (col 0)) - (insert - (with-current-buffer (find-file-noselect file) - (goto-char (point-min)) - (when (re-search-forward - (format "(declare-function[ \t\n]+%s" fn) nil t) - (goto-char (match-beginning 0)) - (setq line (line-number-at-pos)) - (setq col (1+ (current-column)))) - (format "%s:%d:%d:" - (file-name-nondirectory file) - line col)))) + (insert (format "%s:%d:" (file-relative-name file) (or line 0))) entry)) (warning-fill-prefix " ")) + (unless line + (with-current-buffer (find-file-noselect file) + (goto-char (point-min)) + (when (and (not line) + (re-search-forward + (format "(declare-function[ \t\n]+%s" fn) nil t)) + (goto-char (match-beginning 0)) + (setq line (line-number-at-pos))))) (display-warning 'check-declare (format-message "said `%s' was defined in %s: %s" - fn (file-name-nondirectory fnfile) type) + fn (file-relative-name fnfile) type) nil check-declare-warning-buffer))) (declare-function compilation-forget-errors "compile" ()) @@ -289,7 +270,18 @@ TYPE is a string giving the nature of the error. Warning is displayed in (defun check-declare-files (&rest files) "Check veracity of all `declare-function' statements in FILES. Return a list of any errors found." - (let (alist err errlist) + (if (get-buffer check-declare-warning-buffer) + (kill-buffer check-declare-warning-buffer)) + (let ((buf (get-buffer-create check-declare-warning-buffer)) + alist err errlist) + (with-current-buffer buf + (unless (derived-mode-p 'compilation-mode) + (compilation-mode)) + (setq mode-line-process + '(:propertize ":run" face compilation-mode-line-run)) + (let ((inhibit-read-only t)) + (insert "\f\n")) + (compilation-forget-errors)) (dolist (file files) (setq alist (cons (cons file (check-declare-scan file)) alist))) ;; Sort so that things are ordered by the files supposed to @@ -298,19 +290,15 @@ Return a list of any errors found." (if (setq err (check-declare-verify (car e) (cdr e))) (setq errlist (cons (cons (car e) err) errlist)))) (setq errlist (nreverse errlist)) - (if (get-buffer check-declare-warning-buffer) - (kill-buffer check-declare-warning-buffer)) - (with-current-buffer (get-buffer-create check-declare-warning-buffer) - (unless (derived-mode-p 'compilation-mode) - (compilation-mode)) - (let ((inhibit-read-only t)) - (insert "\f\n")) - (compilation-forget-errors)) ;; Sort back again so that errors are ordered by the files ;; containing the declare-function statements. (dolist (e (check-declare-sort errlist)) (dolist (f (cdr e)) (check-declare-warn (car e) (cadr f) (car f) (nth 2 f)))) + (with-current-buffer buf + (setq mode-line-process + '(:propertize ":exit" face compilation-mode-line-run)) + (force-mode-line-update)) errlist)) ;;;###autoload @@ -320,34 +308,22 @@ See `check-declare-directory' for more information." (interactive "fFile to check: ") (or (file-exists-p file) (error "File `%s' not found" file)) - (let ((m (format "Checking %s..." file)) - errlist) - (message "%s" m) - (setq errlist (check-declare-files file)) - (message "%s%s" m (check-declare-errmsg errlist)) - errlist)) + (check-declare-files file)) ;;;###autoload (defun check-declare-directory (root) "Check veracity of all `declare-function' statements under directory ROOT. Returns non-nil if any false statements are found." (interactive "DDirectory to check: ") - (or (file-directory-p (setq root (expand-file-name root))) + (setq root (directory-file-name (file-relative-name root))) + (or (file-directory-p root) (error "Directory `%s' not found" root)) - (let ((m "Checking `declare-function' statements...") - (m2 "Finding files with declarations...") - errlist files) - (message "%s" m) - (message "%s" m2) - (setq files (process-lines find-program root - "-name" "*.el" - "-exec" grep-program - "-l" "^[ \t]*(declare-function" "{}" "+")) - (message "%s%d found" m2 (length files)) + (let ((files (process-lines find-program root + "-name" "*.el" + "-exec" grep-program + "-l" "^[ \t]*(declare-function" "{}" "+"))) (when files - (setq errlist (apply 'check-declare-files files)) - (message "%s%s" m (check-declare-errmsg errlist t)) - errlist))) + (apply #'check-declare-files files)))) (provide 'check-declare) commit b4d1cddc1b238f0c53ef7eb52e7dcf3467d412ea Author: Paul Eggert Date: Wed May 18 00:14:18 2016 -0700 Pacify byte-compiler for byte-compile-macroexpand-declare-function * lisp/emacs-lisp/bytecomp.el: Change signature of byte-compile-macroexpand-declare-function to match that of declare-function. diff --git a/lisp/emacs-lisp/bytecomp.el b/lisp/emacs-lisp/bytecomp.el index 11eb44c..aa13210 100644 --- a/lisp/emacs-lisp/bytecomp.el +++ b/lisp/emacs-lisp/bytecomp.el @@ -2958,23 +2958,24 @@ for symbols generated by the byte compiler itself." (list body)))) ;; Special macro-expander used during byte-compilation. -(defun byte-compile-macroexpand-declare-function (fn file &rest args) - (let ((gotargs (and (consp args) (listp (car args)))) +(defun byte-compile-macroexpand-declare-function (fn file &optional arglist + fileonly) + (let ((gotargs (listp arglist)) (unresolved (assq fn byte-compile-unresolved-functions))) (when unresolved ; function was called before declaration (if (and gotargs (byte-compile-warning-enabled-p 'callargs)) - (byte-compile-arglist-warn fn (car args) nil) + (byte-compile-arglist-warn fn arglist nil) (setq byte-compile-unresolved-functions (delq unresolved byte-compile-unresolved-functions)))) (push (cons fn (if gotargs - (list 'declared (car args)) + (list 'declared arglist) t)) ; Arglist not specified. byte-compile-function-environment)) ;; We are stating that it _will_ be defined at runtime. (setq byte-compile-noruntime-functions (delq fn byte-compile-noruntime-functions)) ;; Delegate the rest to the normal macro definition. - (macroexpand `(declare-function ,fn ,file ,@args))) + (macroexpand `(declare-function ,fn ,file ,arglist ,fileonly))) ;; This is the recursive entry point for compiling each subform of an commit 639fd22e294fa1702c93531ebb96efb4f3cdffbd Author: Paul Eggert Date: Wed May 18 00:12:01 2016 -0700 Pacify byte-compiler for with-wrapper-hook * lisp/subr.el (subr--with-wrapper-hook-no-warnings): New macro, split out from with-wrapper-hook. * lisp/abbrev.el (abbrev--default-expand): * lisp/minibuffer.el (completion--in-region): * lisp/simple.el (buffer-substring--filter): * lisp/subr.el (with-wrapper-hook): Use it. diff --git a/lisp/abbrev.el b/lisp/abbrev.el index 7814ea2..163dc8e 100644 --- a/lisp/abbrev.el +++ b/lisp/abbrev.el @@ -848,7 +848,7 @@ if expansion occurred, else nil.)" "Default function to use for `abbrev-expand-function'. This respects the wrapper hook `abbrev-expand-functions'. Calls `abbrev-insert' to insert any expansion, and returns what it does." - (with-wrapper-hook abbrev-expand-functions () + (subr--with-wrapper-hook-no-warnings abbrev-expand-functions () (pcase-let ((`(,sym ,name ,wordstart ,wordend) (abbrev--before-point))) (when sym (let ((startpos (copy-marker (point) t)) diff --git a/lisp/minibuffer.el b/lisp/minibuffer.el index 1ee05d3..9190c1f 100644 --- a/lisp/minibuffer.el +++ b/lisp/minibuffer.el @@ -1970,7 +1970,7 @@ if there was no valid completion, else t." "Default function to use for `completion-in-region-function'. Its arguments and return value are as specified for `completion-in-region'. This respects the wrapper hook `completion-in-region-functions'." - (with-wrapper-hook + (subr--with-wrapper-hook-no-warnings ;; FIXME: Maybe we should use this hook to provide a "display ;; completions" operation as well. completion-in-region-functions (start end collection predicate) diff --git a/lisp/simple.el b/lisp/simple.el index e257062..65664c9 100644 --- a/lisp/simple.el +++ b/lisp/simple.el @@ -4061,7 +4061,8 @@ Its arguments and return value are as specified for `filter-buffer-substring'. This respects the wrapper hook `filter-buffer-substring-functions', and the abnormal hook `buffer-substring-filters'. No filtering is done unless a hook says to." - (with-wrapper-hook filter-buffer-substring-functions (beg end delete) + (subr--with-wrapper-hook-no-warnings + filter-buffer-substring-functions (beg end delete) (cond ((or delete buffer-substring-filters) (save-excursion diff --git a/lisp/subr.el b/lisp/subr.el index 0fa6404..438f00a 100644 --- a/lisp/subr.el +++ b/lisp/subr.el @@ -1546,6 +1546,10 @@ FUN is then called once." (declare (indent 2) (debug (form sexp body)) (obsolete "use a -function variable modified by `add-function'." "24.4")) + `(subr--with-wrapper-hook-no-warnings ,hook ,args ,@body)) + +(defmacro subr--with-wrapper-hook-no-warnings (hook args &rest body) + "Like (with-wrapper-hook HOOK ARGS BODY), but without warnings." ;; We need those two gensyms because CL's lexical scoping is not available ;; for function arguments :-( (let ((funs (make-symbol "funs")) commit ccd5156c42771fc3262fa6b8103dc9d8429898d2 Author: Paul Eggert Date: Wed May 18 00:11:48 2016 -0700 Pacify byte-compiler in lisp/url * lisp/url/url-misc.el, lisp/url/url-file.el (mm-disable-multibyte): Add decl. diff --git a/lisp/url/url-file.el b/lisp/url/url-file.el index 9eb9377..61e83c0 100644 --- a/lisp/url/url-file.el +++ b/lisp/url/url-file.el @@ -27,6 +27,7 @@ (require 'url-vars) (require 'url-parse) (require 'url-dired) +(declare-function mm-disable-multibyte "mm-util" ()) (defconst url-file-default-port 21 "Default FTP port.") (defconst url-file-asynchronous-p t "FTP transfers are asynchronous.") diff --git a/lisp/url/url-misc.el b/lisp/url/url-misc.el index 2c277fb..14b9f7e 100644 --- a/lisp/url/url-misc.el +++ b/lisp/url/url-misc.el @@ -24,6 +24,7 @@ (require 'url-vars) (require 'url-parse) +(declare-function mm-disable-multibyte "mm-util" ()) (autoload 'Info-goto-node "info" "" t) (autoload 'man "man" nil t) commit 374f6a5f34a83d3e4c518f0726558642293fdd71 Author: Paul Eggert Date: Wed May 18 00:06:12 2016 -0700 Port --enable-gcc-warnings to GCC 6.1 * configure.ac (WERROR_CFLAGS): Omit -Wunused-const-variable=2. * lib-src/etags.c (LOOKING_AT, LOOKING_AT_NOCASE): Omit test whether pointer plus a constant equals a null pointer. * src/alloc.c (compact_small_strings): Avoid pointer arithmetic on null pointers. * src/alloc.c (mark_face_cache): * src/fontset.c (free_realized_fontsets, Fset_fontset_font): * src/fringe.c (draw_fringe_bitmap_1) (Fset_fringe_bitmap_face): * src/macfont.m (macfont_draw): * src/msdos.c (IT_set_face, IT_clear_screen): * src/nsfont.m (nsfont_draw): * src/nsterm.h (FRAME_DEFAULT_FACE): * src/nsterm.m (ns_draw_window_cursor) (ns_draw_vertical_window_border, ns_draw_window_divider) (ns_dumpglyphs_box_or_relief) (ns_maybe_dumpglyphs_background, ns_dumpglyphs_image) (ns_dumpglyphs_stretch): * src/w32term.c (w32_draw_vertical_window_border) (w32_draw_window_divider, x_set_mouse_face_gc): * src/xdisp.c (estimate_mode_line_height, init_iterator) (handle_face_prop, handle_single_display_spec, pop_it) (CHAR_COMPOSED_P, get_next_display_element) (next_element_from_display_vector, extend_face_to_end_of_line) (fill_gstring_glyph_string,BUILD_COMPOSITE_GLYPH_STRING): * src/xfaces.c (Finternal_merge_in_global_face, Fface_font) (lookup_named_face): * src/xterm.c (x_draw_vertical_window_border) (x_draw_window_divider, x_set_mouse_face_gc): Prefer FACE_OPT_FROM_ID to FACE_FROM_ID when the result might be null. * src/xterm.c (try_window_id): Redo loop to convince GCC 6.1 that it is null pointer safe. (x_color_cells): Use eassume as necessary to pacify GCC 6.1. * src/dispextern.h (FACE_FROM_ID, IMAGE_FROM_ID): Now returns non-null. (FACE_OPT_FROM_ID, IMAGE_OPT_FROM_ID): New macro, with the old behavior of the non-_OPT macro, to be used when the result might be a null pointer. * src/dispnew.c (buffer_posn_from_coords, marginal_area_string) [HAVE_WINDOW_SYSTEM]: * src/intervals.h (INTERVAL_WRITABLE_P): * src/term.c (turn_off_face): * src/xdisp.c (get_glyph_face_and_encoding, fill_image_glyph_string) (produce_image_glyph, produce_xwidget_glyph): * src/xfaces.c (lookup_named_face): Remove unnecessary test for null pointer. * src/keyboard.c (read_char): Suppress bogus -Wclobbered warning. * src/process.c (would_block): New function. (server_accept_connection, wait_reading_process_output, send_process): Use it. * src/xdisp.c (get_window_cursor_type, note_mouse_highlight): Prefer IMAGE_OPT_FROM_ID to IMAGE_FROM_ID when the result might be null. diff --git a/configure.ac b/configure.ac index 448c48d..22ec494 100644 --- a/configure.ac +++ b/configure.ac @@ -930,6 +930,7 @@ AS_IF([test $gl_gcc_warnings = no], nw="$nw -Wformat-nonliteral" # we do this a lot nw="$nw -Wvla" # Emacs uses . nw="$nw -Wswitch-default" # Too many warnings for now + nw="$nw -Wunused-const-variable=2" # lisp.h declares const objects. nw="$nw -Winline" # OK to ignore 'inline' nw="$nw -Wstrict-overflow" # OK to optimize assuming that # signed overflow has undefined behavior diff --git a/lib-src/etags.c b/lib-src/etags.c index e8b71e6..570d217 100644 --- a/lib-src/etags.c +++ b/lib-src/etags.c @@ -4070,13 +4070,13 @@ Yacc_entries (FILE *inf) ((assert ("" kw), true) /* syntax error if not a literal string */ \ && strneq ((cp), kw, sizeof (kw)-1) /* cp points at kw */ \ && notinname ((cp)[sizeof (kw)-1]) /* end of kw */ \ - && ((cp) = skip_spaces ((cp)+sizeof (kw)-1))) /* skip spaces */ + && ((cp) = skip_spaces ((cp) + sizeof (kw) - 1), true)) /* skip spaces */ /* Similar to LOOKING_AT but does not use notinname, does not skip */ #define LOOKING_AT_NOCASE(cp, kw) /* the keyword is a literal string */ \ ((assert ("" kw), true) /* syntax error if not a literal string */ \ && strncaseeq ((cp), kw, sizeof (kw)-1) /* cp points at kw */ \ - && ((cp) += sizeof (kw)-1)) /* skip spaces */ + && ((cp) += sizeof (kw) - 1, true)) /* skip spaces */ /* * Read a file, but do no processing. This is used to do regexp diff --git a/src/alloc.c b/src/alloc.c index c5a4f42..054e1ca 100644 --- a/src/alloc.c +++ b/src/alloc.c @@ -2174,89 +2174,96 @@ free_large_strings (void) static void compact_small_strings (void) { - struct sblock *b, *tb, *next; - sdata *from, *to, *end, *tb_end; - sdata *to_end, *from_end; - /* TB is the sblock we copy to, TO is the sdata within TB we copy to, and TB_END is the end of TB. */ - tb = oldest_sblock; - tb_end = (sdata *) ((char *) tb + SBLOCK_SIZE); - to = tb->data; - - /* Step through the blocks from the oldest to the youngest. We - expect that old blocks will stabilize over time, so that less - copying will happen this way. */ - for (b = oldest_sblock; b; b = b->next) + struct sblock *tb = oldest_sblock; + if (tb) { - end = b->next_free; - eassert ((char *) end <= (char *) b + SBLOCK_SIZE); + sdata *tb_end = (sdata *) ((char *) tb + SBLOCK_SIZE); + sdata *to = tb->data; - for (from = b->data; from < end; from = from_end) + /* Step through the blocks from the oldest to the youngest. We + expect that old blocks will stabilize over time, so that less + copying will happen this way. */ + struct sblock *b = tb; + do { - /* Compute the next FROM here because copying below may - overwrite data we need to compute it. */ - ptrdiff_t nbytes; - struct Lisp_String *s = from->string; + sdata *end = b->next_free; + eassert ((char *) end <= (char *) b + SBLOCK_SIZE); + + for (sdata *from = b->data; from < end; ) + { + /* Compute the next FROM here because copying below may + overwrite data we need to compute it. */ + ptrdiff_t nbytes; + struct Lisp_String *s = from->string; #ifdef GC_CHECK_STRING_BYTES - /* Check that the string size recorded in the string is the - same as the one recorded in the sdata structure. */ - if (s && string_bytes (s) != SDATA_NBYTES (from)) - emacs_abort (); + /* Check that the string size recorded in the string is the + same as the one recorded in the sdata structure. */ + if (s && string_bytes (s) != SDATA_NBYTES (from)) + emacs_abort (); #endif /* GC_CHECK_STRING_BYTES */ - nbytes = s ? STRING_BYTES (s) : SDATA_NBYTES (from); - eassert (nbytes <= LARGE_STRING_BYTES); + nbytes = s ? STRING_BYTES (s) : SDATA_NBYTES (from); + eassert (nbytes <= LARGE_STRING_BYTES); - nbytes = SDATA_SIZE (nbytes); - from_end = (sdata *) ((char *) from + nbytes + GC_STRING_EXTRA); + nbytes = SDATA_SIZE (nbytes); + sdata *from_end = (sdata *) ((char *) from + + nbytes + GC_STRING_EXTRA); #ifdef GC_CHECK_STRING_OVERRUN - if (memcmp (string_overrun_cookie, - (char *) from_end - GC_STRING_OVERRUN_COOKIE_SIZE, - GC_STRING_OVERRUN_COOKIE_SIZE)) - emacs_abort (); + if (memcmp (string_overrun_cookie, + (char *) from_end - GC_STRING_OVERRUN_COOKIE_SIZE, + GC_STRING_OVERRUN_COOKIE_SIZE)) + emacs_abort (); #endif - /* Non-NULL S means it's alive. Copy its data. */ - if (s) - { - /* If TB is full, proceed with the next sblock. */ - to_end = (sdata *) ((char *) to + nbytes + GC_STRING_EXTRA); - if (to_end > tb_end) + /* Non-NULL S means it's alive. Copy its data. */ + if (s) { - tb->next_free = to; - tb = tb->next; - tb_end = (sdata *) ((char *) tb + SBLOCK_SIZE); - to = tb->data; - to_end = (sdata *) ((char *) to + nbytes + GC_STRING_EXTRA); - } + /* If TB is full, proceed with the next sblock. */ + sdata *to_end = (sdata *) ((char *) to + + nbytes + GC_STRING_EXTRA); + if (to_end > tb_end) + { + tb->next_free = to; + tb = tb->next; + tb_end = (sdata *) ((char *) tb + SBLOCK_SIZE); + to = tb->data; + to_end = (sdata *) ((char *) to + nbytes + GC_STRING_EXTRA); + } - /* Copy, and update the string's `data' pointer. */ - if (from != to) - { - eassert (tb != b || to < from); - memmove (to, from, nbytes + GC_STRING_EXTRA); - to->string->data = SDATA_DATA (to); - } + /* Copy, and update the string's `data' pointer. */ + if (from != to) + { + eassert (tb != b || to < from); + memmove (to, from, nbytes + GC_STRING_EXTRA); + to->string->data = SDATA_DATA (to); + } - /* Advance past the sdata we copied to. */ - to = to_end; + /* Advance past the sdata we copied to. */ + to = to_end; + } + from = from_end; } + b = b->next; } - } + while (b); - /* The rest of the sblocks following TB don't contain live data, so - we can free them. */ - for (b = tb->next; b; b = next) - { - next = b->next; - lisp_free (b); + /* The rest of the sblocks following TB don't contain live data, so + we can free them. */ + for (b = tb->next; b; ) + { + struct sblock *next = b->next; + lisp_free (b); + b = next; + } + + tb->next_free = to; + tb->next = NULL; } - tb->next_free = to; - tb->next = NULL; current_sblock = tb; } @@ -6119,7 +6126,7 @@ mark_face_cache (struct face_cache *c) int i, j; for (i = 0; i < c->used; ++i) { - struct face *face = FACE_FROM_ID (c->f, i); + struct face *face = FACE_OPT_FROM_ID (c->f, i); if (face) { diff --git a/src/dispextern.h b/src/dispextern.h index 7035872..4deebc1 100644 --- a/src/dispextern.h +++ b/src/dispextern.h @@ -1811,13 +1811,20 @@ struct face_cache bool_bf menu_face_changed_p : 1; }; +/* Return a pointer to the cached face with ID on frame F. */ + +#define FACE_FROM_ID(F, ID) \ + (eassert (UNSIGNED_CMP (ID, <, FRAME_FACE_CACHE (F)->used)), \ + eassume (FRAME_FACE_CACHE (F)->faces_by_id[ID]), \ + FRAME_FACE_CACHE (F)->faces_by_id[ID]) + /* Return a pointer to the face with ID on frame F, or null if such a face doesn't exist. */ -#define FACE_FROM_ID(F, ID) \ - (UNSIGNED_CMP (ID, <, FRAME_FACE_CACHE (F)->used) \ - ? FRAME_FACE_CACHE (F)->faces_by_id[ID] \ - : NULL) +#define FACE_OPT_FROM_ID(F, ID) \ + (UNSIGNED_CMP (ID, <, FRAME_FACE_CACHE (F)->used) \ + ? FACE_FROM_ID (F, ID) \ + : NULL) #ifdef HAVE_WINDOW_SYSTEM @@ -3082,13 +3089,20 @@ struct image_cache }; +/* A pointer to the image with id ID on frame F. */ + +#define IMAGE_FROM_ID(F, ID) \ + (eassert (UNSIGNED_CMP (ID, <, FRAME_IMAGE_CACHE (F)->used)), \ + eassume (FRAME_IMAGE_CACHE (F)->images[ID]), \ + FRAME_IMAGE_CACHE (F)->images[ID]) + /* Value is a pointer to the image with id ID on frame F, or null if no image with that id exists. */ -#define IMAGE_FROM_ID(F, ID) \ - (((ID) >= 0 && (ID) < (FRAME_IMAGE_CACHE (F)->used)) \ - ? FRAME_IMAGE_CACHE (F)->images[ID] \ - : NULL) +#define IMAGE_OPT_FROM_ID(F, ID) \ + (UNSIGNED_CMP (ID, <, FRAME_IMAGE_CACHE (F)->used) \ + ? IMAGE_FROM_ID (F, ID) \ + : NULL) /* Size of bucket vector of image caches. Should be prime. */ diff --git a/src/dispnew.c b/src/dispnew.c index 51caa5b..4cc908a 100644 --- a/src/dispnew.c +++ b/src/dispnew.c @@ -5177,8 +5177,8 @@ buffer_posn_from_coords (struct window *w, int *x, int *y, struct display_pos *p #ifdef HAVE_WINDOW_SYSTEM if (it.what == IT_IMAGE) { - if ((img = IMAGE_FROM_ID (it.f, it.image_id)) != NULL - && !NILP (img->spec)) + img = IMAGE_OPT_FROM_ID (it.f, it.image_id); + if (img && !NILP (img->spec)) *object = img->spec; } #endif @@ -5275,7 +5275,7 @@ mode_line_string (struct window *w, enum window_part part, if (glyph->type == IMAGE_GLYPH) { struct image *img; - img = IMAGE_FROM_ID (WINDOW_XFRAME (w), glyph->u.img_id); + img = IMAGE_OPT_FROM_ID (WINDOW_XFRAME (w), glyph->u.img_id); if (img != NULL) *object = img->spec; y0 -= row->ascent - glyph->ascent; @@ -5362,7 +5362,7 @@ marginal_area_string (struct window *w, enum window_part part, if (glyph->type == IMAGE_GLYPH) { struct image *img; - img = IMAGE_FROM_ID (WINDOW_XFRAME (w), glyph->u.img_id); + img = IMAGE_OPT_FROM_ID (WINDOW_XFRAME (w), glyph->u.img_id); if (img != NULL) *object = img->spec; y0 -= row->ascent - glyph->ascent; diff --git a/src/fontset.c b/src/fontset.c index 4ab1367..d87901d 100644 --- a/src/fontset.c +++ b/src/fontset.c @@ -1304,7 +1304,7 @@ free_realized_fontsets (Lisp_Object base) { struct frame *f = XFRAME (FONTSET_FRAME (this)); int face_id = XINT (XCDR (XCAR (tail))); - struct face *face = FACE_FROM_ID (f, face_id); + struct face *face = FACE_OPT_FROM_ID (f, face_id); /* Face THIS itself is also freed by the following call. */ free_realized_face (f, face); @@ -1636,7 +1636,7 @@ appended. By default, FONT-SPEC overrides the previous settings. */) continue; if (fontset_id != FRAME_FONTSET (f)) continue; - face = FACE_FROM_ID (f, DEFAULT_FACE_ID); + face = FACE_OPT_FROM_ID (f, DEFAULT_FACE_ID); if (face) font_object = font_load_for_lface (f, face->lface, font_spec); else diff --git a/src/fringe.c b/src/fringe.c index 061f786..55f37b8 100644 --- a/src/fringe.c +++ b/src/fringe.c @@ -620,7 +620,7 @@ draw_fringe_bitmap_1 (struct window *w, struct glyph_row *row, int left_p, int o break; } - p.face = FACE_FROM_ID (f, face_id); + p.face = FACE_OPT_FROM_ID (f, face_id); if (p.face == NULL) { @@ -1627,7 +1627,7 @@ If FACE is nil, reset face to default fringe face. */) { struct frame *f = SELECTED_FRAME (); - if (FACE_FROM_ID (f, FRINGE_FACE_ID) + if (FACE_OPT_FROM_ID (f, FRINGE_FACE_ID) && lookup_derived_face (f, face, FRINGE_FACE_ID, 1) < 0) error ("No such face"); } diff --git a/src/intervals.h b/src/intervals.h index b8cdcfd..6a5a412 100644 --- a/src/intervals.h +++ b/src/intervals.h @@ -197,12 +197,12 @@ set_interval_plist (INTERVAL i, Lisp_Object plist) /* Is this interval writable? Replace later with cache access. */ #define INTERVAL_WRITABLE_P(i) \ - (i && (NILP (textget ((i)->plist, Qread_only)) \ - || !NILP (textget ((i)->plist, Qinhibit_read_only)) \ - || ((CONSP (Vinhibit_read_only) \ - ? !NILP (Fmemq (textget ((i)->plist, Qread_only), \ - Vinhibit_read_only)) \ - : !NILP (Vinhibit_read_only))))) \ + (NILP (textget ((i)->plist, Qread_only)) \ + || !NILP (textget ((i)->plist, Qinhibit_read_only)) \ + || ((CONSP (Vinhibit_read_only) \ + ? !NILP (Fmemq (textget ((i)->plist, Qread_only), \ + Vinhibit_read_only)) \ + : !NILP (Vinhibit_read_only)))) /* Macros to tell whether insertions before or after this interval should stick to it. Now we have Vtext_property_default_nonsticky, diff --git a/src/keyboard.c b/src/keyboard.c index fe04b3f..ef2e278 100644 --- a/src/keyboard.c +++ b/src/keyboard.c @@ -2280,6 +2280,11 @@ read_decoded_event_from_main_queue (struct timespec *end_time, } } +#if 4 < __GNUC__ + (6 <= __GNUC_MINOR__) +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wclobbered" +#endif + /* Read a character from the keyboard; call the redisplay if needed. */ /* commandflag 0 means do not autosave, but do redisplay. -1 means do not redisplay, but do autosave. @@ -3120,6 +3125,10 @@ read_char (int commandflag, Lisp_Object map, return c; } +#if 4 < __GNUC__ + (6 <= __GNUC_MINOR__) +# pragma GCC diagnostic pop +#endif + /* Record a key that came from a mouse menu. Record it for echoing, for this-command-keys, and so on. */ diff --git a/src/macfont.m b/src/macfont.m index 0445628..7900134 100644 --- a/src/macfont.m +++ b/src/macfont.m @@ -2856,7 +2856,8 @@ So we use CTFontDescriptorCreateMatchingFontDescriptor (no { if (s->hl == DRAW_MOUSE_FACE) { - face = FACE_FROM_ID (s->f, MOUSE_HL_INFO (s->f)->mouse_face_face_id); + face = FACE_OPT_FROM_ID (s->f, + MOUSE_HL_INFO (s->f)->mouse_face_face_id); if (!face) face = FACE_FROM_ID (s->f, MOUSE_FACE_ID); } diff --git a/src/msdos.c b/src/msdos.c index 62411ea..c2b19a6 100644 --- a/src/msdos.c +++ b/src/msdos.c @@ -795,8 +795,8 @@ static void IT_set_face (int face) { struct frame *sf = SELECTED_FRAME (); - struct face *fp = FACE_FROM_ID (sf, face); - struct face *dfp = FACE_FROM_ID (sf, DEFAULT_FACE_ID); + struct face *fp = FACE_OPT_FROM_ID (sf, face); + struct face *dfp = FACE_OPT_FROM_ID (sf, DEFAULT_FACE_ID); unsigned long fg, bg, dflt_fg, dflt_bg; struct tty_display_info *tty = FRAME_TTY (sf); @@ -1076,7 +1076,7 @@ IT_clear_screen (struct frame *f) any valid faces and will abort. Instead, use the initial screen colors; that should mimic what a Unix tty does, which simply clears the screen with whatever default colors are in use. */ - if (FACE_FROM_ID (SELECTED_FRAME (), DEFAULT_FACE_ID) == NULL) + if (FACE_OPT_FROM_ID (SELECTED_FRAME (), DEFAULT_FACE_ID) == NULL) ScreenAttrib = (initial_screen_colors[0] << 4) | initial_screen_colors[1]; else IT_set_face (0); diff --git a/src/nsfont.m b/src/nsfont.m index 92e7d11..7c97c6f 100644 --- a/src/nsfont.m +++ b/src/nsfont.m @@ -1071,7 +1071,7 @@ is false when (FROM > 0 || TO < S->nchars). */ face = s->face; break; case NS_DUMPGLYPH_MOUSEFACE: - face = FACE_FROM_ID (s->f, MOUSE_HL_INFO (s->f)->mouse_face_face_id); + face = FACE_OPT_FROM_ID (s->f, MOUSE_HL_INFO (s->f)->mouse_face_face_id); if (!face) face = FACE_FROM_ID (s->f, MOUSE_FACE_ID); break; diff --git a/src/nsterm.h b/src/nsterm.h index 6cad337..c2285c9 100644 --- a/src/nsterm.h +++ b/src/nsterm.h @@ -1014,7 +1014,7 @@ struct x_output #define FRAME_NS_TITLEBAR_HEIGHT(f) ((f)->output_data.ns->titlebar_height) #define FRAME_TOOLBAR_HEIGHT(f) ((f)->output_data.ns->toolbar_height) -#define FRAME_DEFAULT_FACE(f) FACE_FROM_ID (f, DEFAULT_FACE_ID) +#define FRAME_DEFAULT_FACE(f) FACE_OPT_FROM_ID (f, DEFAULT_FACE_ID) #define FRAME_NS_VIEW(f) ((f)->output_data.ns->view) #define FRAME_CURSOR_COLOR(f) ((f)->output_data.ns->cursor_color) diff --git a/src/nsterm.m b/src/nsterm.m index 1d48c04..b815d77 100644 --- a/src/nsterm.m +++ b/src/nsterm.m @@ -2878,7 +2878,7 @@ Note that CURSOR_WIDTH is meaningful only for (h)bar cursors. ns_clip_to_row (w, glyph_row, ANY_AREA, NO); /* do ns_focus(f, &r, 1); if remove */ - face = FACE_FROM_ID (f, phys_cursor_glyph->face_id); + face = FACE_OPT_FROM_ID (f, phys_cursor_glyph->face_id); if (face && NS_FACE_BACKGROUND (face) == ns_index_color (FRAME_CURSOR_COLOR (f), f)) { @@ -2950,7 +2950,7 @@ Note that CURSOR_WIDTH is meaningful only for (h)bar cursors. NSTRACE ("ns_draw_vertical_window_border"); - face = FACE_FROM_ID (f, VERTICAL_BORDER_FACE_ID); + face = FACE_OPT_FROM_ID (f, VERTICAL_BORDER_FACE_ID); if (face) [ns_lookup_indexed_color(face->foreground, f) set]; @@ -2972,7 +2972,7 @@ Note that CURSOR_WIDTH is meaningful only for (h)bar cursors. NSTRACE ("ns_draw_window_divider"); - face = FACE_FROM_ID (f, WINDOW_DIVIDER_FACE_ID); + face = FACE_OPT_FROM_ID (f, WINDOW_DIVIDER_FACE_ID); if (face) [ns_lookup_indexed_color(face->foreground, f) set]; @@ -3305,9 +3305,9 @@ Function modeled after x_draw_glyph_string_box (). if (s->hl == DRAW_MOUSE_FACE) { - face = FACE_FROM_ID (s->f, MOUSE_HL_INFO (s->f)->mouse_face_face_id); + face = FACE_OPT_FROM_ID (s->f, MOUSE_HL_INFO (s->f)->mouse_face_face_id); if (!face) - face = FACE_FROM_ID (s->f, MOUSE_FACE_ID); + face = FACE_OPT_FROM_ID (s->f, MOUSE_FACE_ID); } else face = s->face; @@ -3372,8 +3372,9 @@ Function modeled after x_draw_glyph_string_box (). struct face *face; if (s->hl == DRAW_MOUSE_FACE) { - face = FACE_FROM_ID (s->f, - MOUSE_HL_INFO (s->f)->mouse_face_face_id); + face + = FACE_OPT_FROM_ID (s->f, + MOUSE_HL_INFO (s->f)->mouse_face_face_id); if (!face) face = FACE_FROM_ID (s->f, MOUSE_FACE_ID); } @@ -3439,7 +3440,7 @@ Function modeled after x_draw_glyph_string_box (). with its background color), we must clear just the image area. */ if (s->hl == DRAW_MOUSE_FACE) { - face = FACE_FROM_ID (s->f, MOUSE_HL_INFO (s->f)->mouse_face_face_id); + face = FACE_OPT_FROM_ID (s->f, MOUSE_HL_INFO (s->f)->mouse_face_face_id); if (!face) face = FACE_FROM_ID (s->f, MOUSE_FACE_ID); } @@ -3556,7 +3557,8 @@ Function modeled after x_draw_glyph_string_box (). if (s->hl == DRAW_MOUSE_FACE) { - face = FACE_FROM_ID (s->f, MOUSE_HL_INFO (s->f)->mouse_face_face_id); + face = FACE_OPT_FROM_ID (s->f, + MOUSE_HL_INFO (s->f)->mouse_face_face_id); if (!face) face = FACE_FROM_ID (s->f, MOUSE_FACE_ID); } diff --git a/src/process.c b/src/process.c index eed875d..3e5b83d 100644 --- a/src/process.c +++ b/src/process.c @@ -151,6 +151,18 @@ bool inhibit_sentinels; # define SOCK_CLOEXEC 0 #endif +/* True if ERRNUM represents an error where the system call would + block if a blocking variant were used. */ +static bool +would_block (int errnum) +{ +#ifdef EWOULDBLOCK + if (EWOULDBLOCK != EAGAIN && errnum == EWOULDBLOCK) + return true; +#endif + return errnum == EAGAIN; +} + #ifndef HAVE_ACCEPT4 /* Emulate GNU/Linux accept4 and socket well enough for this module. */ @@ -4453,15 +4465,7 @@ server_accept_connection (Lisp_Object server, int channel) if (s < 0) { int code = errno; - - if (code == EAGAIN) - return; -#ifdef EWOULDBLOCK - if (code == EWOULDBLOCK) - return; -#endif - - if (!NILP (ps->log)) + if (!would_block (code) && !NILP (ps->log)) call3 (ps->log, server, Qnil, concat3 (build_string ("accept failed with code"), Fnumber_to_string (make_number (code)), @@ -5016,12 +5020,8 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd, int nread = read_process_output (proc, wait_proc->infd); if (nread < 0) { - if (errno == EIO || errno == EAGAIN) - break; -#ifdef EWOULDBLOCK - if (errno == EWOULDBLOCK) - break; -#endif + if (errno == EIO || would_block (errno)) + break; } else { @@ -5405,11 +5405,7 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd, if (do_display) redisplay_preserve_echo_area (12); } -#ifdef EWOULDBLOCK - else if (nread == -1 && errno == EWOULDBLOCK) - ; -#endif - else if (nread == -1 && errno == EAGAIN) + else if (nread == -1 && would_block (errno)) ; #ifdef WINDOWSNT /* FIXME: Is this special case still needed? */ @@ -6147,11 +6143,7 @@ send_process (Lisp_Object proc, const char *buf, ptrdiff_t len, if (rv < 0) { - if (errno == EAGAIN -#ifdef EWOULDBLOCK - || errno == EWOULDBLOCK -#endif - ) + if (would_block (errno)) /* Buffer is full. Wait, accepting input; that may allow the program to finish doing output and read more. */ diff --git a/src/term.c b/src/term.c index 4397210..07cc3a9 100644 --- a/src/term.c +++ b/src/term.c @@ -1954,8 +1954,6 @@ turn_off_face (struct frame *f, int face_id) struct face *face = FACE_FROM_ID (f, face_id); struct tty_display_info *tty = FRAME_TTY (f); - eassert (face != NULL); - if (tty->TS_exit_attribute_mode) { /* Capability "me" will turn off appearance modes double-bright, diff --git a/src/w32term.c b/src/w32term.c index 72e1245..14a43c1 100644 --- a/src/w32term.c +++ b/src/w32term.c @@ -613,7 +613,7 @@ w32_draw_vertical_window_border (struct window *w, int x, int y0, int y1) r.bottom = y1; hdc = get_frame_dc (f); - face = FACE_FROM_ID (f, VERTICAL_BORDER_FACE_ID); + face = FACE_OPT_FROM_ID (f, VERTICAL_BORDER_FACE_ID); if (face) w32_fill_rect (f, hdc, face->foreground, &r); else @@ -630,9 +630,11 @@ w32_draw_window_divider (struct window *w, int x0, int x1, int y0, int y1) { struct frame *f = XFRAME (WINDOW_FRAME (w)); HDC hdc = get_frame_dc (f); - struct face *face = FACE_FROM_ID (f, WINDOW_DIVIDER_FACE_ID); - struct face *face_first = FACE_FROM_ID (f, WINDOW_DIVIDER_FIRST_PIXEL_FACE_ID); - struct face *face_last = FACE_FROM_ID (f, WINDOW_DIVIDER_LAST_PIXEL_FACE_ID); + struct face *face = FACE_OPT_FROM_ID (f, WINDOW_DIVIDER_FACE_ID); + struct face *face_first + = FACE_OPT_FROM_ID (f, WINDOW_DIVIDER_FIRST_PIXEL_FACE_ID); + struct face *face_last + = FACE_OPT_FROM_ID (f, WINDOW_DIVIDER_LAST_PIXEL_FACE_ID); unsigned long color = face ? face->foreground : FRAME_FOREGROUND_PIXEL (f); unsigned long color_first = (face_first ? face_first->foreground @@ -991,7 +993,7 @@ x_set_mouse_face_gc (struct glyph_string *s) /* What face has to be used last for the mouse face? */ face_id = MOUSE_HL_INFO (s->f)->mouse_face_face_id; - face = FACE_FROM_ID (s->f, face_id); + face = FACE_OPT_FROM_ID (s->f, face_id); if (face == NULL) face = FACE_FROM_ID (s->f, MOUSE_FACE_ID); diff --git a/src/xdisp.c b/src/xdisp.c index d0ff952..bec7339 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -1813,7 +1813,7 @@ estimate_mode_line_height (struct frame *f, enum face_id face_id) cache and mode line face are not yet initialized. */ if (FRAME_FACE_CACHE (f)) { - struct face *face = FACE_FROM_ID (f, face_id); + struct face *face = FACE_OPT_FROM_ID (f, face_id); if (face) { if (face->font) @@ -2918,7 +2918,7 @@ init_iterator (struct it *it, struct window *w, /* If we have a boxed mode line, make the first character appear with a left box line. */ - face = FACE_FROM_ID (it->f, remapped_base_face_id); + face = FACE_OPT_FROM_ID (it->f, remapped_base_face_id); if (face && face->box != FACE_NO_BOX) it->start_of_box_run_p = true; } @@ -3877,9 +3877,9 @@ handle_face_prop (struct it *it) { struct face *new_face = FACE_FROM_ID (it->f, new_face_id); /* If it->face_id is -1, old_face below will be NULL, see - the definition of FACE_FROM_ID. This will happen if this + the definition of FACE_OPT_FROM_ID. This will happen if this is the initial call that gets the face. */ - struct face *old_face = FACE_FROM_ID (it->f, it->face_id); + struct face *old_face = FACE_OPT_FROM_ID (it->f, it->face_id); /* If the value of face_id of the iterator is -1, we have to look in front of IT's position and see whether there is a @@ -3888,7 +3888,7 @@ handle_face_prop (struct it *it) { int prev_face_id = face_before_it_pos (it); - old_face = FACE_FROM_ID (it->f, prev_face_id); + old_face = FACE_OPT_FROM_ID (it->f, prev_face_id); } /* If the new face has a box, but the old face does not, @@ -3988,7 +3988,7 @@ handle_face_prop (struct it *it) if (new_face_id != it->face_id) { struct face *new_face = FACE_FROM_ID (it->f, new_face_id); - struct face *old_face = FACE_FROM_ID (it->f, it->face_id); + struct face *old_face = FACE_OPT_FROM_ID (it->f, it->face_id); /* If new face has a box but old face hasn't, this is the start of a run of characters with box, i.e. it has a @@ -4847,7 +4847,6 @@ handle_single_display_spec (struct it *it, Lisp_Object spec, Lisp_Object object, it->font_height = XCAR (XCDR (spec)); if (!NILP (it->font_height)) { - struct face *face = FACE_FROM_ID (it->f, it->face_id); int new_height = -1; if (CONSP (it->font_height) @@ -4866,6 +4865,7 @@ handle_single_display_spec (struct it *it, Lisp_Object spec, Lisp_Object object, { /* Call function with current height as argument. Value is the new height. */ + struct face *face = FACE_FROM_ID (it->f, it->face_id); Lisp_Object height; height = safe_call1 (it->font_height, face->lface[LFACE_HEIGHT_INDEX]); @@ -4887,6 +4887,7 @@ handle_single_display_spec (struct it *it, Lisp_Object spec, Lisp_Object object, /* Evaluate IT->font_height with `height' bound to the current specified height to get the new height. */ ptrdiff_t count = SPECPDL_INDEX (); + struct face *face = FACE_FROM_ID (it->f, it->face_id); specbind (Qheight, face->lface[LFACE_HEIGHT_INDEX]); value = safe_eval (it->font_height); @@ -6096,7 +6097,7 @@ pop_it (struct it *it) break; case GET_FROM_STRING: { - struct face *face = FACE_FROM_ID (it->f, it->face_id); + struct face *face = FACE_OPT_FROM_ID (it->f, it->face_id); /* Restore the face_box_p flag, since it could have been overwritten by the face of the object that we just finished @@ -6777,7 +6778,7 @@ static next_element_function const get_next_element[NUM_IT_METHODS] = || ((IT)->cmp_it.stop_pos == (CHARPOS) \ && composition_reseat_it (&(IT)->cmp_it, CHARPOS, BYTEPOS, \ END_CHARPOS, (IT)->w, \ - FACE_FROM_ID ((IT)->f, (IT)->face_id), \ + FACE_OPT_FROM_ID ((IT)->f, (IT)->face_id), \ (IT)->string))) @@ -7206,7 +7207,7 @@ get_next_display_element (struct it *it) if (it->method == GET_FROM_STRING && it->sp) { int face_id = underlying_face_id (it); - struct face *face = FACE_FROM_ID (it->f, face_id); + struct face *face = FACE_OPT_FROM_ID (it->f, face_id); if (face) { @@ -7739,8 +7740,8 @@ next_element_from_display_vector (struct it *it) /* Glyphs in the display vector could have the box face, so we need to set the related flags in the iterator, as appropriate. */ - this_face = FACE_FROM_ID (it->f, it->face_id); - prev_face = FACE_FROM_ID (it->f, prev_face_id); + this_face = FACE_OPT_FROM_ID (it->f, it->face_id); + prev_face = FACE_OPT_FROM_ID (it->f, prev_face_id); /* Is this character the first character of a box-face run? */ it->start_of_box_run_p = (this_face && this_face->box != FACE_NO_BOX @@ -7765,7 +7766,7 @@ next_element_from_display_vector (struct it *it) it->saved_face_id); } } - next_face = FACE_FROM_ID (it->f, next_face_id); + next_face = FACE_OPT_FROM_ID (it->f, next_face_id); it->end_of_box_run_p = (this_face && this_face->box != FACE_NO_BOX && (!next_face || next_face->box == FACE_NO_BOX)); @@ -18662,7 +18663,7 @@ try_window_id (struct window *w) eassert (MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row)); row = find_last_row_displaying_text (w->current_matrix, &it, first_unchanged_at_end_row); - eassert (row && MATRIX_ROW_DISPLAYS_TEXT_P (row)); + eassume (row && MATRIX_ROW_DISPLAYS_TEXT_P (row)); adjust_window_ends (w, row, true); eassert (w->window_end_bytepos >= 0); IF_DEBUG (debug_method_add (w, "A")); @@ -18692,10 +18693,9 @@ try_window_id (struct window *w) struct glyph_row *current_row = current_matrix->rows + vpos; struct glyph_row *desired_row = desired_matrix->rows + vpos; - for (row = NULL; - row == NULL && vpos >= first_vpos; - --vpos, --current_row, --desired_row) + for (row = NULL; !row; --vpos, --current_row, --desired_row) { + eassert (first_vpos <= vpos); if (desired_row->enabled_p) { if (MATRIX_ROW_DISPLAYS_TEXT_P (desired_row)) @@ -18705,7 +18705,6 @@ try_window_id (struct window *w) row = current_row; } - eassert (row != NULL); w->window_end_vpos = vpos + 1; w->window_end_pos = Z - MATRIX_ROW_END_CHARPOS (row); w->window_end_bytepos = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row); @@ -19630,15 +19629,14 @@ extend_face_to_end_of_line (struct it *it) return; /* The default face, possibly remapped. */ - default_face = FACE_FROM_ID (f, lookup_basic_face (f, DEFAULT_FACE_ID)); + default_face = FACE_OPT_FROM_ID (f, lookup_basic_face (f, DEFAULT_FACE_ID)); /* Face extension extends the background and box of IT->face_id to the end of the line. If the background equals the background of the frame, we don't have to do anything. */ - if (it->face_before_selective_p) - face = FACE_FROM_ID (f, it->saved_face_id); - else - face = FACE_FROM_ID (f, it->face_id); + face = FACE_OPT_FROM_ID (f, (it->face_before_selective_p + ? it->face_id + : it->saved_face_id)); if (FRAME_WINDOW_P (f) && MATRIX_ROW_DISPLAYS_TEXT_P (it->glyph_row) @@ -24612,7 +24610,6 @@ get_glyph_face_and_encoding (struct frame *f, struct glyph *glyph, face = FACE_FROM_ID (f, glyph->face_id); /* Make sure X resources of the face are allocated. */ - eassert (face != NULL); prepare_face_for_display (f, face); if (face->font) @@ -24744,7 +24741,7 @@ fill_gstring_glyph_string (struct glyph_string *s, int face_id, s->cmp_id = glyph->u.cmp.id; s->cmp_from = glyph->slice.cmp.from; s->cmp_to = glyph->slice.cmp.to + 1; - s->face = FACE_FROM_ID (s->f, face_id); + s->face = FACE_OPT_FROM_ID (s->f, face_id); lgstring = composition_gstring_from_id (s->cmp_id); s->font = XFONT_OBJECT (LGSTRING_FONT (lgstring)); glyph++; @@ -24873,7 +24870,6 @@ fill_image_glyph_string (struct glyph_string *s) { eassert (s->first_glyph->type == IMAGE_GLYPH); s->img = IMAGE_FROM_ID (s->f, s->first_glyph->u.img_id); - eassert (s->img); s->slice = s->first_glyph->slice.img; s->face = FACE_FROM_ID (s->f, s->first_glyph->face_id); s->font = s->face->font; @@ -25337,7 +25333,7 @@ compute_overhangs_and_x (struct glyph_string *s, int x, bool backward_p) #define BUILD_COMPOSITE_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \ do { \ int face_id = (row)->glyphs[area][START].face_id; \ - struct face *base_face = FACE_FROM_ID (f, face_id); \ + struct face *base_face = FACE_OPT_FROM_ID (f, face_id); \ ptrdiff_t cmp_id = (row)->glyphs[area][START].u.cmp.id; \ struct composition *cmp = composition_table[cmp_id]; \ XChar2b *char2b; \ @@ -25960,7 +25956,6 @@ produce_image_glyph (struct it *it) eassert (it->what == IT_IMAGE); face = FACE_FROM_ID (it->f, it->face_id); - eassert (face); /* Make sure X resources of the face is loaded. */ prepare_face_for_display (it->f, face); @@ -25975,7 +25970,6 @@ produce_image_glyph (struct it *it) } img = IMAGE_FROM_ID (it->f, it->image_id); - eassert (img); /* Make sure X resources of the image is loaded. */ prepare_image_for_display (it->f, img); @@ -26131,7 +26125,6 @@ produce_xwidget_glyph (struct it *it) eassert (it->what == IT_XWIDGET); struct face *face = FACE_FROM_ID (it->f, it->face_id); - eassert (face); /* Make sure X resources of the face is loaded. */ prepare_face_for_display (it->f, face); @@ -28018,7 +28011,7 @@ get_window_cursor_type (struct window *w, struct glyph *glyph, int *width, /* Using a block cursor on large images can be very annoying. So use a hollow cursor for "large" images. If image is not transparent (no mask), also use hollow cursor. */ - struct image *img = IMAGE_FROM_ID (f, glyph->u.img_id); + struct image *img = IMAGE_OPT_FROM_ID (f, glyph->u.img_id); if (img != NULL && IMAGEP (img->spec)) { /* Arbitrarily, interpret "Large" as >32x32 and >NxN @@ -30105,7 +30098,7 @@ note_mouse_highlight (struct frame *f, int x, int y) /* Look for :pointer property on image. */ if (glyph != NULL && glyph->type == IMAGE_GLYPH) { - struct image *img = IMAGE_FROM_ID (f, glyph->u.img_id); + struct image *img = IMAGE_OPT_FROM_ID (f, glyph->u.img_id); if (img != NULL && IMAGEP (img->spec)) { Lisp_Object image_map, hotspot; diff --git a/src/xfaces.c b/src/xfaces.c index ac13700..c42e553 100644 --- a/src/xfaces.c +++ b/src/xfaces.c @@ -3694,7 +3694,7 @@ Default face attributes override any local face attributes. */) if (EQ (face, Qdefault)) { struct face_cache *c = FRAME_FACE_CACHE (f); - struct face *newface, *oldface = FACE_FROM_ID (f, DEFAULT_FACE_ID); + struct face *newface, *oldface = FACE_OPT_FROM_ID (f, DEFAULT_FACE_ID); Lisp_Object attrs[LFACE_VECTOR_SIZE]; /* This can be NULL (e.g., in batch mode). */ @@ -3777,7 +3777,7 @@ return the font name used for CHARACTER. */) { struct frame *f = decode_live_frame (frame); int face_id = lookup_named_face (f, face, true); - struct face *fface = FACE_FROM_ID (f, face_id); + struct face *fface = FACE_OPT_FROM_ID (f, face_id); if (! fface) return Qnil; @@ -4429,15 +4429,13 @@ lookup_named_face (struct frame *f, Lisp_Object symbol, bool signal_p) { Lisp_Object attrs[LFACE_VECTOR_SIZE]; Lisp_Object symbol_attrs[LFACE_VECTOR_SIZE]; - struct face *default_face = FACE_FROM_ID (f, DEFAULT_FACE_ID); + struct face *default_face = FACE_OPT_FROM_ID (f, DEFAULT_FACE_ID); if (default_face == NULL) { if (!realize_basic_faces (f)) return -1; default_face = FACE_FROM_ID (f, DEFAULT_FACE_ID); - if (default_face == NULL) - emacs_abort (); /* realize_basic_faces must have set it up */ } if (! get_lface_attributes (f, symbol, symbol_attrs, signal_p, 0)) @@ -4600,9 +4598,6 @@ lookup_derived_face (struct frame *f, Lisp_Object symbol, int face_id, Lisp_Object symbol_attrs[LFACE_VECTOR_SIZE]; struct face *default_face = FACE_FROM_ID (f, face_id); - if (!default_face) - emacs_abort (); - if (!get_lface_attributes (f, symbol, symbol_attrs, signal_p, 0)) return -1; @@ -4706,7 +4701,7 @@ x_supports_face_attributes_p (struct frame *f, merge_face_vectors (f, attrs, merged_attrs, 0); face_id = lookup_face (f, merged_attrs); - face = FACE_FROM_ID (f, face_id); + face = FACE_OPT_FROM_ID (f, face_id); if (! face) error ("Cannot make face"); @@ -4976,14 +4971,12 @@ face for italic. */) attrs[i] = Qunspecified; merge_face_ref (f, attributes, attrs, true, 0); - def_face = FACE_FROM_ID (f, DEFAULT_FACE_ID); + def_face = FACE_OPT_FROM_ID (f, DEFAULT_FACE_ID); if (def_face == NULL) { if (! realize_basic_faces (f)) error ("Cannot realize default face"); def_face = FACE_FROM_ID (f, DEFAULT_FACE_ID); - if (def_face == NULL) - emacs_abort (); /* realize_basic_faces must have set it up */ } /* Dispatch to the appropriate handler. */ @@ -5453,7 +5446,7 @@ realize_x_face (struct face_cache *cache, Lisp_Object attrs[LFACE_VECTOR_SIZE]) /* Determine the font to use. Most of the time, the font will be the same as the font of the default face, so try that first. */ - default_face = FACE_FROM_ID (f, DEFAULT_FACE_ID); + default_face = FACE_OPT_FROM_ID (f, DEFAULT_FACE_ID); if (default_face && lface_same_font_attributes_p (default_face->lface, attrs)) { @@ -6093,7 +6086,6 @@ face_at_string_position (struct window *w, Lisp_Object string, *endptr = -1; base_face = FACE_FROM_ID (f, base_face_id); - eassert (base_face); /* Optimize the default case that there is no face property. */ if (NILP (prop) @@ -6140,7 +6132,7 @@ merge_faces (struct frame *f, Lisp_Object face_name, int face_id, Lisp_Object attrs[LFACE_VECTOR_SIZE]; struct face *base_face; - base_face = FACE_FROM_ID (f, base_face_id); + base_face = FACE_OPT_FROM_ID (f, base_face_id); if (!base_face) return base_face_id; @@ -6168,7 +6160,7 @@ merge_faces (struct frame *f, Lisp_Object face_name, int face_id, struct face *face; if (face_id < 0) return base_face_id; - face = FACE_FROM_ID (f, face_id); + face = FACE_OPT_FROM_ID (f, face_id); if (!face) return base_face_id; merge_face_vectors (f, face->lface, attrs, 0); @@ -6288,7 +6280,7 @@ DEFUN ("dump-face", Fdump_face, Sdump_face, 0, 1, 0, doc: /* */) { struct face *face; CHECK_NUMBER (n); - face = FACE_FROM_ID (SELECTED_FRAME (), XINT (n)); + face = FACE_OPT_FROM_ID (SELECTED_FRAME (), XINT (n)); if (face == NULL) error ("Not a valid face"); dump_realized_face (face); diff --git a/src/xterm.c b/src/xterm.c index 28856cf..beef61d 100644 --- a/src/xterm.c +++ b/src/xterm.c @@ -1062,7 +1062,7 @@ x_draw_vertical_window_border (struct window *w, int x, int y0, int y1) struct frame *f = XFRAME (WINDOW_FRAME (w)); struct face *face; - face = FACE_FROM_ID (f, VERTICAL_BORDER_FACE_ID); + face = FACE_OPT_FROM_ID (f, VERTICAL_BORDER_FACE_ID); if (face) XSetForeground (FRAME_X_DISPLAY (f), f->output_data.x->normal_gc, face->foreground); @@ -1081,9 +1081,11 @@ static void x_draw_window_divider (struct window *w, int x0, int x1, int y0, int y1) { struct frame *f = XFRAME (WINDOW_FRAME (w)); - struct face *face = FACE_FROM_ID (f, WINDOW_DIVIDER_FACE_ID); - struct face *face_first = FACE_FROM_ID (f, WINDOW_DIVIDER_FIRST_PIXEL_FACE_ID); - struct face *face_last = FACE_FROM_ID (f, WINDOW_DIVIDER_LAST_PIXEL_FACE_ID); + struct face *face = FACE_OPT_FROM_ID (f, WINDOW_DIVIDER_FACE_ID); + struct face *face_first + = FACE_OPT_FROM_ID (f, WINDOW_DIVIDER_FIRST_PIXEL_FACE_ID); + struct face *face_last + = FACE_OPT_FROM_ID (f, WINDOW_DIVIDER_LAST_PIXEL_FACE_ID); unsigned long color = face ? face->foreground : FRAME_FOREGROUND_PIXEL (f); unsigned long color_first = (face_first ? face_first->foreground @@ -1505,7 +1507,7 @@ x_set_mouse_face_gc (struct glyph_string *s) /* What face has to be used last for the mouse face? */ face_id = MOUSE_HL_INFO (s->f)->mouse_face_face_id; - face = FACE_FROM_ID (s->f, face_id); + face = FACE_OPT_FROM_ID (s->f, face_id); if (face == NULL) face = FACE_FROM_ID (s->f, MOUSE_FACE_ID); @@ -2156,6 +2158,7 @@ static const XColor * x_color_cells (Display *dpy, int *ncells) { struct x_display_info *dpyinfo = x_display_info_for_display (dpy); + eassume (dpyinfo); if (dpyinfo->color_cells == NULL) { @@ -2352,17 +2355,19 @@ x_alloc_nearest_color_1 (Display *dpy, Colormap cmap, XColor *color) equal to a cached pixel color recorded earlier, there was a change in the colormap, so clear the color cache. */ struct x_display_info *dpyinfo = x_display_info_for_display (dpy); - XColor *cached_color; + eassume (dpyinfo); - if (dpyinfo->color_cells - && (cached_color = &dpyinfo->color_cells[color->pixel], - (cached_color->red != color->red - || cached_color->blue != color->blue - || cached_color->green != color->green))) + if (dpyinfo->color_cells) { - xfree (dpyinfo->color_cells); - dpyinfo->color_cells = NULL; - dpyinfo->ncolor_cells = 0; + XColor *cached_color = &dpyinfo->color_cells[color->pixel]; + if (cached_color->red != color->red + || cached_color->blue != color->blue + || cached_color->green != color->green) + { + xfree (dpyinfo->color_cells); + dpyinfo->color_cells = NULL; + dpyinfo->ncolor_cells = 0; + } } } commit 6f5db0255cab2e17ab53ee68f6dc2f4d75978d80 Author: Paul Eggert Date: Wed May 18 00:05:53 2016 -0700 Sync from gnulib This incorporates: 2016-05-17 manywarnings: update for GCC 6.1 2016-05-13 intdiv0, memmem, nocrash, strcasestr, strstr: no exit * m4/manywarnings.m4, m4/nocrash.m4: Copy from gnulib. diff --git a/m4/manywarnings.m4 b/m4/manywarnings.m4 index 12d68da..90823b0 100644 --- a/m4/manywarnings.m4 +++ b/m4/manywarnings.m4 @@ -1,4 +1,4 @@ -# manywarnings.m4 serial 7 +# manywarnings.m4 serial 8 dnl Copyright (C) 2008-2016 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, @@ -129,6 +129,7 @@ AC_DEFUN([gl_MANYWARN_ALL_GCC], -Wdiscarded-qualifiers \ -Wdiv-by-zero \ -Wdouble-promotion \ + -Wduplicated-cond \ -Wempty-body \ -Wendif-labels \ -Wenum-compare \ @@ -140,7 +141,10 @@ AC_DEFUN([gl_MANYWARN_ALL_GCC], -Wformat-signedness \ -Wformat-y2k \ -Wformat-zero-length \ + -Wframe-address \ -Wfree-nonheap-object \ + -Whsa \ + -Wignored-attributes \ -Wignored-qualifiers \ -Wimplicit \ -Wimplicit-function-declaration \ @@ -158,6 +162,7 @@ AC_DEFUN([gl_MANYWARN_ALL_GCC], -Wmain \ -Wmaybe-uninitialized \ -Wmemset-transposed-args \ + -Wmisleading-indentation \ -Wmissing-braces \ -Wmissing-declarations \ -Wmissing-field-initializers \ @@ -168,6 +173,8 @@ AC_DEFUN([gl_MANYWARN_ALL_GCC], -Wnarrowing \ -Wnested-externs \ -Wnonnull \ + -Wnonnull-compare \ + -Wnull-dereference \ -Wodr \ -Wold-style-declaration \ -Wold-style-definition \ @@ -184,10 +191,12 @@ AC_DEFUN([gl_MANYWARN_ALL_GCC], -Wpragmas \ -Wreturn-local-addr \ -Wreturn-type \ + -Wscalar-storage-order \ -Wsequence-point \ -Wshadow \ -Wshift-count-negative \ -Wshift-count-overflow \ + -Wshift-negative-value \ -Wsizeof-array-argument \ -Wsizeof-pointer-memaccess \ -Wstack-protector \ @@ -205,6 +214,7 @@ AC_DEFUN([gl_MANYWARN_ALL_GCC], -Wswitch-default \ -Wsync-nand \ -Wsystem-headers \ + -Wtautological-compare \ -Wtrampolines \ -Wtrigraphs \ -Wtype-limits \ @@ -237,6 +247,8 @@ AC_DEFUN([gl_MANYWARN_ALL_GCC], # them here so that the above 'comm' command doesn't report a false match. gl_manywarn_set="$gl_manywarn_set -Warray-bounds=2" gl_manywarn_set="$gl_manywarn_set -Wnormalized=nfc" + gl_manywarn_set="$gl_manywarn_set -Wshift-overflow=2" + gl_manywarn_set="$gl_manywarn_set -Wunused-const-variable=2" # These are needed for older GCC versions. if test -n "$GCC"; then diff --git a/m4/nocrash.m4 b/m4/nocrash.m4 index ecc55c6..d8dd8f1 100644 --- a/m4/nocrash.m4 +++ b/m4/nocrash.m4 @@ -110,11 +110,12 @@ nocrash_init (void) #else /* Avoid a crash on POSIX systems. */ #include +#include /* A POSIX signal handler. */ static void exception_handler (int sig) { - exit (1); + _exit (1); } static void nocrash_init (void)