mirror of
https://github.com/beefytech/Beef.git
synced 2025-06-21 09:27:59 +02:00
Merge pull request #1630 from disarray2077/linux_fixes
Make `GetLocalTimeZoneFromTzFile` not crash and add willdcard check to `BfpFindFileData_CheckFilter`
This commit is contained in:
commit
69739d9329
16 changed files with 469 additions and 17 deletions
|
@ -1942,7 +1942,8 @@ namespace System {
|
|||
}
|
||||
// the data returned from the PAL is completely bogus; return a dummy entry
|
||||
return CreateCustomTimeZone(c_localId, TimeSpan.Zero, c_localId, c_localId);*/
|
||||
Runtime.NotImplemented();
|
||||
// TODO: Not implemented.
|
||||
return Utc;
|
||||
}
|
||||
#endif // !FEATURE_WIN32_REGISTRY
|
||||
|
||||
|
|
|
@ -140,6 +140,7 @@
|
|||
<ClCompile Include="..\..\BeefySysLib\platform\win\CrashCatcher.cpp" />
|
||||
<ClCompile Include="..\..\BeefySysLib\platform\win\Platform.cpp" />
|
||||
<ClCompile Include="..\..\BeefySysLib\third_party\utf8proc\utf8proc.c" />
|
||||
<ClCompile Include="..\..\BeefySysLib\third_party\putty\wildcard.c" />
|
||||
<ClCompile Include="..\..\BeefySysLib\util\BeefPerf.cpp" />
|
||||
<ClCompile Include="..\..\BeefySysLib\util\String.cpp" />
|
||||
<ClCompile Include="..\..\BeefySysLib\util\UTF8.cpp" />
|
||||
|
@ -356,6 +357,7 @@
|
|||
<ClInclude Include="..\..\BeefySysLib\platform\win\BFPlatform.h" />
|
||||
<ClInclude Include="..\..\BeefySysLib\platform\win\CrashCatcher.h" />
|
||||
<ClInclude Include="..\..\BeefySysLib\third_party\utf8proc\utf8proc.h" />
|
||||
<ClInclude Include="..\..\BeefySysLib\third_party\putty\wildcard.h" />
|
||||
<ClInclude Include="..\..\BeefySysLib\util\BeefPerf.h" />
|
||||
<ClInclude Include="..\..\BeefySysLib\util\String.h" />
|
||||
<ClInclude Include="..\..\BeefySysLib\util\UTF8.h" />
|
||||
|
|
|
@ -25,6 +25,9 @@
|
|||
<Filter Include="BeefySysLib\third_party\utf8proc">
|
||||
<UniqueIdentifier>{0027c869-120a-44d3-80e6-e2ab12ce83bc}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="BeefySysLib\third_party\putty">
|
||||
<UniqueIdentifier>{59aee039-211d-47df-abb4-ca95d75d2c56}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="BeefySysLib\util">
|
||||
<UniqueIdentifier>{8e5503bc-1b01-46f1-be03-bb504d93f05d}</UniqueIdentifier>
|
||||
</Filter>
|
||||
|
@ -105,6 +108,9 @@
|
|||
<ClCompile Include="..\..\BeefySysLib\third_party\utf8proc\utf8proc.c">
|
||||
<Filter>BeefySysLib\third_party\utf8proc</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\BeefySysLib\third_party\putty\wildcard.c">
|
||||
<Filter>BeefySysLib\third_party\putty</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\BeefySysLib\util\BeefPerf.cpp">
|
||||
<Filter>BeefySysLib\util</Filter>
|
||||
</ClCompile>
|
||||
|
@ -326,6 +332,9 @@
|
|||
<ClInclude Include="..\..\BeefySysLib\third_party\utf8proc\utf8proc.h">
|
||||
<Filter>BeefySysLib\third_party\utf8proc</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\BeefySysLib\third_party\putty\wildcard.h">
|
||||
<Filter>BeefySysLib\third_party\putty</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\BeefySysLib\util\BeefPerf.h">
|
||||
<Filter>BeefySysLib\util</Filter>
|
||||
</ClInclude>
|
||||
|
|
|
@ -252,6 +252,7 @@
|
|||
<WarningLevel Condition="'$(Configuration)|$(Platform)'=='Release Static CStatic|x64'">TurnOffAllWarnings</WarningLevel>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\BeefySysLib\third_party\utf8proc\utf8proc.c" />
|
||||
<ClCompile Include="..\BeefySysLib\third_party\putty\wildcard.c" />
|
||||
<ClCompile Include="..\BeefySysLib\util\AllocDebug.cpp" />
|
||||
<ClCompile Include="..\BeefySysLib\util\BeefPerf.cpp" />
|
||||
<ClCompile Include="..\BeefySysLib\util\String.cpp" />
|
||||
|
@ -271,6 +272,7 @@
|
|||
<ClInclude Include="..\BeefySysLib\third_party\libffi\i686-pc-cygwin\include\ffi.h" />
|
||||
<ClInclude Include="..\BeefySysLib\third_party\libffi\i686-pc-cygwin\include\ffitarget.h" />
|
||||
<ClInclude Include="..\BeefySysLib\third_party\utf8proc\utf8proc.h" />
|
||||
<ClInclude Include="..\BeefySysLib\third_party\putty\wildcard.h" />
|
||||
<ClInclude Include="..\BeefySysLib\util\BeefPerf.h" />
|
||||
<ClInclude Include="..\BeefySysLib\util\String.h" />
|
||||
<ClInclude Include="..\BeefySysLib\util\UTF8.h" />
|
||||
|
|
|
@ -28,6 +28,9 @@
|
|||
<Filter Include="BeefySysLib\third_party\libffi\x86">
|
||||
<UniqueIdentifier>{f94ea9c5-428b-4925-a59e-b7688752d7d7}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="BeefySysLib\third_party\putty">
|
||||
<UniqueIdentifier>{e790c845-8b10-4edd-b2c0-71e35b0d80b2}</UniqueIdentifier>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="rt\Internal.cpp">
|
||||
|
@ -87,6 +90,9 @@
|
|||
<ClCompile Include="..\BeefySysLib\third_party\libffi\src\types.c">
|
||||
<Filter>BeefySysLib\third_party\libffi</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\BeefySysLib\third_party\putty\wildcard.c">
|
||||
<Filter>BeefySysLib\third_party\putty</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="rt\Chars.cpp">
|
||||
<Filter>rt</Filter>
|
||||
</ClCompile>
|
||||
|
@ -148,6 +154,9 @@
|
|||
<CustomBuild Include="..\BeefySysLib\third_party\libffi\i686-pc-cygwin\src\x86\win32.asm">
|
||||
<Filter>BeefySysLib\third_party\libffi\x86</Filter>
|
||||
</CustomBuild>
|
||||
<ClInclude Include="..\BeefySysLib\third_party\putty\wildcard.h">
|
||||
<Filter>BeefySysLib\third_party\putty</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="BeefRT.def" />
|
||||
|
|
|
@ -221,6 +221,7 @@ file(GLOB SRC_FILES
|
|||
../BeefySysLib/util/UTF8.cpp
|
||||
../BeefySysLib/util/Hash.cpp
|
||||
../BeefySysLib/third_party/utf8proc/utf8proc.c
|
||||
../BeefySysLib/third_party/putty/wildcard.c
|
||||
)
|
||||
|
||||
if (${IOS})
|
||||
|
|
|
@ -1926,6 +1926,7 @@ copy /y "$(OutDir)$(TargetName).lib" "$(SolutionDir)\BeefLibs\Beefy2D\dist\"</Co
|
|||
<WarningLevel Condition="'$(Configuration)|$(Platform)'=='Release Static|x64'">TurnOffAllWarnings</WarningLevel>
|
||||
<WarningLevel Condition="'$(Configuration)|$(Platform)'=='Release|x64'">TurnOffAllWarnings</WarningLevel>
|
||||
</ClCompile>
|
||||
<ClCompile Include="third_party\putty\wildcard.c" />
|
||||
<ClCompile Include="util\AllocDebug.cpp" />
|
||||
<ClCompile Include="util\BeefPerf.cpp" />
|
||||
<ClCompile Include="util\BSpline.cpp" />
|
||||
|
@ -2152,6 +2153,7 @@ copy /y "$(OutDir)$(TargetName).lib" "$(SolutionDir)\BeefLibs\Beefy2D\dist\"</Co
|
|||
<ClInclude Include="third_party\zlib\zconf.h" />
|
||||
<ClInclude Include="third_party\zlib\zlib.h" />
|
||||
<ClInclude Include="third_party\zlib\zutil.h" />
|
||||
<ClInclude Include="third_party\putty\wildcard.h" />
|
||||
<ClInclude Include="Util\AllocDebug.h" />
|
||||
<ClInclude Include="util\Array.h" />
|
||||
<ClInclude Include="util\BeefPerf.h" />
|
||||
|
|
|
@ -78,6 +78,9 @@
|
|||
<Filter Include="src\third_party\miniz">
|
||||
<UniqueIdentifier>{a159b9ee-1a71-44f5-a412-1e01e20b70c7}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="src\third_party\putty">
|
||||
<UniqueIdentifier>{0007a912-9292-4e32-8884-0f0cd276e42d}</UniqueIdentifier>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="platform\win\DXRenderDevice.cpp">
|
||||
|
@ -731,6 +734,9 @@
|
|||
<ClCompile Include="util\ZipFile.cpp">
|
||||
<Filter>src\util</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="third_party\putty\wildcard.c">
|
||||
<Filter>src\third_party\putty</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="Common.h">
|
||||
|
@ -1123,6 +1129,9 @@
|
|||
<ClInclude Include="util\ZipFile.h">
|
||||
<Filter>src\util</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="third_party\putty\wildcard.h">
|
||||
<Filter>src\third_party\putty</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<CustomBuild Include="third_party\libffi\i686-pc-cygwin\src\x86\win32.asm">
|
||||
|
|
|
@ -859,6 +859,7 @@
|
|||
<WarningLevel Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Level1</WarningLevel>
|
||||
<WarningLevel Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Level1</WarningLevel>
|
||||
</ClCompile>
|
||||
<ClCompile Include="third_party\putty\wildcard.c" />
|
||||
<ClCompile Include="util\AllocDebug.cpp" />
|
||||
<ClCompile Include="util\BeefPerf.cpp" />
|
||||
<ClCompile Include="util\BSpline.cpp" />
|
||||
|
@ -1025,6 +1026,7 @@
|
|||
<ClInclude Include="third_party\zlib\zconf.h" />
|
||||
<ClInclude Include="third_party\zlib\zlib.h" />
|
||||
<ClInclude Include="third_party\zlib\zutil.h" />
|
||||
<ClInclude Include="third_party\putty\wildcard.h" />
|
||||
<ClInclude Include="util\BeefPerf.h" />
|
||||
<ClInclude Include="util\BSpline.h" />
|
||||
<ClInclude Include="util\CabUtil.h" />
|
||||
|
|
|
@ -69,6 +69,9 @@
|
|||
<Filter Include="src\third_party\miniz">
|
||||
<UniqueIdentifier>{d32cb9b0-e79b-49fe-82e2-33302be0baf6}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="src\third_party\putty">
|
||||
<UniqueIdentifier>{bec18ceb-a7ca-4150-99ee-60a16944b93c}</UniqueIdentifier>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="platform\win\DXRenderDevice.cpp">
|
||||
|
@ -584,6 +587,9 @@
|
|||
<ClCompile Include="third_party\miniz\miniz.c">
|
||||
<Filter>src\third_party\miniz</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="third_party\putty\wildcard.c">
|
||||
<Filter>src\third_party\putty</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="Common.h">
|
||||
|
@ -898,6 +904,9 @@
|
|||
<ClInclude Include="third_party\miniz\miniz.h">
|
||||
<Filter>src\third_party\miniz</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="third_party\putty\wildcard.h">
|
||||
<Filter>src\third_party\putty</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<CustomBuild Include="third_party\libffi\i686-pc-cygwin\src\x86\win32.asm">
|
||||
|
|
|
@ -274,6 +274,7 @@ file(GLOB SRC_FILES
|
|||
third_party/zlib/uncompr.c
|
||||
third_party/zlib/zutil.c
|
||||
third_party/miniz/miniz.c
|
||||
third_party/putty/wildcard.c
|
||||
util/AllocDebug.cpp
|
||||
util/BeefPerf.cpp
|
||||
util/BSpline.cpp
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#include "../../util/CritSect.h"
|
||||
#include "../../util/Dictionary.h"
|
||||
#include "../../util/Hash.h"
|
||||
#include "../../third_party/putty/wildcard.h"
|
||||
#ifdef BFP_HAS_EXECINFO
|
||||
#include <execinfo.h>
|
||||
#endif
|
||||
|
@ -2380,7 +2381,8 @@ static bool BfpFindFileData_CheckFilter(BfpFindFileData* findData)
|
|||
return false;
|
||||
}
|
||||
|
||||
//TODO: Check actual wildcards.
|
||||
if (!wc_match(findData->mWildcard.c_str(), findData->mDirEnt->d_name))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#include "../util/CritSect.h"
|
||||
#include "../util/Dictionary.h"
|
||||
#include "../util/HashSet.h"
|
||||
#include "../../third_party/putty/wildcard.h"
|
||||
|
||||
#include "util/AllocDebug.h"
|
||||
|
||||
|
@ -3485,6 +3486,7 @@ struct BfpFindFileData
|
|||
{
|
||||
BfpFindFileFlags mFlags;
|
||||
WIN32_FIND_DATA mFindData;
|
||||
Beefy::String mWildcard;
|
||||
HANDLE mHandle;
|
||||
};
|
||||
|
||||
|
@ -3496,29 +3498,43 @@ static bool BfpFindFileData_CheckFilter(BfpFindFileData* findData)
|
|||
bool isDir = (findData->mFindData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0;
|
||||
if (isDir)
|
||||
{
|
||||
if ((findData->mFlags & BfpFindFileFlag_Directories) != 0)
|
||||
{
|
||||
if ((wcscmp(findData->mFindData.cFileName, L".") == 0) || (wcscmp(findData->mFindData.cFileName, L"..") == 0))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
if ((findData->mFlags & BfpFindFileFlag_Directories) == 0)
|
||||
return false;
|
||||
|
||||
if ((wcscmp(findData->mFindData.cFileName, L".") == 0) || (wcscmp(findData->mFindData.cFileName, L"..") == 0))
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((findData->mFlags & BfpFindFileFlag_Files) != 0)
|
||||
return true;
|
||||
if ((findData->mFlags & BfpFindFileFlag_Files) == 0)
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
|
||||
Beefy::String fileName = UTF8Encode(findData->mFindData.cFileName);
|
||||
if (!wc_match(findData->mWildcard.c_str(), fileName.c_str()))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
BFP_EXPORT BfpFindFileData* BFP_CALLTYPE BfpFindFileData_FindFirstFile(const char* path, BfpFindFileFlags flags, BfpFileResult* outResult)
|
||||
{
|
||||
UTF16String wPath = UTF8Decode(path);
|
||||
Beefy::String findStr = path;
|
||||
Beefy::String wildcard;
|
||||
|
||||
int lastSlashPos = std::max((int)findStr.LastIndexOf('/'), (int)findStr.LastIndexOf('\\'));
|
||||
if (lastSlashPos != -1)
|
||||
{
|
||||
wildcard = findStr.Substring(lastSlashPos + 1);
|
||||
findStr = findStr.Substring(0, lastSlashPos + 1);
|
||||
findStr.Append("*");
|
||||
}
|
||||
if (wildcard == "*.*")
|
||||
wildcard = "*";
|
||||
|
||||
BfpFindFileData* findData = new BfpFindFileData();
|
||||
findData->mFlags = flags;
|
||||
findData->mWildcard = wildcard;
|
||||
|
||||
FINDEX_SEARCH_OPS searchOps;
|
||||
if ((flags & BfpFindFileFlag_Files) == 0)
|
||||
|
@ -3526,6 +3542,7 @@ BFP_EXPORT BfpFindFileData* BFP_CALLTYPE BfpFindFileData_FindFirstFile(const cha
|
|||
else
|
||||
searchOps = FindExSearchNameMatch;
|
||||
|
||||
UTF16String wPath = UTF8Decode(findStr);
|
||||
findData->mHandle = ::FindFirstFileExW(wPath.c_str(), FindExInfoBasic, &findData->mFindData, searchOps, NULL, 0);
|
||||
if (findData->mHandle == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
|
|
28
BeefySysLib/third_party/putty/LICENSE
vendored
Normal file
28
BeefySysLib/third_party/putty/LICENSE
vendored
Normal file
|
@ -0,0 +1,28 @@
|
|||
PuTTY is copyright 1997-2020 Simon Tatham.
|
||||
|
||||
Portions copyright Robert de Bath, Joris van Rantwijk, Delian
|
||||
Delchev, Andreas Schultz, Jeroen Massar, Wez Furlong, Nicolas Barry,
|
||||
Justin Bradford, Ben Harris, Malcolm Smith, Ahmad Khalifa, Markus
|
||||
Kuhn, Colin Watson, Christopher Staite, Lorenz Diener, Christian
|
||||
Brabandt, Jeff Smith, Pavel Kryukov, Maxim Kuznetsov, Svyatoslav
|
||||
Kuzmich, Nico Williams, Viktor Dukhovni, Josh Dersch, Lars Brinkhoff,
|
||||
and CORE SDI S.A.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person
|
||||
obtaining a copy of this software and associated documentation files
|
||||
(the "Software"), to deal in the Software without restriction,
|
||||
including without limitation the rights to use, copy, modify, merge,
|
||||
publish, distribute, sublicense, and/or sell copies of the Software,
|
||||
and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE
|
||||
FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
|
||||
CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
340
BeefySysLib/third_party/putty/wildcard.c
vendored
Normal file
340
BeefySysLib/third_party/putty/wildcard.c
vendored
Normal file
|
@ -0,0 +1,340 @@
|
|||
/*
|
||||
* Wildcard matching engine for use with SFTP-based file transfer
|
||||
* programs (PSFTP, new-look PSCP): since SFTP has no notion of
|
||||
* getting the remote side to do globbing (and rightly so) we have
|
||||
* to do it locally, by retrieving all the filenames in a directory
|
||||
* and checking each against the wildcard pattern.
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "wildcard.h"
|
||||
|
||||
/*
|
||||
* Definition of wildcard syntax:
|
||||
*
|
||||
* - * matches any sequence of characters, including zero.
|
||||
* - ? matches exactly one character which can be anything.
|
||||
* - [abc] matches exactly one character which is a, b or c.
|
||||
* - [a-f] matches anything from a through f.
|
||||
* - [^a-f] matches anything _except_ a through f.
|
||||
* - [-_] matches - or _; [^-_] matches anything else. (The - is
|
||||
* non-special if it occurs immediately after the opening
|
||||
* bracket or ^.)
|
||||
* - [a^] matches an a or a ^. (The ^ is non-special if it does
|
||||
* _not_ occur immediately after the opening bracket.)
|
||||
* - \*, \?, \[, \], \\ match the single characters *, ?, [, ], \.
|
||||
* - All other characters are non-special and match themselves.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Some notes on differences from POSIX globs (IEEE Std 1003.1, 2003 ed.):
|
||||
* - backslashes act as escapes even within [] bracket expressions
|
||||
* - does not support [!...] for non-matching list (POSIX are weird);
|
||||
* NB POSIX allows [^...] as well via "A bracket expression starting
|
||||
* with an unquoted circumflex character produces unspecified
|
||||
* results". If we wanted to allow [!...] we might want to define
|
||||
* [^!] as having its literal meaning (match '^' or '!').
|
||||
* - none of the scary [[:class:]] stuff, etc
|
||||
*/
|
||||
|
||||
/*
|
||||
* The wildcard matching technique we use is very simple and
|
||||
* potentially O(N^2) in running time, but I don't anticipate it
|
||||
* being that bad in reality (particularly since N will be the size
|
||||
* of a filename, which isn't all that much). Perhaps one day, once
|
||||
* PuTTY has grown a regexp matcher for some other reason, I might
|
||||
* come back and reimplement wildcards by translating them into
|
||||
* regexps or directly into NFAs; but for the moment, in the
|
||||
* absence of any other need for the NFA->DFA translation engine,
|
||||
* anything more than the simplest possible wildcard matcher is
|
||||
* vast code-size overkill.
|
||||
*
|
||||
* Essentially, these wildcards are much simpler than regexps in
|
||||
* that they consist of a sequence of rigid fragments (? and [...]
|
||||
* can never match more or less than one character) separated by
|
||||
* asterisks. It is therefore extremely simple to look at a rigid
|
||||
* fragment and determine whether or not it begins at a particular
|
||||
* point in the test string; so we can search along the string
|
||||
* until we find each fragment, then search for the next. As long
|
||||
* as we find each fragment in the _first_ place it occurs, there
|
||||
* will never be a danger of having to backpedal and try to find it
|
||||
* again somewhere else.
|
||||
*/
|
||||
|
||||
enum {
|
||||
WC_TRAILINGBACKSLASH = 1,
|
||||
WC_UNCLOSEDCLASS,
|
||||
WC_INVALIDRANGE
|
||||
};
|
||||
|
||||
/*
|
||||
* Error reporting is done by returning various negative values
|
||||
* from the wildcard routines. Passing any such value to wc_error
|
||||
* will give a human-readable message.
|
||||
*/
|
||||
const char *wc_error(int value)
|
||||
{
|
||||
value = abs(value);
|
||||
switch (value) {
|
||||
case WC_TRAILINGBACKSLASH:
|
||||
return "'\' occurred at end of string (expected another character)";
|
||||
case WC_UNCLOSEDCLASS:
|
||||
return "expected ']' to close character class";
|
||||
case WC_INVALIDRANGE:
|
||||
return "character range was not terminated (']' just after '-')";
|
||||
}
|
||||
return "INTERNAL ERROR: unrecognised wildcard error number";
|
||||
}
|
||||
|
||||
/*
|
||||
* This is the routine that tests a target string to see if an
|
||||
* initial substring of it matches a fragment. If successful, it
|
||||
* returns 1, and advances both `fragment' and `target' past the
|
||||
* fragment and matching substring respectively. If unsuccessful it
|
||||
* returns zero. If the wildcard fragment suffers a syntax error,
|
||||
* it returns <0 and the precise value indexes into wc_error.
|
||||
*/
|
||||
static int wc_match_fragment(const char **fragment, const char **target,
|
||||
const char *target_end)
|
||||
{
|
||||
const char *f, *t;
|
||||
|
||||
f = *fragment;
|
||||
t = *target;
|
||||
/*
|
||||
* The fragment terminates at either the end of the string, or
|
||||
* the first (unescaped) *.
|
||||
*/
|
||||
while (*f && *f != '*' && t < target_end) {
|
||||
/*
|
||||
* Extract one character from t, and one character's worth
|
||||
* of pattern from f, and step along both. Return 0 if they
|
||||
* fail to match.
|
||||
*/
|
||||
if (*f == '\\') {
|
||||
/*
|
||||
* Backslash, which means f[1] is to be treated as a
|
||||
* literal character no matter what it is. It may not
|
||||
* be the end of the string.
|
||||
*/
|
||||
if (!f[1])
|
||||
return -WC_TRAILINGBACKSLASH; /* error */
|
||||
if (f[1] != *t)
|
||||
return 0; /* failed to match */
|
||||
f += 2;
|
||||
} else if (*f == '?') {
|
||||
/*
|
||||
* Question mark matches anything.
|
||||
*/
|
||||
f++;
|
||||
} else if (*f == '[') {
|
||||
bool invert = false;
|
||||
bool matched = false;
|
||||
/*
|
||||
* Open bracket introduces a character class.
|
||||
*/
|
||||
f++;
|
||||
if (*f == '^') {
|
||||
invert = true;
|
||||
f++;
|
||||
}
|
||||
while (*f != ']') {
|
||||
if (*f == '\\')
|
||||
f++; /* backslashes still work */
|
||||
if (!*f)
|
||||
return -WC_UNCLOSEDCLASS; /* error again */
|
||||
if (f[1] == '-') {
|
||||
int lower, upper, ourchr;
|
||||
lower = (unsigned char) *f++;
|
||||
f++; /* eat the minus */
|
||||
if (*f == ']')
|
||||
return -WC_INVALIDRANGE; /* different error! */
|
||||
if (*f == '\\')
|
||||
f++; /* backslashes _still_ work */
|
||||
if (!*f)
|
||||
return -WC_UNCLOSEDCLASS; /* error again */
|
||||
upper = (unsigned char) *f++;
|
||||
ourchr = (unsigned char) *t;
|
||||
if (lower > upper) {
|
||||
int t = lower; lower = upper; upper = t;
|
||||
}
|
||||
if (ourchr >= lower && ourchr <= upper)
|
||||
matched = true;
|
||||
} else {
|
||||
matched |= (*t == *f++);
|
||||
}
|
||||
}
|
||||
if (invert == matched)
|
||||
return 0; /* failed to match character class */
|
||||
f++; /* eat the ] */
|
||||
} else {
|
||||
/*
|
||||
* Non-special character matches itself.
|
||||
*/
|
||||
if (*f != *t)
|
||||
return 0;
|
||||
f++;
|
||||
}
|
||||
/*
|
||||
* Now we've done that, increment t past the character we
|
||||
* matched.
|
||||
*/
|
||||
t++;
|
||||
}
|
||||
if (!*f || *f == '*') {
|
||||
/*
|
||||
* We have reached the end of f without finding a mismatch;
|
||||
* so we're done. Update the caller pointers and return 1.
|
||||
*/
|
||||
*fragment = f;
|
||||
*target = t;
|
||||
return 1;
|
||||
}
|
||||
/*
|
||||
* Otherwise, we must have reached the end of t before we
|
||||
* reached the end of f; so we've failed. Return 0.
|
||||
*/
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* This is the real wildcard matching routine. It returns 1 for a
|
||||
* successful match, 0 for an unsuccessful match, and <0 for a
|
||||
* syntax error in the wildcard.
|
||||
*/
|
||||
static int wc_match_inner(
|
||||
const char *wildcard, const char *target, size_t target_len)
|
||||
{
|
||||
const char *target_end = target + target_len;
|
||||
int ret;
|
||||
|
||||
/*
|
||||
* Every time we see a '*' _followed_ by a fragment, we just
|
||||
* search along the string for a location at which the fragment
|
||||
* matches. The only special case is when we see a fragment
|
||||
* right at the start, in which case we just call the matching
|
||||
* routine once and give up if it fails.
|
||||
*/
|
||||
if (*wildcard != '*') {
|
||||
ret = wc_match_fragment(&wildcard, &target, target_end);
|
||||
if (ret <= 0)
|
||||
return ret; /* pass back failure or error alike */
|
||||
}
|
||||
|
||||
while (*wildcard) {
|
||||
assert(*wildcard == '*');
|
||||
while (*wildcard == '*')
|
||||
wildcard++;
|
||||
|
||||
/*
|
||||
* It's possible we've just hit the end of the wildcard
|
||||
* after seeing a *, in which case there's no need to
|
||||
* bother searching any more because we've won.
|
||||
*/
|
||||
if (!*wildcard)
|
||||
return 1;
|
||||
|
||||
/*
|
||||
* Now `wildcard' points at the next fragment. So we
|
||||
* attempt to match it against `target', and if that fails
|
||||
* we increment `target' and try again, and so on. When we
|
||||
* find we're about to try matching against the empty
|
||||
* string, we give up and return 0.
|
||||
*/
|
||||
ret = 0;
|
||||
while (*target) {
|
||||
const char *save_w = wildcard, *save_t = target;
|
||||
|
||||
ret = wc_match_fragment(&wildcard, &target, target_end);
|
||||
|
||||
if (ret < 0)
|
||||
return ret; /* syntax error */
|
||||
|
||||
if (ret > 0 && !*wildcard && target != target_end) {
|
||||
/*
|
||||
* Final special case - literally.
|
||||
*
|
||||
* This situation arises when we are matching a
|
||||
* _terminal_ fragment of the wildcard (that is,
|
||||
* there is nothing after it, e.g. "*a"), and it
|
||||
* has matched _too early_. For example, matching
|
||||
* "*a" against "parka" will match the "a" fragment
|
||||
* against the _first_ a, and then (if it weren't
|
||||
* for this special case) matching would fail
|
||||
* because we're at the end of the wildcard but not
|
||||
* at the end of the target string.
|
||||
*
|
||||
* In this case what we must do is measure the
|
||||
* length of the fragment in the target (which is
|
||||
* why we saved `target'), jump straight to that
|
||||
* distance from the end of the string using
|
||||
* strlen, and match the same fragment again there
|
||||
* (which is why we saved `wildcard'). Then we
|
||||
* return whatever that operation returns.
|
||||
*/
|
||||
target = target_end - (target - save_t);
|
||||
wildcard = save_w;
|
||||
return wc_match_fragment(&wildcard, &target, target_end);
|
||||
}
|
||||
|
||||
if (ret > 0)
|
||||
break;
|
||||
target++;
|
||||
}
|
||||
if (ret > 0)
|
||||
continue;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* If we reach here, it must be because we successfully matched
|
||||
* a fragment and then found ourselves right at the end of the
|
||||
* wildcard. Hence, we return 1 if and only if we are also
|
||||
* right at the end of the target.
|
||||
*/
|
||||
return target == target_end;
|
||||
}
|
||||
|
||||
int wc_match(const char *wildcard, const char *target)
|
||||
{
|
||||
return wc_match_inner(wildcard, target, strlen(target));
|
||||
}
|
||||
|
||||
/*
|
||||
* Another utility routine that translates a non-wildcard string
|
||||
* into its raw equivalent by removing any escaping backslashes.
|
||||
* Expects a target string buffer of anything up to the length of
|
||||
* the original wildcard. You can also pass NULL as the output
|
||||
* buffer if you're only interested in the return value.
|
||||
*
|
||||
* Returns true on success, or false if a wildcard character was
|
||||
* encountered. In the latter case the output string MAY not be
|
||||
* zero-terminated and you should not use it for anything!
|
||||
*/
|
||||
bool wc_unescape(char *output, const char *wildcard)
|
||||
{
|
||||
while (*wildcard) {
|
||||
if (*wildcard == '\\') {
|
||||
wildcard++;
|
||||
/* We are lenient about trailing backslashes in non-wildcards. */
|
||||
if (*wildcard) {
|
||||
if (output)
|
||||
*output++ = *wildcard;
|
||||
wildcard++;
|
||||
}
|
||||
} else if (*wildcard == '*' || *wildcard == '?' ||
|
||||
*wildcard == '[' || *wildcard == ']') {
|
||||
return false; /* it's a wildcard! */
|
||||
} else {
|
||||
if (output)
|
||||
*output++ = *wildcard;
|
||||
wildcard++;
|
||||
}
|
||||
}
|
||||
if (output)
|
||||
*output = '\0';
|
||||
return true; /* it's clean */
|
||||
}
|
18
BeefySysLib/third_party/putty/wildcard.h
vendored
Normal file
18
BeefySysLib/third_party/putty/wildcard.h
vendored
Normal file
|
@ -0,0 +1,18 @@
|
|||
#ifndef PUTTY_WILDCARD_H_INCLUDE
|
||||
#define PUTTY_WILDCARD_H_INCLUDE
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
const char *wc_error(int value);
|
||||
int wc_match(const char *wildcard, const char *target);
|
||||
bool wc_unescape(char *output, const char *wildcard);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // PUTTY_WILDCARD_H_INCLUDE
|
Loading…
Add table
Add a link
Reference in a new issue