+(defun idlwave-shell-scan-for-state ()
+ "Scan for state info. Looks for messages in output from last IDL
+command indicating where IDL has stopped. The types of messages we are
+interested in are execution halted, stepped, breakpoint, interrupted
+at and trace messages. For breakpoint messages process any attached
+count or command parameters. Update the stop line if a message is
+found. The variable `idlwave-shell-current-state' is set to 'error,
+'halt, or 'breakpoint, which describes the status, or nil for none of
+the above."
+ (let (trace)
+ (cond
+ ;; Make sure we have output
+ ((not idlwave-shell-command-output))
+
+ ;; First Priority: Syntax and other errors
+ ((or
+ (string-match idlwave-shell-syntax-error
+ idlwave-shell-command-output)
+ (string-match idlwave-shell-other-error
+ idlwave-shell-command-output))
+ (with-current-buffer
+ (get-buffer-create idlwave-shell-error-buffer)
+ (erase-buffer)
+ (insert idlwave-shell-command-output)
+ (goto-char (point-min))
+ (setq idlwave-shell-error-last (point)))
+ (setq idlwave-shell-current-state 'error)
+ (idlwave-shell-goto-next-error))
+
+ ;; Second Priority: Halting errors
+ ((string-match idlwave-shell-halting-error
+ idlwave-shell-command-output)
+ ;; Grab the file and line state info.
+ (setq idlwave-shell-calling-stack-index 0)
+ (setq idlwave-shell-halt-frame
+ (idlwave-shell-parse-line
+ (substring idlwave-shell-command-output
+ (match-beginning 2)))
+ idlwave-shell-current-state 'error)
+ (idlwave-shell-display-line (idlwave-shell-pc-frame)))
+
+ ;; Third Priority: Various types of innocuous HALT and
+ ;; TRACEBACK messages.
+ ((or (setq trace (string-match idlwave-shell-trace-message-re
+ idlwave-shell-command-output))
+ (string-match idlwave-shell-halt-messages-re
+ idlwave-shell-command-output))
+ ;; Grab the file and line state info.
+ (setq idlwave-shell-calling-stack-index 0)
+ (setq idlwave-shell-halt-frame
+ (idlwave-shell-parse-line
+ (substring idlwave-shell-command-output (match-end 0))))
+ (setq idlwave-shell-current-state 'halt)
+ ;; Don't debug trace messages
+ (idlwave-shell-display-line
+ (idlwave-shell-pc-frame) nil
+ (if trace 'disable
+ (if idlwave-shell-electric-debug-mode 'force))))
+
+ ;; Fourth Priority: Breakpoints
+ ((string-match idlwave-shell-break-message
+ idlwave-shell-command-output)
+ (setq idlwave-shell-calling-stack-index 0)
+ (setq idlwave-shell-halt-frame
+ (idlwave-shell-parse-line
+ (substring idlwave-shell-command-output (match-end 0))))
+ ;; We used to count hits on breakpoints
+ ;; this is no longer supported since IDL breakpoints
+ ;; have learned counting.
+ ;; Do breakpoint command processing
+ (let ((bp (assoc
+ (list
+ (nth 0 idlwave-shell-halt-frame)
+ (nth 1 idlwave-shell-halt-frame))
+ idlwave-shell-bp-alist)))
+ ;(message "Scanning with %s" bp)
+ (if bp
+ (let ((cmd (idlwave-shell-bp-get bp 'cmd)))
+ (if cmd ;; Execute any breakpoint command
+ (if (listp cmd) (eval cmd) (funcall cmd))))
+ ;; A breakpoint that we did not know about - perhaps it was
+ ;; set by the user... Let's update our list.
+ (idlwave-shell-bp-query)))
+ (setq idlwave-shell-current-state 'breakpoint)
+ (idlwave-shell-display-line (idlwave-shell-pc-frame)))
+
+ ;; Last Priority: Can't Step errors
+ ((string-match idlwave-shell-cant-continue-error
+ idlwave-shell-command-output)
+ (setq idlwave-shell-current-state 'breakpoint))
+
+ ;; Otherwise, no particular state
+ (t (setq idlwave-shell-current-state nil)))))
+
+
+(defun idlwave-shell-parse-line (string &optional skip-main)
+ "Parse IDL message for the subroutine, file name and line number."
+;We need to work hard here to remove the stupid line breaks inserted by
+;IDL5. These line breaks can be right in the middle of procedure
+;or file names.
+;It is very difficult to come up with a robust solution. This one seems
+;to be pretty good though.
+;
+;Here is in what ways it improves over the previous solution:
+;
+;1. The procedure name can be split and will be restored.
+;2. The number can be split. I have never seen this, but who knows.
+;3. We do not require the `.pro' extension for files.
+;
+;This function can still break when the file name ends on an end line
+;and the message line contains an additional line with garbage. Then
+;the first part of that garbage will be added to the file name.
+;However, the function checks the existence of the files with and
+;without this last part - thus the function only breaks if file name
+;plus garbage match an existing regular file. This is hopefully very
+;unlikely.
+;
+;If optional arg SKIP-MAIN is non-nil, don't parse $MAIN$ routine stop
+;statements.