Author Topic: So you're writing this large lisp application ...  (Read 6688 times)

0 Members and 1 Guest are viewing this topic.

MP

  • Seagull
  • Posts: 17750
  • Have thousands of dwgs to process? Contact me.
So you're writing this large lisp application ...
« on: October 08, 2005, 08:14:44 AM »
... and it just isn't functioning the way you want.

So ... to debug it you (1) dump variables (2) put in breakpoints .

What else do you do?
Engineering Technologist • CAD Automation Practitioner
Automation ▸ Design ▸ Drafting ▸ Document Control ▸ Client
cadanalyst@gmail.comhttp://cadanalyst.slack.comhttp://linkedin.com/in/cadanalyst

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: So you're writing this large lisp application ...
« Reply #1 on: October 08, 2005, 08:23:24 AM »
>>>>  the way you want.


errors or slow or inconsistant output ??

but yes, essentially dumps and breakpoints. :-(
kdub, kdub_nz in other timelines.
Perfection is not optional.
Everything will work just as you expect it to, unless your expectations are incorrect.
Discipline: None at all.

Mark

  • Custom Title
  • Seagull
  • Posts: 28762
Re: So you're writing this large lisp application ...
« Reply #2 on: October 08, 2005, 08:32:47 AM »
I sometimes use "(alert (princ var))".

Do you consider that ^ a break point?
TheSwamp.org  (serving the CAD community since 2003)

Peter Jamtgaard

  • Guest
Re: So you're writing this large lisp application ...
« Reply #3 on: October 08, 2005, 08:56:28 AM »
Break the application up into smaller subroutines and functions.
Test each function for desired results.
Spagetti code is functional but hard to debug.
Structured programming is easier to debug, and much of the code becomes reusable.

Like create a library (toolbox.lsp) of useful functions that you use all the time.
Then load the toolbox in every drawing or have the individual routine load the library, or use autoload.

If a routine is used in multiple other routines, move it to your toolbox and take it out of your individual routines.

This keeps the code easier to upgrade and also keeps similar routines

Peter

MP

  • Seagull
  • Posts: 17750
  • Have thousands of dwgs to process? Contact me.
Re: So you're writing this large lisp application ...
« Reply #4 on: October 08, 2005, 09:05:56 AM »
As noted I've found that most folks debug the same way, at least by observing coders at my primary client's office. What's interesting is that as often as this exercise is performed many folks don't have dedicated functions for this important task, as few as they need to be.

So yes -- I too put in dumps and breakpoints.

In it's distilled form I have two simple functions, one called (Dump x) and the other called (Wait). Ok, there's a third called (DumpAndWait x) which is self explainatory and a convenience function 'cause I be lazy.

(Dump x) takes a sole parameter and spews formatted information about the argument -- and here's an important trait -- it then returns the argument as received, in other words it does a pass thru. If the argument passed is a quoted symbol it prints the name and then the data it hosts, otherwise just the data. Example (Dump 'x) versus (Dump x). This will allow me to do things like (setq myPi (Dump pi)), spewing info about the symbol pi, but returning it so it assigned via the setq statement to variable myPi.

(Wait) does nothing but halt program execution until the user presses [Enter].

So ... let's say I define (Dump x), (Wait) and (DumpAndWait x) in a library called debug.lsp.

A contrived little proggy:

Code: [Select]
(defun c:TEST  ( / a b c d e )

    (princ "Begin TEST ...\n\n")

    (setq
        a  1
        b  "2"
        c  ((lambda (x) (repeat 8 (setq x (append x x)))) '(1 2 3))
        d  (ssget "x")
    )

    (dump 'a)

    (dump 'b)
   
    (dump 'c)

    (dump 'd)
   
    (cond
        (   (eq 'pickset (type d))
            (dump (setq e (ssname d 0)))
            (dump (vlax-ename->vla-object e))
        )   
    )

    (princ "End TEST ...\n\n")

    (princ)

)

Might spew ...

Code: [Select]
Begin TEST ...

;================================ Dump 1.0 =================================
;
; Atom Name: A
; Atom Type: INT
;
;===========================================================================
;
; 1
;
;===========================================================================


;================================ Dump 1.0 =================================
;
; Atom Name: B
; Atom Type: STR
;
;===========================================================================
;
; StrLen = 1
;
; "2"
;
;===========================================================================


;================================ Dump 1.0 =================================
;
; Atom Name: C
; Atom Type: LIST
;
;===========================================================================
;
; Length = 768
;
; (1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3
; 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1
;  2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1
; 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2
;  3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2
; 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3
;  1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3
; 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1
;  2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1
; 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2
;  3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2
; 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3
;  1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3
; 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1
;  2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1
; 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2
;  3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2
; 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3
;  1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3
; 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1
;  2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1
; 2 3)
;
;===========================================================================


;================================ Dump 1.0 =================================
;
; Atom Name: D
; Atom Type: PICKSET
;
;===========================================================================
;
; SSLength = 1
;
; <Selection set: 21>
;
;===========================================================================


;================================ Dump 1.0 =================================
;
; Atom Type: ENAME
;
;===========================================================================
;
; (
;   (-1 . <Entity name: 7ef70f68>)
;   (0 . "CIRCLE")
;   (330 . <Entity name: 7ef70cf8>)
;   (5 . "A5")
;   (100 . "AcDbEntity")
;   (67 . 0)
;   (410 . "Model")
;   (8 . "0")
;   (100 . "AcDbCircle")
;   (10 33.5609 4.2347 0.0)
;   (40 . 1.30078)
;   (210 0.0 0.0 1.0)
; )
;
;===========================================================================


;================================ Dump 1.0 =================================
;
; Atom Type: VLA-OBJECT
;
;===========================================================================
;
; IAcadCircle: AutoCAD Circle Interface
; Property values:
;   Application (RO) = #<VLA-OBJECT IAcadApplication 00c2eb8c>
;   Area = 5.31566
;   Center = (33.5609 4.2347 0.0)
;   Circumference = 8.17304
;   Diameter = 2.60156
;   Document (RO) = #<VLA-OBJECT IAcadDocument 0cf37924>
;   Handle (RO) = "A5"
;   HasExtensionDictionary (RO) = 0
;   Hyperlinks (RO) = #<VLA-OBJECT IAcadHyperlinks 0e4c0574>
;   Layer = "0"
;   Linetype = "ByLayer"
;   LinetypeScale = 1.0
;   Lineweight = -1
;   Normal = (0.0 0.0 1.0)
;   ObjectID (RO) = 2130120552
;   ObjectName (RO) = "AcDbCircle"
;   OwnerID (RO) = 2130119928
;   PlotStyleName = "ByLayer"
;   Radius = 1.30078
;   Thickness = 0.0
;   TrueColor = #<VLA-OBJECT IAcadAcCmColor 0e4c0cc0>
;   Visible = -1
; Methods supported:
;   ArrayPolar (3)
;   ArrayRectangular (6)
;   Copy ()
;   Delete ()
;   GetBoundingBox (2)
;   GetExtensionDictionary ()
;   GetXData (3)
;   Highlight (1)
;   IntersectWith (2)
;   Mirror (2)
;   Mirror3D (3)
;   Move (2)
;   Offset (1)
;   Rotate (2)
;   Rotate3D (3)
;   ScaleEntity (2)
;   SetXData (2)
;   TransformBy (1)
;   Update ()
;
;===========================================================================

End TEST ...

When I'm done debuggging the application I may decide to keep the debugging tools in place, but define (Dump x), (Wait) and (DumpAndWait x) locally so they have the same signature but do nothing --

Code: [Select]
(defun c:TEST ( / Dump Wait DumpAndWait  a b c d e )

    (defun Dump (x) x)
    (defun Wait ( ) (princ))
    (defun DumpAndWait (x) x)

    (princ "Begin TEST ...\n\n")

    (setq
        a  1
        b  "2"
        c  ((lambda (x) (repeat 8 (setq x (append x x)))) '(1 2 3))
        d  (ssget "x")
    )

    (dump 'a)

    (dump 'b)

    (dump 'c)

    (dump 'd)

    (cond
        (   (eq 'pickset (type d))
            (dump (setq e (ssname d 0)))
            (dump (vlax-ename->vla-object e))
        )
    )

    (princ "End TEST ...\n\n")

    (princ)

)

A run will now output this --

Code: [Select]
Begin TEST ...

End TEST ...

So friends ... how might I improve upon this debuggin technique?
Engineering Technologist • CAD Automation Practitioner
Automation ▸ Design ▸ Drafting ▸ Document Control ▸ Client
cadanalyst@gmail.comhttp://cadanalyst.slack.comhttp://linkedin.com/in/cadanalyst

MP

  • Seagull
  • Posts: 17750
  • Have thousands of dwgs to process? Contact me.
Re: So you're writing this large lisp application ...
« Reply #5 on: October 08, 2005, 09:21:47 AM »
errors or slow or inconsistant output ??

Rhetorical question? Both unless that's design/desired behavior?

but yes, essentially dumps and breakpoints. :-(

Why so sad?
Engineering Technologist • CAD Automation Practitioner
Automation ▸ Design ▸ Drafting ▸ Document Control ▸ Client
cadanalyst@gmail.comhttp://cadanalyst.slack.comhttp://linkedin.com/in/cadanalyst

MP

  • Seagull
  • Posts: 17750
  • Have thousands of dwgs to process? Contact me.
Re: So you're writing this large lisp application ...
« Reply #6 on: October 08, 2005, 09:23:49 AM »
I sometimes use "(alert (princ var))".

Do you consider that ^ a break point?

I do, it's a dump and a breakpoint.

:)
Engineering Technologist • CAD Automation Practitioner
Automation ▸ Design ▸ Drafting ▸ Document Control ▸ Client
cadanalyst@gmail.comhttp://cadanalyst.slack.comhttp://linkedin.com/in/cadanalyst

MP

  • Seagull
  • Posts: 17750
  • Have thousands of dwgs to process? Contact me.
Re: So you're writing this large lisp application ...
« Reply #7 on: October 08, 2005, 09:25:29 AM »
Break the application up into smaller subroutines and functions ... <other good stuff snipped to save the binary trees>

Fully agree with your post Peter.
Engineering Technologist • CAD Automation Practitioner
Automation ▸ Design ▸ Drafting ▸ Document Control ▸ Client
cadanalyst@gmail.comhttp://cadanalyst.slack.comhttp://linkedin.com/in/cadanalyst

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: So you're writing this large lisp application ...
« Reply #8 on: October 08, 2005, 09:27:38 AM »
:-( 'cause that the only 2 real options I can offer are the ones you mention.

Looks like I do the quoted var list similar to the method you mentioned. I also use dotted pair lists, but thats just dumps too I 'spose.

yeah, rhetorical really .. just wondered if you had a particular issue.
kdub, kdub_nz in other timelines.
Perfection is not optional.
Everything will work just as you expect it to, unless your expectations are incorrect.
Discipline: None at all.

JohnK

  • Administrator
  • Seagull
  • Posts: 10648
Re: So you're writing this large lisp application ...
« Reply #9 on: October 08, 2005, 09:41:17 AM »
wow?! Some hard thinking is doing in my head early morning this  ...*snap*

I think you broke him!?  Dont worry folks, I'll get the coffee.
TheSwamp.org (serving the CAD community since 2003)
Member location map - Add yourself

Donate to TheSwamp.org

MP

  • Seagull
  • Posts: 17750
  • Have thousands of dwgs to process? Contact me.
Re: So you're writing this large lisp application ...
« Reply #10 on: October 08, 2005, 09:44:15 AM »
:-( 'cause that the only 2 real options I can offer are the ones you mention.

Looks like I do the quoted var list similar to the method you mentioned. I also use dotted pair lists, but thats just dumps too I 'spose.

yeah, rhetorical really .. just wondered if you had a particular issue.

I don't do anything special with dotted pairs, it's just a list as far as the dump function is concerned --

Code: [Select]
(dump '((1 . "A string of some kind.")(70 . 42)))

;================================ Dump 1.0 =================================
;
; Atom Type: LIST
;
;===========================================================================
;
; Length = 2
;
; ((1 . "A string of some kind.") (70 . 42))
;
;===========================================================================

Unless the argument passed is an ename, then it attempts to format the entity data accordingly:

Code: [Select]
(dump
    (   (lambda (ss)
            (if (eq 'pickset (type ss))           
                (ssname ss 0)
               'Nada
            )
        )
        (ssget "x")
    )   
)

;================================ Dump 1.0 =================================
;
; Atom Type: ENAME
;
;===========================================================================
;
; (
;   (-1 . <Entity name: 7ef70f68>)
;   (0 . "CIRCLE")
;   (330 . <Entity name: 7ef70cf8>)
;   (5 . "A5")
;   (100 . "AcDbEntity")
;   (67 . 0)
;   (410 . "Model")
;   (8 . "0")
;   (100 . "AcDbCircle")
;   (10 33.5609 4.2347 0.0)
;   (40 . 1.30078)
;   (210 0.0 0.0 1.0)
; )
;
;===========================================================================
Engineering Technologist • CAD Automation Practitioner
Automation ▸ Design ▸ Drafting ▸ Document Control ▸ Client
cadanalyst@gmail.comhttp://cadanalyst.slack.comhttp://linkedin.com/in/cadanalyst

JohnK

  • Administrator
  • Seagull
  • Posts: 10648
Re: So you're writing this large lisp application ...
« Reply #11 on: October 08, 2005, 09:49:19 AM »
*huff* *puff* *sputter* *BANG* *chug, chug...*

What if you pass a procedure as a whole and eval each "line". If you pass a giant list, you would have to start with the inner most list and eval it, pause and eval the next level up. And so on.   ...Feesable? prolly. Level of diff. challenging. Worth it? *Hummm*
TheSwamp.org (serving the CAD community since 2003)
Member location map - Add yourself

Donate to TheSwamp.org

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: So you're writing this large lisp application ...
« Reply #12 on: October 08, 2005, 09:54:48 AM »
Hi Michael

Just a thought. If the headers and lines had 3 semicolons and the dump info was wrapped with in-line comments it would let [you] format the file in the VLisp IDE without losing everything .. and would let [you] select the multiiline code block without getting the leading semi-colon in the mix.

Though that may not be an issue with your editor, just with the VLisp IDE.
kdub, kdub_nz in other timelines.
Perfection is not optional.
Everything will work just as you expect it to, unless your expectations are incorrect.
Discipline: None at all.

MP

  • Seagull
  • Posts: 17750
  • Have thousands of dwgs to process? Contact me.
Re: So you're writing this large lisp application ...
« Reply #13 on: October 08, 2005, 09:59:21 AM »
I'm not sure I see the value in what you're saying John, but if you define a function using defun-q I suppose you could analyze each statement thusly --

Code: [Select]
(defun-q c:TEST ( / Dump Wait DumpAndWait  a b c d e )

    (defun Dump (x) x)
    (defun Wait ( ) (princ))
    (defun DumpAndWait (x) x)

    (princ "Begin TEST ...\n\n")

    (setq
        a  1
        b  "2"
        c  ((lambda (x) (repeat 8 (setq x (append x x)))) '(1 2 3))
        d  (ssget "x")
    )

    (dump 'a)

    (dump 'b)

    (dump 'c)

    (dump 'd)

    (cond
        (   (eq 'pickset (type d))
            (dump (setq e (ssname d 0)))
            (dump (vlax-ename->vla-object e))
        )
    )

    (princ "End TEST ...\n\n")

    (princ)

)

Code: [Select]
(mapcar '(lambda (lst) (mapcar 'dump lst)) c:test)
Then spews accordingly --

(I'll refrain from posing it as it's no small dump).

You could make the lambda portion of the code above, that is '(lambda (lst) (mapcar 'dump lst)) more elaborate, but I'm really not seeing the value of this (beyond the joy of abstration of course).
Engineering Technologist • CAD Automation Practitioner
Automation ▸ Design ▸ Drafting ▸ Document Control ▸ Client
cadanalyst@gmail.comhttp://cadanalyst.slack.comhttp://linkedin.com/in/cadanalyst

MP

  • Seagull
  • Posts: 17750
  • Have thousands of dwgs to process? Contact me.
Re: So you're writing this large lisp application ...
« Reply #14 on: October 08, 2005, 10:08:45 AM »
Hi Michael

Just a thought. If the headers and lines had 3 semicolons and the dump info was wrapped with in-line comments it would let [you] format the file in the VLisp IDE without losing everything .. and would let [you] select the multiiline code block without getting the leading semi-colon in the mix.

Though that may not be an issue with your editor, just with the VLisp IDE.

Hmmm, I don't use the VLIDE so I'm not sure what you mean exactly, "without losing everything". Regarding "select the multiiline code block without getting the leading semi-colon in the mix" doesn't the vlide let you do columnar selection?

I would note that, because I wanted consistant output I patterned all my actual data output to match the formatting vlax-dump-object. While I could write my own version of vlax-dump-object I didn't see the value of that at the time. Hmmm.
Engineering Technologist • CAD Automation Practitioner
Automation ▸ Design ▸ Drafting ▸ Document Control ▸ Client
cadanalyst@gmail.comhttp://cadanalyst.slack.comhttp://linkedin.com/in/cadanalyst

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: So you're writing this large lisp application ...
« Reply #15 on: October 08, 2005, 10:14:15 AM »
Quote
columnar selection
Nope

Generally single semicolons skip out to between column 45 to 60 as autoformatting, depending on config ..

I use UltraEdit and the Vlide. .. fairly conventional :)
kdub, kdub_nz in other timelines.
Perfection is not optional.
Everything will work just as you expect it to, unless your expectations are incorrect.
Discipline: None at all.

MP

  • Seagull
  • Posts: 17750
  • Have thousands of dwgs to process? Contact me.
Re: So you're writing this large lisp application ...
« Reply #16 on: October 08, 2005, 10:15:49 AM »
Eeeuuuwww.

No wonder I don't use it.

Sorry?

Wait a sec, did you just add the UltraEdit reference?
Engineering Technologist • CAD Automation Practitioner
Automation ▸ Design ▸ Drafting ▸ Document Control ▸ Client
cadanalyst@gmail.comhttp://cadanalyst.slack.comhttp://linkedin.com/in/cadanalyst

LE

  • Guest
Re: So you're writing this large lisp application ...
« Reply #17 on: October 08, 2005, 10:57:17 AM »
Basically I simple don't use local variables until I check that they are right, then I add some breakpoints into the areas I think is going to fail, Or  where I am specting certain return, in that phase I use the inspection feature of vlisp or in the command line the !

The functions are saved into modules and every module is inside of a folder with the same name, I use PRJ projects and if one module is needed is simple added.

All the new functions are saved into their category if they don't fit in any existing then a new module is created.


Luis.

CAB

  • Global Moderator
  • Seagull
  • Posts: 10401
Re: So you're writing this large lisp application ...
« Reply #18 on: October 09, 2005, 09:47:22 AM »
I use VLIDE & UltrEdit.
VLIDE to write the code & format.
I use Ultra edit for spell check (not often enough) & 'Cut & Paste'
Ultra Edit has a neat 'Column' mode that us useful to 'Cut & Paste' and also inserting
a character in many rows at one time. Same with the BackSpace key to remove.

In VLIDE ;;; goes to column zero while ;; follows the indent & ; is a inline comment

I use (print xyz) sometimes to drop the value while in progress and BreakPoint to halt
the routine while I ponder over the variables.

I sometimes use (command "point" p1) to see where the position of points in the drawing.

In large apps I use a debug global variable to turn the debug system on/off.

(setq *debug* 1 to 5)
In the routine I use
(and (> *debug* 3) (print var))
or
(if (> *debug* 3)
  (dump_vars)
)

where dump_vars could be this, a dedecated routine

Code: [Select]
  ;; ---------------------------------------------------------------------------
  ;; Function: dump_vars
  ;; Purpose : Used for debug to display the var values at the command prompt.
  ;; ---------------------------------------------------------------------------

  (defun dump_vars ()
    (prompt "\n=-=-=-=-=-=-=-=-=-=   DEBUG MODE =-=-=-=-=-=-=-=-=-=-=")
    (prompt "\n  * * * *    Variable Dump     * * * *")
    (prompt (strcat "\n-> " Plot-Config     " [Plot-Config]- Name if plot, default to Current"))         
    (prompt (strcat "\n-> " (itoa Plot-QTY) " [Plot-QTY]- number of copies of each sheet"))                   
    (prompt (strcat "\n-> " Plot-order      " [Plot-order]- Sort order of tabs \"Alpha\" \"Numeric\" \"Tab\" order")) 
    (prompt (strcat "\n-> " (if RevOrder "True" "False")  " [RevOrder]- t/nil Reverse the order of plots"))
    (prompt (strcat "\n-> " (if PlotAllTabs "True" "False")  " [PlotAllTabs]- t/nil Plot All tabs or use picks"))
    (prompt (strcat "\n-> " (if setlaystate "True" "False")  " [setlaystate]- t/nil set layer state per tab name"))
    (prompt (strcat "\n-> " (if PlotToFile "True" "False") " [PlotToFile]- Flag"))                 
    (prompt (strcat "\n-> " MyPath     " [MyPath]- Path for 'Plot To File'"))         
    (prompt (strcat "\n-> " (itoa Quantity) "[Quantity]- number of sets"))               
    (prompt (strcat "\n-> " (if SaveLayout "True" "False") " [SaveLayout]- Always True- Not an option in this version"))                                           
    (prompt (strcat "\n-> " (if CollateSets  "True" "False") " [CollateSets]- t/nil  Collate plan sets when more than one plotted"))
    (prompt (strcat "\n-> " (if ExcludeTab "True" "False") " [ExcludeTab]- t/nil  Flag to exclude tabs with flag character"))
    (prompt (strcat "\n-> " ExcludeChr " [ExcludeChr]- \"~\" Character marker for exclude tabs"))
    (prompt (strcat "\n-> " (if zoom-all "True" "False") " [zoom-all]- t/nil  Zoom layout before plotting"))
    (prompt (strcat "\n-> " (itoa config#) " [config#]- pointer to config name in list, 0= first item"))
    (prompt (strcat "\n-> Config List [config-list]-> "))
    (setq idx -1)
    (repeat (length config-list)
      (prompt (strcat "\n                              " (nth (setq idx (1+ idx)) config-list)))
    )
    (prompt (strcat "\n-> Tab Name to Plot [tab-list]-> "))
    (foreach tab tab-list
      (prompt (strcat "\n                              " tab)))
    (prompt "\n  * * * *    End Variable Dump     * * * *")
    (prompt "\n=-=-=-=-=-=-=-=-=-=   DEBUG MODE =-=-=-=-=-=-=-=-=-=-=\n")
 ) ; end defun dump_vars
I've reached the age where the happy hour is a nap. (°¿°)
Windows 10 core i7 4790k 4Ghz 32GB GTX 970
Please support this web site.