Debugging Script-Fu Plug-ins

Here are some debugging techniques using the Script-Fu API function (gimp-message)

To get anywhere with a script I have to write many debug statements that let me know if what I think is happening is actually happening. It’s useful to keep all those debug messages in the final script to help future me, or another Script-Fu writer. However seeing all those messages can be annoying when you’re working. How can we set up a script so that you can gain more control over those helpful messages?

It’s possible to use a function to define a global variable in Script-Fu. This can then be used to decide when particular debug messages will get printed out.

(define debug #t)

With this defined in your plugin, you can use an if true statement to control the message activation.

(if debug (gimp-message " This is a debug flag controlled message "))

Hopefully you can see that it’s possible to define more debug flags for extra options.
Another useful technique for pinning down an error is performing a binary search (this half, this quarter, this eighth… …this line.) with message statements. The following procedure definition provides a shortcut, to help this method.

(define (here x)(gimp-message(string-append " >>> " (number->string x) " <<<")))

Having the line (here 1) in your script would call the above procedure and print out the message;

>>> 1 <<<

Because the numbers after the error will not get printed, you can find the problem line with the code.

Sometimes you may want to stop the script, it is possible to force a stop with another small function definition and the ‘quit’ keyword.

(define (err msg)(gimp-message(string-append " >>> " msg " <<<"))(quit))

Having the line (err " the logic was faulty “) in your script would call the above procedure and print out the message;

  Debug Examples Warning
 >>>  the logic was faulty  <<<

I like to debug using the error console, but you can also switch to debugging in the terminal. The following plugin demonstrates that process and a few other tricks.

Copy and save to a file called debug-examples.scm, in a folder called debug-examples, in a Gimp plug-ins location. In Linux, right click debug-examples.scm;
properties->permissions->allow executing file as program

This GIMP 3 plug-in should appear in a Fu-Plugin menu.

#!/usr/bin/env gimp-script-fu-interpreter-3.0
(define (script-fu-debug-examples)
  (let*
    (
      (msg "")(i 0)
    )

    (here 1)

    (if debug (gimp-message " This is a debug flag controlled message "))
    (if info (gimp-message " This is an info flag controlled message "))

    (if info
      (gimp-message
        " usually error messages are printed in the error console dockable "
      )
    )

    (here 2)

    (if info
      (gimp-message
        " sadly, every message gets a loud warning prefix "
      )
    )

    (if info
      (gimp-message
        (string-append
        " (gimp-message-set-handler 1) redirects all debug messages to the"
        " terminal \n bring the terminal to the foreground to see the message "
        )
      )
    )

    (here 3)

    (gimp-message-set-handler 1)

    (if info (gimp-message " This is a message sent to the terminal window"))

    (here 4)

    (gimp-message-set-handler 2)

    (if info
      (gimp-message
        " (gimp-message-set-handler 2) sends them back to the console "
      )
    )

    (if info (gimp-message " This is a message sent to the error console"))

    (if info
      (gimp-message
        " if the error console is closed, errors get sent to the status bar "
      )
    )

    (if info
      (gimp-message
        " (gimp-message-set-handler 0) also redirects them to the status bar "
      )
    )

    (gimp-message-set-handler 0)

     (if info (gimp-message " sent to the status bar "))

    (if info
      (gimp-message
         (string-append
           " if the message sent to the status bar has a newline or is too long"
           "\n to fit in the bar, then a pop-up warning box will appear "
         )
      )
    )

    (gimp-message-set-handler 2)

    (if info
      (gimp-message
        (string-append
        " a debug message can be created inside a loop and then printed out "
        " to avoid a lots of warnings "
        )
      )
    )

    (here 5.1)

    (while (< i 10)
      (set! info (number->string i))
      (set! msg (string-append msg " information from a loop : " info "\n"))
      (set! i (+ i 1))
    )

    (if info (gimp-message msg))

    (if info
      (gimp-message
        (string-append
        " finally, you may want to stop a script if a condition is met "
        " a procedure defined in this plugin (err msg) does that"
        )
      )
    )

    (if (not falseFlag) (err " the logic was faulty "))

    (here 5.2)

  )
)


; debug and error macro
(define (err msg)(gimp-message(string-append " >>> " msg " <<<"))(quit))
(define (here x)(gimp-message(string-append " >>> " (number->string x) " <<<")))
(define debug #t) ; print all debug information
(define info #t)  ; print information
(define falseFlag  #f) ; example of error message

(script-fu-register "script-fu-debug-examples"
 "Debug Examples"
 "An example of debugging methods in Script-Fu"
 "Mark Sweeney"
 "copyright 2023, Mark Sweeney, Under GNU GENERAL PUBLIC LICENSE Version 3"
 "2023"
 ""
)
(script-fu-menu-register "script-fu-debug-examples" "<Image>/Fu-Plugin")