-(defconst byte-compile-last-warned-form nil)
-(defconst byte-compile-last-logged-file nil)
-
-;; Log a message STRING in *Compile-Log*.
-;; Also log the current function and file if not already done.
-(defun byte-compile-log-1 (string &optional fill)
- (cond (noninteractive
- (if (or (and byte-compile-current-file
- (not (equal byte-compile-current-file
- byte-compile-last-logged-file)))
- (and byte-compile-last-warned-form
- (not (eq byte-compile-current-form
- byte-compile-last-warned-form))))
- (message "While compiling %s%s:"
- (or byte-compile-current-form "toplevel forms")
- (if byte-compile-current-file
- (if (stringp byte-compile-current-file)
- (concat " in file " byte-compile-current-file)
- (concat " in buffer "
- (buffer-name byte-compile-current-file)))
- "")))
- (message " %s" string))
- (t
- (save-excursion
- (set-buffer (get-buffer-create "*Compile-Log*"))
- (goto-char (point-max))
- (cond ((or (and byte-compile-current-file
- (not (equal byte-compile-current-file
- byte-compile-last-logged-file)))
- (and byte-compile-last-warned-form
- (not (eq byte-compile-current-form
- byte-compile-last-warned-form))))
-;;; This is redundant, since it is given at the start of the file,
-;;; and the extra clutter gets in the way -- rms.
-;;; (if (and byte-compile-current-file
-;;; (not (equal byte-compile-current-file
-;;; byte-compile-last-logged-file)))
-;;; (insert "\n\^L\n" (current-time-string) "\n"))
- (insert "\nWhile compiling "
- (if byte-compile-current-form
- (format "%s" byte-compile-current-form)
- "toplevel forms"))
-;;; This is redundant, since it is given at the start of the file,
-;;; and the extra clutter gets in the way -- rms.
-;;; (if byte-compile-current-file
-;;; (if (stringp byte-compile-current-file)
-;;; (insert " in file " byte-compile-current-file)
-;;; (insert " in buffer "
-;;; (buffer-name byte-compile-current-file))))
- (insert ":\n")))
- (insert " " string "\n")
- (if (and fill (not (string-match "\n" string)))
- (let ((fill-prefix " ")
- (fill-column 78))
- (fill-paragraph nil)))
- )))
+;; Log something that isn't a warning.
+(defun byte-compile-log-1 (string)
+ (save-excursion
+ (byte-goto-log-buffer)
+ (goto-char (point-max))
+ (byte-compile-warning-prefix nil nil)
+ (cond (noninteractive
+ (message " %s" string))
+ (t
+ (insert (format "%s\n" string))))))
+
+(defvar byte-compile-read-position nil
+ "Character position we began the last `read' from.")
+(defvar byte-compile-last-position nil
+ "Last known character position in the input.")
+
+;; copied from gnus-util.el
+(defsubst byte-compile-delete-first (elt list)
+ (if (eq (car list) elt)
+ (cdr list)
+ (let ((total list))
+ (while (and (cdr list)
+ (not (eq (cadr list) elt)))
+ (setq list (cdr list)))
+ (when (cdr list)
+ (setcdr list (cddr list)))
+ total)))
+
+;; The purpose of this function is to iterate through the
+;; `read-symbol-positions-list'. Each time we process, say, a
+;; function definition (`defun') we remove `defun' from
+;; `read-symbol-positions-list', and set `byte-compile-last-position'
+;; to that symbol's character position. Similarly, if we encounter a
+;; variable reference, like in (1+ foo), we remove `foo' from the
+;; list. If our current position is after the symbol's position, we
+;; assume we've already passed that point, and look for the next
+;; occurrence of the symbol.
+;; So your're probably asking yourself: Isn't this function a
+;; gross hack? And the answer, of course, would be yes.
+(defun byte-compile-set-symbol-position (sym &optional allow-previous)
+ (when byte-compile-read-position
+ (let (last entry)
+ (while (progn
+ (setq last byte-compile-last-position
+ entry (assq sym read-symbol-positions-list))
+ (when entry
+ (setq byte-compile-last-position
+ (+ byte-compile-read-position (cdr entry))
+ read-symbol-positions-list
+ (byte-compile-delete-first
+ entry read-symbol-positions-list)))
+ (or (and allow-previous (not (= last byte-compile-last-position)))
+ (> last byte-compile-last-position)))))))
+
+(defvar byte-compile-last-warned-form nil)
+(defvar byte-compile-last-logged-file nil)
+
+(defun byte-goto-log-buffer ()
+ (set-buffer (get-buffer-create "*Compile-Log*"))
+ (unless (eq major-mode 'compilation-mode)
+ (compilation-mode)))
+
+;; This is used as warning-prefix for the compiler.
+;; It is always called with the warnings buffer current.
+(defun byte-compile-warning-prefix (level entry)
+ (let* ((dir default-directory)
+ (file (cond ((stringp byte-compile-current-file)
+ (format "%s:" (file-relative-name byte-compile-current-file dir)))
+ ((bufferp byte-compile-current-file)
+ (format "Buffer %s:"
+ (buffer-name byte-compile-current-file)))
+ (t "")))
+ (pos (if (and byte-compile-current-file
+ (integerp byte-compile-read-position))
+ (with-current-buffer byte-compile-current-buffer
+ (format "%d:%d:" (count-lines (point-min)
+ byte-compile-last-position)
+ (save-excursion
+ (goto-char byte-compile-last-position)
+ (1+ (current-column)))))
+ ""))
+ (form (if (eq byte-compile-current-form :end) "end of data"
+ (or byte-compile-current-form "toplevel form"))))
+ (when (or (and byte-compile-current-file
+ (not (equal byte-compile-current-file
+ byte-compile-last-logged-file)))
+ (and byte-compile-current-form
+ (not (eq byte-compile-current-form
+ byte-compile-last-warned-form))))
+ (insert (format "\nIn %s:\n" form)))
+ (when level
+ (insert (format "%s%s" file pos))))