mirror of
https://github.com/velopack/velopack.git
synced 2025-10-25 15:19:22 +00:00
Add C++ to editorconfig & update formatting. No functional changes.
This commit is contained in:
@@ -123,3 +123,72 @@ insert_final_newline=false
|
|||||||
[*.vb]
|
[*.vb]
|
||||||
# Modifier preferences
|
# Modifier preferences
|
||||||
visual_basic_preferred_modifier_order = Partial,Default,Private,Protected,Public,Friend,NotOverridable,Overridable,MustOverride,Overloads,Overrides,MustInherit,NotInheritable,Static,Shared,Shadows,ReadOnly,WriteOnly,Dim,Const,WithEvents,Widening,Narrowing,Custom,Async:suggestion
|
visual_basic_preferred_modifier_order = Partial,Default,Private,Protected,Public,Friend,NotOverridable,Overridable,MustOverride,Overloads,Overrides,MustInherit,NotInheritable,Static,Shared,Shadows,ReadOnly,WriteOnly,Dim,Const,WithEvents,Widening,Narrowing,Custom,Async:suggestion
|
||||||
|
|
||||||
|
[*.{c++,cc,cpp,cppm,cxx,h,h++,hh,hpp,hxx,inl,ipp,ixx,tlh,tli}]
|
||||||
|
|
||||||
|
# Visual C++ Code Style settings
|
||||||
|
|
||||||
|
cpp_generate_documentation_comments = xml
|
||||||
|
|
||||||
|
# Visual C++ Formatting settings
|
||||||
|
indent_style = space
|
||||||
|
indent_size = 4
|
||||||
|
|
||||||
|
cpp_indent_braces = false
|
||||||
|
cpp_indent_multi_line_relative_to = innermost_parenthesis
|
||||||
|
cpp_indent_within_parentheses = indent
|
||||||
|
cpp_indent_preserve_within_parentheses = true
|
||||||
|
cpp_indent_case_contents = true
|
||||||
|
cpp_indent_case_labels = false
|
||||||
|
cpp_indent_case_contents_when_block = false
|
||||||
|
cpp_indent_lambda_braces_when_parameter = true
|
||||||
|
cpp_indent_goto_labels = one_left
|
||||||
|
cpp_indent_preprocessor = leftmost_column
|
||||||
|
cpp_indent_access_specifiers = false
|
||||||
|
cpp_indent_namespace_contents = true
|
||||||
|
cpp_indent_preserve_comments = false
|
||||||
|
cpp_new_line_before_open_brace_namespace = new_line
|
||||||
|
cpp_new_line_before_open_brace_type = new_line
|
||||||
|
cpp_new_line_before_open_brace_function = new_line
|
||||||
|
cpp_new_line_before_open_brace_block = same_line
|
||||||
|
cpp_new_line_before_open_brace_lambda = ignore
|
||||||
|
cpp_new_line_scope_braces_on_separate_lines = false
|
||||||
|
cpp_new_line_close_brace_same_line_empty_type = false
|
||||||
|
cpp_new_line_close_brace_same_line_empty_function = false
|
||||||
|
cpp_new_line_before_catch = true
|
||||||
|
cpp_new_line_before_else = true
|
||||||
|
cpp_new_line_before_while_in_do_while = false
|
||||||
|
cpp_space_before_function_open_parenthesis = remove
|
||||||
|
cpp_space_within_parameter_list_parentheses = false
|
||||||
|
cpp_space_between_empty_parameter_list_parentheses = false
|
||||||
|
cpp_space_after_keywords_in_control_flow_statements = true
|
||||||
|
cpp_space_within_control_flow_statement_parentheses = false
|
||||||
|
cpp_space_before_lambda_open_parenthesis = false
|
||||||
|
cpp_space_within_cast_parentheses = false
|
||||||
|
cpp_space_after_cast_close_parenthesis = false
|
||||||
|
cpp_space_within_expression_parentheses = false
|
||||||
|
cpp_space_before_block_open_brace = true
|
||||||
|
cpp_space_between_empty_braces = false
|
||||||
|
cpp_space_before_initializer_list_open_brace = false
|
||||||
|
cpp_space_within_initializer_list_braces = true
|
||||||
|
cpp_space_preserve_in_initializer_list = true
|
||||||
|
cpp_space_before_open_square_bracket = false
|
||||||
|
cpp_space_within_square_brackets = false
|
||||||
|
cpp_space_before_empty_square_brackets = false
|
||||||
|
cpp_space_between_empty_square_brackets = false
|
||||||
|
cpp_space_group_square_brackets = true
|
||||||
|
cpp_space_within_lambda_brackets = false
|
||||||
|
cpp_space_between_empty_lambda_brackets = false
|
||||||
|
cpp_space_before_comma = false
|
||||||
|
cpp_space_after_comma = true
|
||||||
|
cpp_space_remove_around_member_operators = true
|
||||||
|
cpp_space_before_inheritance_colon = true
|
||||||
|
cpp_space_before_constructor_colon = true
|
||||||
|
cpp_space_remove_before_semicolon = true
|
||||||
|
cpp_space_after_semicolon = false
|
||||||
|
cpp_space_remove_around_unary_operator = true
|
||||||
|
cpp_space_around_binary_operator = insert
|
||||||
|
cpp_space_around_assignment_operator = insert
|
||||||
|
cpp_space_pointer_reference_alignment = left
|
||||||
|
cpp_space_around_ternary_operator = insert
|
||||||
|
cpp_wrap_preserve_blocks = one_liners
|
||||||
|
|||||||
@@ -10,22 +10,18 @@ class ATL_NO_VTABLE CDownloadProgressCallback :
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CDownloadProgressCallback()
|
CDownloadProgressCallback()
|
||||||
{
|
{}
|
||||||
}
|
|
||||||
|
|
||||||
DECLARE_NOT_AGGREGATABLE(CDownloadProgressCallback)
|
DECLARE_NOT_AGGREGATABLE(CDownloadProgressCallback)
|
||||||
|
|
||||||
BEGIN_COM_MAP(CDownloadProgressCallback)
|
BEGIN_COM_MAP(CDownloadProgressCallback)
|
||||||
COM_INTERFACE_ENTRY(IBindStatusCallback)
|
COM_INTERFACE_ENTRY(IBindStatusCallback)
|
||||||
END_COM_MAP()
|
END_COM_MAP()
|
||||||
|
|
||||||
DECLARE_PROTECT_FINAL_CONSTRUCT()
|
DECLARE_PROTECT_FINAL_CONSTRUCT()
|
||||||
|
|
||||||
HRESULT FinalConstruct() { return S_OK; }
|
HRESULT FinalConstruct() { return S_OK; }
|
||||||
|
|
||||||
void FinalRelease()
|
void FinalRelease()
|
||||||
{
|
{}
|
||||||
}
|
|
||||||
|
|
||||||
void SetProgressDialog(IProgressDialog* pd)
|
void SetProgressDialog(IProgressDialog* pd)
|
||||||
{
|
{
|
||||||
@@ -45,13 +41,13 @@ public:
|
|||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
STDMETHOD(OnStartBinding)(DWORD /*dwReserved*/, IBinding *pBinding) { return E_NOTIMPL; }
|
STDMETHOD(OnStartBinding)(DWORD /*dwReserved*/, IBinding* pBinding) { return E_NOTIMPL; }
|
||||||
STDMETHOD(GetPriority)(LONG *pnPriority) { return E_NOTIMPL; }
|
STDMETHOD(GetPriority)(LONG* pnPriority) { return E_NOTIMPL; }
|
||||||
STDMETHOD(OnLowResource)(DWORD /*reserved*/) { return E_NOTIMPL; }
|
STDMETHOD(OnLowResource)(DWORD /*reserved*/) { return E_NOTIMPL; }
|
||||||
STDMETHOD(OnStopBinding)(HRESULT /*hresult*/, LPCWSTR /*szError*/) { return E_NOTIMPL; }
|
STDMETHOD(OnStopBinding)(HRESULT /*hresult*/, LPCWSTR /*szError*/) { return E_NOTIMPL; }
|
||||||
STDMETHOD(GetBindInfo)(DWORD *pgrfBINDF, BINDINFO *pbindInfo) { return E_NOTIMPL; }
|
STDMETHOD(GetBindInfo)(DWORD* pgrfBINDF, BINDINFO* pbindInfo) { return E_NOTIMPL; }
|
||||||
STDMETHOD(OnDataAvailable)(DWORD grfBSCF, DWORD dwSize, FORMATETC * /*pformatetc*/, STGMEDIUM *pstgmed) { return E_NOTIMPL; }
|
STDMETHOD(OnDataAvailable)(DWORD grfBSCF, DWORD dwSize, FORMATETC* /*pformatetc*/, STGMEDIUM* pstgmed) { return E_NOTIMPL; }
|
||||||
STDMETHOD(OnObjectAvailable)(REFIID /*riid*/, IUnknown * /*punk*/) { return E_NOTIMPL; }
|
STDMETHOD(OnObjectAvailable)(REFIID /*riid*/, IUnknown* /*punk*/) { return E_NOTIMPL; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
CComPtr<IProgressDialog> m_spProgressDialog;
|
CComPtr<IProgressDialog> m_spProgressDialog;
|
||||||
@@ -98,7 +94,8 @@ HRESULT CFxHelper::InstallDotnet(const RUNTIMEINFO* runtime, bool isQuiet)
|
|||||||
if (dwTempPathResult == 0) {
|
if (dwTempPathResult == 0) {
|
||||||
hr = AtlHresultFromLastError();
|
hr = AtlHresultFromLastError();
|
||||||
goto out;
|
goto out;
|
||||||
} else if (dwTempPathResult > _MAX_PATH) {
|
}
|
||||||
|
else if (dwTempPathResult > _MAX_PATH) {
|
||||||
hr = DISP_E_BUFFERTOOSMALL;
|
hr = DISP_E_BUFFERTOOSMALL;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
@@ -121,7 +118,8 @@ HRESULT CFxHelper::InstallDotnet(const RUNTIMEINFO* runtime, bool isQuiet)
|
|||||||
hr = E_FAIL;
|
hr = E_FAIL;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
if (wcscpy_s(pLastDot, _countof(szFinalTempFileName) - (pLastDot - szFinalTempFileName), L".exe") != 0) {
|
if (wcscpy_s(pLastDot, _countof(szFinalTempFileName) - (pLastDot - szFinalTempFileName), L".exe") != 0) {
|
||||||
hr = E_FAIL;
|
hr = E_FAIL;
|
||||||
goto out;
|
goto out;
|
||||||
|
|||||||
@@ -3,10 +3,12 @@
|
|||||||
|
|
||||||
class CFxHelper
|
class CFxHelper
|
||||||
{
|
{
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static HRESULT InstallDotnet(const RUNTIMEINFO* runtime, bool isQuiet);
|
static HRESULT InstallDotnet(const RUNTIMEINFO* runtime, bool isQuiet);
|
||||||
static HRESULT HandleRebootRequirement(bool isQuiet);
|
static HRESULT HandleRebootRequirement(bool isQuiet);
|
||||||
private:
|
private:
|
||||||
static bool WriteRunOnceEntry();
|
static bool WriteRunOnceEntry();
|
||||||
static bool RebootSystem();
|
static bool RebootSystem();
|
||||||
|
|
||||||
};
|
};
|
||||||
@@ -17,27 +17,21 @@ IStream* LoadImageFromResource(const wchar_t* resid, const wchar_t* restype)
|
|||||||
|
|
||||||
HINSTANCE hInst = GetModuleHandle(NULL);
|
HINSTANCE hInst = GetModuleHandle(NULL);
|
||||||
HRSRC hrsrc = FindResourceW(hInst, resid, restype); // get the handle to the resource
|
HRSRC hrsrc = FindResourceW(hInst, resid, restype); // get the handle to the resource
|
||||||
if (hrsrc)
|
if (hrsrc) {
|
||||||
{
|
|
||||||
DWORD dwResourceSize = SizeofResource(hInst, hrsrc);
|
DWORD dwResourceSize = SizeofResource(hInst, hrsrc);
|
||||||
if (dwResourceSize > 0)
|
if (dwResourceSize > 0) {
|
||||||
{
|
|
||||||
HGLOBAL hGlobalResource = LoadResource(hInst, hrsrc); // load it
|
HGLOBAL hGlobalResource = LoadResource(hInst, hrsrc); // load it
|
||||||
if (hGlobalResource)
|
if (hGlobalResource) {
|
||||||
{
|
|
||||||
void* imagebytes = LockResource(hGlobalResource); // get a pointer to the file bytes
|
void* imagebytes = LockResource(hGlobalResource); // get a pointer to the file bytes
|
||||||
|
|
||||||
// copy image bytes into a real hglobal memory handle
|
// copy image bytes into a real hglobal memory handle
|
||||||
hGlobal = ::GlobalAlloc(GHND, dwResourceSize);
|
hGlobal = ::GlobalAlloc(GHND, dwResourceSize);
|
||||||
if (hGlobal)
|
if (hGlobal) {
|
||||||
{
|
|
||||||
void* pBuffer = ::GlobalLock(hGlobal);
|
void* pBuffer = ::GlobalLock(hGlobal);
|
||||||
if (pBuffer)
|
if (pBuffer) {
|
||||||
{
|
|
||||||
memcpy(pBuffer, imagebytes, dwResourceSize);
|
memcpy(pBuffer, imagebytes, dwResourceSize);
|
||||||
HRESULT hr = CreateStreamOnHGlobal(hGlobal, TRUE, &pStream);
|
HRESULT hr = CreateStreamOnHGlobal(hGlobal, TRUE, &pStream);
|
||||||
if (SUCCEEDED(hr))
|
if (SUCCEEDED(hr)) {
|
||||||
{
|
|
||||||
// pStream now owns the global handle and will invoke GlobalFree on release
|
// pStream now owns the global handle and will invoke GlobalFree on release
|
||||||
hGlobal = nullptr;
|
hGlobal = nullptr;
|
||||||
}
|
}
|
||||||
@@ -47,8 +41,7 @@ IStream* LoadImageFromResource(const wchar_t* resid, const wchar_t* restype)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hGlobal)
|
if (hGlobal) {
|
||||||
{
|
|
||||||
GlobalFree(hGlobal);
|
GlobalFree(hGlobal);
|
||||||
hGlobal = nullptr;
|
hGlobal = nullptr;
|
||||||
}
|
}
|
||||||
@@ -61,8 +54,7 @@ ImageEx::ImageEx(const wchar_t* resid, const wchar_t* restype)
|
|||||||
Initialize();
|
Initialize();
|
||||||
|
|
||||||
auto stream = LoadImageFromResource(resid, restype);
|
auto stream = LoadImageFromResource(resid, restype);
|
||||||
if (stream)
|
if (stream) {
|
||||||
{
|
|
||||||
nativeImage = NULL;
|
nativeImage = NULL;
|
||||||
lastResult = DllExports::GdipLoadImageFromStreamICM(stream, &nativeImage);
|
lastResult = DllExports::GdipLoadImageFromStreamICM(stream, &nativeImage);
|
||||||
m_bIsInitialized = true;
|
m_bIsInitialized = true;
|
||||||
@@ -78,27 +70,22 @@ ImageEx::~ImageEx()
|
|||||||
|
|
||||||
bool ImageEx::InitAnimation(HWND hWnd, CPoint pt)
|
bool ImageEx::InitAnimation(HWND hWnd, CPoint pt)
|
||||||
{
|
{
|
||||||
|
|
||||||
m_hWnd = hWnd;
|
m_hWnd = hWnd;
|
||||||
m_pt = pt;
|
m_pt = pt;
|
||||||
|
|
||||||
if (!m_bIsInitialized)
|
if (!m_bIsInitialized) {
|
||||||
{
|
|
||||||
TRACE(_T("GIF not initialized\n"));
|
TRACE(_T("GIF not initialized\n"));
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
|
|
||||||
if (IsAnimatedGIF())
|
if (IsAnimatedGIF()) {
|
||||||
{
|
if (m_hThread == NULL) {
|
||||||
if (m_hThread == NULL)
|
|
||||||
{
|
|
||||||
|
|
||||||
unsigned int nTID = 0;
|
unsigned int nTID = 0;
|
||||||
|
|
||||||
m_hThread = (HANDLE)_beginthreadex(NULL, 0, _ThreadAnimationProc, this, CREATE_SUSPENDED, &nTID);
|
m_hThread = (HANDLE)_beginthreadex(NULL, 0, _ThreadAnimationProc, this, CREATE_SUSPENDED, &nTID);
|
||||||
|
|
||||||
if (!m_hThread)
|
if (!m_hThread) {
|
||||||
{
|
|
||||||
TRACE(_T("Couldn't start a GIF animation thread\n"));
|
TRACE(_T("Couldn't start a GIF animation thread\n"));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -176,8 +163,7 @@ void ImageEx::ThreadAnimation()
|
|||||||
m_nFramePosition = 0;
|
m_nFramePosition = 0;
|
||||||
|
|
||||||
bool bExit = false;
|
bool bExit = false;
|
||||||
while (bExit == false)
|
while (bExit == false) {
|
||||||
{
|
|
||||||
bExit = DrawFrameGIF();
|
bExit = DrawFrameGIF();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -192,8 +178,7 @@ bool ImageEx::DrawFrameGIF()
|
|||||||
long hmHeight = GetHeight();
|
long hmHeight = GetHeight();
|
||||||
|
|
||||||
HDC hDC = GetDC(m_hWnd);
|
HDC hDC = GetDC(m_hWnd);
|
||||||
if (hDC)
|
if (hDC) {
|
||||||
{
|
|
||||||
Graphics graphics(hDC);
|
Graphics graphics(hDC);
|
||||||
graphics.DrawImage(this, m_pt.x, m_pt.y, hmWidth, hmHeight);
|
graphics.DrawImage(this, m_pt.x, m_pt.y, hmWidth, hmHeight);
|
||||||
ReleaseDC(m_hWnd, hDC);
|
ReleaseDC(m_hWnd, hDC);
|
||||||
@@ -214,15 +199,12 @@ void ImageEx::SetPause(bool bPause)
|
|||||||
if (!IsAnimatedGIF())
|
if (!IsAnimatedGIF())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (bPause && !m_bPause)
|
if (bPause && !m_bPause) {
|
||||||
{
|
|
||||||
::ResetEvent(m_hPause);
|
::ResetEvent(m_hPause);
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
{
|
|
||||||
|
|
||||||
if (m_bPause && !bPause)
|
if (m_bPause && !bPause) {
|
||||||
{
|
|
||||||
::SetEvent(m_hPause);
|
::SetEvent(m_hPause);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -234,8 +216,7 @@ void ImageEx::SetPause(bool bPause)
|
|||||||
void ImageEx::Destroy()
|
void ImageEx::Destroy()
|
||||||
{
|
{
|
||||||
|
|
||||||
if (m_hThread)
|
if (m_hThread) {
|
||||||
{
|
|
||||||
// If pause un pause
|
// If pause un pause
|
||||||
SetPause(false);
|
SetPause(false);
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,8 @@
|
|||||||
#include "resource.h"
|
#include "resource.h"
|
||||||
#include <sddl.h>
|
#include <sddl.h>
|
||||||
|
|
||||||
bool directoryExists(wchar_t* path) {
|
bool directoryExists(wchar_t* path)
|
||||||
|
{
|
||||||
DWORD dwResult = GetFileAttributes(path);
|
DWORD dwResult = GetFileAttributes(path);
|
||||||
|
|
||||||
if (dwResult != INVALID_FILE_ATTRIBUTES) {
|
if (dwResult != INVALID_FILE_ATTRIBUTES) {
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
class MachineInstaller
|
class MachineInstaller
|
||||||
{
|
{
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static bool ShouldSilentInstall();
|
static bool ShouldSilentInstall();
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -114,8 +114,7 @@ RUNTIMEINFO supported_runtimes[] =
|
|||||||
|
|
||||||
const RUNTIMEINFO* GetRuntimeByName(wstring name)
|
const RUNTIMEINFO* GetRuntimeByName(wstring name)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < NUM_RUNTIMES; i++)
|
for (int i = 0; i < NUM_RUNTIMES; i++) {
|
||||||
{
|
|
||||||
const RUNTIMEINFO* item = &supported_runtimes[i];
|
const RUNTIMEINFO* item = &supported_runtimes[i];
|
||||||
auto itemName = wstring(item->name);
|
auto itemName = wstring(item->name);
|
||||||
|
|
||||||
@@ -150,7 +149,8 @@ bool IsFullNetFrameworkInstalled(DWORD requiredVersion)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// TODO this is extremely messy, it should certainly be re-written.
|
// TODO this is extremely messy, it should certainly be re-written.
|
||||||
wstring exec(const char* cmd) {
|
wstring exec(const char* cmd)
|
||||||
|
{
|
||||||
char buffer[128];
|
char buffer[128];
|
||||||
string result = "";
|
string result = "";
|
||||||
FILE* pipe = _popen(cmd, "r");
|
FILE* pipe = _popen(cmd, "r");
|
||||||
@@ -187,12 +187,10 @@ bool IsDotNetCoreInstalled(wstring searchString)
|
|||||||
|
|
||||||
bool IsRuntimeInstalled(const RUNTIMEINFO* runtime)
|
bool IsRuntimeInstalled(const RUNTIMEINFO* runtime)
|
||||||
{
|
{
|
||||||
if (runtime->fxReleaseVersion > 0)
|
if (runtime->fxReleaseVersion > 0) {
|
||||||
{
|
|
||||||
return IsFullNetFrameworkInstalled(runtime->fxReleaseVersion);
|
return IsFullNetFrameworkInstalled(runtime->fxReleaseVersion);
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
{
|
|
||||||
return IsDotNetCoreInstalled(wstring(runtime->dncRuntimeVersionName));
|
return IsDotNetCoreInstalled(wstring(runtime->dncRuntimeVersionName));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -203,8 +201,7 @@ int ParseRuntimeString(std::wstring version, vector<const RUNTIMEINFO*>& runtime
|
|||||||
int ret = S_OK;
|
int ret = S_OK;
|
||||||
wstring temp;
|
wstring temp;
|
||||||
std::wstringstream wss(version);
|
std::wstringstream wss(version);
|
||||||
while (std::getline(wss, temp, L','))
|
while (std::getline(wss, temp, L',')) {
|
||||||
{
|
|
||||||
const RUNTIMEINFO* rt = GetRuntimeByName(temp);
|
const RUNTIMEINFO* rt = GetRuntimeByName(temp);
|
||||||
if (rt != nullptr)
|
if (rt != nullptr)
|
||||||
runtimes.push_back(rt);
|
runtimes.push_back(rt);
|
||||||
|
|||||||
@@ -45,28 +45,23 @@ void CSplashWnd::SetImage(const wchar_t* resid, const wchar_t* restype)
|
|||||||
|
|
||||||
void CSplashWnd::Show()
|
void CSplashWnd::Show()
|
||||||
{
|
{
|
||||||
if (m_hThread == NULL)
|
if (m_hThread == NULL) {
|
||||||
{
|
|
||||||
m_hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
|
m_hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
|
||||||
m_hThread = (HANDLE)_beginthreadex(NULL, 0, SplashThreadProc, static_cast<LPVOID>(this), 0, &m_ThreadId);
|
m_hThread = (HANDLE)_beginthreadex(NULL, 0, SplashThreadProc, static_cast<LPVOID>(this), 0, &m_ThreadId);
|
||||||
if (WaitForSingleObject(m_hEvent, 5000) == WAIT_TIMEOUT)
|
if (WaitForSingleObject(m_hEvent, 5000) == WAIT_TIMEOUT) {
|
||||||
{
|
|
||||||
OutputDebugString(L"Error starting SplashThread\n");
|
OutputDebugString(L"Error starting SplashThread\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
{
|
|
||||||
PostThreadMessage(m_ThreadId, WM_ACTIVATE, WA_CLICKACTIVE, 0);
|
PostThreadMessage(m_ThreadId, WM_ACTIVATE, WA_CLICKACTIVE, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CSplashWnd::Hide()
|
void CSplashWnd::Hide()
|
||||||
{
|
{
|
||||||
if (m_hThread)
|
if (m_hThread) {
|
||||||
{
|
|
||||||
PostThreadMessage(m_ThreadId, WM_QUIT, 0, 0);
|
PostThreadMessage(m_ThreadId, WM_QUIT, 0, 0);
|
||||||
if (WaitForSingleObject(m_hThread, 9000) == WAIT_TIMEOUT)
|
if (WaitForSingleObject(m_hThread, 9000) == WAIT_TIMEOUT) {
|
||||||
{
|
|
||||||
::TerminateThread(m_hThread, 2222);
|
::TerminateThread(m_hThread, 2222);
|
||||||
}
|
}
|
||||||
CloseHandle(m_hThread);
|
CloseHandle(m_hThread);
|
||||||
@@ -101,8 +96,7 @@ unsigned int __stdcall CSplashWnd::SplashThreadProc(void* lpParameter)
|
|||||||
wndcls.lpszClassName = L"SplashWnd";
|
wndcls.lpszClassName = L"SplashWnd";
|
||||||
wndcls.hIcon = LoadIcon(wndcls.hInstance, MAKEINTRESOURCE(IDI_APPLICATION));
|
wndcls.hIcon = LoadIcon(wndcls.hInstance, MAKEINTRESOURCE(IDI_APPLICATION));
|
||||||
|
|
||||||
if (!RegisterClass(&wndcls))
|
if (!RegisterClass(&wndcls)) {
|
||||||
{
|
|
||||||
if (GetLastError() != 0x00000582) // already registered)
|
if (GetLastError() != 0x00000582) // already registered)
|
||||||
{
|
{
|
||||||
OutputDebugString(L"Unable to register class SplashWnd\n");
|
OutputDebugString(L"Unable to register class SplashWnd\n");
|
||||||
@@ -118,13 +112,11 @@ unsigned int __stdcall CSplashWnd::SplashThreadProc(void* lpParameter)
|
|||||||
|
|
||||||
::GetCursorPos(&point);
|
::GetCursorPos(&point);
|
||||||
hMonitor = ::MonitorFromPoint(point, MONITOR_DEFAULTTONEAREST);
|
hMonitor = ::MonitorFromPoint(point, MONITOR_DEFAULTTONEAREST);
|
||||||
if (::GetMonitorInfo(hMonitor, &mi))
|
if (::GetMonitorInfo(hMonitor, &mi)) {
|
||||||
{
|
|
||||||
rcArea.left = (mi.rcMonitor.right + mi.rcMonitor.left - static_cast<long>(pThis->m_pImage->GetWidth())) / 2;
|
rcArea.left = (mi.rcMonitor.right + mi.rcMonitor.left - static_cast<long>(pThis->m_pImage->GetWidth())) / 2;
|
||||||
rcArea.top = (mi.rcMonitor.top + mi.rcMonitor.bottom - static_cast<long>(pThis->m_pImage->GetHeight())) / 2;
|
rcArea.top = (mi.rcMonitor.top + mi.rcMonitor.bottom - static_cast<long>(pThis->m_pImage->GetHeight())) / 2;
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
{
|
|
||||||
SystemParametersInfo(SPI_GETWORKAREA, NULL, &rcArea, NULL);
|
SystemParametersInfo(SPI_GETWORKAREA, NULL, &rcArea, NULL);
|
||||||
rcArea.left = (rcArea.right + rcArea.left - pThis->m_pImage->GetWidth()) / 2;
|
rcArea.left = (rcArea.right + rcArea.left - pThis->m_pImage->GetWidth()) / 2;
|
||||||
rcArea.top = (rcArea.top + rcArea.bottom - pThis->m_pImage->GetHeight()) / 2;
|
rcArea.top = (rcArea.top + rcArea.bottom - pThis->m_pImage->GetHeight()) / 2;
|
||||||
@@ -141,8 +133,7 @@ unsigned int __stdcall CSplashWnd::SplashThreadProc(void* lpParameter)
|
|||||||
wndcls.hInstance,
|
wndcls.hInstance,
|
||||||
NULL);
|
NULL);
|
||||||
|
|
||||||
if (!pThis->m_hSplashWnd)
|
if (!pThis->m_hSplashWnd) {
|
||||||
{
|
|
||||||
OutputDebugString(L"Unable to create SplashWnd\n");
|
OutputDebugString(L"Unable to create SplashWnd\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -159,16 +150,13 @@ unsigned int __stdcall CSplashWnd::SplashThreadProc(void* lpParameter)
|
|||||||
PeekMessage(&msg, NULL, 0, 0, 0); // invoke creating message queue
|
PeekMessage(&msg, NULL, 0, 0, 0); // invoke creating message queue
|
||||||
SetEvent(pThis->m_hEvent);
|
SetEvent(pThis->m_hEvent);
|
||||||
|
|
||||||
while ((bRet = GetMessage(&msg, NULL, 0, 0)) != 0)
|
while ((bRet = GetMessage(&msg, NULL, 0, 0)) != 0) {
|
||||||
{
|
|
||||||
if (msg.message == WM_QUIT) break;
|
if (msg.message == WM_QUIT) break;
|
||||||
|
|
||||||
if (bRet == -1)
|
if (bRet == -1) {
|
||||||
{
|
|
||||||
// handle the error and possibly exit
|
// handle the error and possibly exit
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
{
|
|
||||||
TranslateMessage(&msg);
|
TranslateMessage(&msg);
|
||||||
DispatchMessage(&msg);
|
DispatchMessage(&msg);
|
||||||
}
|
}
|
||||||
@@ -181,24 +169,19 @@ unsigned int __stdcall CSplashWnd::SplashThreadProc(void* lpParameter)
|
|||||||
LRESULT CALLBACK CSplashWnd::SplashWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
LRESULT CALLBACK CSplashWnd::SplashWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
||||||
{
|
{
|
||||||
CSplashWnd* pInstance = reinterpret_cast<CSplashWnd*>(GetWindowLongPtr(hwnd, GWL_USERDATA));
|
CSplashWnd* pInstance = reinterpret_cast<CSplashWnd*>(GetWindowLongPtr(hwnd, GWL_USERDATA));
|
||||||
if (pInstance == NULL)
|
if (pInstance == NULL) {
|
||||||
{
|
|
||||||
return DefWindowProc(hwnd, uMsg, wParam, lParam);
|
return DefWindowProc(hwnd, uMsg, wParam, lParam);
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (uMsg)
|
switch (uMsg) {
|
||||||
{
|
|
||||||
|
|
||||||
case WM_PAINT:
|
case WM_PAINT:
|
||||||
{
|
{
|
||||||
if (pInstance->m_pImage)
|
if (pInstance->m_pImage) {
|
||||||
{
|
if (pInstance->m_pImage->IsAnimatedGIF()) {
|
||||||
if (pInstance->m_pImage->IsAnimatedGIF())
|
|
||||||
{
|
|
||||||
// do nothing, the gif will be drawn by it's own thread.
|
// do nothing, the gif will be drawn by it's own thread.
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
{
|
|
||||||
Gdiplus::Graphics gdip(hwnd);
|
Gdiplus::Graphics gdip(hwnd);
|
||||||
gdip.DrawImage(pInstance->m_pImage, 0, 0, pInstance->m_pImage->GetWidth(), pInstance->m_pImage->GetHeight());
|
gdip.DrawImage(pInstance->m_pImage, 0, 0, pInstance->m_pImage->GetWidth(), pInstance->m_pImage->GetHeight());
|
||||||
}
|
}
|
||||||
@@ -216,8 +199,7 @@ LRESULT CALLBACK CSplashWnd::SplashWndProc(HWND hwnd, UINT uMsg, WPARAM wParam,
|
|||||||
|
|
||||||
case WM_MOUSEMOVE:
|
case WM_MOUSEMOVE:
|
||||||
{
|
{
|
||||||
if (GetCapture() == hwnd)
|
if (GetCapture() == hwnd) {
|
||||||
{
|
|
||||||
RECT rcWnd;
|
RECT rcWnd;
|
||||||
GetWindowRect(hwnd, &rcWnd);
|
GetWindowRect(hwnd, &rcWnd);
|
||||||
|
|
||||||
|
|||||||
@@ -36,7 +36,6 @@ public:
|
|||||||
CSplashWnd(HWND hParent = NULL);
|
CSplashWnd(HWND hParent = NULL);
|
||||||
~CSplashWnd();
|
~CSplashWnd();
|
||||||
void SetImage(const wchar_t* resid, const wchar_t* restype);
|
void SetImage(const wchar_t* resid, const wchar_t* restype);
|
||||||
void SetWindowName(const wchar_t* windowName);
|
|
||||||
void Show();
|
void Show();
|
||||||
void Hide();
|
void Hide();
|
||||||
|
|
||||||
|
|||||||
@@ -15,7 +15,8 @@ void CUpdateRunner::DisplayErrorMessage(CString& errorMessage, wchar_t* logFile)
|
|||||||
// TODO: Something about contacting support?
|
// TODO: Something about contacting support?
|
||||||
if (logFile == NULL) {
|
if (logFile == NULL) {
|
||||||
dlg.SetButtons(&buttons[1], 1, 1);
|
dlg.SetButtons(&buttons[1], 1, 1);
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
dlg.SetButtons(buttons, 2, 1);
|
dlg.SetButtons(buttons, 2, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -62,7 +63,7 @@ out:
|
|||||||
return hr;
|
return hr;
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT FindDesktopFolderView(REFIID riid, void **ppv)
|
HRESULT FindDesktopFolderView(REFIID riid, void** ppv)
|
||||||
{
|
{
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
|
|
||||||
@@ -93,7 +94,7 @@ HRESULT FindDesktopFolderView(REFIID riid, void **ppv)
|
|||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT GetDesktopAutomationObject(REFIID riid, void **ppv)
|
HRESULT GetDesktopAutomationObject(REFIID riid, void** ppv)
|
||||||
{
|
{
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
|
|
||||||
@@ -136,7 +137,7 @@ bool CUpdateRunner::DirectoryExists(wchar_t* szPath)
|
|||||||
(dwAttrib & FILE_ATTRIBUTE_DIRECTORY));
|
(dwAttrib & FILE_ATTRIBUTE_DIRECTORY));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CUpdateRunner::DirectoryIsWritable(wchar_t * szPath)
|
bool CUpdateRunner::DirectoryIsWritable(wchar_t* szPath)
|
||||||
{
|
{
|
||||||
wchar_t szTempFileName[MAX_PATH];
|
wchar_t szTempFileName[MAX_PATH];
|
||||||
UINT uRetVal = GetTempFileNameW(szPath, L"Squirrel", 0, szTempFileName);
|
UINT uRetVal = GetTempFileNameW(szPath, L"Squirrel", 0, szTempFileName);
|
||||||
@@ -287,7 +288,7 @@ gotADir:
|
|||||||
|
|
||||||
CloseHandle(pi.hProcess);
|
CloseHandle(pi.hProcess);
|
||||||
CloseHandle(pi.hThread);
|
CloseHandle(pi.hThread);
|
||||||
return (int) dwExitCode;
|
return (int)dwExitCode;
|
||||||
|
|
||||||
failedExtract:
|
failedExtract:
|
||||||
if (!useFallbackDir) {
|
if (!useFallbackDir) {
|
||||||
@@ -297,5 +298,5 @@ failedExtract:
|
|||||||
|
|
||||||
callback();
|
callback();
|
||||||
DisplayErrorMessage(CString(L"Failed to extract installer"), NULL);
|
DisplayErrorMessage(CString(L"Failed to extract installer"), NULL);
|
||||||
return (int) dwExitCode;
|
return (int)dwExitCode;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,4 +11,5 @@ public:
|
|||||||
static bool DirectoryExists(wchar_t* szPath);
|
static bool DirectoryExists(wchar_t* szPath);
|
||||||
static bool DirectoryIsWritable(wchar_t* szPath);
|
static bool DirectoryIsWritable(wchar_t* szPath);
|
||||||
static int ExtractUpdaterAndRun(wchar_t* lpCommandLine, bool useFallbackDir, std::function<void()>& callback);
|
static int ExtractUpdaterAndRun(wchar_t* lpCommandLine, bool useFallbackDir, std::function<void()>& callback);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|||||||
2103
src/Setup/unzip.cpp
2103
src/Setup/unzip.cpp
File diff suppressed because it is too large
Load Diff
@@ -18,18 +18,19 @@ typedef DWORD ZRESULT;
|
|||||||
// return codes from any of the zip functions. Listed later.
|
// return codes from any of the zip functions. Listed later.
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{ int index; // index of this file within the zip
|
{
|
||||||
|
int index; // index of this file within the zip
|
||||||
TCHAR name[MAX_PATH]; // filename within the zip
|
TCHAR name[MAX_PATH]; // filename within the zip
|
||||||
DWORD attr; // attributes, as in GetFileAttributes.
|
DWORD attr; // attributes, as in GetFileAttributes.
|
||||||
FILETIME atime,ctime,mtime;// access, create, modify filetimes
|
FILETIME atime, ctime, mtime;// access, create, modify filetimes
|
||||||
long comp_size; // sizes of item, compressed and uncompressed. These
|
long comp_size; // sizes of item, compressed and uncompressed. These
|
||||||
long unc_size; // may be -1 if not yet known (e.g. being streamed in)
|
long unc_size; // may be -1 if not yet known (e.g. being streamed in)
|
||||||
} ZIPENTRY;
|
} ZIPENTRY;
|
||||||
|
|
||||||
|
|
||||||
HZIP OpenZip(const TCHAR *fn, const char *password);
|
HZIP OpenZip(const TCHAR* fn, const char* password);
|
||||||
HZIP OpenZip(void *z,unsigned int len, const char *password);
|
HZIP OpenZip(void* z, unsigned int len, const char* password);
|
||||||
HZIP OpenZipHandle(HANDLE h, const char *password);
|
HZIP OpenZipHandle(HANDLE h, const char* password);
|
||||||
// OpenZip - opens a zip file and returns a handle with which you can
|
// OpenZip - opens a zip file and returns a handle with which you can
|
||||||
// subsequently examine its contents. You can open a zip file from:
|
// subsequently examine its contents. You can open a zip file from:
|
||||||
// from a pipe: OpenZipHandle(hpipe_read,0);
|
// from a pipe: OpenZipHandle(hpipe_read,0);
|
||||||
@@ -46,7 +47,7 @@ HZIP OpenZipHandle(HANDLE h, const char *password);
|
|||||||
// but for real windows, the zip makes its own copy of your handle, so you
|
// but for real windows, the zip makes its own copy of your handle, so you
|
||||||
// can close yours anytime.
|
// can close yours anytime.
|
||||||
|
|
||||||
ZRESULT GetZipItem(HZIP hz, int index, ZIPENTRY *ze);
|
ZRESULT GetZipItem(HZIP hz, int index, ZIPENTRY* ze);
|
||||||
// GetZipItem - call this to get information about an item in the zip.
|
// GetZipItem - call this to get information about an item in the zip.
|
||||||
// If index is -1 and the file wasn't opened through a pipe,
|
// If index is -1 and the file wasn't opened through a pipe,
|
||||||
// then it returns information about the whole zipfile
|
// then it returns information about the whole zipfile
|
||||||
@@ -61,14 +62,14 @@ ZRESULT GetZipItem(HZIP hz, int index, ZIPENTRY *ze);
|
|||||||
// then then comp_size and sometimes unc_size as well may not be known until
|
// then then comp_size and sometimes unc_size as well may not be known until
|
||||||
// after the item has been unzipped.
|
// after the item has been unzipped.
|
||||||
|
|
||||||
ZRESULT FindZipItem(HZIP hz, const TCHAR *name, bool ic, int *index, ZIPENTRY *ze);
|
ZRESULT FindZipItem(HZIP hz, const TCHAR* name, bool ic, int* index, ZIPENTRY* ze);
|
||||||
// FindZipItem - finds an item by name. ic means 'insensitive to case'.
|
// FindZipItem - finds an item by name. ic means 'insensitive to case'.
|
||||||
// It returns the index of the item, and returns information about it.
|
// It returns the index of the item, and returns information about it.
|
||||||
// If nothing was found, then index is set to -1 and the function returns
|
// If nothing was found, then index is set to -1 and the function returns
|
||||||
// an error code.
|
// an error code.
|
||||||
|
|
||||||
ZRESULT UnzipItem(HZIP hz, int index, const TCHAR *fn);
|
ZRESULT UnzipItem(HZIP hz, int index, const TCHAR* fn);
|
||||||
ZRESULT UnzipItem(HZIP hz, int index, void *z,unsigned int len);
|
ZRESULT UnzipItem(HZIP hz, int index, void* z, unsigned int len);
|
||||||
ZRESULT UnzipItemHandle(HZIP hz, int index, HANDLE h);
|
ZRESULT UnzipItemHandle(HZIP hz, int index, HANDLE h);
|
||||||
// UnzipItem - given an index to an item, unzips it. You can unzip to:
|
// UnzipItem - given an index to an item, unzips it. You can unzip to:
|
||||||
// to a pipe: UnzipItemHandle(hz,i, hpipe_write);
|
// to a pipe: UnzipItemHandle(hz,i, hpipe_write);
|
||||||
@@ -85,7 +86,7 @@ ZRESULT UnzipItemHandle(HZIP hz, int index, HANDLE h);
|
|||||||
// If you unzip a directory with ZIP_FILENAME, then the directory gets created.
|
// If you unzip a directory with ZIP_FILENAME, then the directory gets created.
|
||||||
// If you unzip it to a handle or a memory block, then nothing gets created
|
// If you unzip it to a handle or a memory block, then nothing gets created
|
||||||
// and it emits 0 bytes.
|
// and it emits 0 bytes.
|
||||||
ZRESULT SetUnzipBaseDir(HZIP hz, const TCHAR *dir);
|
ZRESULT SetUnzipBaseDir(HZIP hz, const TCHAR* dir);
|
||||||
// if unzipping to a filename, and it's a relative filename, then it will be relative to here.
|
// if unzipping to a filename, and it's a relative filename, then it will be relative to here.
|
||||||
// (defaults to current-directory).
|
// (defaults to current-directory).
|
||||||
|
|
||||||
@@ -93,7 +94,7 @@ ZRESULT SetUnzipBaseDir(HZIP hz, const TCHAR *dir);
|
|||||||
ZRESULT CloseZip(HZIP hz);
|
ZRESULT CloseZip(HZIP hz);
|
||||||
// CloseZip - the zip handle must be closed with this function.
|
// CloseZip - the zip handle must be closed with this function.
|
||||||
|
|
||||||
unsigned int FormatZipMessage(ZRESULT code, TCHAR *buf,unsigned int len);
|
unsigned int FormatZipMessage(ZRESULT code, TCHAR* buf, unsigned int len);
|
||||||
// FormatZipMessage - given an error code, formats it as a string.
|
// FormatZipMessage - given an error code, formats it as a string.
|
||||||
// It returns the length of the error message. If buf/len points
|
// It returns the length of the error message. If buf/len points
|
||||||
// to a real buffer, then it also writes as much as possible into there.
|
// to a real buffer, then it also writes as much as possible into there.
|
||||||
@@ -199,7 +200,7 @@ unsigned int FormatZipMessage(ZRESULT code, TCHAR *buf,unsigned int len);
|
|||||||
// one or the other of them based on a dynamic choice. If the header file
|
// one or the other of them based on a dynamic choice. If the header file
|
||||||
// for only one is present, then we will bind to that particular one.
|
// for only one is present, then we will bind to that particular one.
|
||||||
ZRESULT CloseZipU(HZIP hz);
|
ZRESULT CloseZipU(HZIP hz);
|
||||||
unsigned int FormatZipMessageU(ZRESULT code, TCHAR *buf,unsigned int len);
|
unsigned int FormatZipMessageU(ZRESULT code, TCHAR* buf, unsigned int len);
|
||||||
bool IsZipHandleU(HZIP hz);
|
bool IsZipHandleU(HZIP hz);
|
||||||
#ifdef _zip_H
|
#ifdef _zip_H
|
||||||
#undef CloseZip
|
#undef CloseZip
|
||||||
|
|||||||
@@ -61,15 +61,13 @@ int APIENTRY wWinMain(
|
|||||||
|
|
||||||
// see if the requested framework(s) are supported and exit.
|
// see if the requested framework(s) are supported and exit.
|
||||||
int chkFrameworkIdx = cmdLine.Find(L"--checkFramework");
|
int chkFrameworkIdx = cmdLine.Find(L"--checkFramework");
|
||||||
if (chkFrameworkIdx >= 0) {
|
if (chkFrameworkIdx >= 0)
|
||||||
return VerifyRuntimeString(std::wstring(cmdLine).substr(chkFrameworkIdx + 17));
|
return VerifyRuntimeString(std::wstring(cmdLine).substr(chkFrameworkIdx + 17));
|
||||||
}
|
|
||||||
|
|
||||||
if (cmdLine.Find(L"--checkInstall") >= 0) {
|
if (cmdLine.Find(L"--checkInstall") >= 0) {
|
||||||
// If we're already installed, exit as fast as possible
|
// If we're already installed, exit as fast as possible
|
||||||
if (!MachineInstaller::ShouldSilentInstall()) {
|
if (!MachineInstaller::ShouldSilentInstall())
|
||||||
return 0;
|
return 0;
|
||||||
}
|
|
||||||
|
|
||||||
// Make sure update.exe gets silent
|
// Make sure update.exe gets silent
|
||||||
wcscat(lpCmdLine, L" --silent");
|
wcscat(lpCmdLine, L" --silent");
|
||||||
@@ -107,10 +105,8 @@ int APIENTRY wWinMain(
|
|||||||
bool rebootRequired = false;
|
bool rebootRequired = false;
|
||||||
|
|
||||||
// check all required runtimes against the current operating system version
|
// check all required runtimes against the current operating system version
|
||||||
for (auto rt : runtimes)
|
for (auto rt : runtimes) {
|
||||||
{
|
if (!IsRuntimeSupported(rt)) {
|
||||||
if (!IsRuntimeSupported(rt))
|
|
||||||
{
|
|
||||||
// Explain this as nicely as possible and give up.
|
// Explain this as nicely as possible and give up.
|
||||||
MessageBox(0L, L"This program cannot run on this computer; it requires a later version of Windows.", L"Incompatible Operating System", 0);
|
MessageBox(0L, L"This program cannot run on this computer; it requires a later version of Windows.", L"Incompatible Operating System", 0);
|
||||||
exitCode = E_FAIL;
|
exitCode = E_FAIL;
|
||||||
@@ -119,25 +115,20 @@ int APIENTRY wWinMain(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// install any missing runtimes
|
// install any missing runtimes
|
||||||
for (auto rt : runtimes)
|
for (auto rt : runtimes) {
|
||||||
{
|
if (!IsRuntimeInstalled(rt)) {
|
||||||
if (!IsRuntimeInstalled(rt))
|
|
||||||
{
|
|
||||||
HRESULT hr = CFxHelper::InstallDotnet(rt, isQuiet);
|
HRESULT hr = CFxHelper::InstallDotnet(rt, isQuiet);
|
||||||
if (hr == ERROR_SUCCESS_REBOOT_REQUIRED)
|
if (hr == ERROR_SUCCESS_REBOOT_REQUIRED) {
|
||||||
{
|
|
||||||
// we will reboot after installing all required runtimes.
|
// we will reboot after installing all required runtimes.
|
||||||
rebootRequired = true;
|
rebootRequired = true;
|
||||||
}
|
}
|
||||||
else if (FAILED(hr))
|
else if (FAILED(hr)) {
|
||||||
{
|
|
||||||
exitCode = hr; // #yolo
|
exitCode = hr; // #yolo
|
||||||
CUpdateRunner::DisplayErrorMessage(CString(L"Failed to install .NET, you can try installing it manually."), NULL);
|
CUpdateRunner::DisplayErrorMessage(CString(L"Failed to install .NET, you can try installing it manually."), NULL);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
// S_FALSE isn't failure, but we still shouldn't try to install
|
// S_FALSE isn't failure, but we still shouldn't try to install
|
||||||
else if (hr != S_OK)
|
else if (hr != S_OK) {
|
||||||
{
|
|
||||||
exitCode = 0;
|
exitCode = 0;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
@@ -145,8 +136,7 @@ int APIENTRY wWinMain(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// if any runtimes indicated a reboot is required, let's do that now
|
// if any runtimes indicated a reboot is required, let's do that now
|
||||||
if (rebootRequired)
|
if (rebootRequired) {
|
||||||
{
|
|
||||||
exitCode = CFxHelper::HandleRebootRequirement(isQuiet);
|
exitCode = CFxHelper::HandleRebootRequirement(isQuiet);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,12 +31,15 @@ SOFTWARE.
|
|||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
namespace version {
|
namespace version
|
||||||
|
{
|
||||||
|
|
||||||
namespace {
|
namespace
|
||||||
|
{
|
||||||
|
|
||||||
// Compare normal version identifiers.
|
// Compare normal version identifiers.
|
||||||
int compare_normal(const Version_data& l, const Version_data& r) {
|
int compare_normal(const Version_data& l, const Version_data& r)
|
||||||
|
{
|
||||||
if (l.major > r.major) return 1;
|
if (l.major > r.major) return 1;
|
||||||
if (l.major < r.major) return -1;
|
if (l.major < r.major) return -1;
|
||||||
if (l.minor > r.minor) return 1;
|
if (l.minor > r.minor) return 1;
|
||||||
@@ -47,17 +50,20 @@ namespace version {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Compare alphanumeric prerelease identifiers.
|
// Compare alphanumeric prerelease identifiers.
|
||||||
inline int cmp_alnum_prerel_ids(const string& l, const string& r) {
|
inline int cmp_alnum_prerel_ids(const string& l, const string& r)
|
||||||
|
{
|
||||||
auto cmp = l.compare(r);
|
auto cmp = l.compare(r);
|
||||||
if (cmp == 0) {
|
if (cmp == 0) {
|
||||||
return cmp;
|
return cmp;
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
return cmp > 0 ? 1 : -1;
|
return cmp > 0 ? 1 : -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Compare numeric prerelease identifiers.
|
// Compare numeric prerelease identifiers.
|
||||||
inline int cmp_num_prerel_ids(const string& l, const string& r) {
|
inline int cmp_num_prerel_ids(const string& l, const string& r)
|
||||||
|
{
|
||||||
long long li = stoll(l);
|
long long li = stoll(l);
|
||||||
long long ri = stoll(r);
|
long long ri = stoll(r);
|
||||||
if (li == ri) return 0;
|
if (li == ri) return 0;
|
||||||
@@ -74,19 +80,22 @@ namespace version {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Compare prerelease identifiers based on their types.
|
// Compare prerelease identifiers based on their types.
|
||||||
inline int compare_prerel_identifiers(const Prerelease_identifier& l, const Prerelease_identifier& r) {
|
inline int compare_prerel_identifiers(const Prerelease_identifier& l, const Prerelease_identifier& r)
|
||||||
|
{
|
||||||
auto cmp = comparators.at({ l.second, r.second });
|
auto cmp = comparators.at({ l.second, r.second });
|
||||||
return cmp(l.first, r.first);
|
return cmp(l.first, r.first);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline int cmp_rel_prerel(const Prerelease_identifiers& l, const Prerelease_identifiers& r) {
|
inline int cmp_rel_prerel(const Prerelease_identifiers& l, const Prerelease_identifiers& r)
|
||||||
|
{
|
||||||
if (l.empty() && !r.empty()) return 1;
|
if (l.empty() && !r.empty()) return 1;
|
||||||
if (r.empty() && !l.empty()) return -1;
|
if (r.empty() && !l.empty()) return -1;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int Semver200_comparator::compare(const Version_data& l, const Version_data& r) const {
|
int Semver200_comparator::compare(const Version_data& l, const Version_data& r) const
|
||||||
|
{
|
||||||
// Compare normal version components.
|
// Compare normal version components.
|
||||||
int cmp = compare_normal(l, r);
|
int cmp = compare_normal(l, r);
|
||||||
if (cmp != 0) return cmp;
|
if (cmp != 0) return cmp;
|
||||||
|
|||||||
@@ -35,10 +35,13 @@ SOFTWARE.
|
|||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
namespace version {
|
namespace version
|
||||||
|
{
|
||||||
|
|
||||||
namespace {
|
namespace
|
||||||
enum class Parser_state {
|
{
|
||||||
|
enum class Parser_state
|
||||||
|
{
|
||||||
major, minor, patch, prerelease, build
|
major, minor, patch, prerelease, build
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -56,7 +59,8 @@ namespace version {
|
|||||||
{ '0', '9' },{ 'A','Z' },{ 'a','z' },{ '-','-' }
|
{ '0', '9' },{ 'A','Z' },{ 'a','z' },{ '-','-' }
|
||||||
};
|
};
|
||||||
|
|
||||||
inline Transition mkx(const char c, Parser_state p, State_transition_hook pth) {
|
inline Transition mkx(const char c, Parser_state p, State_transition_hook pth)
|
||||||
|
{
|
||||||
return make_tuple(c, p, pth);
|
return make_tuple(c, p, pth);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -69,7 +73,8 @@ namespace version {
|
|||||||
where whole tokens are validated.
|
where whole tokens are validated.
|
||||||
*/
|
*/
|
||||||
inline void process_char(const char c, Parser_state& cstate, Parser_state& pstate,
|
inline void process_char(const char c, Parser_state& cstate, Parser_state& pstate,
|
||||||
const Transitions& transitions, string& target, Validator validate) {
|
const Transitions& transitions, string& target, Validator validate)
|
||||||
|
{
|
||||||
for (const auto& transition : transitions) {
|
for (const auto& transition : transitions) {
|
||||||
if (c == get<0>(transition)) {
|
if (c == get<0>(transition)) {
|
||||||
if (get<2>(transition)) get<2>(transition)(target);
|
if (get<2>(transition)) get<2>(transition)(target);
|
||||||
@@ -83,13 +88,15 @@ namespace version {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Validate normal (major, minor, patch) version components.
|
/// Validate normal (major, minor, patch) version components.
|
||||||
inline void normal_version_validator(const string& tgt, const char c) {
|
inline void normal_version_validator(const string& tgt, const char c)
|
||||||
|
{
|
||||||
if (c < '0' || c > '9') throw Parse_error("invalid character encountered: " + string(1, c));
|
if (c < '0' || c > '9') throw Parse_error("invalid character encountered: " + string(1, c));
|
||||||
if (tgt.compare(0, 1, "0") == 0) throw Parse_error("leading 0 not allowed");
|
if (tgt.compare(0, 1, "0") == 0) throw Parse_error("leading 0 not allowed");
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Validate that prerelease and build version identifiers are comprised of allowed chars only.
|
/// Validate that prerelease and build version identifiers are comprised of allowed chars only.
|
||||||
inline void prerelease_version_validator(const string&, const char c) {
|
inline void prerelease_version_validator(const string&, const char c)
|
||||||
|
{
|
||||||
bool res = false;
|
bool res = false;
|
||||||
for (const auto& r : allowed_prerel_id_chars) {
|
for (const auto& r : allowed_prerel_id_chars) {
|
||||||
res |= (c >= r.first && c <= r.second);
|
res |= (c >= r.first && c <= r.second);
|
||||||
@@ -98,16 +105,19 @@ namespace version {
|
|||||||
throw Parse_error("invalid character encountered: " + string(1, c));
|
throw Parse_error("invalid character encountered: " + string(1, c));
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool is_identifier_numeric(const string& id) {
|
inline bool is_identifier_numeric(const string& id)
|
||||||
|
{
|
||||||
return id.find_first_not_of("0123456789") == string::npos;
|
return id.find_first_not_of("0123456789") == string::npos;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool check_for_leading_0(const string& str) {
|
inline bool check_for_leading_0(const string& str)
|
||||||
|
{
|
||||||
return str.length() > 1 && str[0] == '0';
|
return str.length() > 1 && str[0] == '0';
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Validate every individual prerelease identifier, determine it's type and add it to collection.
|
/// Validate every individual prerelease identifier, determine it's type and add it to collection.
|
||||||
void prerelease_hook_impl(string& id, Prerelease_identifiers& prerelease) {
|
void prerelease_hook_impl(string& id, Prerelease_identifiers& prerelease)
|
||||||
|
{
|
||||||
if (id.empty()) throw Parse_error("version identifier cannot be empty");
|
if (id.empty()) throw Parse_error("version identifier cannot be empty");
|
||||||
Id_type t = Id_type::alnum;
|
Id_type t = Id_type::alnum;
|
||||||
if (is_identifier_numeric(id)) {
|
if (is_identifier_numeric(id)) {
|
||||||
@@ -122,7 +132,8 @@ namespace version {
|
|||||||
|
|
||||||
/// Validate every individual build identifier and add it to collection.
|
/// Validate every individual build identifier and add it to collection.
|
||||||
void build_hook_impl(string& id, Parser_state& pstate, Build_identifiers& build,
|
void build_hook_impl(string& id, Parser_state& pstate, Build_identifiers& build,
|
||||||
std::string& prerelease_id, Prerelease_identifiers& prerelease) {
|
std::string& prerelease_id, Prerelease_identifiers& prerelease)
|
||||||
|
{
|
||||||
// process last token left from parsing prerelease data
|
// process last token left from parsing prerelease data
|
||||||
if (pstate == Parser_state::prerelease) prerelease_hook_impl(prerelease_id, prerelease);
|
if (pstate == Parser_state::prerelease) prerelease_hook_impl(prerelease_id, prerelease);
|
||||||
if (id.empty()) throw Parse_error("version identifier cannot be empty");
|
if (id.empty()) throw Parse_error("version identifier cannot be empty");
|
||||||
@@ -138,7 +149,8 @@ namespace version {
|
|||||||
string is consumed and is either added to current token or triggers state transition. Hooks can be
|
string is consumed and is either added to current token or triggers state transition. Hooks can be
|
||||||
injected into state transitions for validation/customization purposes.
|
injected into state transitions for validation/customization purposes.
|
||||||
*/
|
*/
|
||||||
Version_data Semver200_parser::parse(const string& s) const {
|
Version_data Semver200_parser::parse(const string& s) const
|
||||||
|
{
|
||||||
string major;
|
string major;
|
||||||
string minor;
|
string minor;
|
||||||
string patch;
|
string patch;
|
||||||
@@ -197,13 +209,15 @@ namespace version {
|
|||||||
// triggered for it.
|
// triggered for it.
|
||||||
if (cstate == Parser_state::prerelease) {
|
if (cstate == Parser_state::prerelease) {
|
||||||
prerelease_hook(prerelease_id);
|
prerelease_hook(prerelease_id);
|
||||||
} else if (cstate == Parser_state::build) {
|
}
|
||||||
|
else if (cstate == Parser_state::build) {
|
||||||
build_hook(build_id);
|
build_hook(build_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
return Version_data{ stoi(major), stoi(minor), stoi(patch), prerelease, build };
|
return Version_data{ stoi(major), stoi(minor), stoi(patch), prerelease, build };
|
||||||
} catch (invalid_argument& ex) {
|
}
|
||||||
|
catch (invalid_argument& ex) {
|
||||||
throw Parse_error(ex.what());
|
throw Parse_error(ex.what());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,26 +26,32 @@ SOFTWARE.
|
|||||||
|
|
||||||
#include "version.h"
|
#include "version.h"
|
||||||
|
|
||||||
namespace version {
|
namespace version
|
||||||
|
{
|
||||||
|
|
||||||
/// Parse string into Version_data structure according to semantic versioning 2.0.0 rules.
|
/// Parse string into Version_data structure according to semantic versioning 2.0.0 rules.
|
||||||
struct Semver200_parser {
|
struct Semver200_parser
|
||||||
|
{
|
||||||
Version_data parse(const std::string&) const;
|
Version_data parse(const std::string&) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Compare Version_data to another using semantic versioning 2.0.0 rules.
|
/// Compare Version_data to another using semantic versioning 2.0.0 rules.
|
||||||
struct Semver200_comparator {
|
struct Semver200_comparator
|
||||||
|
{
|
||||||
int compare(const Version_data&, const Version_data&) const;
|
int compare(const Version_data&, const Version_data&) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Concrete version class that binds all semver 2.0.0 functionality together.
|
/// Concrete version class that binds all semver 2.0.0 functionality together.
|
||||||
class Semver200_version : public Basic_version<Semver200_parser, Semver200_comparator> {
|
class Semver200_version : public Basic_version<Semver200_parser, Semver200_comparator>
|
||||||
|
{
|
||||||
public:
|
public:
|
||||||
Semver200_version()
|
Semver200_version()
|
||||||
: Basic_version{ Semver200_parser(), Semver200_comparator() } {}
|
: Basic_version{ Semver200_parser(), Semver200_comparator() }
|
||||||
|
{}
|
||||||
|
|
||||||
Semver200_version(const std::string& v)
|
Semver200_version(const std::string& v)
|
||||||
: Basic_version{ v, Semver200_parser(), Semver200_comparator() } {}
|
: Basic_version{ v, Semver200_parser(), Semver200_comparator() }
|
||||||
|
{}
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -28,10 +28,12 @@ SOFTWARE.
|
|||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
namespace version {
|
namespace version
|
||||||
|
{
|
||||||
|
|
||||||
/// Any error in parsing or validation of version string will result in Parse_error exception being thrown.
|
/// Any error in parsing or validation of version string will result in Parse_error exception being thrown.
|
||||||
class Parse_error : public std::runtime_error {
|
class Parse_error : public std::runtime_error
|
||||||
|
{
|
||||||
using std::runtime_error::runtime_error;
|
using std::runtime_error::runtime_error;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -40,7 +42,8 @@ namespace version {
|
|||||||
Type of identifier affects comparison: alphanumeric identifiers are compared as ASCII strings, while
|
Type of identifier affects comparison: alphanumeric identifiers are compared as ASCII strings, while
|
||||||
numeric identifiers are compared as numbers.
|
numeric identifiers are compared as numbers.
|
||||||
*/
|
*/
|
||||||
enum class Id_type {
|
enum class Id_type
|
||||||
|
{
|
||||||
alnum, ///< Identifier is alphanumerical
|
alnum, ///< Identifier is alphanumerical
|
||||||
num ///< Identifier is numeric
|
num ///< Identifier is numeric
|
||||||
};
|
};
|
||||||
@@ -63,7 +66,8 @@ namespace version {
|
|||||||
using Build_identifiers = std::vector<Build_identifier>;
|
using Build_identifiers = std::vector<Build_identifier>;
|
||||||
|
|
||||||
/// Description of version broken into parts, as per semantic versioning specification.
|
/// Description of version broken into parts, as per semantic versioning specification.
|
||||||
struct Version_data {
|
struct Version_data
|
||||||
|
{
|
||||||
int major; ///< Major version, change only on incompatible API modifications.
|
int major; ///< Major version, change only on incompatible API modifications.
|
||||||
int minor; ///< Minor version, change on backwards-compatible API modifications.
|
int minor; ///< Minor version, change on backwards-compatible API modifications.
|
||||||
int patch; ///< Patch version, change only on bugfixes.
|
int patch; ///< Patch version, change only on bugfixes.
|
||||||
@@ -122,7 +126,8 @@ namespace version {
|
|||||||
Comparator objects.
|
Comparator objects.
|
||||||
*/
|
*/
|
||||||
template<typename Parser, typename Comparator>
|
template<typename Parser, typename Comparator>
|
||||||
class Basic_version {
|
class Basic_version
|
||||||
|
{
|
||||||
public:
|
public:
|
||||||
/// Construct Basic_version object using Parser object to parse default ("0.0.0") version string and Comparator for comparison.
|
/// Construct Basic_version object using Parser object to parse default ("0.0.0") version string and Comparator for comparison.
|
||||||
Basic_version(Parser, Comparator);
|
Basic_version(Parser, Comparator);
|
||||||
@@ -144,7 +149,7 @@ namespace version {
|
|||||||
|
|
||||||
friend bool operator< <>(const Basic_version&, const Basic_version&);
|
friend bool operator< <>(const Basic_version&, const Basic_version&);
|
||||||
friend bool operator== <>(const Basic_version&, const Basic_version&);
|
friend bool operator== <>(const Basic_version&, const Basic_version&);
|
||||||
friend std::ostream& operator<< <>(std::ostream&s, const Basic_version&);
|
friend std::ostream& operator<< <>(std::ostream& s, const Basic_version&);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Parser parser_;
|
Parser parser_;
|
||||||
|
|||||||
@@ -124,7 +124,7 @@ int wmain(int argc, wchar_t* argv[])
|
|||||||
wprintf(L"Setup: %s, Zip: %s\n", setupFile.c_str(), zipFile.c_str());
|
wprintf(L"Setup: %s, Zip: %s\n", setupFile.c_str(), zipFile.c_str());
|
||||||
|
|
||||||
// Read the entire zip file into memory, yolo
|
// Read the entire zip file into memory, yolo
|
||||||
BYTE *pZipBuf, *pSplashBuf;
|
BYTE* pZipBuf, * pSplashBuf;
|
||||||
int cZipBuf, cSplashBuf;
|
int cZipBuf, cSplashBuf;
|
||||||
|
|
||||||
if (FAILED(LoadFileIntoMemory(zipFile, &pZipBuf, &cZipBuf))) {
|
if (FAILED(LoadFileIntoMemory(zipFile, &pZipBuf, &cZipBuf))) {
|
||||||
|
|||||||
@@ -11,8 +11,10 @@
|
|||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
namespace flags {
|
namespace flags
|
||||||
namespace detail {
|
{
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
using argument_map =
|
using argument_map =
|
||||||
std::unordered_map<std::wstring_view, std::optional<std::wstring_view>>;
|
std::unordered_map<std::wstring_view, std::optional<std::wstring_view>>;
|
||||||
|
|
||||||
@@ -21,8 +23,10 @@ namespace flags {
|
|||||||
// * If the token does not begin with a -, it will be considered a value for the
|
// * If the token does not begin with a -, it will be considered a value for the
|
||||||
// previous option. If there was no previous option, it will be considered a
|
// previous option. If there was no previous option, it will be considered a
|
||||||
// positional argument.
|
// positional argument.
|
||||||
struct parser {
|
struct parser
|
||||||
parser(const int argc, wchar_t** argv) {
|
{
|
||||||
|
parser(const int argc, wchar_t** argv)
|
||||||
|
{
|
||||||
for (int i = 1; i < argc; ++i) {
|
for (int i = 1; i < argc; ++i) {
|
||||||
churn(argv[i]);
|
churn(argv[i]);
|
||||||
}
|
}
|
||||||
@@ -32,22 +36,26 @@ namespace flags {
|
|||||||
parser& operator=(const parser&) = delete;
|
parser& operator=(const parser&) = delete;
|
||||||
|
|
||||||
const argument_map& options() const { return options_; }
|
const argument_map& options() const { return options_; }
|
||||||
const std::vector<std::wstring_view>& positional_arguments() const {
|
const std::vector<std::wstring_view>& positional_arguments() const
|
||||||
|
{
|
||||||
return positional_arguments_;
|
return positional_arguments_;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Advance the state machine for the current token.
|
// Advance the state machine for the current token.
|
||||||
void churn(const std::wstring_view& item) {
|
void churn(const std::wstring_view& item)
|
||||||
|
{
|
||||||
item.at(0) == '-' ? on_option(item) : on_value(item);
|
item.at(0) == '-' ? on_option(item) : on_value(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Consumes the current option if there is one.
|
// Consumes the current option if there is one.
|
||||||
void flush() {
|
void flush()
|
||||||
|
{
|
||||||
if (current_option_) on_value();
|
if (current_option_) on_value();
|
||||||
}
|
}
|
||||||
|
|
||||||
void on_option(const std::wstring_view& option) {
|
void on_option(const std::wstring_view& option)
|
||||||
|
{
|
||||||
// Consume the current_option and reassign it to the new option while
|
// Consume the current_option and reassign it to the new option while
|
||||||
// removing all leading dashes.
|
// removing all leading dashes.
|
||||||
flush();
|
flush();
|
||||||
@@ -64,7 +72,8 @@ namespace flags {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void on_value(const std::optional<std::wstring_view>& value = std::nullopt) {
|
void on_value(const std::optional<std::wstring_view>& value = std::nullopt)
|
||||||
|
{
|
||||||
// If there's not an option preceding the value, it's a positional argument.
|
// If there's not an option preceding the value, it's a positional argument.
|
||||||
if (!current_option_) {
|
if (!current_option_) {
|
||||||
if (value) positional_arguments_.emplace_back(*value);
|
if (value) positional_arguments_.emplace_back(*value);
|
||||||
@@ -82,7 +91,8 @@ namespace flags {
|
|||||||
|
|
||||||
// If a key exists, return an optional populated with its value.
|
// If a key exists, return an optional populated with its value.
|
||||||
inline std::optional<std::wstring_view> get_value(
|
inline std::optional<std::wstring_view> get_value(
|
||||||
const argument_map& options, const std::wstring_view& option) {
|
const argument_map& options, const std::wstring_view& option)
|
||||||
|
{
|
||||||
if (const auto it = options.find(option); it != options.end()) {
|
if (const auto it = options.find(option); it != options.end()) {
|
||||||
return it->second;
|
return it->second;
|
||||||
}
|
}
|
||||||
@@ -94,7 +104,8 @@ namespace flags {
|
|||||||
// nullopt.
|
// nullopt.
|
||||||
template <class T>
|
template <class T>
|
||||||
std::optional<T> get(const argument_map& options,
|
std::optional<T> get(const argument_map& options,
|
||||||
const std::wstring_view& option) {
|
const std::wstring_view& option)
|
||||||
|
{
|
||||||
if (const auto view = get_value(options, option)) {
|
if (const auto view = get_value(options, option)) {
|
||||||
if (T value; std::istringstream(std::wstring(*view)) >> value) return value;
|
if (T value; std::istringstream(std::wstring(*view)) >> value) return value;
|
||||||
}
|
}
|
||||||
@@ -104,13 +115,15 @@ namespace flags {
|
|||||||
// Since the values are already stored as strings, there's no need to use `>>`.
|
// Since the values are already stored as strings, there's no need to use `>>`.
|
||||||
template <>
|
template <>
|
||||||
inline std::optional<std::wstring_view> get(const argument_map& options,
|
inline std::optional<std::wstring_view> get(const argument_map& options,
|
||||||
const std::wstring_view& option) {
|
const std::wstring_view& option)
|
||||||
|
{
|
||||||
return get_value(options, option);
|
return get_value(options, option);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
inline std::optional<std::wstring> get(const argument_map& options,
|
inline std::optional<std::wstring> get(const argument_map& options,
|
||||||
const std::wstring_view& option) {
|
const std::wstring_view& option)
|
||||||
|
{
|
||||||
if (const auto view = get<std::wstring_view>(options, option)) {
|
if (const auto view = get<std::wstring_view>(options, option)) {
|
||||||
return std::wstring(*view);
|
return std::wstring(*view);
|
||||||
}
|
}
|
||||||
@@ -123,7 +136,8 @@ namespace flags {
|
|||||||
constexpr std::array<const wchar_t*, 5> falsities{ {L"0", L"n", L"no", L"f", L"false"} };
|
constexpr std::array<const wchar_t*, 5> falsities{ {L"0", L"n", L"no", L"f", L"false"} };
|
||||||
template <>
|
template <>
|
||||||
inline std::optional<bool> get(const argument_map& options,
|
inline std::optional<bool> get(const argument_map& options,
|
||||||
const std::wstring_view& option) {
|
const std::wstring_view& option)
|
||||||
|
{
|
||||||
if (const auto value = get_value(options, option)) {
|
if (const auto value = get_value(options, option)) {
|
||||||
return std::none_of(falsities.begin(), falsities.end(),
|
return std::none_of(falsities.begin(), falsities.end(),
|
||||||
[&value](auto falsity) { return *value == falsity; });
|
[&value](auto falsity) { return *value == falsity; });
|
||||||
@@ -137,7 +151,8 @@ namespace flags {
|
|||||||
// nullopt.
|
// nullopt.
|
||||||
template <class T>
|
template <class T>
|
||||||
std::optional<T> get(const std::vector<std::wstring_view>& positional_arguments,
|
std::optional<T> get(const std::vector<std::wstring_view>& positional_arguments,
|
||||||
size_t positional_index) {
|
size_t positional_index)
|
||||||
|
{
|
||||||
if (positional_index < positional_arguments.size()) {
|
if (positional_index < positional_arguments.size()) {
|
||||||
if (T value; std::istringstream(
|
if (T value; std::istringstream(
|
||||||
std::wstring(positional_arguments[positional_index])) >>
|
std::wstring(positional_arguments[positional_index])) >>
|
||||||
@@ -151,7 +166,8 @@ namespace flags {
|
|||||||
template <>
|
template <>
|
||||||
inline std::optional<std::wstring_view> get(
|
inline std::optional<std::wstring_view> get(
|
||||||
const std::vector<std::wstring_view>& positional_arguments,
|
const std::vector<std::wstring_view>& positional_arguments,
|
||||||
size_t positional_index) {
|
size_t positional_index)
|
||||||
|
{
|
||||||
if (positional_index < positional_arguments.size()) {
|
if (positional_index < positional_arguments.size()) {
|
||||||
return positional_arguments[positional_index];
|
return positional_arguments[positional_index];
|
||||||
}
|
}
|
||||||
@@ -161,7 +177,8 @@ namespace flags {
|
|||||||
template <>
|
template <>
|
||||||
inline std::optional<std::wstring> get(
|
inline std::optional<std::wstring> get(
|
||||||
const std::vector<std::wstring_view>& positional_arguments,
|
const std::vector<std::wstring_view>& positional_arguments,
|
||||||
size_t positional_index) {
|
size_t positional_index)
|
||||||
|
{
|
||||||
if (positional_index < positional_arguments.size()) {
|
if (positional_index < positional_arguments.size()) {
|
||||||
return std::wstring(positional_arguments[positional_index]);
|
return std::wstring(positional_arguments[positional_index]);
|
||||||
}
|
}
|
||||||
@@ -169,30 +186,36 @@ namespace flags {
|
|||||||
}
|
}
|
||||||
} // namespace detail
|
} // namespace detail
|
||||||
|
|
||||||
struct args {
|
struct args
|
||||||
|
{
|
||||||
args(const int argc, wchar_t** argv) : parser_(argc, argv) {}
|
args(const int argc, wchar_t** argv) : parser_(argc, argv) {}
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
std::optional<T> get(const std::wstring_view& option) const {
|
std::optional<T> get(const std::wstring_view& option) const
|
||||||
|
{
|
||||||
return detail::get<T>(parser_.options(), option);
|
return detail::get<T>(parser_.options(), option);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
T get(const std::wstring_view& option, T&& default_value) const {
|
T get(const std::wstring_view& option, T&& default_value) const
|
||||||
|
{
|
||||||
return get<T>(option).value_or(default_value);
|
return get<T>(option).value_or(default_value);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
std::optional<T> get(size_t positional_index) const {
|
std::optional<T> get(size_t positional_index) const
|
||||||
|
{
|
||||||
return detail::get<T>(parser_.positional_arguments(), positional_index);
|
return detail::get<T>(parser_.positional_arguments(), positional_index);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
T get(size_t positional_index, T&& default_value) const {
|
T get(size_t positional_index, T&& default_value) const
|
||||||
|
{
|
||||||
return get<T>(positional_index).value_or(default_value);
|
return get<T>(positional_index).value_or(default_value);
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::vector<std::wstring_view>& positional() const {
|
const std::vector<std::wstring_view>& positional() const
|
||||||
|
{
|
||||||
return parser_.positional_arguments();
|
return parser_.positional_arguments();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user