Refactor command-line tools to use shared header (#481)

This commit is contained in:
Chuck Walbourn 2024-09-17 13:45:26 -07:00 коммит произвёл GitHub
Родитель fc904593c1
Коммит 78d1a3eb89
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: B5690EEEBB952194
8 изменённых файлов: 457 добавлений и 329 удалений

Просмотреть файл

@ -367,6 +367,7 @@ if(BUILD_TOOLS AND WIN32)
xwbtool/xwbtool.cpp
xwbtool/xwbtool.rc
xwbtool/settings.manifest
xwbtool/CmdLineHelpers.h
Audio/WAVFileReader.cpp
Audio/WAVFileReader.h)
target_compile_features(xwbtool PRIVATE cxx_std_17)
@ -381,6 +382,10 @@ if(directxmath_FOUND)
endforeach()
endif()
if(TOOL_EXES)
message(STATUS "Building tools: ${TOOL_EXES}")
endif()
# Model uses dynamic_cast, so we need /GR (Enable RTTI)
if(MSVC)
foreach(t IN LISTS TOOL_EXES ITEMS ${PROJECT_NAME})
@ -428,6 +433,7 @@ elseif(CMAKE_CXX_COMPILER_ID MATCHES "Intel")
set_target_properties(${PROJECT_NAME} PROPERTIES CXX_STANDARD 14)
elseif(CMAKE_CXX_COMPILER_ID MATCHES "MSVC")
if(ENABLE_CODE_ANALYSIS)
message(STATUS "Building with Code Analysis (PREFIX)")
foreach(t IN LISTS TOOL_EXES ITEMS ${PROJECT_NAME})
target_compile_options(${t} PRIVATE /analyze /WX)
endforeach()

Просмотреть файл

@ -294,7 +294,9 @@
{ "name": "x64-Debug-ICX" , "description": "Intel oneAPI Compiler (Debug) for Windows 8", "inherits": [ "base", "x64", "Debug", "IntelLLVM" ] },
{ "name": "x64-Release-ICX" , "description": "Intel oneAPI Compiler (Release) for Windows 8", "inherits": [ "base", "x64", "Release", "IntelLLVM" ] },
{ "name": "x64-Fuzzing" , "description": "MSVC for x64 (Release) with ASan", "inherits": [ "base", "x64", "Release", "MSVC", "Win10", "Fuzzing" ] }
{ "name": "x64-Fuzzing" , "description": "MSVC for x64 (Release) with ASan", "inherits": [ "base", "x64", "Release", "MSVC", "Win10", "Fuzzing" ] },
{ "name": "x64-Analyze" , "description": "MSVC for x64 (Debug) for Windows 8 using /analyze", "inherits": [ "base", "x64", "Debug", "MSVC" ], "cacheVariables": { "ENABLE_CODE_ANALYSIS": true } },
{ "name": "x64-Analyze-Win10" , "description": "MSVC for x64 (Debug) for Windows 10 using /analyze", "inherits": [ "base", "x64", "Debug", "MSVC", "Win10" ], "cacheVariables": { "ENABLE_CODE_ANALYSIS": true } }
],
"testPresets": [
{ "name": "x64-Debug" , "configurePreset": "x64-Debug" },

375
XWBTool/CmdLineHelpers.h Normal file
Просмотреть файл

@ -0,0 +1,375 @@
//--------------------------------------------------------------------------------------
// File: CmdLineHelpers.h
//
// Command-line tool shared functions
//
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
//--------------------------------------------------------------------------------------
#pragma once
#if __cplusplus < 201703L
#error Requires C++17 (and /Zc:__cplusplus with MSVC)
#endif
#include <algorithm>
#include <cstdio>
#include <cwchar>
#include <filesystem>
#include <fstream>
#include <list>
#include <memory>
#include <set>
#include <string>
#ifndef TOOL_VERSION
#error Define TOOL_VERSION before including this header
#endif
namespace Helpers
{
struct handle_closer { void operator()(HANDLE h) { if (h) CloseHandle(h); } };
using ScopedHandle = std::unique_ptr<void, handle_closer>;
inline HANDLE safe_handle(HANDLE h) noexcept { return (h == INVALID_HANDLE_VALUE) ? nullptr : h; }
struct find_closer { void operator()(HANDLE h) noexcept { assert(h != INVALID_HANDLE_VALUE); if (h) FindClose(h); } };
using ScopedFindHandle = std::unique_ptr<void, find_closer>;
#ifdef _PREFAST_
#pragma prefast(disable : 26018, "Only used with static internal arrays")
#endif
struct SConversion
{
std::wstring szSrc;
std::wstring szFolder;
};
template<typename T>
struct SValue
{
const wchar_t* name;
T value;
};
template<typename T>
T LookupByName(const wchar_t _In_z_ *pName, const SValue<T> *pArray)
{
while (pArray->name)
{
if (!_wcsicmp(pName, pArray->name))
return pArray->value;
pArray++;
}
return static_cast<T>(0);
}
template<typename T>
const wchar_t* LookupByValue(T value, const SValue<T> *pArray)
{
while (pArray->name)
{
if (value == pArray->value)
return pArray->name;
pArray++;
}
return L"";
}
void PrintFormat(DXGI_FORMAT Format, const SValue<DXGI_FORMAT>* pFormatList)
{
for (auto pFormat = pFormatList; pFormat->name; pFormat++)
{
if (pFormat->value == Format)
{
wprintf(L"%ls", pFormat->name);
return;
}
}
wprintf(L"*UNKNOWN*");
}
void PrintFormat(DXGI_FORMAT Format, const SValue<DXGI_FORMAT>* pFormatList1, const SValue<DXGI_FORMAT>* pFormatList2)
{
for (auto pFormat = pFormatList1; pFormat->name; pFormat++)
{
if (pFormat->value == Format)
{
wprintf(L"%ls", pFormat->name);
return;
}
}
for (auto pFormat = pFormatList2; pFormat->name; pFormat++)
{
if (pFormat->value == Format)
{
wprintf(L"%ls", pFormat->name);
return;
}
}
wprintf(L"*UNKNOWN*");
}
template<typename T>
void PrintList(size_t cch, const SValue<T> *pValue)
{
while (pValue->name)
{
const size_t cchName = wcslen(pValue->name);
if (cch + cchName + 2 >= 80)
{
wprintf(L"\n ");
cch = 6;
}
wprintf(L"%ls ", pValue->name);
cch += cchName + 2;
pValue++;
}
wprintf(L"\n");
}
void PrintLogo(bool versionOnly, _In_z_ const wchar_t* name, _In_z_ const wchar_t* desc)
{
wchar_t version[32] = {};
wchar_t appName[_MAX_PATH] = {};
if (GetModuleFileNameW(nullptr, appName, _MAX_PATH))
{
const DWORD size = GetFileVersionInfoSizeW(appName, nullptr);
if (size > 0)
{
auto verInfo = std::make_unique<uint8_t[]>(size);
if (GetFileVersionInfoW(appName, 0, size, verInfo.get()))
{
LPVOID lpstr = nullptr;
UINT strLen = 0;
if (VerQueryValueW(verInfo.get(), L"\\StringFileInfo\\040904B0\\ProductVersion", &lpstr, &strLen))
{
wcsncpy_s(version, reinterpret_cast<const wchar_t*>(lpstr), strLen);
}
}
}
}
if (!*version || wcscmp(version, L"1.0.0.0") == 0)
{
swprintf_s(version, L"%03d (library)", TOOL_VERSION);
}
if (versionOnly)
{
wprintf(L"%ls version %ls\n", name, version);
}
else
{
wprintf(L"%ls Version %ls\n", desc, version);
wprintf(L"Copyright (C) Microsoft Corp.\n");
#ifdef _DEBUG
wprintf(L"*** Debug build ***\n");
#endif
wprintf(L"\n");
}
}
void SearchForFiles(const std::filesystem::path& path, std::list<SConversion>& files, bool recursive, _In_opt_z_ const wchar_t* folder)
{
// Process files
WIN32_FIND_DATAW findData = {};
ScopedFindHandle hFile(safe_handle(FindFirstFileExW(path.c_str(),
FindExInfoBasic, &findData,
FindExSearchNameMatch, nullptr,
FIND_FIRST_EX_LARGE_FETCH)));
if (hFile)
{
for (;;)
{
if (!(findData.dwFileAttributes & (FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_DIRECTORY)))
{
SConversion conv = {};
conv.szSrc = path.parent_path().append(findData.cFileName).native();
if (folder)
{
conv.szFolder = folder;
}
files.push_back(conv);
}
if (!FindNextFileW(hFile.get(), &findData))
break;
}
}
// Process directories
if (recursive)
{
auto searchDir = path.parent_path().append(L"*");
hFile.reset(safe_handle(FindFirstFileExW(searchDir.c_str(),
FindExInfoBasic, &findData,
FindExSearchLimitToDirectories, nullptr,
FIND_FIRST_EX_LARGE_FETCH)));
if (!hFile)
return;
for (;;)
{
if (findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
{
if (findData.cFileName[0] != L'.')
{
auto subfolder = (folder)
? (std::wstring(folder) + std::wstring(findData.cFileName) + std::filesystem::path::preferred_separator)
: (std::wstring(findData.cFileName) + std::filesystem::path::preferred_separator);
auto subdir = path.parent_path().append(findData.cFileName).append(path.filename().c_str());
SearchForFiles(subdir, files, recursive, subfolder.c_str());
}
}
if (!FindNextFileW(hFile.get(), &findData))
break;
}
}
}
void ProcessFileList(std::wifstream& inFile, std::list<SConversion>& files)
{
std::list<SConversion> flist;
std::set<std::wstring> excludes;
for (;;)
{
std::wstring fname;
std::getline(inFile, fname);
if (!inFile)
break;
if (fname[0] == L'#')
{
// Comment
}
else if (fname[0] == L'-')
{
if (flist.empty())
{
wprintf(L"WARNING: Ignoring the line '%ls' in -flist\n", fname.c_str());
}
else
{
std::filesystem::path path(fname.c_str() + 1);
auto& npath = path.make_preferred();
if (wcspbrk(fname.c_str(), L"?*") != nullptr)
{
std::list<SConversion> removeFiles;
SearchForFiles(npath, removeFiles, false, nullptr);
for (auto& it : removeFiles)
{
std::wstring name = it.szSrc;
std::transform(name.begin(), name.end(), name.begin(), towlower);
excludes.insert(name);
}
}
else
{
std::wstring name = npath.c_str();
std::transform(name.begin(), name.end(), name.begin(), towlower);
excludes.insert(name);
}
}
}
else if (wcspbrk(fname.c_str(), L"?*") != nullptr)
{
std::filesystem::path path(fname.c_str());
SearchForFiles(path.make_preferred(), flist, false, nullptr);
}
else
{
SConversion conv = {};
std::filesystem::path path(fname.c_str());
conv.szSrc = path.make_preferred().native();
flist.push_back(conv);
}
}
inFile.close();
if (!excludes.empty())
{
// Remove any excluded files
for (auto it = flist.begin(); it != flist.end();)
{
std::wstring name = it->szSrc;
std::transform(name.begin(), name.end(), name.begin(), towlower);
auto item = it;
++it;
if (excludes.find(name) != excludes.end())
{
flist.erase(item);
}
}
}
if (flist.empty())
{
wprintf(L"WARNING: No file names found in -flist\n");
}
else
{
files.splice(files.end(), flist);
}
}
const wchar_t* GetErrorDesc(HRESULT hr)
{
static wchar_t desc[1024] = {};
LPWSTR errorText = nullptr;
const DWORD result = FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_ALLOCATE_BUFFER,
nullptr, static_cast<DWORD>(hr),
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), reinterpret_cast<LPWSTR>(&errorText), 0, nullptr);
*desc = 0;
if (result > 0 && errorText)
{
swprintf_s(desc, L": %ls", errorText);
size_t len = wcslen(desc);
if (len >= 1)
{
desc[len - 1] = 0;
}
if (errorText)
LocalFree(errorText);
for(wchar_t* ptr = desc; *ptr != 0; ++ptr)
{
if (*ptr == L'\r' || *ptr == L'\n')
{
*ptr = L' ';
}
}
}
return desc;
}
}

Просмотреть файл

@ -31,6 +31,7 @@
#endif
#include <Windows.h>
#include <dxgiformat.h>
#if __cplusplus < 201703L
#error Requires C++17 (and /Zc:__cplusplus with MSVC)
@ -57,6 +58,11 @@
#include "WAVFileReader.h"
#define TOOL_VERSION 0
#include "CmdLineHelpers.h"
using namespace Helpers;
#ifdef __INTEL_COMPILER
#pragma warning(disable : 161)
// warning #161: unrecognized #pragma
@ -112,16 +118,6 @@ static_assert(sizeof(XMA2WAVEFORMATEX) == 52, "Mismatch of XMA2 type");
namespace
{
struct handle_closer { void operator()(HANDLE h) { if (h) CloseHandle(h); } };
using ScopedHandle = std::unique_ptr<void, handle_closer>;
inline HANDLE safe_handle(HANDLE h) { return (h == INVALID_HANDLE_VALUE) ? nullptr : h; }
struct find_closer { void operator()(HANDLE h) { assert(h != INVALID_HANDLE_VALUE); if (h) FindClose(h); } };
using ScopedFindHandle = std::unique_ptr<void, find_closer>;
#define BLOCKALIGNPAD(a, b) \
((((a) + ((b) - 1)) / (b)) * (b))
@ -784,65 +780,53 @@ namespace
return false;
}
}
}
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
const wchar_t* g_ToolName = L"xwbtool";
const wchar_t* g_Description = L"Microsoft (R) XACT-style Wave Bank Tool [DirectXTK]";
enum OPTIONS : uint32_t
{
OPT_RECURSIVE = 1,
OPT_STREAMING,
OPT_ADVANCED_FORMAT,
OPT_OUTPUTFILE,
OPT_OUTPUTHEADER,
OPT_TOLOWER,
OPT_OVERWRITE,
OPT_COMPACT,
OPT_NOCOMPACT,
OPT_FRIENDLY_NAMES,
OPT_NOLOGO,
OPT_FILELIST,
OPT_MAX
};
enum OPTIONS : uint32_t
{
OPT_RECURSIVE = 1,
OPT_STREAMING,
OPT_ADVANCED_FORMAT,
OPT_OUTPUTFILE,
OPT_OUTPUTHEADER,
OPT_TOLOWER,
OPT_OVERWRITE,
OPT_COMPACT,
OPT_NOCOMPACT,
OPT_FRIENDLY_NAMES,
OPT_NOLOGO,
OPT_FILELIST,
OPT_MAX
};
static_assert(OPT_MAX <= 32, "dwOptions is a unsigned int bitfield");
static_assert(OPT_MAX <= 32, "dwOptions is a unsigned int bitfield");
struct SConversion
{
std::wstring szSrc;
};
struct WaveFile
{
DirectX::WAVData data;
size_t conv;
MINIWAVEFORMAT miniFmt;
std::unique_ptr<uint8_t[]> waveData;
struct SValue
{
const wchar_t* name;
uint32_t value;
};
WaveFile() noexcept :
data{},
conv(0),
miniFmt{}
{}
struct WaveFile
{
DirectX::WAVData data;
size_t conv;
MINIWAVEFORMAT miniFmt;
std::unique_ptr<uint8_t[]> waveData;
WaveFile(WaveFile&) = delete;
WaveFile& operator= (WaveFile&) = delete;
WaveFile() noexcept :
data{},
conv(0),
miniFmt{}
{}
WaveFile(WaveFile&&) = default;
WaveFile& operator= (WaveFile&&) = default;
};
WaveFile(WaveFile&) = delete;
WaveFile& operator= (WaveFile&) = delete;
WaveFile(WaveFile&&) = default;
WaveFile& operator= (WaveFile&&) = default;
};
namespace
{
void FileNameToIdentifier(_Inout_updates_all_(count) wchar_t* str, size_t count)
{
size_t j = 0;
@ -854,240 +838,35 @@ namespace
*c = t;
}
}
}
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
const SValue g_pOptions[] =
{
{ L"r", OPT_RECURSIVE },
{ L"s", OPT_STREAMING },
{ L"af", OPT_ADVANCED_FORMAT },
{ L"o", OPT_OUTPUTFILE },
{ L"l", OPT_TOLOWER },
{ L"h", OPT_OUTPUTHEADER },
{ L"y", OPT_OVERWRITE },
{ L"c", OPT_COMPACT },
{ L"nc", OPT_NOCOMPACT },
{ L"f", OPT_FRIENDLY_NAMES },
{ L"nologo", OPT_NOLOGO },
{ L"flist", OPT_FILELIST },
{ nullptr, 0 }
};
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
namespace
{
#ifdef _PREFAST_
#pragma prefast(disable : 26018, "Only used with static internal arrays")
#endif
uint32_t LookupByName(const wchar_t *pName, const SValue *pArray)
const SValue<uint32_t> g_pOptions[] =
{
while (pArray->name)
{
if (!_wcsicmp(pName, pArray->name))
return pArray->value;
{ L"r", OPT_RECURSIVE },
{ L"s", OPT_STREAMING },
{ L"af", OPT_ADVANCED_FORMAT },
{ L"o", OPT_OUTPUTFILE },
{ L"l", OPT_TOLOWER },
{ L"h", OPT_OUTPUTHEADER },
{ L"y", OPT_OVERWRITE },
{ L"c", OPT_COMPACT },
{ L"nc", OPT_NOCOMPACT },
{ L"f", OPT_FRIENDLY_NAMES },
{ L"nologo", OPT_NOLOGO },
{ L"flist", OPT_FILELIST },
{ nullptr, 0 }
};
pArray++;
}
return 0;
}
void SearchForFiles(const std::filesystem::path& path, std::list<SConversion>& files, bool recursive)
{
// Process files
WIN32_FIND_DATAW findData = {};
ScopedFindHandle hFile(safe_handle(FindFirstFileExW(path.c_str(),
FindExInfoBasic, &findData,
FindExSearchNameMatch, nullptr,
FIND_FIRST_EX_LARGE_FETCH)));
if (hFile)
{
for (;;)
{
if (!(findData.dwFileAttributes & (FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_DIRECTORY)))
{
SConversion conv = {};
conv.szSrc = path.parent_path().append(findData.cFileName).native();
files.push_back(conv);
}
if (!FindNextFileW(hFile.get(), &findData))
break;
}
}
// Process directories
if (recursive)
{
auto searchDir = path.parent_path().append(L"*");
hFile.reset(safe_handle(FindFirstFileExW(searchDir.c_str(),
FindExInfoBasic, &findData,
FindExSearchLimitToDirectories, nullptr,
FIND_FIRST_EX_LARGE_FETCH)));
if (!hFile)
return;
for (;;)
{
if (findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
{
if (findData.cFileName[0] != L'.')
{
auto subdir = path.parent_path().append(findData.cFileName).append(path.filename().c_str());
SearchForFiles(subdir, files, recursive);
}
}
if (!FindNextFileW(hFile.get(), &findData))
break;
}
}
}
void ProcessFileList(std::wifstream& inFile, std::list<SConversion>& files)
{
std::list<SConversion> flist;
std::set<std::wstring> excludes;
for (;;)
{
std::wstring fname;
std::getline(inFile, fname);
if (!inFile)
break;
if (fname[0] == L'#')
{
// Comment
}
else if (fname[0] == L'-')
{
if (flist.empty())
{
wprintf(L"WARNING: Ignoring the line '%ls' in -flist\n", fname.c_str());
}
else
{
std::filesystem::path path(fname.c_str() + 1);
auto& npath = path.make_preferred();
if (wcspbrk(fname.c_str(), L"?*") != nullptr)
{
std::list<SConversion> removeFiles;
SearchForFiles(npath, removeFiles, false);
for (auto& it : removeFiles)
{
std::wstring name = it.szSrc;
std::transform(name.begin(), name.end(), name.begin(), towlower);
excludes.insert(name);
}
}
else
{
std::wstring name = npath.c_str();
std::transform(name.begin(), name.end(), name.begin(), towlower);
excludes.insert(name);
}
}
}
else if (wcspbrk(fname.c_str(), L"?*") != nullptr)
{
std::filesystem::path path(fname.c_str());
SearchForFiles(path.make_preferred(), flist, false);
}
else
{
SConversion conv = {};
std::filesystem::path path(fname.c_str());
conv.szSrc = path.make_preferred().native();
flist.push_back(conv);
}
}
inFile.close();
if (!excludes.empty())
{
// Remove any excluded files
for (auto it = flist.begin(); it != flist.end();)
{
std::wstring name = it->szSrc;
std::transform(name.begin(), name.end(), name.begin(), towlower);
auto item = it;
++it;
if (excludes.find(name) != excludes.end())
{
flist.erase(item);
}
}
}
if (flist.empty())
{
wprintf(L"WARNING: No file names found in -flist\n");
}
else
{
files.splice(files.end(), flist);
}
}
void PrintLogo(bool versionOnly)
{
wchar_t version[32] = {};
wchar_t appName[_MAX_PATH] = {};
if (GetModuleFileNameW(nullptr, appName, _MAX_PATH))
{
DWORD size = GetFileVersionInfoSizeW(appName, nullptr);
if (size > 0)
{
auto verInfo = std::make_unique<uint8_t[]>(size);
if (GetFileVersionInfoW(appName, 0, size, verInfo.get()))
{
LPVOID lpstr = nullptr;
UINT strLen = 0;
if (VerQueryValueW(verInfo.get(), L"\\StringFileInfo\\040904B0\\ProductVersion", &lpstr, &strLen))
{
wcsncpy_s(version, reinterpret_cast<const wchar_t*>(lpstr), strLen);
}
}
}
}
if (!*version)
{
wcscpy_s(version, L"MISSING");
}
if (versionOnly)
{
wprintf(L"xwbtool version %ls\n", version);
}
else
{
wprintf(L"Microsoft (R) XACT-style Wave Bank Tool [DirectXTK] Version %ls\n", version);
wprintf(L"Copyright (C) Microsoft Corp.\n");
#ifdef _DEBUG
wprintf(L"*** Debug build ***\n");
#endif
wprintf(L"\n");
}
}
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
void PrintUsage()
{
PrintLogo(false);
PrintLogo(false, g_ToolName, g_Description);
static const wchar_t* const s_usage =
L"Usage: xwbtool <options> [--] <wav-files>\n"
@ -1112,44 +891,6 @@ namespace
wprintf(L"%ls", s_usage);
}
const wchar_t* GetErrorDesc(HRESULT hr)
{
static wchar_t desc[1024] = {};
LPWSTR errorText = nullptr;
DWORD result = FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_ALLOCATE_BUFFER,
nullptr, static_cast<DWORD>(hr),
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), reinterpret_cast<LPWSTR>(&errorText), 0, nullptr);
*desc = 0;
if (result > 0 && errorText)
{
swprintf_s(desc, L": %ls", errorText);
size_t len = wcslen(desc);
if (len >= 2)
{
desc[len - 2] = 0;
desc[len - 1] = 0;
}
if (errorText)
LocalFree(errorText);
for (wchar_t* ptr = desc; *ptr != 0; ++ptr)
{
if (*ptr == L'\r' || *ptr == L'\n')
{
*ptr = L' ';
}
}
}
return desc;
}
const char* GetFormatTagName(WORD wFormatTag)
{
switch (wFormatTag)
@ -1242,7 +983,7 @@ int __cdecl wmain(_In_ int argc, _In_z_count_(argc) wchar_t* argv[])
}
else if (!_wcsicmp(pArg, L"--version"))
{
PrintLogo(true);
PrintLogo(true, g_ToolName, g_Description);
return 0;
}
else if (!_wcsicmp(pArg, L"--help"))
@ -1365,7 +1106,7 @@ int __cdecl wmain(_In_ int argc, _In_z_count_(argc) wchar_t* argv[])
{
size_t count = conversion.size();
std::filesystem::path path(pArg);
SearchForFiles(path.make_preferred(), conversion, (dwOptions & (1 << OPT_RECURSIVE)) != 0);
SearchForFiles(path.make_preferred(), conversion, (dwOptions & (1 << OPT_RECURSIVE)) != 0, nullptr);
if (conversion.size() <= count)
{
wprintf(L"No matching files found for %ls\n", pArg);
@ -1389,7 +1130,7 @@ int __cdecl wmain(_In_ int argc, _In_z_count_(argc) wchar_t* argv[])
}
if (~dwOptions & (1 << OPT_NOLOGO))
PrintLogo(false);
PrintLogo(false, g_ToolName, g_Description);
// Determine output file name
if (outputFile.empty())

Просмотреть файл

@ -256,6 +256,7 @@
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\Audio\WAVFileReader.h" />
<ClInclude Include="CmdLineHelpers.h" />
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="xwbtool.rc" />

Просмотреть файл

@ -6,6 +6,7 @@
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\Audio\WAVFileReader.h" />
<ClInclude Include="CmdLineHelpers.h" />
</ItemGroup>
<ItemGroup>
<Filter Include="Resource Files">

Просмотреть файл

@ -256,6 +256,7 @@
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\Audio\WAVFileReader.h" />
<ClInclude Include="CmdLineHelpers.h" />
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="xwbtool.rc" />

Просмотреть файл

@ -6,6 +6,7 @@
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\Audio\WAVFileReader.h" />
<ClInclude Include="CmdLineHelpers.h" />
</ItemGroup>
<ItemGroup>
<Filter Include="Resource Files">