Code : Tout sélectionner
#include-once
#include <AutoItConstants.au3>
#include <Math.au3>
Global Const $_TAB = ' '
; user-callable function, so that noone messes with __VarDump indentation
; $vVar is the variable to be dumped
; $iLimit is the max number of entries of an array, map or DllStruct array element to be displayed in full
Func _VarDump(ByRef $vVar, $iLimit = 20)
If $iLimit < 3 Then $iLimit = 0
Return(__VarDump($vVar, $iLimit))
EndFunc ; =>_VarDump
Func __VarDump(ByRef $vVar, $iLimit, $sIndent = '')
Local $ret, $len, $ptr
Switch VarGetType($vVar)
Case "String"
$len = StringLen($vVar)
Return 'String (' & $len & ") " & __DumpStr($vVar)
Case "Double"
Return 'Double ' & $vVar & (IsInt($vVar) ? '.0' : '')
Case "Int32", "Int64"
Return VarGetType($vVar) & ' ' & $vVar
Case "Array"
Local $iDimensions = UBound($vVar, 0)
Local $iCells = 1
$ret = 'Array'
$iDimensions -= 1
For $i = 0 To $iDimensions
$ret &= '[' & UBound($vVar, $i + 1) & ']'
$iCells *= UBound($vVar, $i + 1)
Next
If $iCells = 0 Then
Return $ret & $_TAB & ' (array is empty)'
Else
Return $ret & @CRLF & __VarDumpArray($vVar, $iLimit, $sIndent)
EndIf
Case "Binary"
$len = BinaryLen($vVar)
$ret = 'Binary (' & BinaryLen($vVar) & ') '
Return($ret & (($len <= 32) ? $vVar : BinaryMid($vVar, 1, 16) & ' ... ' & StringTrimLeft(BinaryMid($vVar, $len - 15, 16), 2)))
Case "Bool"
Return 'Boolean ' & $vVar
Case "Keyword"
Return('Keyword ' & ($vVar = Null ? 'Null' : ($vVar = Default ? 'Default' : 'Other keyword')))
Case "Ptr"
Return(IsHWnd($vVar) ? 'HWnd ' : 'Pointer ' & $vVar)
Case "Object"
Return 'Object ' & ObjName($vVar)
Case "Function", "UserFunction"
Return StringFormat('%-13s', VarGetType($vVar)) & FuncName($vVar)
Case "DllStruct"
$len = DllStructGetSize($vVar)
$ptr = DllStructGetPtr($vVar)
$ret = 'Struct (' & $len & ') @:' & Hex($ptr) & ' (structure alignment is unknown)' & @CRLF
Local $nbElem = 1, $idx, $incr, $data, $type, $indent = $sIndent & $_TAB, $oldvalue, $readvalue, $field, $elem
While 1
$data = DllStructGetData($vVar, $nbElem)
If @error = 2 Then ExitLoop
$type = VarGetType($data)
$idx = 1
$incr = 0
; determine max index of element
While 1
DllStructGetData($vVar, $nbElem, 2 * $idx)
If @error = 3 Then ExitLoop
$incr = $idx
$idx *= 2
WEnd
; index is in [$idx, (2 * $idx) - 1]
$idx += $incr
Do
DllStructGetData($vVar, $nbElem, $idx)
If @error = 3 Then
; approach is asymetric (upper bound is too big)
$idx -= ($incr = 1) ? 1 : $incr / 2
Else
$idx += Int($incr / 2)
EndIf
$incr = Int($incr / 2)
Until $incr = 0
Switch $type
Case "Int32", "Int64"
$ret &= $indent
$data = DllStructGetData($vVar, $nbElem, 1)
DllStructSetData($vVar, $nbElem, 0x7777666655554433, 1)
$readvalue = DllStructGetData($vVar, $nbElem, 1)
Switch $readvalue
Case 0x7777666655554433
$elem = "int64"
; alias: uint64
; alias: int_ptr(x64), long_ptr(x64), lresult(x64), lparam(x64)
; alias: uint_ptr(x64), ulong_ptr(x64), dword_ptr(x64), wparam(x64)
Case 0x55554433
DllStructSetData($vVar, $nbElem, 0x88887777, 1)
$readvalue = DllStructGetData($vVar, $nbElem, 1)
$elem = ($readvalue > 0 ? "uint" : "int")
; int aliases: long, bool, int_ptr(x86), long_ptr(x86), lresult(x86), lparam(x86);
; uint aliases: ulong, dword, uint_ptr(x86), ulong_ptr(x86), dword_ptr(x86), wparam(x86)
Case 0x4433
DllStructSetData($vVar, $nbElem, 0x8888, 1)
$readvalue = DllStructGetData($vVar, $nbElem, 1)
$elem = ($readvalue > 0 ? "ushort" : "short")
; ushort alias: word
Case 0x33
$elem = "byte"
; alias: ubyte
EndSwitch
DllStructSetData($vVar, $nbElem, $data, 1)
If $idx = 1 Then
$ret &= StringFormat('%-' & 9 + StringLen($len) & 's ', $elem) & $data & @CRLF
Else
$ret &= $elem & "[" & $idx & "]" & @CRLF
For $i = 1 To $idx
If $iLimit And $idx > $iLimit And $i > $iLimit Then
$ret &= $indent & StringFormat('%-' & 9 + StringLen($len) & 's ', '') & '... there are ' & $idx - $iLimit & ' more ' & $elem & ' in this array' & @CRLF
ExitLoop
Else
$ret &= $indent & StringFormat('%-' & 9 + StringLen($len) & 's ', '') & DllStructGetData($vVar, $nbElem, $i) & @CRLF
EndIf
Next
EndIf
Case "String"
$oldvalue = DllStructGetData($vVar, $nbElem, 1)
DllStructSetData($vVar, $nbElem, ChrW(0x2573), 1)
$readvalue = DllStructGetData($vVar, $nbElem, 1)
DllStructSetData($vVar, $nbElem, $oldvalue, 1)
$elem = ($readvalue = ChrW(0x2573) ? "wchar" : "char")
If $idx > 1 Then $elem &= "[" & $idx & "]"
$ret &= $indent & StringFormat('%-' & 9 + StringLen($len) & 's ', $elem) & __DumpStr($data) & @CRLF
Case "Binary"
Local $blen = BinaryLen($data)
$elem = "byte"
If $idx > 1 Then $elem &= "[" & $idx & "]"
$ret &= $indent & StringFormat('%-' & 9 + StringLen($len) & 's ', $elem) & (($blen <= 32) ? $data : BinaryMid($data, 1, 16) & ' ... ' & StringTrimLeft(BinaryMid($data, $blen - 15, 16), 2)) & @CRLF
Case "Ptr"
$ret &= $indent
$elem = "ptr"
; alias: hwnd, handle
If $idx = 1 Then
$ret &= StringFormat('%-' & 9 + StringLen($len) & 's ', $elem) & $data & @CRLF
Else
$ret &= $elem & "[" & $idx & "]" & @CRLF
For $i = 1 To $idx
$ret &= $indent & StringFormat('%-' & 9 + StringLen($len) & 's ', '') & DllStructGetData($vVar, $nbElem, $i) & @CRLF
Next
EndIf
Case "Double"
$ret &= $indent
$oldvalue = DllStructGetData($vVar, $nbElem, 1)
DllStructSetData($vVar, $nbElem, 10^-15, 1)
$readvalue = DllStructGetData($vVar, $nbElem, 1)
DllStructSetData($vVar, $nbElem, $oldvalue, 1)
$elem = ($readvalue = 10^-15 ? "double" : "float")
If $idx = 1 Then
$ret &= StringFormat('%-' & 9 + StringLen($len) & 's ', $elem) & $data & (IsInt($data) ? '.0' : '') & @CRLF
Else
$ret &= $elem & "[" & $idx & "]" & @CRLF
For $i = 1 To $idx
If $iLimit And $idx > $iLimit And $i > $iLimit Then
$ret &= $indent & StringFormat('%-' & 9 + StringLen($len) & 's ', '') & '... there are ' & $idx - $iLimit & ' more ' & $elem & ' in this array' & @CRLF
ExitLoop
Else
$ret &= $indent & StringFormat('%-' & 9 + StringLen($len) & 's %s', '', DllStructGetData($vVar, $nbElem, $i)) & (IsInt(DllStructGetData($vVar, $nbElem, $i)) ? '.0' : '') & @CRLF
EndIf
Next
EndIf
EndSwitch
$nbElem += 1
WEnd
Return StringTrimRight($ret, 2)
Case "Map"
Local $iCells = UBound($vVar)
$ret = 'Map[' & $iCells & ']'
If $iCells = 0 Then
Return $ret & $_TAB & ' (map is empty)'
Else
Return $ret & @CRLF & __VarDumpMap($vVar, $iLimit, $sIndent)
EndIf
Case Else
Return StringFormat('%-13s', VarGetType($vVar)) & $vVar
EndSwitch
EndFunc ;==>__VarDump
Func __VarDumpArray(ByRef $aArray, $iLimit, $sIndent = $_TAB)
Local $sDump, $sArrayFetch, $sArrayRead, $iDone = 0, $iElements = 1
Local $iDimensions = UBound($aArray, 0)
Local $aUBounds[$iDimensions]
Local $aIndices[$iDimensions]
$iDimensions -= 1
For $i = 0 To $iDimensions
$aUBounds[$i] = UBound($aArray, $i + 1) - 1
$iElements *= $aUBounds[$i] + 1
$aIndices[$i] = 0
Next
$sIndent &= $_TAB
While $iDone < ($iLimit ? _Min($iLimit, $iElements) : $iElements)
$sArrayFetch = ''
For $i = 0 To $iDimensions
$sArrayFetch &= '[' & $aIndices[$i] & ']'
Next
$sArrayRead = Execute('$aArray' & $sArrayFetch)
$sDump &= $sIndent & $sArrayFetch & ' => ' & __VarDump($sArrayRead, $iLimit, $sIndent) & @CRLF
$iDone += 1
If $iLimit And $iDone = $iLimit Then
$sDump &= $sIndent & '... there are ' & $iElements - $iDone & ' more elements in this array' & @CRLF
ExitLoop
EndIf
For $i = $iDimensions To 0 Step -1
$aIndices[$i] += 1
If $aIndices[$i] > $aUBounds[$i] Then
$aIndices[$i] = 0
Else
ExitLoop
EndIf
Next
WEnd
Return(StringTrimRight($sDump, 2))
EndFunc ;==>__VarDumpArray
Func __VarDumpMap(ByRef $mMap, $iLimit, $sIndent = $_TAB)
Local $i = 0, $sDump
$sIndent &= $_TAB
For $key In Mapkeys($mMap)
$sDump &= $sIndent & StringFormat('%-16s => ', _
"[" & (IsString($key) ? __DumpStr($key) : $key) & "]")
$sDump &= __VarDump($mMap[$key], $iLimit, $sIndent) & @CRLF
If $iLimit And $i = $iLimit - 1 Then
$sDump &= $sIndent & '... there are ' & UBound($mMap) - $i - 1 & ' more elements in this map' & @CRLF
ExitLoop
EndIf
$i += 1
Next
Return(StringTrimRight($sDump, 2))
EndFunc ;==>__VarDumpMap
Func __DumpStr($vVar)
Local $len = StringLen($vVar)
$vVar = Execute("'" & StringRegExpReplace(StringReplace($vVar, "'", "''"), "([\p{Cc}])", "<0x' & Hex(AscW('$1'), 2) & '>") & "'")
Return "'" & (($len <= 64) ? $vVar : StringMid($vVar, 1, 32) & ' ... ' & StringTrimLeft(StringMid($vVar, $len - 31, 32), 2)) & "'"
EndFunc ;==>__DumpStr