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

Method PerformLoopReadFile

source/script.cpp:11579–11636  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

11577
11578
11579ResultType Line::PerformLoopReadFile(ResultToken *aResultToken, Line *&aJumpToLine, Line *aUntil
11580 , LPTSTR aReadFileName, LPTSTR aWriteFileName)
11581{
11582 TextFile tfile;
11583 bool file_is_open = tfile.Open(aReadFileName, DEFAULT_READ_FLAGS, g->Encoding & CP_AHKCP);
11584 if (!file_is_open)
11585 {
11586 // Failed to open the input file. If an ELSE is present, executing it if the file wasn't found
11587 // seems much more useful than executing ELSE only for empty files; but if there's no ELSE, it's
11588 // probably best to throw an error.
11589 DWORD error = GetLastError();
11590 if ( !(mRelatedLine->mActionType == ACT_ELSE && (error == ERROR_FILE_NOT_FOUND || error == ERROR_PATH_NOT_FOUND)) )
11591 return g_script.Win32Error(error);
11592 // Otherwise, execute the ELSE below.
11593 }
11594
11595 // Make a persistent copy in case aWriteFileName's contents are in the deref buffer:
11596 if ( !(aWriteFileName = _tcsdup(aWriteFileName)) )
11597 return MemoryError();
11598
11599 LoopReadFileStruct loop_info { aWriteFileName };
11600 size_t line_length;
11601 ResultType result = CONDITION_FALSE;
11602 Line *jump_to_line = nullptr;
11603 global_struct &g = *::g; // Primarily for performance in this case.
11604 g.mLoopReadFile = &loop_info;
11605
11606 if (file_is_open)
11607 for (;; ++g.mLoopIteration)
11608 {
11609 if ( !(line_length = tfile.ReadLine(loop_info.mCurrentLine, _countof(loop_info.mCurrentLine) - 1)) ) // -1 to ensure there's room for a null-terminator.
11610 break;
11611 if (loop_info.mCurrentLine[line_length - 1] == '\n') // Remove end-of-line character.
11612 --line_length;
11613 loop_info.mCurrentLine[line_length] = '\0';
11614
11615 PERFORMLOOP_EXECUTE_BODY
11616 PERFORMLOOP_EVALUATE_UNTIL
11617 }
11618
11619 if (result == CONDITION_FALSE)
11620 {
11621 // No lines were read, so execute this loop's ELSE if present. It's done here rather than
11622 // in ExecUntil so that FileAppend can be used within the ELSE to write to mWriteFile.
11623 if (mRelatedLine->mActionType == ACT_ELSE)
11624 result = mRelatedLine->mNextLine->ExecUntil(ONLY_ONE_LINE, aResultToken, &aJumpToLine);
11625 else
11626 result = OK; // Never return CONDITION_FALSE, otherwise ExecUntil() will execute the ELSE a second time.
11627 }
11628
11629 if (loop_info.mWriteFile)
11630 {
11631 loop_info.mWriteFile->Close();
11632 delete loop_info.mWriteFile;
11633 }
11634
11635 return result;
11636}

Callers 1

ExecUntilMethod · 0.80

Calls 6

MemoryErrorFunction · 0.85
Win32ErrorMethod · 0.80
ReadLineMethod · 0.80
ExecUntilMethod · 0.80
OpenMethod · 0.45
CloseMethod · 0.45

Tested by

no test coverage detected