Jump to content

Recommended Posts

Posted (edited)

I had a dissatisfaction with IsNumber so this function was born: 

; =================================================================================================
; UDF: DataTypeChecker.au3
; Author:        Dao Van Trong - TRONG.PRO
; Released:      2025-08-25
; Description:   A strict‐hex only data type checker for AutoIt.
;                Detects AutoIt-specific objects, native numeric types,
;                binary/boolean, strict-hex strings, numeric strings
;                in US/EU formats, boolean-like strings, and falls back
;                to plain strings or unknown.
;
;                Exports:
;                  CheckDataType($vInput, $bShowDebug = False)
;                  GetDataTypeName($iCode)
;
;                Internal helpers (not intended for direct external use):
;                  _DebugResult($iCode, $sText)
;                  _ParseNumeric($sInput, $bShowDebug = False)
; =================================================================================================


; =================================================================================================
; Function:    CheckDataType
; Purpose:     Determine the data type code of any AutoIt variable or string.
; Parameters:
;     $vInput     - Any AutoIt variable or literal to examine.
;     $bShowDebug - Optional. When True, debug messages are printed to the console.
; Returns:     Integer type code:
;                 1 = String
;                 2 = Int32
;                 3 = Int64
;                 4 = Double/Float
;                 5 = Binary/Hex
;                 6 = Boolean
;                 7 = Array
;                 8 = Map
;                 9 = Pointer
;                10 = DLL Struct
;                11 = Window Handle
;                12 = Object
;                13 = Keyword
;                14 = Function
;                15 = UserFunction
;                16 = Unknown
; =================================================================================================
Func CheckDataType($vInput, $bShowDebug = False)
    ; 1) AutoIt-specific objects
    If IsArray($vInput) Then Return _DebugResult(7, "Array", $vInput)
    If IsMap($vInput) Then Return _DebugResult(8, "Map", $vInput)
    If IsPtr($vInput) Then Return _DebugResult(9, "Pointer", $vInput)
    If IsDllStruct($vInput) Then Return _DebugResult(10, "DLL Struct", $vInput)
    If IsHWnd($vInput) Then Return _DebugResult(11, "Window Handle", $vInput)
    If IsObj($vInput) Then Return _DebugResult(12, "Object", $vInput)
    If IsKeyword($vInput) Then Return _DebugResult(13, "Keyword", $vInput)

    Local $sType = VarGetType($vInput)
    If IsFunc($vInput) Then
        If $sType = "UserFunction" Then
            Return _DebugResult(15, "UserFunction", $vInput)
        Else
            Return _DebugResult(14, "Function", $vInput)
        EndIf
    EndIf

    ; 2) Native numeric
    If $sType = "Int32" Then Return _DebugResult(2, "Int32", $vInput)
    If $sType = "Int64" Then Return _DebugResult(3, "Int64", $vInput)
    If $sType = "Double" Then Return _DebugResult(4, "Double/Float", $vInput)

    ; 3) Native binary & boolean
    If IsBinary($vInput) Then Return _DebugResult(5, "Binary/Hex", $vInput)
    If IsBool($vInput) Then Return _DebugResult(6, "Boolean", $vInput)

    ; 4) String analysis – strict-hex first, then numeric/boolean-like, then fallback
    If IsString($vInput) Then
        If $bShowDebug Then ConsoleWrite("- [DEBUG] String analysis..." & @CRLF)
        Local $s = StringStripWS($vInput, 8)

        ; 4.1) Hex with 0x prefix, even-length body
        If StringRegExp($s, "^0[xX][0-9A-Fa-f]+$") Then
            Local $hexBody = StringMid($s, 3)
            If Mod(StringLen($hexBody), 2) = 0 Then
                Return _DebugResult(5, "Hex string (0x prefix, strict)", $vInput)
            ElseIf $bShowDebug Then
                ConsoleWrite("- [DEBUG] Prefix hex odd length, skip" & @CRLF)
            EndIf
        EndIf

        ; 4.2) Bare hex (no prefix), even length,
        ;       but skip if purely digits (prioritize numeric)
        If StringRegExp($s, "^[0-9A-Fa-f]+$") Then
            ; if only digits (no A-F letters), treat as numeric
            If StringRegExp($s, "^[0-9]+$") Then
                If $bShowDebug Then
                    ConsoleWrite("- [DEBUG] Bare digits only, defer to numeric parse" & @CRLF)
                EndIf
            ElseIf Mod(StringLen($s), 2) = 0 Then
                Return _DebugResult(5, "Hex string (bare, strict)", $vInput)
            ElseIf $bShowDebug Then
                ConsoleWrite("- [DEBUG] Bare hex odd length, skip" & @CRLF)
            EndIf
        EndIf

        ; 4.3) Numeric parse (int32/int64/double)
        Local $numInfo = _ParseNumeric($s, $bShowDebug)
        If $numInfo[0] Then
            Return _DebugResult($numInfo[1], GetDataTypeName($numInfo[1]) & " (string)", $vInput)
        EndIf

        ; 4.4) Boolean-like strings
        Local $sl = StringLower($s)
        If $sl = "true" Or $sl = "false" Then
            Return _DebugResult(6, "Boolean-like string", $vInput)
        EndIf

        ; 4.5) Fallback string
        Return _DebugResult(1, "String", $vInput)
    EndIf

    ; 5) Unknown
    Return _DebugResult(16, "Unknown", $vInput)
EndFunc   ;==>CheckDataType


; =================================================================================================
; Function:    _DebugResult
; Purpose:     Internal helper to print debug messages and return a code.
; Parameters:
;     $iCode - Integer code to return.
;     $sText - Description text to display in debug.
; Returns:     $iCode
; =================================================================================================
Func _DebugResult($iCode, $sText, $sInput)
    $sInput = StringReplace($sInput, @CRLF, '@CRLF')
    ConsoleWrite(StringFormat("- [DEBUG] Input '%s' (Len: %d) is: %s (Type=%d)" & @CRLF, $sInput, StringLen($sInput), $sText, $iCode))
    Return $iCode
EndFunc   ;==>_DebugResult


; =================================================================================================
; Function:    _ParseNumeric
; Purpose:     Internal numeric parser supporting US and EU formats.
; Parameters:
;     $sInput     - String to parse for numeric patterns.
;     $bShowDebug - Optional. When True, debug messages are printed.
; Returns:     A two-element array: [0] = True/False if numeric,
;                                       [1] = type code (2=Int32,3=Int64,4=Double)
; =================================================================================================
Func _ParseNumeric($sInput, $bShowDebug = False)
    Local $res[2] = [False, 0]
    If $sInput = "" Then Return $res
    If StringRegExp($sInput, "^0[0-9]+$") Then Return $res

    Local $patUS = "^[+-]?[0-9]{1,3}(,[0-9]{3})*(\.[0-9]+)?$"
    Local $patEU = "^[+-]?[0-9]{1,3}(\.[0-9]{3})*(,[0-9]+)?$"
    Local $patThousand = "^[+-]?[0-9]{1,3}([,\.][0-9]{3})+$"
    Local $patSimpleEU = "^[+-]?[0-9]+,[0-9]+$"

    Local $matched = False
    Local $numStr = $sInput
    Local $hasDec = False

    ; US format: 1,234.56
    If StringRegExp($sInput, $patUS) Then
        $matched = True
        $numStr = StringReplace($sInput, ",", "")
        $hasDec = StringInStr($sInput, ".", 0) > 0
    EndIf

    ; EU format: 1.234,56
    If Not $matched And StringRegExp($sInput, $patEU) Then
        $matched = True
        $numStr = StringReplace(StringReplace($sInput, ".", ""), ",", ".")
        $hasDec = True
    EndIf

    ; Thousand separators only: 1,234 or 1.234
    If Not $matched And StringRegExp($sInput, $patThousand) Then
        $matched = True
        $numStr = StringReplace(StringReplace($sInput, ",", ""), ".", "")
    EndIf

    ; Simple EU decimals: 123,45
    If Not $matched And StringRegExp($sInput, $patSimpleEU) Then
        $matched = True
        $numStr = StringReplace($sInput, ",", ".")
        $hasDec = True
    EndIf

    If Not $matched Then Return $res

    Local $val = Number($numStr)
    ; Decide Double vs Int
    If $hasDec Or $val <> Int($val) Then
        Local $aResult[2] = [True, 4]
        Return $aResult
    EndIf

    ; Int32 vs Int64
    If $val >= -2147483648 And $val <= 2147483647 Then
        Local $aResult[2] = [True, 2]
        Return $aResult
    Else
        Local $aResult[2] = [True, 3]
        Return $aResult
    EndIf
EndFunc   ;==>_ParseNumeric


; =================================================================================================
; Function:    GetDataTypeName
; Purpose:     Map a numeric code to its human-readable type name.
; Parameters:
;     $iCode - Integer type code (1–16).
; Returns:     String name corresponding to that code.
; =================================================================================================
Func GetDataTypeName($i)
    Select
        Case $i = 1
            Return "String"
        Case $i = 2
            Return "Int32"
        Case $i = 3
            Return "Int64"
        Case $i = 4
            Return "Double/Float"
        Case $i = 5
            Return "Binary/Hex"
        Case $i = 6
            Return "Boolean"
        Case $i = 7
            Return "Array"
        Case $i = 8
            Return "Map"
        Case $i = 9
            Return "Pointer"
        Case $i = 10
            Return "DLL Struct"
        Case $i = 11
            Return "Window Handle"
        Case $i = 12
            Return "Object"
        Case $i = 13
            Return "Keyword"
        Case $i = 14
            Return "Function"
        Case $i = 15
            Return "UserFunction"
        Case Else
            Return "Unknown"
    EndSelect
EndFunc   ;==>GetDataTypeName

; -------------------------------------------------------------------
; Helper: is this ANY numeric type? (native or string)
; -------------------------------------------------------------------
Func _IsNumber($v)
    Local $c = CheckDataType($v, False)
    Return ($c = 2 Or $c = 3 Or $c = 4)
EndFunc   ;==>_IsNumber

; =================================================================================================
; USAGE EXAMPLE / SELF-TEST
; =================================================================================================

ConsoleWrite("!=== STRICT‐HEX MODE TYPE CHECK RESULTS ===" & @CRLF)

; Test a variety of inputs
Local $aTestValues[] = [123, 9223372036854775807, 12.34, "0123", "12.34", "Hello", "0xFF", "ABCD", "ABC", "A", "True", "False", "", _
        "C:\Windows\System32", "https://www.google.com", "user@example.com", "12345", _
        "1,234", "1.234", "1,234.56", "1.234,56", "1,234,567.89", "1.234.567,89", "12,5", _
        "0xABC", "0xABCD", "F", "FF", "123ABC", "ABCDEF", Default, @CRLF, GetDataTypeName]

For $i = 0 To UBound($aTestValues) - 1
    Local $v = $aTestValues[$i]
    Local $code = CheckDataType($v)                        ; strict‐hex always on
    ConsoleWrite( _
            StringFormat( _
            "> %-20s -> %-14s (%d)" & @CRLF, _
            "'" & String($v) & "'", _
            GetDataTypeName($code), _
            $code _
            ) _
            )
Next


ConsoleWrite(@CRLF & "!=== DETAILED DEBUG FOR HEX CASES ===" & @CRLF)

; Show internal decision for each hex candidate
Local $debugTests[] = ["ABC", "ABCD", "0xABC", "0xABCD", "F", "FF"]
For $i = 0 To UBound($debugTests) - 1
    Local $s = $debugTests[$i]
    ConsoleWrite(@CRLF & "+ Debug analysis for '" & $s & "':" & @CRLF)
    CheckDataType($s, True)    ; debug = True prints each logic step
Next


ConsoleWrite(@CRLF & "!=== USAGE EXAMPLES ===" & @CRLF)

; Actual AutoIt types
Local $myArray[3] = [1, 2, 3]
Local $myMap[]     ; map
$myMap["key"] = "value"

ConsoleWrite("+ IsNumber:           " & _IsNumber('1') & @CRLF)
ConsoleWrite("+ Int32:           " & GetDataTypeName(CheckDataType(42)) & @CRLF)
ConsoleWrite("+ Int64:           " & GetDataTypeName(CheckDataType(5000000000)) & @CRLF)
ConsoleWrite("+ Double:          " & GetDataTypeName(CheckDataType(3.14159)) & @CRLF)
ConsoleWrite("+ String Int:      " & GetDataTypeName(CheckDataType("42")) & @CRLF)
ConsoleWrite("+ Intl Number:     " & GetDataTypeName(CheckDataType("1.234,56")) & @CRLF)
ConsoleWrite("+ Hex String:      " & GetDataTypeName(CheckDataType("0xFF")) & @CRLF)

ConsoleWrite("+ Array:           " & GetDataTypeName(CheckDataType($myArray)) & @CRLF)
ConsoleWrite("+ Map:             " & GetDataTypeName(CheckDataType($myMap)) & @CRLF)
ConsoleWrite("+ Boolean True:    " & GetDataTypeName(CheckDataType(True)) & @CRLF)
ConsoleWrite("+ String Bool:     " & GetDataTypeName(CheckDataType("false")) & @CRLF)
ConsoleWrite("+ Keyword Default: " & GetDataTypeName(CheckDataType(Default)) & @CRLF)
ConsoleWrite("+ Function @CRLF:  " & GetDataTypeName(CheckDataType(@CRLF)) & @CRLF)
ConsoleWrite("+ UserFunc:        " & GetDataTypeName(CheckDataType(GetDataTypeName)) & @CRLF)

:)

Edited by Trong
add function

Regards,
 

Posted (edited)

You can add 3 AutoIt types: Keyword, Function and UserFunction. Also you can differentiate between Int32, Int64, Double and float signals.

Edited by jchd

This wonderful site allows debugging and testing regular expressions (many flavors available). An absolute must have in your bookmarks.
Another excellent RegExp tutorial. Don't forget downloading your copy of up-to-date pcretest.exe and pcregrep.exe here
RegExp tutorial: enough to get started
PCRE v8.33 regexp documentation latest available release and currently implemented in AutoIt beta.

SQLitespeed is another feature-rich premier SQLite manager (includes import/export). Well worth a try.
SQLite Expert (freeware Personal Edition or payware Pro version) is a very useful SQLite database manager.
An excellent eBook covering almost every aspect of SQLite3: a must-read for anyone doing serious work.
SQL tutorial (covers "generic" SQL, but most of it applies to SQLite as well)
A work-in-progress SQLite3 tutorial. Don't miss other LxyzTHW pages!
SQLite official website with full documentation (may be newer than the SQLite library that comes standard with AutoIt)

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   1 member

×
×
  • Create New...