﻿;-- TIME_STAMP   2022-05-20 16:39:08   v 0.1


#cs
    ABOUT
        1.
        Execute Lua scripts or single Lua commands from SciTE using an external Lua installation.
        Return values are output to the SciTE console. A syntax check is performed before execution.
        Lua files can be called in SciTE in the same way as AutoIt files with parameters.
        Thus, up to 4 parameters can be passed for testing within SciTE.

        2.
        Execute Lua scripts or single Lua commands from an au3 script.
        Return values are output to the file: @ScriptDir & '\LuaRunner_Result.txt'.
        A syntax check is performed before execution.
        The number of parameters that can be passed to a Lua file is limited only by Lua itself.
        Using:
        Add LuaRunner.exe and the Lua folder to your Autot project directory.
        Run the script in au3 with a command as in EXAMPLE.

        LuaRunner recognizes whether it was called from SciTE or not. So the correct output form is selected.

    REQUIREMENTS
        A folder including all lua folders and files (\bin\*, \doc\*, \include\*)
        If stored somewhere, assign this path to "Global $pathLua".
        Or save it in the same directory as "LuaRunner.exe".

        Add to your User properties (Command number, path and shortcut must be adjusted.):
            # 49 Run Lua file with external Lua
            command.name.49.$(file.patterns.lua)=Lua call with Parameters
            command.49.$(file.patterns.lua)="C:\CODE\AutoIt\TOOLS\LuaRunner.exe" "-f" "$(FilePath)" $(1) $(2) $(3) $(4)
            command.mode.49.$(file.patterns.lua)=subsystem:0,savebefore:no
            command.shortcut.49.$(file.patterns.lua)=Ctrl+Alt+L

    CALL
        LuaRunner.exe -f File.lua [P1] [P2] .. [Pn]
        LuaRunner.exe -l "Lua script line"

    PARAMETERS
        -f                  A Lua file is executed.
        -fs                 A Lua file is executed in silent mode. Only error messages and result are displayed.
        File.lua            The file to be executed.
        [P1] [P2] .. [Pn]   optional: parameters to pass to the File.lua
        -l                  A Lua script line is executed
        -ls                 A Lua script line is executed in silent mode. Only error messages and result are displayed.
        "Lua script line"   The Lua script line

    EXAMPLE
        LuaRunner.exe -f "C:\Code\Lua\example.lua" "some\file\path.txt" "2nd-param"
        LuaRunner.exe -l "print('Hello World!')"

    NOTE
        To access the passed parameters when calling a Lua file, the table "arg" is used in the Lua script.
        Unlike normal Lua tables, this one has a value at index 0: the path of the Lua file. For each parameter passed, there is another entry.
#ce


#include <File.au3>
#include <WinAPIProc.au3>

Global $PIDcaller = _WinAPI_GetParentProcess(), $NameCaller = ''
Global $aList = ProcessList()
For $i = 1 To $aList[0][0]
    If $aList[$i][1] = $PIDcaller Then
        $NameCaller = $aList[$i][0]
        ExitLoop
    EndIf
Next
Global $bSciTECall = (StringInStr($NameCaller, 'SciTE') > 0)

Global $FileResult = @ScriptDir & '\LuaRunner_Result.txt' ; only used if not called from SciTE


;---------------------------------------------------------------------------------------------------
; Assign path if not stored in script directory
Global $pathLua = "C:\portable\Lua_5.4.4\lua\bin\lua.exe"

; If "$pathLua" not exists, search in @ScriptDir
If Not FileExists($pathLua) Then
    $pathLua = _FindLua()
    If $pathLua = '' Then Exit MsgBox(16+4096, 'ERROR', '! No lua.exe found !')
EndIf

Global $pathLuaC = StringTrimRight($pathLua, 4) & 'c.exe'
If Not FileExists($pathLuaC) Then Exit MsgBox(16+4096, 'ERROR', '! No luac.exe found !' & @CRLF & 'The Lua installation is incomplete.')
;---------------------------------------------------------------------------------------------------


Global $sVer = StringRegExpReplace(_RunLua(StringFormat('"%s" -e"print(_VERSION)"', $pathLua), False), '[\r\n]*', '')
$sVer = StringFormat('(%s):', $sVer)

Select
    Case $CMDLINE[0] = 0
        Exit MsgBox(16+4096, 'ERROR', '! No parameter was passed !')
    Case $CMDLINE[0] < 2
        Exit MsgBox(16+4096, 'ERROR', '! No file or script line was passed !')
EndSelect

Global $sCmd = '', $sParam = '', $sErrCmd = '', $sSyntaxCheck

Global $bSilent = False
If StringRight($CMDLINE[1], 1) = 's' Then
    $CMDLINE[1] = StringTrimRight($CMDLINE[1], 1)
    $bSilent = True
EndIf

Switch $CMDLINE[1]
    Case '-f'  ; "FILE" ["PARAM1", "PARAM..n"]
        If Not FileExists($CMDLINE[2]) Then Exit MsgBox(16+4096, 'ERROR', '! The lua file path not exists !' & @CRLF & @CRLF & '"' & $CMDLINE[2] & '"')
        If $CMDLINE[0] > 2 Then ; param for lua file passed
            For $i = 3 To $CMDLINE[0]
                $sParam &= ' ' & $CMDLINE[$i]
            Next
        EndIf
        $sSyntaxCheck = _Syntaxcheck('-f', $CMDLINE[2])
        If $sSyntaxCheck <> '' Then
            _ConsoleWrite('! Syntax Error !' & @CRLF & $sSyntaxCheck)
            Exit MsgBox(16+4096, 'ERROR', '! Syntax Error !' & ($bSciTECall ? '' : @CRLF & $sSyntaxCheck))
        EndIf
        $sCmd = StringFormat('"%s" "%s"%s', $pathLua, $CMDLINE[2], $sParam)
        If Not $bSilent Then _ConsoleWrite(StringFormat('>Running:%s%s', $sVer, $sCmd) & @CRLF)
    Case '-l'  ; "LINE"
        $sSyntaxCheck = _Syntaxcheck('-l', $CMDLINE[2])
        If $sSyntaxCheck <> '' Then
            _ConsoleWrite('! Syntax Error !' & @CRLF & $sSyntaxCheck)
            Exit MsgBox(16+4096, 'ERROR', '! Syntax Error !' & ($bSciTECall ? '' : @CRLF & $sSyntaxCheck))
        EndIf
        $sCmd = StringFormat('"%s" -e"%s"', $pathLua, $CMDLINE[2])
        If Not $bSilent Then _ConsoleWrite(StringFormat('>Running:%s"%s" "lua-script-line"', $sVer, $pathLua) & @CRLF)
EndSwitch

_RunLua($sCmd)


;---------------------------------------------------------------------------------------------------
Func _ConsoleWrite($_sWrite)
    If $bSciTECall Then ConsoleWrite($_sWrite)
EndFunc

Func _Syntaxcheck($_Type, $_Run)
    Local Static $TmpFile = @TempDir & '\syntax_check_line.lua'
    If $_Type = '-l' Then
        If FileExists($TmpFile) Then FileDelete($TmpFile)
        FileWrite($TmpFile, $_Run)
        $_Run = $TmpFile
    EndIf
    Local $sCmd = StringFormat('"%s" -p "%s"', $pathLuaC, $_Run)
    Local $sCheck = _RunLua($sCmd, False, True)
    If $sCheck = '' Then Return $sCheck
    Return StringTrimLeft($sCheck, StringLen($pathLuaC)+2 )
EndFunc


Func _RunLua($_sCmd, $_bConsole=True, $_bCheck=False)
    Local $iPID = Run($_sCmd, '', @SW_HIDE, BitOR(0x2,0x4))
    Local $sOutput = '', $sError = ''
    While 1
        $sOutput &= StdoutRead($iPID)
        If @error Then ExitLoop
    WEnd

    While 1
        $sError &= StderrRead($iPID)
        If @error Then ExitLoop
    WEnd

    If $_bCheck Then Return $sError

    If $_bConsole Then
        If $sError <> '' Then _ConsoleWrite('!> ERROR' & @CRLF & '!> ' & $sError & @CRLF)
        If $sOutput <> '' Then _ConsoleWrite($sOutput & @CRLF)
        If Not $bSilent Then _ConsoleWrite(StringFormat('>ExitRunner: %02d:%02d:%02d\n', @HOUR, @MIN, @SEC))
        If Not $bSciTECall Then
            If $sOutput <> '' Then
                _WriteOutFile($sOutput)
                If Not $bSilent Then MsgBox(64+4096, 'Done', 'Result is stored to' & @CRLF & @CRLF & '"' & $FileResult & '"')
                Exit
            Else
                If Not $bSilent Then MsgBox(64+4096, 'Done', 'Process completed without result value.')
                Exit
            EndIf
        EndIf
    Else
        Return ($sError = '' ? $sOutput : $sError)
    EndIf
EndFunc


Func _WriteOutFile($_sWrite)
    Local $fH = FileOpen($FileResult, 8+2)
    FileWrite($fH, $_sWrite)
    FileClose($fH)
EndFunc


Func _FindLua($_path=@ScriptDir)
    Local $aDir = _FileListToArray($_path, '*', 2, True)
    For $i = 1 To $aDir[0]
        If FileExists($aDir[$i] & '\bin\lua.exe') Then Return $aDir[$i] & '\bin\lua.exe'
    Next
    Return ''
EndFunc
;---------------------------------------------------------------------------------------------------
