#include <WinAPIFiles.au3>
Global $sAutoItExe = @AutoItExe ;Should be 3.3.12.0 / 3.3.9.4 / 3.3.8.X / 3.3.6.X
;Global $sAutoItExe = 'D:\AutoIt_Versions\AutoIt_3.3.12.0\AutoIt3.exe'
$sFile = FileOpenDialog('Select script file (source from your compiled script)...', @ScriptDir, 'AutoIt v3 Script (*.au3)')
If @error Then Exit
$iLine = InputBox('Get error code line', 'Please enter error line number from compiled script:' & @CRLF & @CRLF & '(the AutoIt version of selected source file should match the version that used to compile the script)', '')
If @error Then Exit
SplashTextOn('Generating error code line', 'Please wait...', 200, 50, -1, -1, BitOR(16, 32), '', 12, 800)
$sCodeLine = _AU3_GetErrLineCode($sFile, $iLine)
SplashOff()
MsgBox(64, 'Result', StringFormat('Error code line (#%i) for <%s>:\r\n%s', $iLine, StringRegExpReplace($sFile, '^.*\\', ''), $sCodeLine))
Func _AU3_GetErrLineCode($sScript_File, $iLine)
	Local $sSrc_Raw, $iPos1, $iPos2, $iLen
	
	$sSrc_Raw = _AU3_StripToRaw($sScript_File)
	
	If @error Then
		Return SetError(1, 0, '')
	EndIf
	
	$sSrc_Raw = StringStripWS($sSrc_Raw, 3)
	$iPos1 = StringInStr($sSrc_Raw, @LF, 2, $iLine - 1)
	$iPos2 = StringInStr($sSrc_Raw, @LF, 2, $iLine)
	$iLen = ($iPos2 > 0 ? $iPos2 - $iPos1 : -1)
	
	Return StringStripWS(StringMid($sSrc_Raw, $iPos1, $iLen), 3)
EndFunc
Func _AU3_StripToRaw($sSrcFile, $bReset = False)
	If $sSrcFile = '' Or Not FileExists($sSrcFile) Then
		Return SetError(1, 0, 0)
	EndIf
	
	Local Static $sSrcRaw = ''
	Local Static $sInclds = '|'
	
	If $bReset Then
		$sSrcRaw = ''
		$sInclds = '|'
	EndIf
	
	Local $sInclude = '', $sLine = '', $iPos = 0, $sFName = '', $sFnc = '', $aFnc, $aVars
	Local $sScriptDir = StringRegExpReplace($sSrcFile, '\\[^\\]+$', '')
	Local $sRead = FileRead($sSrcFile)
	
	;!!! Strip comment block here (before checking #include-once)...
	_AU3_StringStripCommentBlocks($sRead)
	
	If StringRegExp($sRead, '(?mi)^\h*#include-once') Then
		If StringInStr($sInclds, '|' & $sSrcFile & '|', 2) Then
			$sRead = StringRegExpReplace($sRead, '(?msi)\R?^\h*#include-once.*', '')
		Else
			$sInclds &= $sSrcFile & '|'
		EndIf
	EndIf
	
	$sRead = StringStripCR($sRead)
	Local $aRead = StringSplit($sRead, @LF)
	
	For $i = 1 To $aRead[0]
		If StringStripWS($aRead[$i], 8) = '' Then
			ContinueLoop
		EndIf
		
		If StringRegExp($aRead[$i], '(?i)^\h*(;|#include-once|#pragma\h+compile\()') Then
			ContinueLoop
		EndIf
		
		_AU3_StringStripComments($aRead[$i])
		
		If Not StringRegExp($aRead[$i], '(?i)^\h*#include\h*[<"'']') Then
			$sLine = $aRead[$i]
			
			;Merge broken (with _) lines
			If StringRegExp($aRead[$i], '_\h*$') Then
				$sLine = StringRegExpReplace($aRead[$i], '^\h+|[_\h]+$', '')
				
				While 1
					$i += 1
					
					If $i >= $aRead[0] Then
						ExitLoop
					EndIf
					
					_AU3_StringStripComments($aRead[$i])
					$aRead[$i] = StringRegExpReplace($aRead[$i], '[_\h]+$', '')
					
					If @extended = 0 Then
						$sLine &= ' ' & StringStripWS($aRead[$i], 1)
						ExitLoop
					EndIf
					
					$sLine &= ' ' & StringStripWS($aRead[$i], 1)
				WEnd
			EndIf
			
			$sSrcRaw &= StringStripWS($sLine, 1) & @CRLF
			
			ContinueLoop
		EndIf
		
		;Get include path
		$sInclude = _AU3_IncludeToPath($aRead[$i], $sScriptDir)
		
		If Not @error Then
			;Recursive call for include
			$sSrcRaw = _AU3_StripToRaw($sInclude)
		EndIf
	Next
	
	Return $sSrcRaw
EndFunc
Func _AU3_IncludeToPath($sInclude, $sScriptDir = @ScriptDir)
	Local $aRegExp, $aRet, $sSYS, $sAU3, $sWorkDir
	Local $iError = 0, $sRet = ''
	
	$aRegExp = StringRegExp($sInclude, '(?i)^\h*#include\h+(<|"|'')([^>"'']+)(?:>|"|'')\h*(;.*?)?$', 3)
    
    If UBound($aRegExp) < 2 Then
		Return SetError(1, 0, '')
	EndIf
	
    $sInclude = $aRegExp[1]
	
	;Get AutoIt Include folder
	Local Static $sAutoIt_Incl_Dir = StringRegExpReplace($sAutoItExe, '\\[^\\]+$', '') & '\Include'
	
	;Get User Include folders
	Local Static $aUDL = StringRegExp(RegRead('HKCU\Software\AutoIt v3\AutoIt', 'Include'), '([^;]+)(?:;|$)', 3)
	
	While 1
		;Check include type 4 (include with full path)
		If Not _WinAPI_PathIsRelative($sInclude) Then
			If FileExists($sInclude) Then
				$sRet = $sInclude
			Else
				$iError = 2
			EndIf
			
			ExitLoop
		EndIf
		
		;Set Current & AutoIt Include file
		$sAU3 = $sScriptDir & '\' & $sInclude
		$sSYS = $sAutoIt_Incl_Dir & '\' & $sInclude
		
		;Check include type 1 and 2 (before user includes check)
		If $aRegExp[0] == '<' Then
			If FileExists($sSYS) Then
				$sRet = $sSYS
				ExitLoop
			EndIf
		ElseIf $aRegExp[0] == '"' Or $aRegExp[0] == "'" Then
			If FileExists($sAU3) Then
				$sRet = $sAU3
				ExitLoop
			EndIf
		EndIf
		
		;Check include type 3 (search in user includes)
		For $i = 0 To UBound($aUDL) - 1
			$aUDL[$i] &= '\' & $sInclude
			
			If FileExists($aUDL[$i]) Then
				$sRet = $aUDL[$i]
				ExitLoop 2
			EndIf
		Next
		
		;Check include type 1 and 2 (after user includes check)
		If $aRegExp[0] == '<' Then
			If FileExists($sAU3) Then
				$sRet = $sAU3
				ExitLoop
			EndIf
		ElseIf $aRegExp[0] == '"' Or $aRegExp[0] == "'" Then
			If FileExists($sSYS) Then
				$sRet = $sSYS
				ExitLoop
			EndIf
		EndIf
		
		;Include file not found
		$iError = 3
		ExitLoop
	WEnd
	
	If Not $iError Then
		$sWorkDir = @WorkingDir
		
		If $sWorkDir <> $sScriptDir Then
			FileChangeDir($sScriptDir)
		EndIf
		
		$sRet = _WinAPI_GetFullPathName($sRet)
		
		If @error Or $sRet = '' Then
			$iError = 4
		EndIf
		
		If $sWorkDir <> $sScriptDir Then
			FileChangeDir($sWorkDir)
		EndIf
	Else
		$sRet = ''
	EndIf
	
    Return SetError($iError, 0, $sRet)
EndFunc
Func _AU3_StringStripCommentBlocks(ByRef $sString)
	Local $aSplit = StringSplit(StringStripCR($sString), @LF)
	Local $iCmntsStart_Count
	
	$sString = ''
	
	For $i = 1 To $aSplit[0]
		If StringRegExp($aSplit[$i], '(?i)^\h*#(cs|comments-start)([\h;].*)?$') Then
			$iCmntsStart_Count = 1
			
			While 1
				If $i + 1 >= $aSplit[0] Then
					ExitLoop
				EndIf
				
				$i += 1
				
				If StringRegExp($aSplit[$i], '(?i)^\h*#(cs|comments-start)([\h;].*)?') Then
					$iCmntsStart_Count += 1
					ContinueLoop
				EndIf
				
				If StringRegExp($aSplit[$i], '(?i)^\h*#(ce|comments-end)([\h;].*)?') Then
					$iCmntsStart_Count -= 1
					
					If $iCmntsStart_Count <= 0 Then
						ExitLoop
					EndIf
				EndIf
			WEnd
			
			ContinueLoop
		EndIf
		
		$sString &= $aSplit[$i] & @CRLF
	Next
EndFunc
Func _AU3_StringStripComments(ByRef $sString)
	Local $aStrs = StringRegExp($sString, '("[^"]*"|''[^'']*'')', 3)
	Local $sStrs = StringRegExpReplace($sString, '("[^"]*"|''[^'']*'')', '#~_~@~_~#')
	Local $iInStr = StringInStr($sStrs, ';', 2)
	
	If $iInStr = 0 Then
		Return
	EndIf
	
	$sString = StringStripWS(StringLeft($sStrs, $iInStr - 1), 2)
	
	For $i = 0 To UBound($aStrs) - 1
		$sString = StringReplace($sString, '#~_~@~_~#', $aStrs[$i], 1, 2)
	Next
EndFunc