| 6656 | } |
| 6657 | |
| 6658 | void 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 |
nothing calls this directly
no outgoing calls
no test coverage detected