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

Method IncludeLibrary

source/script.cpp:6658–6731  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

6656}
6657
6658void Script::IncludeLibrary(LPTSTR aFuncName, size_t aFuncNameLength, bool &aErrorWasShown, bool &aFileWasFound)
6659// Caller must ensure that aFuncName doesn't already exist as a defined function.
6660// If aFuncNameLength is 0, the entire length of aFuncName is used.
6661{
6662 aErrorWasShown = false; // Set default for this output parameter.
6663 aFileWasFound = false;
6664
6665 int i;
6666 DWORD attr;
6667
6668 static FuncLibrary sLib[FUNC_LIB_COUNT] = {0};
6669
6670 if (!sLib[0].path) // Allocate & discover paths only upon first use because many scripts won't use anything from the library. This saves a bit of memory and performance.
6671 InitFuncLibraries(sLib);
6672 // Above must ensure that all sLib[].path elements are non-NULL (but they can be "" to indicate "no library").
6673
6674 if (!aFuncNameLength) // Caller didn't specify, so use the entire string.
6675 aFuncNameLength = _tcslen(aFuncName);
6676 if (aFuncNameLength > MAX_VAR_NAME_LENGTH) // Too long to fit in the allowed space, and also too long to be a valid function name.
6677 return;
6678
6679 TCHAR *dest, *first_underscore, class_name_buf[MAX_VAR_NAME_LENGTH + 1];
6680 LPTSTR naked_filename = aFuncName; // Set up for the first iteration.
6681 size_t naked_filename_length = aFuncNameLength; //
6682
6683 for (int second_iteration = 0; second_iteration < 2; ++second_iteration)
6684 {
6685 for (i = 0; i < FUNC_LIB_COUNT; ++i)
6686 {
6687 if (!*sLib[i].path) // Library is marked disabled, so skip it.
6688 continue;
6689
6690 dest = (LPTSTR) tmemcpy(sLib[i].path + sLib[i].length, naked_filename, naked_filename_length); // Append the filename to the library path.
6691 _tcscpy(dest + naked_filename_length, FUNC_LIB_EXT); // Append the file extension.
6692
6693 attr = GetFileAttributes(sLib[i].path); // Testing confirms that GetFileAttributes() doesn't support wildcards; which is good because we want filenames containing question marks to be "not found" rather than being treated as a match-pattern.
6694 if (attr == 0xFFFFFFFF || (attr & FILE_ATTRIBUTE_DIRECTORY)) // File doesn't exist or it's a directory.
6695 continue;
6696 // Since above didn't "continue", a file exists whose name matches that of the requested function.
6697 aFileWasFound = true; // Indicate success for #include <lib>, which doesn't necessarily expect a function to be found.
6698
6699 // g->CurrentFunc is non-NULL when the function-call being resolved is inside
6700 // a function. Save and reset it for correct behaviour in the include file:
6701 auto current_func = g->CurrentFunc;
6702 g->CurrentFunc = NULL;
6703
6704 // Fix for v1.1.06.00: If the file contains any lib #includes, it must be loaded AFTER the
6705 // above writes sLib[i].path to the iLib file, otherwise the wrong filename could be written.
6706 if (!LoadIncludedFile(sLib[i].path, false, false)) // Fix for v1.0.47.05: Pass false for allow-dupe because otherwise, it's possible for a stdlib file to attempt to include itself (especially via the LibNamePrefix_ method) and thus give a misleading "duplicate function" vs. "func does not exist" error message. Obsolete: For performance, pass true for allow-dupe so that it doesn't have to check for a duplicate file (seems too rare to worry about duplicates since by definition, the function doesn't yet exist so it's file shouldn't yet be included).
6707 aErrorWasShown = true; // Above has just displayed its error (e.g. syntax error in a line, failed to open the include file, etc). So override the default set earlier.
6708
6709 g->CurrentFunc = current_func; // Restore.
6710 return; // A file was found, so look no further.
6711 } // for() each library directory.
6712
6713 // Now that the first iteration is done, set up for the second one that searches by class/prefix.
6714 // Notes about ambiguity and naming collisions:
6715 // By the time it gets to the prefix/class search, it's almost given up. Even if it wrongly finds a

Callers

nothing calls this directly

Calls

no outgoing calls

Tested by

no test coverage detected