RPTools.net

Discussion and Support

Skip to content

It is currently Tue Dec 12, 2017 1:36 am 






Reply to topic  [ 18 posts ]  Go to page 1, 2  Next

Previous topic | Next topic 

  Print view

Author Message
User avatar  Offline
Deity
 
Joined: Tue Jul 01, 2008 6:48 pm
Posts: 6237
 Post subject: Humbly Submitted: Debugging Trick
PostPosted: Thu Jun 25, 2009 3:10 pm 
This may be old hat or obvious, but I just thought of it, and figured I'd throw it to the pack and see how long they could feed on it ;).

One of the toughest things I've run into with macros is debugging them - you can use abort(0) to break them, but it's tough to see the "variable trace" or whatever you might call it - what variables are at certain times. It occurred to me that user defined functions and the dialog() function could offer a solution. So, I submit a simple debugging dialog/function thing:

First, create the macro onCampaignLoad on a library token, or add the following to your existing onCampaignLoad macro:
Code:
[defineFunction("debug", "debugDialog@Lib:Token")]


Second, create a macro called debugDialog on that same library token:
Code:
[dialog("debugger"):
{
    [h:numArgs = argCount()]
    [count(numArgs, "<br>"): arg(roll.count)]
}]


Then (after running onCampaignLoad to make sure the function gets defined), you can insert the following code anywhere in your macro, and it will pop up a dialog containing every argument you pass to it, separated by breaks. debug() will accept any number of arguments. So, for example, if I had some code like this:

Code:
[h:multiplier=json.get(DamMultiplier,attackType)]
[h:resistAll=json.get(Resist,"all")]


And I needed to figure out what those values were (maybe because my damage macro was broken; trust me, this is from personal experience :D), I would edit the macro and insert:

Code:
[debug(multiplier, resistAll)]


right after the variables in question, and when the macro was run, a dialog would pop up with the values of multiplier and resistAll in it. I've found it very handy.

If you want to drop the debugger into a campaign, just download:

Debugger library token


If you do use it, one trick I use is to feed it arguments like this:

debug("multiplier", multiplier, "resistAll", resistAll)

So that when it produces the dialog, the name of the variable is shown above the actual value of that variable. The output looks like:

multiplier
1
resistAll
5

_________________

What I'm Working On

MapTool Tutorials:
Introduction to Tokens
Introduction to Properties
Introduction to Macro Writing
Introduction to Light and Sight


Top
 Profile  
 
User avatar  Offline
Dragon
 
Joined: Sun Jun 15, 2008 1:40 pm
Posts: 444
Location: Montréal, QC
 Post subject: Re: Humbly Submitted: Debugging Trick
PostPosted: Thu Jun 25, 2009 7:36 pm 
It hadn't occurred to me to output to the chat interface, although I used to use a lot of HTML comments to block such output. To get around all that, I just use an "input" dialogue in a single line that I can temporarily add and move around within a MACRO:
Code:
[H: input("debug |"+ "so far, so good" +"| debugging | LABEL")]

It's formatted so I can replace the output with a variable I want to check (similar to your approach, but a little less elegantly):
Code:
[H: input("debug |"+ "so far, so good" +"| debugging | LABEL","debug |"+ var1 +"| var1 | LABEL")]


This also allows me to check where a Macro is choking / failing, in the event MapTool gives an unhelpful error message.
Now that I'm using the [H: ] roll option more to hide output, your solution might be a lot easier, and a simple way to learn about user-defined functions 8)

Thanks.

EDIT: I just read your original post more carefully and realized you are outputting to a dialogue, not the chat console - never mind :oops: I've been using my little since before dialogues were introduced, and am still in the process of updating my code (and practices) from 1.3b47

_________________
"The trouble with communicating is believing you have achieved it"
[ d20 StatBlock Importer ] [ Batch Edit Macros ] [ Canned Speech UI ] [ Lib: Math ]


Top
 Profile  
 
User avatar  Offline
Dragon
 
Joined: Sun Mar 22, 2009 1:25 am
Posts: 957
 Post subject: Re: Humbly Submitted: Debugging Trick
PostPosted: Fri Jun 26, 2009 2:27 am 
I use input() for debugging as well, for the simple reason that it pauses execution while waiting for user input. I actually use two different debugging functions, debug() and pause().

I use a ton of user-defined functions, so I wanted a way to keep the debugging in place.. since once you get about 10 levels deep in UDFs, it's pretty hard to tell where the error is actually coming from. >.< So, that's what debug() does for me; it allows me to turn debug mode on, and then I get a bunch of these (see pic), which allow me to 'step' through the code.

Image

Which comes from having this is my macro:
Code:
[ debug( getMacroName(), getMacroLocation(), "All variables should have a value.",
    "FunctionName", "IgnoreOutput", "NewScope", "Group", "PublicFunction" )
]
 

Granted, when I just want some quick debugging, that's overkill. That's where pause() comes in.
Image
Which I get from
Code:
[ pause( "FunctionName", "IgnoreOutput", "NewScope", "Group", "PublicFunction" ) ] 

or
Image
Which I get from just putting [ pause() ] in a macro. In any case I can press OK to continue executing the macro, or Cancel to .. cancel the execution if I don't like what I'm seeing.


Here's the code, if you're interesting. You'll notice that the heavy duty debugger is actually two functions; that is so the parser doesn't have to work through the entire macro if debug mode is off.
Code:
[ defineFunction("debug", "debug@this", 1, 0 ) ]
[
 defineFunction("displayDebug", "displayDebug@this", 1, 0 ) ]
[
 defineFunction("pause", "pause@this", 1, 0 ) ] 

Code:
[ DEBUG_MODE = 1 ]

[
 if( DEBUG_MODE ): displayDebug( macro.args ) ] 

Code:
<!-- Translate -->
[
 toolkit.DebuggerTitle = "Debugger" ]
[
 toolkit.DebuggerTitleCaps = upper( toolkit.DebuggerTitle ) ]
[
 toolkit.DebugExpectationsTitle = "Expectations" ]
[
 toolkit.DebugEnvironmentTitle = "Environment" ]
[
 toolkit.DebugCurrentMacroTitle = "Current Macro" ]
[
 toolkit.DebugMacroLocationTitle = "Macro Location" ]
[
 toolkit.DebugCurrentTokenTitle = "Current Token" ]
[
 toolkit.DebugImpersonatedTokenTitle = "Impersonated Token" ]
[
 toolkit.DebugImpersonatedTokenNone = "No impersonated tokens" ]
[
 toolkit.DebugSelectedTokensTitle = "Selected Tokens" ]
[
 toolkit.DebugSelectedTokensNone = "No selected tokens" ]
[
 toolkit.DebugVariableTraceTitle = "Variable Trace" ]

<!--
 Layout -->
[
 toolkit.DebugInputParameters = ".|<html>" +
    "<span style='font-size:2.00em;'><b><i>%{toolkit.DebuggerTitleCaps}</i></b></span>" +
    "<table cellspacing='2' cellpadding='0' style='background-color:#595751'>" +
    "<tr><td>" +
    "<table cellspacing='10' cellpadding='0' style='background-color:#faf9f5'>" +
    "<tr><td valign='top' width='50%'><span style='font-size:1.7em'><b>%{toolkit.DebugEnvironmentTitle}</b></span>" +
    "<table width='200px' border='0' cellspacing='2' cellpadding='0'>%{toolkit.DebugEnvironmentRows}</table></td>" +
    "<td width='200px' valign='top'><span style='font-size:1.7em'><b>%{toolkit.DebugVariableTraceTitle}</b></span>" +
    "<table width='100%' border='0' cellspacing='2' cellpadding='0'>%{toolkit.DebugVariableRows}</table>" +
    "</td></tr><tr><td colspan='2'>" +
    "<table width='100%' cellpadding='0' cellspacing='2'>" +
    "<tr><td style='font-size:1.2em;'><b>%{toolkit.DebugExpectationsTitle}</b></td></tr>" +
    "<tr><td style='background-color:#EDECE8;'>%{toolkit.DebugExpectations}</td></tr></table></td></tr>" +
    "</table></td></tr></table></html>"+
    "|%{toolkit.DebuggerTitle}|LABEL|SPAN=TRUE"
]
[
 toolkit.DebugTableRow = "<tr><td style='background-color:#EDECE8;'>" +
    "<b>%{toolkit.DebugTableRowTitle}</b></td></tr>" +
    "<tr><td>%{toolkit.DebugTableRowContent}</td></tr>"
]

<!--
 Get parameters from macro.args -->
[
 toolkit.DebugMacroName = json.get( arg( 0 ), 0 ) ]
[
 toolkit.DebugMacroLocation = json.get( arg( 0 ), 1 ) ]
[
 toolkit.DebugExpectations = json.get( arg( 0 ), 2 ) ]
[
 toolkit.DebugVariables = json.remove( json.remove( json.remove( arg( 0 ), 0 ), 0 ), 0 ) ] 

<!-- Build toolkit.DebugEnvironmentRows -->
[
 toolkit.DebugEnvironmentRows = "" ]

<!--
 Macro name -->
[
 toolkit.DebugTableRowTitle = toolkit.DebugCurrentMacroTitle ]
[
 toolkit.DebugTableRowContent = toolkit.DebugMacroName ]
[
 toolkit.DebugEnvironmentRows = toolkit.DebugEnvironmentRows + strformat( toolkit.DebugTableRow ) ]

<!--
 Macro location -->
[
 toolkit.DebugTableRowTitle = toolkit.DebugMacroLocationTitle ]
[
 toolkit.DebugTableRowContent = toolkit.DebugMacroLocation ]
[
 toolkit.DebugEnvironmentRows = toolkit.DebugEnvironmentRows + strformat( toolkit.DebugTableRow ) ]

<!--
 Current token -->
[
 toolkit.DebugTableRowTitle = toolkit.DebugCurrentTokenTitle ]
[
 toolkit.DebugTableRowContent = getName( currentToken() ) + "<br><i>" + currentToken() + "</i>" ]
[
 toolkit.DebugEnvironmentRows = toolkit.DebugEnvironmentRows + strformat( toolkit.DebugTableRow ) ]

<!--
 Impersonated token -->
[
 toolkit.DebugTableRowTitle = toolkit.DebugImpersonatedTokenTitle ]
[
 if( hasImpersonated() ), code:
{
    [ toolkit.DebugTableRowContent = getImpersonatedName() + "<br><i>" + getImpersonated() + "</i>" ]
};{
    [ toolkit.DebugTableRowContent = toolkit.DebugImpersonatedTokenNone ]
}
 ]
[
 toolkit.DebugEnvironmentRows = toolkit.DebugEnvironmentRows + strformat( toolkit.DebugTableRow ) ]

<!--
 Selected tokens -->
[
 toolkit.DebugTableRowTitle = toolkit.DebugSelectedTokensTitle ]
[
 toolkit.SelectedTokens = getSelected("json") ]
[
 toolkit.SelectedTokenCount = json.length( toolkit.SelectedTokens ) ]
[
 if( toolkit.SelectedTokenCount > 0 ), code:
{
    [ toolkit.DebugTableRowContent = "" ]
    [ foreach( SelectedToken, toolkit.SelectedTokens ), code:
    {
        [ toolkit.DebugTableRowContent = toolkit.DebugTableRowContent +
            if( roll.count != 0, "</td></tr>", "" ) +
            getName( SelectedToken ) +
            "<br><i>" + SelectedToken + "</i>"
        ]
    } ]
};{
    [ toolkit.DebugTableRowContent = toolkit.DebugSelectedTokensNone ]
}
 ]
[
 toolkit.DebugEnvironmentRows = toolkit.DebugEnvironmentRows + strformat( toolkit.DebugTableRow ) ]

<!--
 Build toolkit.DebugVariableRows -->
[
 toolkit.DebugVariableRows = "" ]
[
 foreach( DebugVariable, toolkit.DebugVariables ), code:
{
    [ toolkit.DebugTableRowTitle = DebugVariable ]
    [ toolkit.DebugTableRowContent = eval( DebugVariable ) ]
    [ toolkit.DebugVariableRows = toolkit.DebugVariableRows + strformat( toolkit.DebugTableRow ) ]
}
 ]

<!--
 Show debug -->
[
 toolkit.DebugBreak = input( strformat( toolkit.DebugInputParameters ) ) ]
[
 abort( toolkit.DebugBreak ) ] 

Code:
[ toolkit.DebugVariableCount = argCount() ]
[
 toolkit.DebugInputParameter = ".|<html>" +
    "<table cellspacing='2' cellpadding='0' style='background-color:#595751'>" +
    "<tr><td>" +
    "<table width='300px' cellspacing='0' cellpadding='2' style='background-color:#FAF9F5;'>" +
    "%{toolkit.DebugVariableRows}</table></td></tr></html>" +
    "|Debugger|LABEL|SPAN=TRUE"
]
[
 toolkit.DebugVariableRow = "<tr %{toolkit.DebugVariableRowStyle}><td>" +
    "<b>%{toolkit.DebugVariableName}</b></td><td>%{toolkit.DebugVariableContent}" +
    "</td></tr>"
]
[
 toolkit.DebugVariableRows = "<tr style='background-color:#E0DDD5; font-size:1.1em;'><td><b>Variable</b></td><td><b>Value</b></td></tr>" ]
[
 count( toolkit.DebugVariableCount ), code:
{
    [ toolkit.DebugVariableRowStyle = "" ]
    [ toolkit.DebugVariableName = arg( roll.count ) ]
    [ toolkit.DebugVariableContent = eval( arg( roll.count ) ) ]
    [ if( floor( roll.count/) == roll.count/), code:
    {
        [ toolkit.DebugVariableRowStyle = "style='background-color:#EDECE8;'" ]
    } ]
    [ toolkit.DebugVariableRows = toolkit.DebugVariableRows +
        strformat( toolkit.DebugVariableRow )
    ]
}
 ]
[
 if( toolkit.DebugVariableCount == 0 ), code:
{
    [ toolkit.DebugVariableRows = "<tr><td style='font-size: 1.4em' align='center'><b>Pause</b></td></tr>" ]
}
 ]

[
 toolkit.DebugBreak = input( strformat( toolkit.DebugInputParameter ) )]
[
 abort( toolkit.DebugBreak ) ] 

_________________
My Wiki User Page


Last edited by zEal on Fri Jun 26, 2009 12:51 pm, edited 1 time in total.

Top
 Profile  
 
User avatar  Offline
Deity
 
Joined: Tue Jul 01, 2008 6:48 pm
Posts: 6237
 Post subject: Re: Humbly Submitted: Debugging Trick
PostPosted: Fri Jun 26, 2009 7:18 am 
Wow. That's...impressive. I'm not sure I'd go that far (or that I need to, using only a few UDFs, but I will be liberally stealing some of that).

_________________

What I'm Working On

MapTool Tutorials:
Introduction to Tokens
Introduction to Properties
Introduction to Macro Writing
Introduction to Light and Sight


Top
 Profile  
 
User avatar  Offline
Dragon
 
Joined: Sun Jun 15, 2008 1:40 pm
Posts: 444
Location: Montréal, QC
 Post subject: Re: Humbly Submitted: Debugging Trick
PostPosted: Fri Jun 26, 2009 10:04 am 
Yoinked! :wink:
I never would have come up with all that on my own, and I admit I don't fully understand it all :( but I like the effect and all the information it provides.
Thanks for sharing zEal, (and rumble for starting this off), this is extremely helpful.

_________________
"The trouble with communicating is believing you have achieved it"
[ d20 StatBlock Importer ] [ Batch Edit Macros ] [ Canned Speech UI ] [ Lib: Math ]


Top
 Profile  
 
User avatar  Offline
Dragon
 
Joined: Sun Mar 22, 2009 1:25 am
Posts: 957
 Post subject: Re: Humbly Submitted: Debugging Trick
PostPosted: Fri Jun 26, 2009 1:07 pm 
Rumble wrote:
I'm not sure I'd go that far (or that I need to, using only a few UDFs, but I will be liberally stealing some of that).
Yeah, I tend to go overboard on everything. >.> I guess the jist of it is that you might be able to improve your own debug macro by using an input() instead, because it pauses execution and can behave much like a dialog if you use a single spanned label (you could use more than one label, but it takes more code to build that sort of input string and then eval() it ). Also, if you don't have your UDF create a new variable scope then you can have access to both the variable name and its value from a single parameter ( via eval() ).

biodude wrote:
Yoinked! :wink:
I never would have come up with all that on my own, and I admit I don't fully understand it all :( but I like the effect and all the information it provides.
You might want to recopy the displayDebug code, when stripping out some of my own UDFs to make it fit for posting I borked the impersonated token section. :oops:

_________________
My Wiki User Page


Top
 Profile  
 
User avatar  Offline
Deity
 
Joined: Tue Jul 01, 2008 6:48 pm
Posts: 6237
 Post subject: Re: Humbly Submitted: Debugging Trick
PostPosted: Fri Jun 26, 2009 2:04 pm 
Oh, I plan to switch to input(). I had no idea you could embed HTML in it - I'm stoked about that. And pausing macros is a great and useful idea.

_________________

What I'm Working On

MapTool Tutorials:
Introduction to Tokens
Introduction to Properties
Introduction to Macro Writing
Introduction to Light and Sight


Top
 Profile  
 
User avatar  Offline
Dragon
 
Joined: Sun Mar 22, 2009 1:25 am
Posts: 957
 Post subject: Re: Humbly Submitted: Debugging Trick
PostPosted: Fri Jun 26, 2009 2:30 pm 
Yeah, it's amazing all the places you can embed html/css in MapTool.. I think the list would be shorter on where you can't.

Image

_________________
My Wiki User Page


Top
 Profile  
 
User avatar  Offline
Dragon
 
Joined: Sun Jun 15, 2008 1:40 pm
Posts: 444
Location: Montréal, QC
 Post subject: Re: Humbly Submitted: Debugging Trick
PostPosted: Fri Jun 26, 2009 9:11 pm 
zEal wrote:
You might want to recopy the displayDebug code, when stripping out some of my own UDFs to make it fit for posting I borked the impersonated token section. :oops:

Yeah, I actually couldn't get the full debug function to work correctly until I de-selected "run on selected token" and a few other tweaks - I still get error when trying to use it from within a Campaign Macro, which is where a bunch of my code is still located.
From I could decipher, most of the debug & pause code is intended to work from within another user defined function (they don't create new variable scopes and thus can simply call variables from the code that called the debug function), but this wasn't working for me in 1.3b54 from within campaign macros :(
I ended up modifying your pause function so I can simply pass it label & value pairs: e.g. "variableName", variableValue), but now with much nicer formatting in the input() dialogue. I also didn't know you could include fully formatted HTML in the input dialogue. Very cool.

I also occurs to me that one could also create a frame with variable names & values and watch them change live while the code was running, although without the pauses, that could be a bit overwhelming and slow down the rest of the processing ... but it might be entertaining in certain rare situations.

_________________
"The trouble with communicating is believing you have achieved it"
[ d20 StatBlock Importer ] [ Batch Edit Macros ] [ Canned Speech UI ] [ Lib: Math ]


Top
 Profile  
 
 Offline
Dragon
 
Joined: Tue Mar 31, 2009 6:44 pm
Posts: 263
 Post subject: Re: Humbly Submitted: Debugging Trick
PostPosted: Sun Jul 26, 2009 1:48 pm 
Am I the only one wondering what other marvels are contained within zEal's MacroToolkit? :)

_________________
MapTools Forks: Thread


Top
 Profile  
 
User avatar  Offline
Dragon
 
Joined: Sun Jun 15, 2008 1:40 pm
Posts: 444
Location: Montréal, QC
 Post subject: Re: Humbly Submitted: Debugging Trick
PostPosted: Thu Aug 06, 2009 9:54 pm 
... some secrets are best kept hidden from those who would be corrutped by it's power :-P

On a (slightly) more serious note, I recently noticed zEal's fantastic pause() function going buggy (how do you debug a debugging macro?) When passed a number of variable names (in quotations), it would spit out a table with the correct number of rows, but only the first variable name (& value) in each row. I recently deduced the culprit: I was using a custom robust eval() function. Because eval() was now a user-defined function, the arg() function was returning arguments to the eval call, not the original pause() call. So, the two don't play nice as is.

I added a couple of variable declarations to store the arguments in so that this sort of thing would be less of an issue. Here it is with my revisions (I hope I didn't deface zEal's creation too badly).
Code:
[ toolkit.DebugVariableCount = argCount() ]
[
 toolkit.DebugVariableArray = macro.args ]
[
 toolkit.DebugInputParameter = ".|<html>" +
    "<table cellspacing='2' cellpadding='0' style='background-color:#595751'>" +
    "<tr><td>" +
    "<table width='300px' cellspacing='0' cellpadding='2' style='background-color:#FAF9F5;'>" +
    "%{toolkit.DebugVariableRows}</table></td></tr></html>" +
    "|Debugger|LABEL|SPAN=TRUE"
]
[
 toolkit.DebugVariableRow = "<tr %{toolkit.DebugVariableRowStyle}><td>" +
    "<b>%{toolkit.DebugVariableName}</b></td><td>%{toolkit.DebugVariableContent}" +
    "</td></tr>"
]
[
 toolkit.DebugVariableRows = "<tr style='background-color:#E0DDD5; font-size:1.1em;'><td><b>Variable</b></td><td><b>Value</b></td></tr>" ]
[
 count( toolkit.DebugVariableCount ), code:
{
    [ toolkit.DebugVariableRowStyle = "" ]
    [ toolkit.DebugVariableName = json.get( toolkit.DebugVariableArray, roll.count ) ]
    [ toolkit.DebugVariableContent = eval( toolkit.DebugVariableName ) ]    <!-- this may not be compatible with a custom eval function (which would overwrite macro.args) -->
    [ if( floor( roll.count/) == roll.count/), code:
    {
        [ toolkit.DebugVariableRowStyle = "style='background-color:#EDECE8;'" ]
    } ]
    [ toolkit.DebugVariableRows = toolkit.DebugVariableRows +
        strformat( toolkit.DebugVariableRow )
    ]
}
 ]
[
 if( toolkit.DebugVariableCount == 0 ), code:
{
    [ toolkit.DebugVariableRows = "<tr><td style='font-size: 1.4em' align='center'><b>Pause</b></td></tr>" ]
}
 ]

[
 toolkit.DebugBreak = input( strformat( toolkit.DebugInputParameter ) )]
[
 abort( toolkit.DebugBreak ) ] 
 

_________________
"The trouble with communicating is believing you have achieved it"
[ d20 StatBlock Importer ] [ Batch Edit Macros ] [ Canned Speech UI ] [ Lib: Math ]


Top
 Profile  
 
User avatar  Offline
TheBard
 
Joined: Tue Mar 21, 2006 7:26 pm
Posts: 3484
Location: Austin, Tx
 Post subject: Re: Humbly Submitted: Debugging Trick
PostPosted: Fri Aug 07, 2009 7:44 am 
You people scare me.

In a good way

_________________
ImageImage ImageImageImageImage
Support RPTools by shopping
Image
Image


Top
 Profile  
 
 Offline
Cave Troll
 
Joined: Tue Dec 30, 2008 8:46 am
Posts: 82
 Post subject: Re: Humbly Submitted: Debugging Trick
PostPosted: Sun Oct 25, 2009 7:47 pm 
It looks cool, but I really cannot make heads nor tails of how it works and all I get are JSON errors all over when I call debug(). There must be some more magic fubarium required as usual with macros :( God I cannot wait for javascript.


Top
 Profile  
 
User avatar  Offline
Deity
 
Joined: Fri Mar 20, 2009 4:40 am
Posts: 9427
Location: Netherlands
 Post subject: Re: Humbly Submitted: Debugging Trick
PostPosted: Tue Nov 10, 2009 4:10 am 
thank you thank you thank you thank you thank you!

that was for the pause button. I spend hours tracing the most annoying AND (in retrospect) stupid bug.

As with the debug button I agree with Alhazred, how do you get that thing to work?

_________________
GETTING STARTED WITH MAPTOOLS - TUTORIALS, DOCS, VIDEOS, TOOLS, ETC

My stuff
Excel Tools: Table and Light editors
MT Tools: Bag of Tricks: Tools for Maptool, Dungeon Builder I, Dungeon Builder II,onMouseOverEvent and
DPI.
Frameworks: Dark Heresy, Rogue Trader, Deathwatch, Black Crusade, Only War, SET Card Game, RoboRally
Wiki: Debugging Tutorial, Speed Up Your Macros, Working With Two CODE Levels, Shortcut Keys, Avoiding Stack Overflow, READ THIS


Top
 Profile  
 
User avatar  Offline
Great Wyrm
 
Joined: Tue Aug 23, 2011 10:41 am
Posts: 1134
Location: Cornwall, UK
 Post subject: Re: Humbly Submitted: Debugging Trick
PostPosted: Sun Oct 02, 2011 8:14 am 
zEal wrote:
I use input() for debugging as well, for the simple reason that it pauses execution while waiting for user input. I actually use two different debugging functions, debug() and pause().

I use a ton of user-defined functions, so I wanted a way to keep the debugging in place.. since once you get about 10 levels deep in UDFs, it's pretty hard to tell where the error is actually coming from. >.< So, that's what debug() does for me; it allows me to turn debug mode on, and then I get a bunch of these (see pic), which allow me to 'step' through the code.

Image

Which comes from having this is my macro:
Code:
[ debug( getMacroName(), getMacroLocation(), "All variables should have a value.",
    "FunctionName", "IgnoreOutput", "NewScope", "Group", "PublicFunction" )
]
 

Granted, when I just want some quick debugging, that's overkill. That's where pause() comes in.
Image
Which I get from
Code:
[ pause( "FunctionName", "IgnoreOutput", "NewScope", "Group", "PublicFunction" ) ] 

or
Image
Which I get from just putting [ pause() ] in a macro. In any case I can press OK to continue executing the macro, or Cancel to .. cancel the execution if I don't like what I'm seeing.


Here's the code, if you're interesting. You'll notice that the heavy duty debugger is actually two functions; that is so the parser doesn't have to work through the entire macro if debug mode is off.
[spoiler=onCampaignLoad]
Code:
[ defineFunction("debug", "debug@this", 1, 0 ) ]
[
 defineFunction("displayDebug", "displayDebug@this", 1, 0 ) ]
[
 defineFunction("pause", "pause@this", 1, 0 ) ] 

Code:
[ DEBUG_MODE = 1 ]

[
 if( DEBUG_MODE ): displayDebug( macro.args ) ] 

Code:
<!-- Translate -->
[
 toolkit.DebuggerTitle = "Debugger" ]
[
 toolkit.DebuggerTitleCaps = upper( toolkit.DebuggerTitle ) ]
[
 toolkit.DebugExpectationsTitle = "Expectations" ]
[
 toolkit.DebugEnvironmentTitle = "Environment" ]
[
 toolkit.DebugCurrentMacroTitle = "Current Macro" ]
[
 toolkit.DebugMacroLocationTitle = "Macro Location" ]
[
 toolkit.DebugCurrentTokenTitle = "Current Token" ]
[
 toolkit.DebugImpersonatedTokenTitle = "Impersonated Token" ]
[
 toolkit.DebugImpersonatedTokenNone = "No impersonated tokens" ]
[
 toolkit.DebugSelectedTokensTitle = "Selected Tokens" ]
[
 toolkit.DebugSelectedTokensNone = "No selected tokens" ]
[
 toolkit.DebugVariableTraceTitle = "Variable Trace" ]

<!--
 Layout -->
[
 toolkit.DebugInputParameters = ".|<html>" +
    "<span style='font-size:2.00em;'><b><i>%{toolkit.DebuggerTitleCaps}</i></b></span>" +
    "<table cellspacing='2' cellpadding='0' style='background-color:#595751'>" +
    "<tr><td>" +
    "<table cellspacing='10' cellpadding='0' style='background-color:#faf9f5'>" +
    "<tr><td valign='top' width='50%'><span style='font-size:1.7em'><b>%{toolkit.DebugEnvironmentTitle}</b></span>" +
    "<table width='200px' border='0' cellspacing='2' cellpadding='0'>%{toolkit.DebugEnvironmentRows}</table></td>" +
    "<td width='200px' valign='top'><span style='font-size:1.7em'><b>%{toolkit.DebugVariableTraceTitle}</b></span>" +
    "<table width='100%' border='0' cellspacing='2' cellpadding='0'>%{toolkit.DebugVariableRows}</table>" +
    "</td></tr><tr><td colspan='2'>" +
    "<table width='100%' cellpadding='0' cellspacing='2'>" +
    "<tr><td style='font-size:1.2em;'><b>%{toolkit.DebugExpectationsTitle}</b></td></tr>" +
    "<tr><td style='background-color:#EDECE8;'>%{toolkit.DebugExpectations}</td></tr></table></td></tr>" +
    "</table></td></tr></table></html>"+
    "|%{toolkit.DebuggerTitle}|LABEL|SPAN=TRUE"
]
[
 toolkit.DebugTableRow = "<tr><td style='background-color:#EDECE8;'>" +
    "<b>%{toolkit.DebugTableRowTitle}</b></td></tr>" +
    "<tr><td>%{toolkit.DebugTableRowContent}</td></tr>"
]

<!--
 Get parameters from macro.args -->
[
 toolkit.DebugMacroName = json.get( arg( 0 ), 0 ) ]
[
 toolkit.DebugMacroLocation = json.get( arg( 0 ), 1 ) ]
[
 toolkit.DebugExpectations = json.get( arg( 0 ), 2 ) ]
[
 toolkit.DebugVariables = json.remove( json.remove( json.remove( arg( 0 ), 0 ), 0 ), 0 ) ] 

<!-- Build toolkit.DebugEnvironmentRows -->
[
 toolkit.DebugEnvironmentRows = "" ]

<!--
 Macro name -->
[
 toolkit.DebugTableRowTitle = toolkit.DebugCurrentMacroTitle ]
[
 toolkit.DebugTableRowContent = toolkit.DebugMacroName ]
[
 toolkit.DebugEnvironmentRows = toolkit.DebugEnvironmentRows + strformat( toolkit.DebugTableRow ) ]

<!--
 Macro location -->
[
 toolkit.DebugTableRowTitle = toolkit.DebugMacroLocationTitle ]
[
 toolkit.DebugTableRowContent = toolkit.DebugMacroLocation ]
[
 toolkit.DebugEnvironmentRows = toolkit.DebugEnvironmentRows + strformat( toolkit.DebugTableRow ) ]

<!--
 Current token -->
[
 toolkit.DebugTableRowTitle = toolkit.DebugCurrentTokenTitle ]
[
 toolkit.DebugTableRowContent = getName( currentToken() ) + "<br><i>" + currentToken() + "</i>" ]
[
 toolkit.DebugEnvironmentRows = toolkit.DebugEnvironmentRows + strformat( toolkit.DebugTableRow ) ]

<!--
 Impersonated token -->
[
 toolkit.DebugTableRowTitle = toolkit.DebugImpersonatedTokenTitle ]
[
 if( hasImpersonated() ), code:
{
    [ toolkit.DebugTableRowContent = getImpersonatedName() + "<br><i>" + getImpersonated() + "</i>" ]
};{
    [ toolkit.DebugTableRowContent = toolkit.DebugImpersonatedTokenNone ]
}
 ]
[
 toolkit.DebugEnvironmentRows = toolkit.DebugEnvironmentRows + strformat( toolkit.DebugTableRow ) ]

<!--
 Selected tokens -->
[
 toolkit.DebugTableRowTitle = toolkit.DebugSelectedTokensTitle ]
[
 toolkit.SelectedTokens = getSelected("json") ]
[
 toolkit.SelectedTokenCount = json.length( toolkit.SelectedTokens ) ]
[
 if( toolkit.SelectedTokenCount > 0 ), code:
{
    [ toolkit.DebugTableRowContent = "" ]
    [ foreach( SelectedToken, toolkit.SelectedTokens ), code:
    {
        [ toolkit.DebugTableRowContent = toolkit.DebugTableRowContent +
            if( roll.count != 0, "</td></tr>", "" ) +
            getName( SelectedToken ) +
            "<br><i>" + SelectedToken + "</i>"
        ]
    } ]
};{
    [ toolkit.DebugTableRowContent = toolkit.DebugSelectedTokensNone ]
}
 ]
[
 toolkit.DebugEnvironmentRows = toolkit.DebugEnvironmentRows + strformat( toolkit.DebugTableRow ) ]

<!--
 Build toolkit.DebugVariableRows -->
[
 toolkit.DebugVariableRows = "" ]
[
 foreach( DebugVariable, toolkit.DebugVariables ), code:
{
    [ toolkit.DebugTableRowTitle = DebugVariable ]
    [ toolkit.DebugTableRowContent = eval( DebugVariable ) ]
    [ toolkit.DebugVariableRows = toolkit.DebugVariableRows + strformat( toolkit.DebugTableRow ) ]
}
 ]

<!--
 Show debug -->
[
 toolkit.DebugBreak = input( strformat( toolkit.DebugInputParameters ) ) ]
[
 abort( toolkit.DebugBreak ) ] 

Code:
[ toolkit.DebugVariableCount = argCount() ]
[
 toolkit.DebugInputParameter = ".|<html>" +
    "<table cellspacing='2' cellpadding='0' style='background-color:#595751'>" +
    "<tr><td>" +
    "<table width='300px' cellspacing='0' cellpadding='2' style='background-color:#FAF9F5;'>" +
    "%{toolkit.DebugVariableRows}</table></td></tr></html>" +
    "|Debugger|LABEL|SPAN=TRUE"
]
[
 toolkit.DebugVariableRow = "<tr %{toolkit.DebugVariableRowStyle}><td>" +
    "<b>%{toolkit.DebugVariableName}</b></td><td>%{toolkit.DebugVariableContent}" +
    "</td></tr>"
]
[
 toolkit.DebugVariableRows = "<tr style='background-color:#E0DDD5; font-size:1.1em;'><td><b>Variable</b></td><td><b>Value</b></td></tr>" ]
[
 count( toolkit.DebugVariableCount ), code:
{
    [ toolkit.DebugVariableRowStyle = "" ]
    [ toolkit.DebugVariableName = arg( roll.count ) ]
    [ toolkit.DebugVariableContent = eval( arg( roll.count ) ) ]
    [ if( floor( roll.count/) == roll.count/), code:
    {
        [ toolkit.DebugVariableRowStyle = "style='background-color:#EDECE8;'" ]
    } ]
    [ toolkit.DebugVariableRows = toolkit.DebugVariableRows +
        strformat( toolkit.DebugVariableRow )
    ]
}
 ]
[
 if( toolkit.DebugVariableCount == 0 ), code:
{
    [ toolkit.DebugVariableRows = "<tr><td style='font-size: 1.4em' align='center'><b>Pause</b></td></tr>" ]
}
 ]

[
 toolkit.DebugBreak = input( strformat( toolkit.DebugInputParameter ) )]
[
 abort( toolkit.DebugBreak ) ] 



Just wanted to say thankyou for this, It has made debugging my code so much easier. I just drop a Pause before and after any line I think is suspect, and run the macro until it breaks. Useful for the vague errors that MapTool says when your macro is doing something bad.

_________________
How to get around the two code nest limit in MapTool (and MOTE)


Top
 Profile  
 
Display posts from previous:  Sort by  
Reply to topic  [ 18 posts ]  Go to page 1, 2  Next

You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:

Who is online

In total there is 1 user online :: 0 registered, 0 hidden and 1 guest (based on users active over the past 5 minutes)
Most users ever online was 243 on Sun Nov 04, 2012 6:14 am

Users browsing this forum: No registered users and 1 guest





Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group

Style based on Andreas08 by Andreas Viklund

Style by Elizabeth Shulman