MCPcopy Create free account
hub / github.com/AutoHotkey/AutoHotkey-v1.0 / PerformLoop

Method PerformLoop

Source/script.cpp:6281–6451  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

6279
6280
6281ResultType Line::PerformLoop(WIN32_FIND_DATA *apCurrentFile, RegItemStruct *apCurrentRegItem
6282 , LoopReadFileStruct *apCurrentReadFile, char *aCurrentField, bool &aContinueMainLoop
6283 , Line *&aJumpToLine, AttributeType aAttr, FileLoopModeType aFileLoopMode
6284 , bool aRecurseSubfolders, char *aFilePattern, __int64 aIterationLimit, bool aIsInfinite
6285 , __int64 &aIndex)
6286// Note: Even if aFilePattern is just a directory (i.e. with not wildcard pattern), it seems best
6287// not to append "\\*.*" to it because the pattern might be a script variable that the user wants
6288// to conditionally resolve to various things at runtime. In other words, it's valid to have
6289// only a single directory be the target of the loop.
6290{
6291 BOOL file_found = FALSE;
6292 HANDLE file_search = INVALID_HANDLE_VALUE;
6293 char file_path[MAX_PATH] = "";
6294 char naked_filename_or_pattern[MAX_PATH] = "";
6295 // apCurrentFile is the file of the file-loop that encloses this file-loop, if any.
6296 // The below is our own current_file, which will take precedence over apCurrentFile
6297 // if this loop is a file-loop:
6298 WIN32_FIND_DATA new_current_file = {0};
6299 if (aAttr == ATTR_LOOP_FILE)
6300 {
6301 file_search = FindFirstFile(aFilePattern, &new_current_file);
6302 file_found = (file_search != INVALID_HANDLE_VALUE);
6303 // Make a local copy of the path given in aFilePattern because as the lines of
6304 // the loop are executed, the deref buffer (which is what aFilePattern might
6305 // point to if we were called from ExecUntil()) may be overwritten --
6306 // and we will need the path string for every loop iteration. We also need
6307 // to determine naked_filename_or_pattern:
6308 strlcpy(file_path, aFilePattern, sizeof(file_path));
6309 char *last_backslash = strrchr(file_path, '\\');
6310 if (last_backslash)
6311 {
6312 strlcpy(naked_filename_or_pattern, last_backslash + 1, sizeof(naked_filename_or_pattern));
6313 *(last_backslash + 1) = '\0'; // i.e. retain the final backslash on the string.
6314 }
6315 else
6316 {
6317 strlcpy(naked_filename_or_pattern, file_path, sizeof(naked_filename_or_pattern));
6318 *file_path = '\0'; // There is no path, so use current working directory.
6319 }
6320 for (; file_found && FileIsFilteredOut(new_current_file, aFileLoopMode, file_path)
6321 ; file_found = FindNextFile(file_search, &new_current_file));
6322 }
6323
6324 // Note: It seems best NOT to report warning if the loop iterates zero times
6325 // (e.g if no files are found by FindFirstFile() above), since that could
6326 // easily be an expected outcome.
6327
6328 ResultType result;
6329 Line *jump_to_line = NULL;
6330 for (; aIsInfinite || file_found || aIndex < aIterationLimit; ++aIndex)
6331 {
6332 // Execute once the body of the loop (either just one statement or a block of statements).
6333 // Preparser has ensured that every LOOP has a non-NULL next line.
6334 // apCurrentFile is sent as an arg so that more than one nested/recursive
6335 // file-loop can be supported:
6336 result = mNextLine->ExecUntil(ONLY_ONE_LINE, &jump_to_line
6337 , file_found ? &new_current_file : apCurrentFile // inner loop's file takes precedence over outer's.
6338 , apCurrentRegItem, apCurrentReadFile, aCurrentField

Callers 1

ExecUntilMethod · 0.80

Calls 3

strlcpyFunction · 0.85
snprintfFunction · 0.85
ExecUntilMethod · 0.80

Tested by

no test coverage detected