Skip to content

Instantly share code, notes, and snippets.

@paladintodd
Created November 17, 2015 17:43
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save paladintodd/dc638275868d840d1655 to your computer and use it in GitHub Desktop.
Save paladintodd/dc638275868d840d1655 to your computer and use it in GitHub Desktop.
DebugX
* DebugX: Class for creating messages during debugging.
* Created 11/3/15 by Todd Landrum, todd@paladinpgm.com
* With thanks to:
* Tamar Granor - Who's speed talk at Southwest Fox 2015 inspired the Start, Stop and Loop functions.
* You can use this method to easily add messages to your code for debugging purposes.
* Messagbes can be sent to the debug window or a text file.
* It can be used in a number of ways.
* To just give messages in your code:
* DebugX.Message("This is some message")
* It has a timer built-in so you can get the time it took some code to run:
* DebugX.Start("My timer is starting")
* <some code>
* DebugX.End("The code has finished")
* It has a looping function built-in as well.
* DebugX.nLoop = 10
* do while DebugX.nLoop
* <some code>
* enddo
* IMPORTANT: There is a lIsDevelopement property. If this is .f., then no messages
* will be output and for a loop, it will always do it just once regardless of nLoop.
* This way if you leave this in your code by mistake, it won't hurt anything in production.
* The INIT method sets this property for me - you should override it!
DEFINE CLASS DebugX AS Custom
cOutputType = "Debug" && 'Debug' if you want messages to the debug output, else 'Text' for text file
cOutputTextFile = "Debug.txt" && Default name, change if you want.
lOutputEraseTextFile = .t. && First message should create a new text file, erasing any existing one.
lShowSeconds = .f. && Seconds are shown for each message, set to .t. if the .Start() method is called.
lIsDevelopment = .t. && Output will not happen if this is .f.
&& The init function sets this, you should override it.
tStartDateTime = {} && For the Start/Stop timer functions.
tEndDateTime = {}
nStartSeconds = 0
nEndSeconds = 0
nTotalSeconds = 0
nSecondsInDay = 86400
nLoop = 1 && Number of loops to perform
**************************
PROCEDURE Init()
* This is the code for me that determines if I'm
* on my development machine. You'd change this to
* something you want.
this.lIsDevelopment = FILE("w:\paladin.txt")
ENDPROC
**************************
FUNCTION Destroy()
ENDFUNC
**************************
FUNCTION Start()
PARAMETERS tMsg
IF EMPTY(tMsg)
tMsg = "Start"
ENDIF
this.tStartDateTime = DATETIME()
this.nStartSeconds = SECONDS()
this.lShowSeconds = .t.
this.Message(tMsg)
ENDFUNC
**************************
FUNCTION Stop()
PARAMETERS tMsg
IF EMPTY(tMsg)
tMsg = "Stop"
ENDIF
this.tEndDateTime = DATETIME()
this.nEndSeconds = SECONDS()
this.nTotalSeconds = this.CalcSeconds()
this.Message(tMsg)
this.lShowSeconds = .f.
ENDFUNC
**************************
FUNCTION CalcSeconds()
PARAMETERS nStartSeconds, nEndSeconds
IF EMPTY(nStartSeconds)
nStartSeconds = this.nStartSeconds
ENDIF
IF EMPTY(nEndSeconds)
nEndSeconds = this.nEndSeconds
ENDIF
* Adjust total seconds if we ran over midnight
LOCAL lDays, lSeconds
lDays = TTOD(DATETIME()) - TTOD(this.tStartDateTime)
lSeconds = nEndSeconds - nStartSeconds
IF lDays > 0
lSeconds = lSeconds + (lDays * this.nSecondsInADay)
ENDIF
RETURN lSeconds
ENDFUNC
**************************
FUNCTION Loop
IF !this.lIsDevelopment
this.nLoop = 1
ENDIF
LOCAL lReturn
lReturn = (this.nLoop > 0)
this.nLoop = this.nLoop - 1
RETURN lReturn
ENDFUNC
**************************
FUNCTION Message
PARAMETERS tMessage
* tMessage = Message to output
* tInit = Determines if a new text file should be created or append.
IF !this.lIsDevelopment
RETURN
ENDIF
LOCAL lMsg
lMsg = tMessage + " : " + TTOC(DATETIME())
IF this.lShowSeconds
lMsg = lMsg + ", Seconds Elapsed: " + tran(this.CalcSeconds(this.nStartSeconds, SECONDS()))
endif
IF this.cOutputType = "Debug"
DEBUGOUT lMsg
ELSE
IF this.lOutputEraseTextFile && First time, we want to create blank output file.
DELETE FILE (this.cOutputTextFile)
this.lOutputEraseTextFile = .f. && Don't erase output file anymore
ENDIF
* Get any existing output, append this onto it.
LOCAL lStr
IF FILE(this.cOutputTextFile)
lStr = FILETOSTR(this.cOutputTextFile)
lStr = lStr + CHR(13) + CHR(10)
else
lStr = ""
endif
STRTOFILE(lStr + lMsg, this.cOutputTextFile)
ENDIF
ENDFUNC
ENDDEFINE
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment