MCPcopy Create free account
hub / github.com/AutoHotkey/AutoHotkey / ParseLoopFilePattern

Method ParseLoopFilePattern

source/script.cpp:10965–11089  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

10963
10964
10965bool Line::ParseLoopFilePattern(LPTSTR aFilePattern, LoopFilesStruct &lfs, ResultType &aResult)
10966// Parse aFilePattern and initialize lfs.
10967{
10968 if (!*aFilePattern) // Some checks below may rely on empty aFilePattern having been excluded.
10969 // FindFirstFile() would find nothing in this case, but continuing may cause unnecessary
10970 // rescursion through all subdirectories of the working directory.
10971 return false;
10972 // Note: Even if aFilePattern is just a directory (i.e. with no wildcard pattern), it seems best
10973 // not to append "\\*.*" to it because the pattern might be a script variable that the user wants
10974 // to conditionally resolve to various things at runtime. In other words, it's valid to have
10975 // only a single directory be the target of the loop.
10976
10977 // v1.1.31.00: This function was revised.
10978 // - Resolve aFilePattern to a full path immediately so that changing the working directory
10979 // does not disrupt recursion or A_LoopFileLongPath/ShortPath.
10980 // - Take care that path lengths are not limited to below what the system allows.
10981 // That is, directory+pattern can be up to MAX_PATH on ANSI and 32767 on Unicode,
10982 // although the latter requires the \\?\ prefix or Windows 10 long path awareness.
10983 // - Optimize A_LoopFileLongPath and A_LoopFileShortPath by resolving the path prefix
10984 // up-front and utilizing the names returned by FindFirstFile() during the loop.
10985 // This can be much faster because file system access is minimized. Benchmarks
10986 // showed improvement even for single-iteration loops which use A_LoopFileLongPath.
10987
10988 // Prior to v1.1.31.00, A_LoopFileLongPath worked as follows:
10989 // - Each reference to A_LoopFileLongPath results in two BIV_LoopFileLongPath calls.
10990 // - BIV_LoopFileLongPath calls GetFullPathName() and ConvertFilespecToCorrectCase().
10991 // - CFTCC() calls FindFirstFile() once for each slash-delimited name.
10992 // - For example, with "c:\foo\bar\baz.txt", A_LoopFileLongPath results in SIX calls to
10993 // FindFirstFile().
10994
10995 // Find the final name or pattern component of aFilePattern.
10996 LPTSTR name_part, cp;
10997 for (name_part = cp = aFilePattern; *cp; cp++)
10998 if (*cp == '\\' || *cp == '/')
10999 name_part = cp + 1;
11000
11001 if (name_part == aFilePattern && *name_part && name_part[1] == ':') // Single character followed by ':' but not '\\' or '/'.
11002 name_part += 2;
11003
11004 size_t pattern_length = cp - name_part;
11005 if (pattern_length > _countof(lfs.pattern)) // Most likely too long to match a real path/filename.
11006 return false;
11007 tmemcpy(lfs.pattern, name_part, pattern_length + 1);
11008 lfs.pattern_length = pattern_length;
11009
11010 size_t orig_dir_length = name_part - aFilePattern;
11011 if (orig_dir_length)
11012 {
11013 if ( !(lfs.orig_dir = tmalloc(orig_dir_length + 1)) )
11014 {
11015 aResult = MemoryError();
11016 return false;
11017 }
11018 tmemcpy(lfs.orig_dir, aFilePattern, orig_dir_length);
11019 lfs.orig_dir[orig_dir_length] = '\0';
11020 lfs.orig_dir_length = orig_dir_length;
11021 }
11022 else

Callers

nothing calls this directly

Calls 2

MemoryErrorFunction · 0.85

Tested by

no test coverage detected