How to get list of auto uncluded library functions??

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
10inchOfSnow
Posts: 23
Joined: 26 Jul 2019, 06:41

How to get list of auto uncluded library functions??

03 Aug 2021, 07:35

How to get list of auto uncluded library functions and other #included files?
And another one, how to do something then file was included (or auto included)?
Read the docs, can't find anything
User avatar
mikeyww
Posts: 26877
Joined: 09 Sep 2014, 18:38

Re: How to get list of auto uncluded library functions??

03 Aug 2021, 07:37

The includes are hard-coded, so I'd think that the script knows the list.
User avatar
mikeyww
Posts: 26877
Joined: 09 Sep 2014, 18:38

Re: How to get list of auto uncluded library functions??

03 Aug 2021, 10:53

I'm not saying that there isn't a way. I simply did not understand your situation that would require it.
User avatar
Alguimist
Posts: 428
Joined: 05 Oct 2015, 16:41
Contact:

Re: How to get list of auto uncluded library functions??

03 Aug 2021, 14:07

There is a function called EnumIncludes:

Code: Select all

/**
 * Function: EnumIncludes
 *     Enumerates all #Include files in the specified script by passing the
 *     the full path to each included file, in turn, to the specified callback
 *     function.
 * Syntax:
 *     count := EnumIncludes( AhkScript, callback [, AhkExe ] )
 * Parameter(s):
 *     count      [retval] - total number of identified #Include(s)
 *     AhkScript      [in] - AutoHotkey script file to scan
 *     callback       [in] - callback function, must be a "Function object"
 *     AhkExe    [in, opt] - if specified, must be the path to the AutoHotkey.exe
 *                           to use as reference for the standard library folder
 *                           location. Defaults to A_AhkPath
 * Remarks:
 *     To continue enumeration, the callback function must return true(1); to stop
 *     enumeration, it must return false(0) or blank("").
 */
EnumIncludes(AhkScript, callback, AhkExe:="")
{
	if !IsObject(callback)
		throw Exception("Invalid parameter -> object expected", -1, callback)
	
	static FullPath
	if !VarSetCapacity(FullPath)
		VarSetCapacity(FullPath, 260 * (A_IsUnicode ? 2 : 1))

	if DllCall("GetFullPathName", "Str", AhkScript, "UInt", 260, "Str", FullPath, "Ptr", 0, "UInt")
		AhkScript := FullPath
	SplitPath, % AhkScript ,, AhkScriptDir

	if (AhkExe != "") && DllCall("GetFullPathName", "Str", AhkExe, "UInt", 260, "Str", FullPath, "Ptr", 0, "UInt")
		AhkExe := FullPath
	if (AhkExe == "") || !FileExist(AhkExe)
		AhkExe := A_AhkPath
	
	cwd := A_WorkingDir
	SetWorkingDir, %AhkScriptDir%
	
	WshExec := "" ; for /iLib (auto-includes)
	includes := {}, count := 0
	script := [ AhkScript ]
	queue := [ AhKScript ]
	while IsObject(f := ObjRemoveAt(queue, 1)) || (f := FileOpen(f, 0|4))
	{
		IsBlockComment := false
		IsContSection := false

		AtEOF := ComObjType(f) ? "AtEndOfStream" : "AtEOF"
		while !f[AtEOF] ; when resumed, will always continue at last postion of file pointer
		{
			line := Trim(f.ReadLine(), " `t`r`n")
			if (line == "")
				continue
			
			if !IsBlockComment && !IsContSection
				if !(IsBlockComment := InStr(line, "/*") == 1) && (InStr(line, "(") == 1)
					IsContSection := line ~= "i)^\((?:\s*(?(?<=\s)(?!;)|(?<=\())(\bJoin\S*|[^\s)]+))*(?<!:)(?:\s+;.*)?$"
			; skip if within block comment/continuation section or if it's a solitary line comment
			if (IsBlockComment && (InStr(line, "*/")==1 ? !(IsBlockComment := false) : 1))
			|| (IsContSection && (InStr(line, ")")==1 ? !(IsContSection := false) : 1))
			|| (InStr(line, ";") == 1)
				continue

			if RegExMatch(line, "Oi)^#Include(?:Again)?(?:\s*,\s*|\s+)(?:\*i\s+)?(\S.*?)(?:\s*|\s+;.*)$", match)
			{
				ThisInclude := ""
				
				static ss_End := A_AhkVersion < "2" ? 0 : -1
				if (InStr(match[1], "<") == 1) && (SubStr(match[1], ss_End) == ">")
				{
					lib := Trim(SubStr(match[1], 2, -1), " `t")
					if pfx := InStr(lib, "_",, 2)
						pfx := SubStr(lib, 1, pfx-1)

					libs := [AhkScript . "\..\Lib", A_MyDocuments . "\AutoHotkey\Lib", AhkExe . "\..\Lib"]
					for i, dir in libs
					{
						if FileExist(ThisInclude := Format("{1}\{2}.ahk", dir, lib))
						|| (pfx && FileExist(ThisInclude := Format("{1}\{2}.ahk", dir, pfx)))
							break
						ThisInclude := ""
					}
				}
				else
				{
					ThisInclude := StrReplace(match[1], "`%A_ScriptDir`%", AhkScriptDir)
					ThisInclude := StrReplace(ThisInclude, "`%A_AppData`%", A_AppData)
					ThisInclude := StrReplace(ThisInclude, "`%A_AppDataCommon`%", A_AppDataCommon)
					ThisInclude := StrReplace(ThisInclude, "`%A_LineFile`%", script[1])

					if InStr(FileExist(ThisInclude), "D")
					{
						SetWorkingDir, %ThisInclude%
						continue
					}
				}

				if (ThisInclude != "") && DllCall("GetFullPathName", "Str", ThisInclude, "UInt", 260, "Str", FullPath, "Ptr", 0, "UInt")
					ThisInclude := FullPath

				if FileExist(ThisInclude) && !includes[ThisInclude]
				{
					includes[ThisInclude] := ++count ; value doesn't really matter as long as it's 'truthy'
					if !callback.Call(ThisInclude)
					{
						f.Close(), f := ""
						break 2
					}
					
					ObjPush(script, ThisInclude)
					ObjPush(queue, ThisInclude)
				}
			} ; if RegExMatch( ... )
		} ; while !f[AtEOF]

		f.Close(), f := "" ; close file/stream
		ObjRemoveAt(script, 1)

		if !ObjLength(queue) && !WshExec
		{
			cmd := Format("{1}{2}{1} /iLib * /ErrorStdOut {1}{3}{1}", Chr(34), A_AhkPath, AhkScript)
			WshExec := ComObjCreate("WScript.Shell").Exec(cmd)
			
			if (err := WshExec.StdErr.ReadAll())
			{
				e := Exception("Failed to retrieve auto-included script files. Script contains syntax error(s).", -1, cmd)
				; idea taken from Lexikos' LoadFile
				if RegExMatch(err, "Os)(.*?) \((\d+)\) : ==> (.*?)(?:\s*Specifically: (.*?))?\R?$", m)
					e.Message .= "`n`nReason:`t" . m[3] . "`nLine text:`t" . m[4] . "`nFile:`t" . m[1] . "`nLine:`t" . m[2]
				throw e
			}
			
			ObjPush(script, "*")
			ObjPush(queue, WshExec.StdOut)
		}
	} ; while IsObject(f := ObjRemoveAt(queue, 1)) ...
 	
	SetWorkingDir, %cwd%

	return count ; NumGet(&includes + 4*A_PtrSize)
}
10inchOfSnow
Posts: 23
Joined: 26 Jul 2019, 06:41

Re: How to get list of auto uncluded library functions??

04 Aug 2021, 01:49

mikeyww wrote:
03 Aug 2021, 10:53
I'm not saying that there isn't a way. I simply did not understand your situation that would require it.
Well, I want to post some of my scripts, the point is that I use a lot of my functions and classes auto-included and it would be handy to get a list so I don't have to copy the whole library.
10inchOfSnow
Posts: 23
Joined: 26 Jul 2019, 06:41

Re: How to get list of auto uncluded library functions??

04 Aug 2021, 01:52

Alguimist wrote:
03 Aug 2021, 14:07
There is a function called EnumIncludes:

Code: Select all

/**
 * Function: EnumIncludes
 *     Enumerates all #Include files in the specified script by passing the
 *     the full path to each included file, in turn, to the specified callback
 *     function.
 * Syntax:
 *     count := EnumIncludes( AhkScript, callback [, AhkExe ] )
 * Parameter(s):
 *     count      [retval] - total number of identified #Include(s)
 *     AhkScript      [in] - AutoHotkey script file to scan
 *     callback       [in] - callback function, must be a "Function object"
 *     AhkExe    [in, opt] - if specified, must be the path to the AutoHotkey.exe
 *                           to use as reference for the standard library folder
 *                           location. Defaults to A_AhkPath
 * Remarks:
 *     To continue enumeration, the callback function must return true(1); to stop
 *     enumeration, it must return false(0) or blank("").
 */
EnumIncludes(AhkScript, callback, AhkExe:="")
{
	if !IsObject(callback)
		throw Exception("Invalid parameter -> object expected", -1, callback)
	
	static FullPath
	if !VarSetCapacity(FullPath)
		VarSetCapacity(FullPath, 260 * (A_IsUnicode ? 2 : 1))

	if DllCall("GetFullPathName", "Str", AhkScript, "UInt", 260, "Str", FullPath, "Ptr", 0, "UInt")
		AhkScript := FullPath
	SplitPath, % AhkScript ,, AhkScriptDir

	if (AhkExe != "") && DllCall("GetFullPathName", "Str", AhkExe, "UInt", 260, "Str", FullPath, "Ptr", 0, "UInt")
		AhkExe := FullPath
	if (AhkExe == "") || !FileExist(AhkExe)
		AhkExe := A_AhkPath
	
	cwd := A_WorkingDir
	SetWorkingDir, %AhkScriptDir%
	
	WshExec := "" ; for /iLib (auto-includes)
	includes := {}, count := 0
	script := [ AhkScript ]
	queue := [ AhKScript ]
	while IsObject(f := ObjRemoveAt(queue, 1)) || (f := FileOpen(f, 0|4))
	{
		IsBlockComment := false
		IsContSection := false

		AtEOF := ComObjType(f) ? "AtEndOfStream" : "AtEOF"
		while !f[AtEOF] ; when resumed, will always continue at last postion of file pointer
		{
			line := Trim(f.ReadLine(), " `t`r`n")
			if (line == "")
				continue
			
			if !IsBlockComment && !IsContSection
				if !(IsBlockComment := InStr(line, "/*") == 1) && (InStr(line, "(") == 1)
					IsContSection := line ~= "i)^\((?:\s*(?(?<=\s)(?!;)|(?<=\())(\bJoin\S*|[^\s)]+))*(?<!:)(?:\s+;.*)?$"
			; skip if within block comment/continuation section or if it's a solitary line comment
			if (IsBlockComment && (InStr(line, "*/")==1 ? !(IsBlockComment := false) : 1))
			|| (IsContSection && (InStr(line, ")")==1 ? !(IsContSection := false) : 1))
			|| (InStr(line, ";") == 1)
				continue

			if RegExMatch(line, "Oi)^#Include(?:Again)?(?:\s*,\s*|\s+)(?:\*i\s+)?(\S.*?)(?:\s*|\s+;.*)$", match)
			{
				ThisInclude := ""
				
				static ss_End := A_AhkVersion < "2" ? 0 : -1
				if (InStr(match[1], "<") == 1) && (SubStr(match[1], ss_End) == ">")
				{
					lib := Trim(SubStr(match[1], 2, -1), " `t")
					if pfx := InStr(lib, "_",, 2)
						pfx := SubStr(lib, 1, pfx-1)

					libs := [AhkScript . "\..\Lib", A_MyDocuments . "\AutoHotkey\Lib", AhkExe . "\..\Lib"]
					for i, dir in libs
					{
						if FileExist(ThisInclude := Format("{1}\{2}.ahk", dir, lib))
						|| (pfx && FileExist(ThisInclude := Format("{1}\{2}.ahk", dir, pfx)))
							break
						ThisInclude := ""
					}
				}
				else
				{
					ThisInclude := StrReplace(match[1], "`%A_ScriptDir`%", AhkScriptDir)
					ThisInclude := StrReplace(ThisInclude, "`%A_AppData`%", A_AppData)
					ThisInclude := StrReplace(ThisInclude, "`%A_AppDataCommon`%", A_AppDataCommon)
					ThisInclude := StrReplace(ThisInclude, "`%A_LineFile`%", script[1])

					if InStr(FileExist(ThisInclude), "D")
					{
						SetWorkingDir, %ThisInclude%
						continue
					}
				}

				if (ThisInclude != "") && DllCall("GetFullPathName", "Str", ThisInclude, "UInt", 260, "Str", FullPath, "Ptr", 0, "UInt")
					ThisInclude := FullPath

				if FileExist(ThisInclude) && !includes[ThisInclude]
				{
					includes[ThisInclude] := ++count ; value doesn't really matter as long as it's 'truthy'
					if !callback.Call(ThisInclude)
					{
						f.Close(), f := ""
						break 2
					}
					
					ObjPush(script, ThisInclude)
					ObjPush(queue, ThisInclude)
				}
			} ; if RegExMatch( ... )
		} ; while !f[AtEOF]

		f.Close(), f := "" ; close file/stream
		ObjRemoveAt(script, 1)

		if !ObjLength(queue) && !WshExec
		{
			cmd := Format("{1}{2}{1} /iLib * /ErrorStdOut {1}{3}{1}", Chr(34), A_AhkPath, AhkScript)
			WshExec := ComObjCreate("WScript.Shell").Exec(cmd)
			
			if (err := WshExec.StdErr.ReadAll())
			{
				e := Exception("Failed to retrieve auto-included script files. Script contains syntax error(s).", -1, cmd)
				; idea taken from Lexikos' LoadFile
				if RegExMatch(err, "Os)(.*?) \((\d+)\) : ==> (.*?)(?:\s*Specifically: (.*?))?\R?$", m)
					e.Message .= "`n`nReason:`t" . m[3] . "`nLine text:`t" . m[4] . "`nFile:`t" . m[1] . "`nLine:`t" . m[2]
				throw e
			}
			
			ObjPush(script, "*")
			ObjPush(queue, WshExec.StdOut)
		}
	} ; while IsObject(f := ObjRemoveAt(queue, 1)) ...
 	
	SetWorkingDir, %cwd%

	return count ; NumGet(&includes + 4*A_PtrSize)
}
Thx, not sure, but for me this can count buildin functions and can't libs included (return 1) and classes (this is by design, I think).
User avatar
mikeyww
Posts: 26877
Joined: 09 Sep 2014, 18:38

Re: How to get list of auto uncluded library functions??

04 Aug 2021, 05:49

Thank you for explaining the script's purpose for you. One of the others may have the answer about the functions.

Return to “Ask for Help (v1)”

Who is online

Users browsing this forum: No registered users and 209 guests