• Skip to main content
  • Skip to search
  • Skip to footer
Cadence Home
  • This search text may be transcribed, used, stored, or accessed by our third-party service providers per our Cookie Policy and Privacy Policy.

  1. Community Forums
  2. Custom IC SKILL
  3. Accessing SKILL runtime error locations outside the IDE...

Stats

  • Replies 8
  • Subscribers 149
  • Views 278
  • Members are here 0

Accessing SKILL runtime error locations outside the IDE (Vim workflow)

TF202506034656
TF202506034656 1 day ago

Good evening,

I primarily develop SKILL in Vim and rarely use the SKILL IDE. The IDE has one feature that I've been looking for ways to emulate. When a runtime error occurs, it focuses the editor on the offending line and highlights it.

Is there any way to access this same functionality through the public API outside of the IDE? I understand highlighting + viewpoint shifting definitely isn't possible, but  I could emulate this myself. 


Anything would help, I could do highlighting if there was some way to at least get the line number.



I'm running version IC23.1-64b and follow the usual load("script.il") in the CIW and execute workflow.

Thanks,

Trevor Farias

  • Cancel
  • Sign in to reply
Parents
  • Aurel B
    Aurel B 1 day ago

    Hi,

    If you want to enter the dark side of SKILL, you can actually redefine the errorHandler function to whatever you like.

    Be careful

    Aurélien 

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • Cancel
  • Aurel B
    Aurel B 1 day ago in reply to Aurel B

    No idea why I could not format my code properly this time...

    The following defines an error handler that tries to look for the first errorful function in the stack and open its definition if you loaded your files with debugMode enabled (and keepSrcInfo is probably required as well) 

    (inScheme (let ()

    (defglobalfun errorHandler ( @rest errset_values
    @aux ( errport (symeval 'errport) ) ( stack_trace (get_stack_trace) )
    )
    "Custom error handler to call editor on errorful file."
    ;; This function is minimalist on purpose as we don't want to raise errors inside the error handler
    (fprintf errport "%N\n" errset_values)
    (fprintf errport "%s\n" stack_trace)
    (errset (try_to_open_editor errset_values stack_trace) t)
    );fun

    (defun get_stack_trace ()
    "Return the current stack trace string."
    (let ( ( port (outstring) )
    )
    (unwindProtect
    ;; 9999 is meant to be bigger than the maximum stack size
    ;; 8 is exactly the number of levels so that the stack trace do not report the functions we are currently defining
    ;; (When modifying this code, make sure to adapt this number accordingly)
    (progn (stacktrace t 9999 8 port) (getOutstring port))
    (close port)
    );unwind
    ));let ;fun

    (defun try_to_open_editor ( errset_values stack_trace )
    "Try to parse ERRSET_VALUES or STACK_TRACE to raise editor at the proper location."
    (let ( file line )
    (cond
    ;; Try to parse errset values
    ( (setq file (pcre_get_match "error while loading file - \"(.+)\"" (car (nth 4 errset_values))))
    (setq line (pcre_get_match "at line ([0-9]+)$" (car (nth 4 errset_values))))
    (open_editor file (if line (atoi line) 0))
    )
    ;; Try to find the first function whose location is stored
    ;; Skip the first <<< Stack Trace >>> line
    ( (exists sexp_str (cdr (parseString stack_trace "\n"))
    (let ( ( sexp (linereadstring sexp_str))
    )
    (when (and (listp sexp) (listp (car sexp)))
    (destructuringBind ( _file _line ) (get_function_source (caar sexp))
    (setq line _line)
    (setq file _file)
    ));dbind ;when
    ));let ;exists
    (open_editor file (cond ( (integerp line) line ) ( (stringp line) (atoi line) ) ( t 0 )))
    )
    );cond
    ));let ;fun

    (defun get_function_source ( name "s" )
    "Try to get source information of function named NAME.
    This works only if function was loaded in debug mode and using `(sstatus keepSrcInfo t)`."
    (if (stringp (get name '_loadFile))
    ;; Function source is defined, use it
    (list (get name '_loadFile) (get name '_loadLine))
    ;; Try with `whereIs`, no idea if this is useful
    (letseq ( ( po_port (symeval 'poport) )
    ( tmp_port (outstring) )
    ( msg (unwindProtect
    (progn (set 'poport tmp_port) (funcall 'whereIs name) (getOutstring tmp_port))
    (progn (set 'poport po_port ) (close tmp_port))
    ) )
    )
    (list
    (pcre_get_match "is defined in file \"(.+)\"" msg)
    (pcre_get_match "at line ([0-9]+).$" msg)
    ));list ;letseq
    ));if ;defun

    (defun pcre_get_match ( pattern string "tt" )
    "Safely return the first PCRE group if PATTERN matches STRING, return nil otherwise"
    (let ( ( magic (rexMagic) )
    )
    (unwindProtect
    (progn (rexMagic t) (when (pcreMatchp pattern string) (pcreSubstitute "\\1")))
    (rexMagic magic)
    )
    ));let ;def

    (defun open_editor ( file line "tx" )
    "Open editor on FILE at LINE."
    ;; I do not despise `vi` users but I'm used to a better editor (which is also coded in Lisp!)
    ;; Feel free to replace it with whatever commands that will raise `vi` on the proper FILE+LINE
    (sh (lsprintf "emacsclient -n +%d '%s' &" line file))
    )

    ));Scheme ;closure

    ;*/
    • Cancel
    • Vote Up +1 Vote Down
    • Sign in to reply
    • Cancel
  • TF202506034656
    TF202506034656 1 day ago in reply to Aurel B

    I was this close to sending a huge thank you, and then I saw the last comment...
    In all seriousness this is wonderful, I am 100% incorporating this masterpiece into my workflow. I very much appreciate this!
    Thanks, Trevor

    • Cancel
    • Vote Up +1 Vote Down
    • Sign in to reply
    • Cancel
Reply
  • TF202506034656
    TF202506034656 1 day ago in reply to Aurel B

    I was this close to sending a huge thank you, and then I saw the last comment...
    In all seriousness this is wonderful, I am 100% incorporating this masterpiece into my workflow. I very much appreciate this!
    Thanks, Trevor

    • Cancel
    • Vote Up +1 Vote Down
    • Sign in to reply
    • Cancel
Children
No Data

Community Guidelines

The Cadence Design Communities support Cadence users and technologists interacting to exchange ideas, news, technical information, and best practices to solve problems and get the most from Cadence technology. The community is open to everyone, and to provide the most value, we require participants to follow our Community Guidelines that facilitate a quality exchange of ideas and information. By accessing, contributing, using or downloading any materials from the site, you agree to be bound by the full Community Guidelines.

© 2025 Cadence Design Systems, Inc. All Rights Reserved.

  • Terms of Use
  • Privacy
  • Cookie Policy
  • US Trademarks
  • Do Not Sell or Share My Personal Information