From dfdb03a5431ca5a0c369cf3d9cbff41dde6a974e Mon Sep 17 00:00:00 2001 From: Sven Strickroth Date: Wed, 3 Aug 2016 14:22:37 +0200 Subject: [PATCH] Drop some magic numbers This improves commit fbe3dc89ead9076cb02119fa4ba6f11c81455cda. Signed-off-by: Sven Strickroth --- src/Git/Git.cpp | 18 ++++++------ src/Git/Git.h | 3 +- src/Git/GitIndex.cpp | 2 +- src/Git/GitRevRefBrowser.cpp | 5 ++-- src/Git/TGitPath.cpp | 4 +-- src/Git/gitindex.h | 5 ++-- src/TortoiseMerge/Patch.cpp | 25 +++++++++-------- src/TortoiseProc/AppUtils.cpp | 10 +++---- src/TortoiseProc/BisectStartDlg.cpp | 5 ++-- src/TortoiseProc/BrowseRefsDlg.cpp | 32 +++++++++++++--------- src/TortoiseProc/ChooseVersion.h | 9 +++--- src/TortoiseProc/Commands/CatCommand.cpp | 3 +- src/TortoiseProc/Commands/CloneCommand.cpp | 4 +-- src/TortoiseProc/Commands/DropCopyAddCommand.cpp | 2 +- src/TortoiseProc/FileDiffDlg.cpp | 2 +- src/TortoiseProc/FindDlg.cpp | 8 +++--- src/TortoiseProc/GitLogListAction.cpp | 6 ++-- src/TortoiseProc/GitLogListBase.cpp | 6 ++-- src/TortoiseProc/PushDlg.cpp | 8 +++--- src/TortoiseProc/RequestPullDlg.cpp | 3 +- .../RevisionGraph/RevGraphFilterDlg.cpp | 9 +++--- src/TortoiseProc/TortoiseProc.cpp | 6 ++-- src/TortoiseShell/GITPropertyPage.cpp | 3 +- src/Utils/StringUtils.cpp | 11 +++++++- src/Utils/StringUtils.h | 4 +++ test/UnitTests/StringUtilsTest.cpp | 21 ++++++++++++++ 26 files changed, 132 insertions(+), 82 deletions(-) diff --git a/src/Git/Git.cpp b/src/Git/Git.cpp index 54423d8a3..3bd87bec8 100644 --- a/src/Git/Git.cpp +++ b/src/Git/Git.cpp @@ -328,20 +328,20 @@ int CGit::RunAsync(CString cmd, PROCESS_INFORMATION *piOut, HANDLE *hReadOut, HA memset(&this->m_CurrentGitPi,0,sizeof(PROCESS_INFORMATION)); - bool startsWithGit = wcsncmp(cmd, L"git", 3) == 0; - if (ms_bMsys2Git && startsWithGit && wcsncmp(cmd, L"git.exe config ", 15) != 0) + bool startsWithGit = CStringUtils::StartsWith(cmd, L"git"); + if (ms_bMsys2Git && startsWithGit && !CStringUtils::StartsWith(cmd, L"git.exe config ")) { cmd.Replace(_T("\\"), _T("\\\\\\\\")); cmd.Replace(_T("\""), _T("\\\"")); cmd = _T('"') + CGit::ms_LastMsysGitDir + _T("\\bash.exe\" -c \"/usr/bin/") + cmd + _T('"'); } - else if (ms_bCygwinGit && startsWithGit && wcsncmp(cmd, L"git.exe config ", 15) != 0) + else if (ms_bCygwinGit && startsWithGit && !CStringUtils::StartsWith(cmd, L"git.exe config ")) { cmd.Replace(_T('\\'), _T('/')); cmd.Replace(_T("\""), _T("\\\"")); cmd = _T('"') + CGit::ms_LastMsysGitDir + _T("\\bash.exe\" -c \"/bin/") + cmd + _T('"'); } - else if (startsWithGit || wcsncmp(cmd, L"bash", 4) == 0) + else if (startsWithGit || CStringUtils::StartsWith(cmd, L"bash")) { int firstSpace = cmd.Find(_T(" ")); if (firstSpace > 0) @@ -887,9 +887,9 @@ CString CGit::GetFullRefName(const CString& shortRefName) CString CGit::StripRefName(CString refName) { - if(wcsncmp(refName, L"refs/heads/", 11) == 0) + if (CStringUtils::StartsWith(refName, L"refs/heads/")) refName = refName.Mid(11); - else if(wcsncmp(refName, L"refs/", 5) == 0) + else if (CStringUtils::StartsWith(refName, L"refs/")) refName = refName.Mid(5); return refName.TrimRight(); } @@ -1202,7 +1202,7 @@ int CGit::RunLogFile(CString cmd, const CString &filename, CString *stdErr) LPTSTR pEnv = m_Environment; DWORD dwFlags = CREATE_UNICODE_ENVIRONMENT; - if (wcsncmp(cmd, L"git", 3) == 0) + if (CStringUtils::StartsWith(cmd, L"git")) { int firstSpace = cmd.Find(L' '); if (firstSpace > 0) @@ -2811,13 +2811,13 @@ CString CGit::GetShortName(const CString& ref, REF_TYPE *out_type) CString bisectBad; g_Git.GetBisectTerms(&bisectGood, &bisectBad); TCHAR c; - if (wcsncmp(shortname, bisectGood, bisectGood.GetLength()) == 0 && ((c = shortname.GetAt(bisectGood.GetLength())) == '-' || c == '\0')) + if (CStringUtils::StartsWith(shortname, bisectGood) && ((c = shortname.GetAt(bisectGood.GetLength())) == '-' || c == '\0')) { type = CGit::BISECT_GOOD; shortname = bisectGood; } - if (wcsncmp(shortname, bisectBad, bisectBad.GetLength()) == 0 && ((c = shortname.GetAt(bisectBad.GetLength())) == '-' || c == '\0')) + if (CStringUtils::StartsWith(shortname, bisectBad) && ((c = shortname.GetAt(bisectBad.GetLength())) == '-' || c == '\0')) { type = CGit::BISECT_BAD; shortname = bisectBad; diff --git a/src/Git/Git.h b/src/Git/Git.h index 6a7281734..1bf3c927a 100644 --- a/src/Git/Git.h +++ b/src/Git/Git.h @@ -24,6 +24,7 @@ #include "GitAdminDir.h" #include "gitdll.h" #include +#include "StringUtils.h" #define REG_MSYSGIT_PATH _T("Software\\TortoiseGit\\MSysGit") #define REG_SYSTEM_GITCONFIGPATH _T("Software\\TortoiseGit\\SystemConfig") @@ -460,7 +461,7 @@ public: static BOOL GetShortName(const CString& ref, CString& shortname, const CString& prefix) { //TRACE(_T("%s %s\r\n"),ref,prefix); - if (ref.Left(prefix.GetLength()) == prefix) + if (CStringUtils::StartsWith(ref, prefix)) { shortname = ref.Right(ref.GetLength() - prefix.GetLength()); if (shortname.Right(3) == _T("^{}")) diff --git a/src/Git/GitIndex.cpp b/src/Git/GitIndex.cpp index 357c4592e..f2f298fdd 100644 --- a/src/Git/GitIndex.cpp +++ b/src/Git/GitIndex.cpp @@ -1093,7 +1093,7 @@ bool CGitIgnoreList::CheckAndUpdateCoreExcludefile(const CString &adminDir) config.GetString(_T("core.excludesfile"), excludesFile); if (excludesFile.IsEmpty()) excludesFile = GetWindowsHome() + _T("\\.config\\git\\ignore"); - else if (wcsncmp(excludesFile, L"~/", 2) == 0) + else if (CStringUtils::StartsWith(excludesFile, L"~/")) excludesFile = GetWindowsHome() + excludesFile.Mid(1); CAutoWriteLock lockMap(m_SharedMutex); diff --git a/src/Git/GitRevRefBrowser.cpp b/src/Git/GitRevRefBrowser.cpp index abd013e5f..1a859a74b 100644 --- a/src/Git/GitRevRefBrowser.cpp +++ b/src/Git/GitRevRefBrowser.cpp @@ -1,7 +1,7 @@ // TortoiseGit - a Windows shell extension for easy version control -// Copyright (C) 2009-2015 - TortoiseGit +// Copyright (C) 2009-2016 - TortoiseGit // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License @@ -23,6 +23,7 @@ #include "gittype.h" #include "Git.h" #include "GitRevRefBrowser.h" +#include "StringUtils.h" GitRevRefBrowser::GitRevRefBrowser() : GitRev() { @@ -64,7 +65,7 @@ int GitRevRefBrowser::GetGitRevRefMap(MAP_REF_GITREVREFBROWSER& map, CString& er CString date = singleRef.Tokenize(L"\04", valuePos).Trim(); ref.m_AuthorDate = StrToInt(date); - if (wcsncmp(refName, L"refs/heads/", 11) == 0) + if (CStringUtils::StartsWith(refName, L"refs/heads/")) ref.m_Description = descriptions[refName.Mid(11)]; map.emplace(refName, ref); diff --git a/src/Git/TGitPath.cpp b/src/Git/TGitPath.cpp index 66055d800..d7468bc20 100644 --- a/src/Git/TGitPath.cpp +++ b/src/Git/TGitPath.cpp @@ -373,7 +373,7 @@ CTGitPath CTGitPath::GetSubPath(const CTGitPath &root) { CTGitPath path; - if (wcsncmp(GetWinPathString(), root.GetWinPathString(), root.GetWinPathString().GetLength()) == 0) + if (CStringUtils::StartsWith(GetWinPathString(), root.GetWinPathString())) { CString str=GetWinPathString(); path.SetFromWin(str.Right(str.GetLength()-root.GetWinPathString().GetLength()-1)); @@ -1134,7 +1134,7 @@ int CTGitPathList::FillBasedOnIndexFlags(unsigned short flag, unsigned short fla CString one = CUnicodeUtils::GetUnicode(e->path); - if (!(!list || (*list)[j].GetWinPathString().IsEmpty() || one == (*list)[j].GetGitPathString() || (PathIsDirectory(g_Git.CombinePath((*list)[j].GetWinPathString())) && wcsncmp(one, (*list)[j].GetGitPathString() + L"/", (*list)[j].GetGitPathString().GetLength() + 1) == 0))) + if (!(!list || (*list)[j].GetWinPathString().IsEmpty() || one == (*list)[j].GetGitPathString() || (PathIsDirectory(g_Git.CombinePath((*list)[j].GetWinPathString())) && CStringUtils::StartsWith(one, (*list)[j].GetGitPathString() + L'/')))) continue; //SetFromGit will clear all status diff --git a/src/Git/gitindex.h b/src/Git/gitindex.h index 609b8e922..876b18bd6 100644 --- a/src/Git/gitindex.h +++ b/src/Git/gitindex.h @@ -23,6 +23,7 @@ #include "UnicodeUtils.h" #include "ReaderWriterLock.h" #include "GitAdminDir.h" +#include "StringUtils.h" class CGitIndex { @@ -106,7 +107,7 @@ public: std::vector toRemove; for (auto it = this->cbegin(); it != this->cend(); ++it) { - if (wcsncmp((*it).first, thePath, thePath.GetLength()) == 0) + if (CStringUtils::StartsWith((*it).first, thePath)) toRemove.push_back((*it).first); } for (auto it = toRemove.cbegin(); it != toRemove.cend(); ++it) @@ -242,7 +243,7 @@ public: std::vector toRemove; for (auto it = this->cbegin(); it != this->cend(); ++it) { - if (wcsncmp((*it).first, thePath, thePath.GetLength()) == 0) + if (CStringUtils::StartsWith((*it).first, thePath)) toRemove.push_back((*it).first); } for (auto it = toRemove.cbegin(); it != toRemove.cend(); ++it) diff --git a/src/TortoiseMerge/Patch.cpp b/src/TortoiseMerge/Patch.cpp index fad27d3ea..cd295eb69 100644 --- a/src/TortoiseMerge/Patch.cpp +++ b/src/TortoiseMerge/Patch.cpp @@ -25,6 +25,7 @@ #include "TortoiseMerge.h" #include "GitAdminDir.h" #include "Patch.h" +#include "StringUtils.h" #ifdef _DEBUG #define new DEBUG_NEW @@ -83,7 +84,7 @@ BOOL CPatch::ParsePatchFile(CFileTextLines &PatchLines) case 0: { // diff - if (wcsncmp(sLine, L"diff ", 5) == 0) + if (CStringUtils::StartsWith(sLine, L"diff ")) { if (chunks) { @@ -103,7 +104,7 @@ BOOL CPatch::ParsePatchFile(CFileTextLines &PatchLines) case 1: { //index - if (wcsncmp(sLine, L"index", 5) == 0) + if (CStringUtils::StartsWith(sLine, L"index")) { int dotstart=sLine.Find(_T("..")); if(dotstart>=0 && chunks) @@ -115,7 +116,7 @@ BOOL CPatch::ParsePatchFile(CFileTextLines &PatchLines) } //--- - if (wcsncmp(sLine, L"--- ", 4) == 0) + if (CStringUtils::StartsWith(sLine, L"--- ")) { if (state == 0) { @@ -149,12 +150,12 @@ BOOL CPatch::ParsePatchFile(CFileTextLines &PatchLines) if (chunks->sFilePath.Find('\t')>=0) chunks->sFilePath = chunks->sFilePath.Left(chunks->sFilePath.Find('\t')); - if (wcsncmp(chunks->sFilePath, L"\"", 1) == 0 && chunks->sFilePath.ReverseFind(_T('"')) == chunks->sFilePath.GetLength() - 1) + if (CStringUtils::StartsWith(chunks->sFilePath, L"\"") && chunks->sFilePath.ReverseFind(_T('"')) == chunks->sFilePath.GetLength() - 1) chunks->sFilePath=chunks->sFilePath.Mid(1, chunks->sFilePath.GetLength() - 2); - if (wcsncmp(chunks->sFilePath, L"a/", 2) == 0) + if (CStringUtils::StartsWith(chunks->sFilePath, L"a/")) chunks->sFilePath=chunks->sFilePath.Mid(2); - if (wcsncmp(chunks->sFilePath, L"b/", 2) == 0) + if (CStringUtils::StartsWith(chunks->sFilePath, L"b/")) chunks->sFilePath=chunks->sFilePath.Mid(2); @@ -167,7 +168,7 @@ BOOL CPatch::ParsePatchFile(CFileTextLines &PatchLines) } if (state == 0) { - if (wcsncmp(sLine,L"@@", 2) == 0) + if (CStringUtils::StartsWith(sLine, L"@@")) { if (chunks) { @@ -184,7 +185,7 @@ BOOL CPatch::ParsePatchFile(CFileTextLines &PatchLines) case 3: { // +++ - if (wcsncmp(sLine, L"+++", 3) != 0) + if (!CStringUtils::StartsWith(sLine, L"+++")) { // no starting "+++" found m_sErrorMessage.Format(IDS_ERR_PATCH_NOADDFILELINE, nIndex); @@ -205,12 +206,12 @@ BOOL CPatch::ParsePatchFile(CFileTextLines &PatchLines) chunks->sFilePath2 = sLine.Left(bracket-1).Trim(); if (chunks->sFilePath2.Find('\t')>=0) chunks->sFilePath2 = chunks->sFilePath2.Left(chunks->sFilePath2.Find('\t')); - if (wcsncmp(chunks->sFilePath2, L"\"", 1) == 0 && chunks->sFilePath2.ReverseFind(_T('"')) == chunks->sFilePath2.GetLength() - 1) + if (CStringUtils::StartsWith(chunks->sFilePath2, L"\"") && chunks->sFilePath2.ReverseFind(_T('"')) == chunks->sFilePath2.GetLength() - 1) chunks->sFilePath2=chunks->sFilePath2.Mid(1, chunks->sFilePath2.GetLength() - 2); - if (wcsncmp(chunks->sFilePath2, L"a/", 2) == 0) + if (CStringUtils::StartsWith(chunks->sFilePath2, L"a/")) chunks->sFilePath2=chunks->sFilePath2.Mid(2); - if (wcsncmp(chunks->sFilePath2, L"b/", 2) == 0) + if (CStringUtils::StartsWith(chunks->sFilePath2, L"b/")) chunks->sFilePath2=chunks->sFilePath2.Mid(2); chunks->sFilePath2.Replace(_T('/'),_T('\\')); @@ -225,7 +226,7 @@ BOOL CPatch::ParsePatchFile(CFileTextLines &PatchLines) case 4: { //start of a new chunk - if (wcsncmp(sLine, L"@@", 2) != 0) + if (!CStringUtils::StartsWith(sLine, L"@@")) { //chunk doesn't start with "@@" //so there's garbage in between two file diffs diff --git a/src/TortoiseProc/AppUtils.cpp b/src/TortoiseProc/AppUtils.cpp index d8a4db1a8..55ff502d6 100644 --- a/src/TortoiseProc/AppUtils.cpp +++ b/src/TortoiseProc/AppUtils.cpp @@ -155,9 +155,9 @@ bool CAppUtils::StashApply(CString ref, bool showChanges /* true */) { CString cmd,out; cmd = _T("git.exe stash apply "); - if (wcsncmp(ref, L"refs/", 5) == 0) + if (CStringUtils::StartsWith(ref, L"refs/")) ref = ref.Mid(5); - if (wcsncmp(ref, L"stash{", 6) == 0) + if (CStringUtils::StartsWith(ref, L"stash{")) ref = _T("stash@") + ref.Mid(5); cmd += ref; @@ -901,7 +901,7 @@ namespace { return false; for (const CString& prefix : { L"http://", L"https://", L"git://", L"ftp://", L"file://", L"mailto:" }) { - if (wcsncmp(sText, prefix, prefix.GetLength()) == 0 && sText.GetLength() != prefix.GetLength()) + if (CStringUtils::StartsWith(sText, prefix) && sText.GetLength() != prefix.GetLength()) return true; } return false; @@ -2171,7 +2171,7 @@ CString CAppUtils::GetClipboardLink(const CString &skipGitPrefix, int paramsCoun for (const CString& prefix : { L"http://", L"https://", L"git://", L"ssh://", L"git@" }) { - if (wcsncmp(sClipboardText, prefix, prefix.GetLength()) == 0 && sClipboardText.GetLength() != prefix.GetLength()) + if (CStringUtils::StartsWith(sClipboardText, prefix) && sClipboardText.GetLength() != prefix.GetLength()) return sClipboardText; } @@ -2182,7 +2182,7 @@ CString CAppUtils::GetClipboardLink(const CString &skipGitPrefix, int paramsCoun return sClipboardText; // trim prefixes like "git clone " - if (!skipGitPrefix.IsEmpty() && wcsncmp(sClipboardText, skipGitPrefix, skipGitPrefix.GetLength()) == 0) + if (!skipGitPrefix.IsEmpty() && CStringUtils::StartsWith(sClipboardText, skipGitPrefix)) { sClipboardText = sClipboardText.Mid(skipGitPrefix.GetLength()).Trim(); int spacePos = -1; diff --git a/src/TortoiseProc/BisectStartDlg.cpp b/src/TortoiseProc/BisectStartDlg.cpp index 11b6fcb0d..1e60af840 100644 --- a/src/TortoiseProc/BisectStartDlg.cpp +++ b/src/TortoiseProc/BisectStartDlg.cpp @@ -26,6 +26,7 @@ #include "LogDlg.h" #include "MessageBox.h" #include "AppUtils.h" +#include "StringUtils.h" IMPLEMENT_DYNAMIC(CBisectStartDlg, CHorizontalResizableStandAloneDialog) @@ -128,10 +129,10 @@ void CBisectStartDlg::OnBnClickedOk() m_LastGoodRevision = m_cLastGoodRevision.GetString().Trim(); m_FirstBadRevision = m_cFirstBadRevision.GetString().Trim(); - if (wcsncmp(m_FirstBadRevision, L"remotes/", 8) == 0) + if (CStringUtils::StartsWith(m_FirstBadRevision, L"remotes/")) m_FirstBadRevision = m_FirstBadRevision.Mid(8); - if (wcsncmp(m_FirstBadRevision, L"remotes/", 8) == 0) + if (CStringUtils::StartsWith(m_FirstBadRevision, L"remotes/")) m_FirstBadRevision = m_FirstBadRevision.Mid(8); CHorizontalResizableStandAloneDialog::OnOK(); diff --git a/src/TortoiseProc/BrowseRefsDlg.cpp b/src/TortoiseProc/BrowseRefsDlg.cpp index 0687ad90e..bc1aa07bf 100644 --- a/src/TortoiseProc/BrowseRefsDlg.cpp +++ b/src/TortoiseProc/BrowseRefsDlg.cpp @@ -37,6 +37,7 @@ #include "SysProgressDlg.h" #include "LoglistUtils.h" #include "GitRevRefBrowser.h" +#include "StringUtils.h" static int SplitRemoteBranchName(CString ref, CString &remote, CString &branch) { @@ -392,9 +393,9 @@ CString CBrowseRefsDlg::GetSelectedRef(bool onlyIfLeaf, bool pickFirstSelIfMulti while ((index = m_ListRefLeafs.GetNextSelectedItem(pos)) >= 0) { CString ref = ((CShadowTree*)m_ListRefLeafs.GetItemData(index))->GetRefName(); - if(wcsncmp(ref, L"refs/", 5) == 0) + if (CStringUtils::StartsWith(ref, L"refs/")) ref = ref.Mid(5); - if(wcsncmp(ref, L"heads/", 6) == 0) + if (CStringUtils::StartsWith(ref, L"heads/")) ref = ref.Mid(6); refs += ref + _T(" "); } @@ -444,13 +445,13 @@ void CBrowseRefsDlg::Refresh(CString selectRef) if (GitRevRefBrowser::GetGitRevRefMap(refMap, err, [&](const CString& refName) { //Use ref based on m_pickRef_Kind - if (wcsncmp(refName, L"refs/heads/", 11) == 0 && !(m_pickRef_Kind & gPickRef_Head)) + if (CStringUtils::StartsWith(refName, L"refs/heads/") && !(m_pickRef_Kind & gPickRef_Head)) return false; //Skip - if (wcsncmp(refName, L"refs/tags/", 10) == 0 && !(m_pickRef_Kind & gPickRef_Tag)) + if (CStringUtils::StartsWith(refName, L"refs/tags/") && !(m_pickRef_Kind & gPickRef_Tag)) return false; //Skip - if (wcsncmp(refName, L"refs/remotes/", 13) == 0 && !(m_pickRef_Kind & gPickRef_Remote)) + if (CStringUtils::StartsWith(refName, L"refs/remotes/") && !(m_pickRef_Kind & gPickRef_Remote)) return false; //Skip - if (m_pickRef_Kind == gPickRef_Remote && wcsncmp(refName, L"refs/remotes/", 13) != 0) // do not show refs/stash if only remote branches are requested + if (m_pickRef_Kind == gPickRef_Remote && !CStringUtils::StartsWith(refName, L"refs/remotes/")) // do not show refs/stash if only remote branches are requested return false; return true; })) @@ -490,7 +491,7 @@ bool CBrowseRefsDlg::SelectRef(CString refName, bool bExactMatch) refName = newRefName; //else refName is not a valid ref. Try to select as good as possible. } - if (_wcsnicmp(refName, L"refs", 4) != 0) + if (!CStringUtils::StartsWith(refName, L"refs")) return false; // Not a ref name CShadowTree& treeLeafHead = GetTreeNode(refName, nullptr, false); @@ -524,7 +525,7 @@ CShadowTree& CBrowseRefsDlg::GetTreeNode(CString refName, CShadowTree* pTreePos, { if (!pTreePos) { - if(_wcsnicmp(refName, L"refs/", 5) == 0) + if (CStringUtils::StartsWith(refName, L"refs/")) refName=refName.Mid(5); pTreePos=&m_TreeRoot; } @@ -745,8 +746,13 @@ bool CBrowseRefsDlg::DoDeleteRef(CString completeRefName) { bool bIsRemoteBranch = false; bool bIsBranch = false; - if (wcsncmp(completeRefName, L"refs/remotes/",13) == 0) {bIsBranch = true; bIsRemoteBranch = true;} - else if (wcsncmp(completeRefName, L"refs/heads/",11) == 0) {bIsBranch = true;} + if (CStringUtils::StartsWith(completeRefName, L"refs/remotes/")) + { + bIsBranch = true; + bIsRemoteBranch = true; + } + else if (CStringUtils::StartsWith(completeRefName, L"refs/heads/")) + bIsBranch = true; if (bIsRemoteBranch) { @@ -785,7 +791,7 @@ bool CBrowseRefsDlg::DoDeleteRef(CString completeRefName) return false; } } - else if (wcsncmp(completeRefName, L"refs/tags/", 10) == 0) + else if (CStringUtils::StartsWith(completeRefName, L"refs/tags/")) { if (g_Git.DeleteRef(completeRefName)) { @@ -1389,7 +1395,7 @@ bool CBrowseRefsDlg::PickRefForCombo(CComboBoxEx* pComboBox, int pickRef_Kind) CString resultRef = PickRef(false,origRef,pickRef_Kind); if(resultRef.IsEmpty()) return false; - if(wcsncmp(resultRef,L"refs/",5)==0) + if (CStringUtils::StartsWith(resultRef, L"refs/")) resultRef = resultRef.Mid(5); // if(wcsncmp(resultRef,L"heads/",6)==0) // resultRef = resultRef.Mid(6); @@ -1448,7 +1454,7 @@ void CBrowseRefsDlg::OnLvnEndlabeleditListRefLeafs(NMHDR *pNMHDR, LRESULT *pResu newName = m_pListCtrlRoot->GetRefName() + L'/'; newName += pDispInfo->item.pszText; - if(wcsncmp(newName,L"refs/heads/",11)!=0) + if (!CStringUtils::StartsWith(newName, L"refs/heads/")) { CMessageBox::Show(m_hWnd, IDS_PROC_BROWSEREFS_NOCHANGEOFTYPE, IDS_APPNAME, MB_OK | MB_ICONERROR); return; diff --git a/src/TortoiseProc/ChooseVersion.h b/src/TortoiseProc/ChooseVersion.h index 8b8c47845..ecf6cdc30 100644 --- a/src/TortoiseProc/ChooseVersion.h +++ b/src/TortoiseProc/ChooseVersion.h @@ -22,6 +22,7 @@ #include "BrowseRefsDlg.h" #include "MessageBox.h" #include "registry.h" +#include "StringUtils.h" static UINT WM_GUIUPDATES = RegisterWindowMessage(_T("TORTOISEGIT_CHOOSEVERSION_GUIUPDATES")); @@ -157,22 +158,22 @@ protected: refName = fullRefName; } - if(wcsncmp(refName,L"refs/",5)==0) + if (CStringUtils::StartsWith(refName, L"refs/")) refName = refName.Mid(5); - if(wcsncmp(refName,L"heads/",6)==0) + if (CStringUtils::StartsWith(refName, L"heads/")) { refName = refName.Mid(6); SetDefaultChoose(IDC_RADIO_BRANCH); m_ChooseVersioinBranch.SetCurSel( m_ChooseVersioinBranch.FindStringExact(-1, refName)); } - else if(wcsncmp(refName,L"remotes/",8)==0) + else if (CStringUtils::StartsWith(refName, L"remotes/")) { SetDefaultChoose(IDC_RADIO_BRANCH); m_ChooseVersioinBranch.SetCurSel( m_ChooseVersioinBranch.FindStringExact(-1, refName)); } - else if(wcsncmp(refName,L"tags/",5)==0) + else if (CStringUtils::StartsWith(refName, L"tags/")) { refName = refName.Mid(5); refName.Replace(_T("^{}"), _T("")); diff --git a/src/TortoiseProc/Commands/CatCommand.cpp b/src/TortoiseProc/Commands/CatCommand.cpp index cc513523d..47f6937a0 100644 --- a/src/TortoiseProc/Commands/CatCommand.cpp +++ b/src/TortoiseProc/Commands/CatCommand.cpp @@ -23,6 +23,7 @@ #include "Git.h" #include "MessageBox.h" #include "SmartHandle.h" +#include "StringUtils.h" bool CatCommand::Execute() { @@ -92,7 +93,7 @@ bool CatCommand::Execute() return false; } - if (wcsncmp(output, L"blob", 4) == 0) + if (CStringUtils::StartsWith(output, L"blob")) cmd.Format(_T("git.exe cat-file -p %s"), (LPCTSTR)revision); else cmd.Format(_T("git.exe show %s -- \"%s\""), (LPCTSTR)revision, (LPCTSTR)this->cmdLinePath.GetWinPathString()); diff --git a/src/TortoiseProc/Commands/CloneCommand.cpp b/src/TortoiseProc/Commands/CloneCommand.cpp index 443720618..a8e34ab8d 100644 --- a/src/TortoiseProc/Commands/CloneCommand.cpp +++ b/src/TortoiseProc/Commands/CloneCommand.cpp @@ -21,7 +21,7 @@ #include "CloneCommand.h" #include "GitProgressDlg.h" - +#include "StringUtils.h" #include "CloneDlg.h" #include "ProgressDlg.h" #include "AppUtils.h" @@ -134,7 +134,7 @@ bool CloneCommand::Execute() CString url=dlg.m_URL; // is this a windows format UNC path, ie starts with \\? - if (wcsncmp(url, L"\\\\", 2) == 0) + if (CStringUtils::StartsWith(url, L"\\\\")) { // yes, change all \ to / // this should not be necessary but msysgit does not support the use \ here yet diff --git a/src/TortoiseProc/Commands/DropCopyAddCommand.cpp b/src/TortoiseProc/Commands/DropCopyAddCommand.cpp index 8669f7f85..c00941ebc 100644 --- a/src/TortoiseProc/Commands/DropCopyAddCommand.cpp +++ b/src/TortoiseProc/Commands/DropCopyAddCommand.cpp @@ -103,7 +103,7 @@ bool DropCopyAddCommand::Execute() { if (!lastRepo.IsEmpty()) { - if (wcsncmp(filepath, lastRepo, lastRepo.GetLength()) == 0) + if (CStringUtils::StartsWith(filepath, lastRepo)) continue; else lastRepo.Empty(); diff --git a/src/TortoiseProc/FileDiffDlg.cpp b/src/TortoiseProc/FileDiffDlg.cpp index 2d4940d6e..253884b57 100644 --- a/src/TortoiseProc/FileDiffDlg.cpp +++ b/src/TortoiseProc/FileDiffDlg.cpp @@ -1237,7 +1237,7 @@ LRESULT CFileDiffDlg::OnRefLoad(WPARAM /*wParam*/, LPARAM /*lParam*/) { CString str=m_Reflist[i]; - if (wcsncmp(str, L"remotes/", 8) == 0) + if (CStringUtils::StartsWith(str, L"remotes/")) str=str.Mid(8); m_ctrRev1Edit.AddSearchString(str); diff --git a/src/TortoiseProc/FindDlg.cpp b/src/TortoiseProc/FindDlg.cpp index b688e8c47..86d131153 100644 --- a/src/TortoiseProc/FindDlg.cpp +++ b/src/TortoiseProc/FindDlg.cpp @@ -20,7 +20,7 @@ #include "stdafx.h" #include "resource.h" #include "FindDlg.h" - +#include "StringUtils.h" // CFindDlg dialog @@ -175,11 +175,11 @@ void CFindDlg::AddToList() { int nImage = -1; CString ref = m_RefList[i]; - if (wcsncmp(ref, L"refs/tags", 9) == 0) + if (CStringUtils::StartsWith(ref, L"refs/tags")) nImage = 0; - else if (wcsncmp(ref, L"refs/remotes", 12) ==0) + else if (CStringUtils::StartsWith(ref, L"refs/remotes")) nImage = 2; - else if (wcsncmp(ref, L"refs/heads", 10) == 0) + else if (CStringUtils::StartsWith(ref, L"refs/heads")) nImage = 1; if(ref.Find(filter)>=0) diff --git a/src/TortoiseProc/GitLogListAction.cpp b/src/TortoiseProc/GitLogListAction.cpp index 2add0964a..67cfff610 100644 --- a/src/TortoiseProc/GitLogListAction.cpp +++ b/src/TortoiseProc/GitLogListAction.cpp @@ -44,7 +44,7 @@ IMPLEMENT_DYNAMIC(CGitLogList, CHintCtrl) static void GetFirstEntryStartingWith(STRING_VECTOR& heystack, const CString& needle, CString& result) { - auto it = std::find_if(heystack.cbegin(), heystack.cend(), [&needle](const CString& entry) { return wcsncmp(entry, needle, needle.GetLength()) == 0; }); + auto it = std::find_if(heystack.cbegin(), heystack.cend(), [&needle](const CString& entry) { return CStringUtils::StartsWith(entry, needle); }); if (it == heystack.cend()) return; result = *it; @@ -799,7 +799,7 @@ void CGitLogList::ContextMenuAction(int cmd,int FirstSelect, int LastSelect, CMe while (pos2) { CString ref = m_arShownList.SafeGetAt(GetNextSelectedItem(pos2))->m_Ref; - if (wcsncmp(ref, L"refs/", 5) == 0) + if (CStringUtils::StartsWith(ref, L"refs/")) ref = ref.Mid(5); int refpos = ref.ReverseFind('{'); if (refpos > 0 && ref.Mid(refpos - 1, 2) != _T("@{")) @@ -811,7 +811,7 @@ void CGitLogList::ContextMenuAction(int cmd,int FirstSelect, int LastSelect, CMe { CString ref = *revIt; CString sCmd, out; - if (wcsncmp(ref, L"stash", 5) == 0) + if (CStringUtils::StartsWith(ref, L"stash")) sCmd.Format(_T("git.exe stash drop %s"), (LPCTSTR)ref); else sCmd.Format(_T("git.exe reflog delete %s"), (LPCTSTR)ref); diff --git a/src/TortoiseProc/GitLogListBase.cpp b/src/TortoiseProc/GitLogListBase.cpp index ba7d23dd0..9ef8c4a2d 100644 --- a/src/TortoiseProc/GitLogListBase.cpp +++ b/src/TortoiseProc/GitLogListBase.cpp @@ -2110,7 +2110,7 @@ void CGitLogListBase::OnContextMenu(CWnd* pWnd, CPoint point) if(!pSelLogEntry->m_Ref.IsEmpty()) { popup.AppendMenuIcon(ID_REFLOG_DEL, IDS_REFLOG_DEL, IDI_DELETE); - if (GetSelectedCount() == 1 && wcsncmp(pSelLogEntry->m_Ref, L"refs/stash", 10) == 0) + if (GetSelectedCount() == 1 && CStringUtils::StartsWith(pSelLogEntry->m_Ref, L"refs/stash")) popup.AppendMenuIcon(ID_REFLOG_STASH_APPLY, IDS_MENUSTASHAPPLY, IDI_RELOCATE); popup.AppendMenu(MF_SEPARATOR, NULL); } @@ -2213,7 +2213,7 @@ void CGitLogListBase::OnContextMenu(CWnd* pWnd, CPoint point) if (m_ContextMenuMask&GetContextMenuBit(ID_PUSH) && ((!isStash && !m_HashMap[pSelLogEntry->m_CommitHash].empty()) || showExtendedMenu)) { // show the push-option only if the log entry has an associated local branch - bool isLocal = find_if(m_HashMap[pSelLogEntry->m_CommitHash], [](const CString& ref) { return wcsncmp(ref, L"refs/heads/", 11) == 0; }) != m_HashMap[pSelLogEntry->m_CommitHash].cend(); + bool isLocal = find_if(m_HashMap[pSelLogEntry->m_CommitHash], [](const CString& ref) { return CStringUtils::StartsWith(ref, L"refs/heads/"); }) != m_HashMap[pSelLogEntry->m_CommitHash].cend(); if (isLocal || showExtendedMenu) { CString str; @@ -3414,7 +3414,7 @@ CString CGitLogListBase::GetTagInfo(GitRev* pLogEntry) STRING_VECTOR &vector = m_HashMap[pLogEntry->m_CommitHash]; for (size_t i = 0; i < vector.size(); ++i) { - if (wcsncmp(vector[i], L"refs/tags/", 10) == 0) + if (CStringUtils::StartsWith(vector[i], L"refs/tags/")) { CString tag = vector[i]; int start = vector[i].Find(_T("^{}")); diff --git a/src/TortoiseProc/PushDlg.cpp b/src/TortoiseProc/PushDlg.cpp index 1c071576b..03f70ed8e 100644 --- a/src/TortoiseProc/PushDlg.cpp +++ b/src/TortoiseProc/PushDlg.cpp @@ -23,7 +23,7 @@ #include "stdafx.h" #include "TortoiseProc.h" #include "PushDlg.h" - +#include "StringUtils.h" #include "Git.h" #include "registry.h" #include "AppUtils.h" @@ -256,14 +256,14 @@ void CPushDlg::Refresh() m_BranchSource.SetList(list); else MessageBox(g_Git.GetGitLastErr(_T("Could not get list of local branches.")), _T("TortoiseGit"), MB_ICONERROR); - if (wcsncmp(m_BranchSourceName, _T("refs/"), 5) == 0) + if (CStringUtils::StartsWith(m_BranchSourceName, L"refs/")) m_BranchSourceName = m_BranchSourceName.Mid(5); - if (wcsncmp(m_BranchSourceName, _T("heads/"), 6) == 0) + if (CStringUtils::StartsWith(m_BranchSourceName, L"heads/")) { m_BranchSourceName = m_BranchSourceName.Mid(6); m_BranchSource.SetCurSel(m_BranchSource.FindStringExact(-1, m_BranchSourceName)); } - else if (wcsncmp(m_BranchSourceName, _T("remotes/"), 8) == 0) + else if (CStringUtils::StartsWith(m_BranchSourceName, L"remotes/")) m_BranchSource.SetCurSel(m_BranchSource.FindStringExact(-1, m_BranchSourceName)); else if (m_BranchSourceName.IsEmpty()) m_BranchSource.SetCurSel(current); diff --git a/src/TortoiseProc/RequestPullDlg.cpp b/src/TortoiseProc/RequestPullDlg.cpp index 504d5c713..da1c64fbf 100644 --- a/src/TortoiseProc/RequestPullDlg.cpp +++ b/src/TortoiseProc/RequestPullDlg.cpp @@ -26,6 +26,7 @@ #include "LogDlg.h" #include "MessageBox.h" #include "AppUtils.h" +#include "StringUtils.h" IMPLEMENT_DYNAMIC(CRequestPullDlg, CHorizontalResizableStandAloneDialog) @@ -129,7 +130,7 @@ void CRequestPullDlg::OnBnClickedOk() return; } - if (wcsncmp(m_StartRevision, L"remotes/", 8) == 0) + if (CStringUtils::StartsWith(m_StartRevision, L"remotes/")) m_StartRevision = m_StartRevision.Mid(8); m_regSendMail = m_bSendMail; diff --git a/src/TortoiseProc/RevisionGraph/RevGraphFilterDlg.cpp b/src/TortoiseProc/RevisionGraph/RevGraphFilterDlg.cpp index 2e7ffe0a5..d6ca0ce45 100644 --- a/src/TortoiseProc/RevisionGraph/RevGraphFilterDlg.cpp +++ b/src/TortoiseProc/RevisionGraph/RevGraphFilterDlg.cpp @@ -23,6 +23,7 @@ #include "gittype.h" #include "Git.h" #include "BrowseRefsDlg.h" +#include "StringUtils.h" IMPLEMENT_DYNAMIC(CRevGraphFilterDlg, CDialog) @@ -76,25 +77,25 @@ BOOL CRevGraphFilterDlg::OnInitDialog() m_ctrlFromRev.AddSearchString(list[i]); m_ctrlToRev.AddSearchString(list[i]); - if (wcsncmp(str, L"refs/", 5) == 0) + if (CStringUtils::StartsWith(str, L"refs/")) { m_ctrlFromRev.AddSearchString(list[i].Mid(5)); m_ctrlToRev.AddSearchString(list[i].Mid(5)); } - if (wcsncmp(str, L"refs/heads/", 11) == 0) + if (CStringUtils::StartsWith(str, L"refs/heads/")) { m_ctrlFromRev.AddSearchString(list[i].Mid(11)); m_ctrlToRev.AddSearchString(list[i].Mid(11)); } - if (wcsncmp(str, L"refs/remotes/", 13) == 0) + if (CStringUtils::StartsWith(str, L"refs/remotes/")) { m_ctrlFromRev.AddSearchString(list[i].Mid(13)); m_ctrlToRev.AddSearchString(list[i].Mid(13)); } - if (wcsncmp(str, L"refs/tags/", 10) == 0) + if (CStringUtils::StartsWith(str, L"refs/tags/")) { m_ctrlFromRev.AddSearchString(list[i].Mid(10)); m_ctrlToRev.AddSearchString(list[i].Mid(10)); diff --git a/src/TortoiseProc/TortoiseProc.cpp b/src/TortoiseProc/TortoiseProc.cpp index b530442c0..85391fb4b 100644 --- a/src/TortoiseProc/TortoiseProc.cpp +++ b/src/TortoiseProc/TortoiseProc.cpp @@ -276,16 +276,16 @@ BOOL CTortoiseProcApp::InitInstance() if (parser.HasKey(_T("urlhandler"))) { CString url = parser.GetVal(_T("urlhandler")); - if (wcsncmp(url, L"tgit://clone/", 13) == 0) + if (CStringUtils::StartsWith(url, L"tgit://clone/")) url = url.Mid(13); // 21 = "tgit://clone/".GetLength() - else if (wcsncmp(url, L"github-windows://openRepo/", 26) == 0) + else if (CStringUtils::StartsWith(url, L"github-windows://openRepo/")) { url = url.Mid(26); // 26 = "github-windows://openRepo/".GetLength() int questioMark = url.Find('?'); if (questioMark > 0) url = url.Left(questioMark); } - else if (wcsncmp(url, L"smartgit://cloneRepo/", 21) == 0) + else if (CStringUtils::StartsWith(url, L"smartgit://cloneRepo/")) url = url.Mid(21); // 21 = "smartgit://cloneRepo/".GetLength() else { diff --git a/src/TortoiseShell/GITPropertyPage.cpp b/src/TortoiseShell/GITPropertyPage.cpp index 13bb9365f..b00b16dbc 100644 --- a/src/TortoiseShell/GITPropertyPage.cpp +++ b/src/TortoiseShell/GITPropertyPage.cpp @@ -26,6 +26,7 @@ #include "UnicodeUtils.h" #include "CreateProcessHelper.h" #include "FormatMessageWrapper.h" +#include "StringUtils.h" #define MAX_STRING_LENGTH 4096 //should be big enough @@ -561,7 +562,7 @@ void CGitPropertyPage::InitWorkfileView() { git_reference_lookup(head.GetPointer(), repository, "HEAD"); branch = CUnicodeUtils::GetUnicode(git_reference_symbolic_target(head)); - if (wcsncmp(branch, L"refs/heads/", 11) == 0) + if (CStringUtils::StartsWith(branch, L"refs/heads/")) branch = branch.Mid(11); // 11 = len("refs/heads/") } else if (!git_repository_head(head.GetPointer(), repository)) diff --git a/src/Utils/StringUtils.cpp b/src/Utils/StringUtils.cpp index a1d927772..a17e2c014 100644 --- a/src/Utils/StringUtils.cpp +++ b/src/Utils/StringUtils.cpp @@ -255,7 +255,6 @@ bool CStringUtils::ReadStringFromTextFile(const CString& path, CString& text) } return true; } - #endif // #ifdef _MFC_VER #if defined(CSTRING_AVAILABLE) || defined(_MFC_VER) @@ -574,8 +573,18 @@ void CStringUtils::ParseEmailAddress(CString mailaddress, CString& parsedAddress if (parsedName && parsedName->IsEmpty()) get_sane_name(parsedName, &mailaddress, parsedAddress); } + +bool CStringUtils::StartsWith(const wchar_t* heystack, const CString& needle) +{ + return wcsncmp(heystack, needle, needle.GetLength()) == 0; +} #endif // #if defined(CSTRING_AVAILABLE) || defined(_MFC_VER) +bool CStringUtils::StartsWith(const wchar_t* heystack, const wchar_t* needle) +{ + return wcsncmp(heystack, needle, wcslen(needle)) == 0; +} + bool CStringUtils::WriteStringToTextFile(const std::wstring& path, const std::wstring& text, bool bUTF8 /* = true */) { DWORD dwWritten = 0; diff --git a/src/Utils/StringUtils.h b/src/Utils/StringUtils.h index 7ae243023..00d9c6435 100644 --- a/src/Utils/StringUtils.h +++ b/src/Utils/StringUtils.h @@ -110,7 +110,11 @@ public: static void ParseEmailAddress(CString mailaddress, CString& parsedAddress, CString* parsedName = nullptr); static bool IsPlainReadableASCII(const CString& text); + + static bool StartsWith(const wchar_t* heystack, const CString& needle); #endif + static bool StartsWith(const wchar_t* heystack, const wchar_t* needle); + /** * Writes the string \text to the file \path, either in utf16 or utf8 encoding, * depending on the \c bUTF8 param. diff --git a/test/UnitTests/StringUtilsTest.cpp b/test/UnitTests/StringUtilsTest.cpp index c66edb0a7..3f61a8f4b 100644 --- a/test/UnitTests/StringUtilsTest.cpp +++ b/test/UnitTests/StringUtilsTest.cpp @@ -228,3 +228,24 @@ TEST(CStringUtils, IsPlainReadableASCII) EXPECT_FALSE(CStringUtils::IsPlainReadableASCII(L"\u570B")); EXPECT_FALSE(CStringUtils::IsPlainReadableASCII(L"\u7ACB")); } + +TEST(CStringUtils, StartsWith) +{ + CString heystack = L"sometest"; + EXPECT_TRUE(CStringUtils::StartsWith(heystack, L"sometest")); + EXPECT_TRUE(CStringUtils::StartsWith(heystack, L"")); + EXPECT_TRUE(CStringUtils::StartsWith(heystack, L"sometes")); + EXPECT_FALSE(CStringUtils::StartsWith(heystack, L"someteste")); + EXPECT_FALSE(CStringUtils::StartsWith(heystack, L"sometess")); + + CString empty; + CString sometest = L"sometest"; + CString sometes = L"sometes"; + CString someteste = L"someteste"; + CString sometess = L"sometess"; + EXPECT_TRUE(CStringUtils::StartsWith(heystack, sometest)); + EXPECT_TRUE(CStringUtils::StartsWith(heystack, empty)); + EXPECT_TRUE(CStringUtils::StartsWith(heystack, sometes)); + EXPECT_FALSE(CStringUtils::StartsWith(heystack, someteste)); + EXPECT_FALSE(CStringUtils::StartsWith(heystack, sometess)); +} -- 2.11.4.GIT