[Openmcl-devel] capturing compile errors and warnings

John DeSoi desoi at pgedit.com
Tue Jun 15 20:19:36 PDT 2010

Hi Gary,

On Jun 14, 2010, at 10:53 PM, Gary Byers wrote:

> There isn't a real easy out-of-the-box way to do this, but it's
> probably not too hard to cobble something together (and might be an
> interesting exercise.)  If you think that this sort of thing is "an
> interesting exercise", you'll probably be fascinated by the exercise
> called "fixing any bugs or omissions in this code."

Thanks very much for your help. First "interesting exercise" was that it worked for breaks but not compiler warnings. But obviously WARN does call ccl::%break-message. I found ccl::report-compiler-warning and just added the same advise call.

>  There might
> be some other, less disruptive approaches somewhere between this behavior
> and what currently happens.

Yes, it could be annoying if it happened all the time. My current desire is to evaluate stuff in the editor without having to arrange the listener window so it is visible all the time in order to know if there are any problems. I added a :before method to eval-in-listener-process so that the listener is raised only when this method is used. Not the best design, but good enough for now.

Thanks again,

John DeSoi, Ph.D.


(advise ccl::%break-message
  (ccl::application-ui-operation ccl::*application*
       :note-break-message *error-output*))

;note: ccl::%break-message is called by WARN but the compiler uses REPORT-COMPILER-WARNING
(advise ccl::report-compiler-warning 
        (ccl::application-ui-operation ccl::*application*
       :note-break-message *error-output*))

; Set the flag before eval-in-listener-process is used. This prevents bringing the listener forward for 
; errors and warnings that were not the result of an IDE operation, e.g. compiling a big system.
(defvar *raise-listener-on-errors-and-warnings* nil)

(defmethod eval-in-listener-process :before ((process cocoa-listener-process)
                                     string &key path package offset)
  (declare (ignore string path package offset))
  (setf *raise-listener-on-errors-and-warnings* t))

(defmethod ccl::ui-object-do-operation ((o ns::ns-application)
                                        (operation (eql :note-break-message))
                                        &rest args)
  "The first and only arg is a stream to which a condition is about to
  be printed by WARN or ERROR or ... .  If there's a window associated
  with that stream, activate that window."
  ;; Most streams don't have "windows associated with them", but the
  ;; output streams associated with Cocoa listeners do.  Try to see
  ;; if output is ultimately going to such a stream.
  (when *raise-listener-on-errors-and-warnings*
    (setf *raise-listener-on-errors-and-warnings* nil) ;only needs to be used once per interface operation anyway
    (let* ((stream (car args)))
      (do* ()
           ((not (or (typep stream 'synonym-stream)
                     (typep stream 'two-way-stream))))
        (if (typep stream 'synonym-stream)
          (setq stream (ignore-errors (symbol-value (synonym-stream-symbol stream))))
          (if (typep stream 'two-way-stream)
            (setq stream (two-way-stream-output-stream stream)))))
      (when (typep stream 'gui::cocoa-listener-output-stream)
        (let* ((hemlock-view (slot-value stream 'gui::hemlock-view)))
          (when hemlock-view
            (let* ((pane (hi::hemlock-view-pane hemlock-view)))
              (when (typep pane 'ns:ns-view)
                (let* ((window (#/window pane)))
                  (#/makeKeyAndOrderFront: window +null-ptr+))))))))))

More information about the Openmcl-devel mailing list