diff --git a/scintilla/deelx/DeelxRegexSearch.cxx b/scintilla/deelx/DeelxRegexSearch.cxx index fda3cd3e8..57e9bd465 100644 --- a/scintilla/deelx/DeelxRegexSearch.cxx +++ b/scintilla/deelx/DeelxRegexSearch.cxx @@ -27,6 +27,9 @@ #include #include +#define VC_EXTRALEAN 1 +#include + #pragma warning( push ) #pragma warning( disable : 4996 ) // Scintilla's "unsafe" use of std::copy() (SplitVector.h) // // or use -D_SCL_SECURE_NO_WARNINGS preprocessor define @@ -235,6 +238,7 @@ long DeelxRegexSearch::FindText(Document* doc, Sci::Position minPos, Sci::Positi + #if 0 #define _MAX(a,b) ((a)>(b)?(a):(b)) @@ -288,59 +292,36 @@ const char* DeelxRegexSearch::SubstituteByPosition(Document* doc, const char* te return nullptr; } + std::string rawReplStrg = convertReplExpr(std::string(text, *length)); + m_SubstBuffer.clear(); - for (int j = 0; j < *length; j++) { - if ((text[j] == '$') || (text[j] == '\\')) + for (int j = 0; j < rawReplStrg.length(); j++) { + if ((rawReplStrg[j] == '$') || (rawReplStrg[j] == '\\')) { - if ((text[j + 1] >= '0') && (text[j + 1] <= '9')) + if ((m_Match.IsMatched() != 0) && (rawReplStrg[j + 1] >= '0') && (rawReplStrg[j + 1] <= '9')) { - unsigned int patNum = text[j + 1] - '0'; + unsigned int grpNum = rawReplStrg[j + 1] - '0'; - if (patNum <= m_Match.MaxGroupNumber()) { - deelx::index_t gStart = m_Match.GetGroupStart(patNum); - deelx::index_t len = m_Match.GetGroupEnd(patNum) - gStart; + if (grpNum <= m_Match.MaxGroupNumber()) + { + deelx::index_t gStart = m_Match.GetGroupStart(grpNum); + deelx::index_t len = m_Match.GetGroupEnd(grpNum) - gStart; - m_SubstBuffer.append(doc->RangePointer(SciPos(gStart), len), len); + m_SubstBuffer.append(doc->RangePointer(SciPos(gStart), SciPos(len)), len); } ++j; } + else if (rawReplStrg[j] == '\\') { + m_SubstBuffer.push_back('\\'); + ++j; + } else { - ++j; - switch (text[j]) { - case 'a': - m_SubstBuffer.push_back('\a'); - break; - case 'b': - m_SubstBuffer.push_back('\b'); - break; - case 'f': - m_SubstBuffer.push_back('\f'); - break; - case 'n': - m_SubstBuffer.push_back('\n'); - break; - case 'r': - m_SubstBuffer.push_back('\r'); - break; - case 't': - m_SubstBuffer.push_back('\t'); - break; - case 'v': - m_SubstBuffer.push_back('\v'); - break; - case '\\': - m_SubstBuffer.push_back('\\'); - break; - default: - m_SubstBuffer.push_back('\\'); - --j; - break; - } + m_SubstBuffer.push_back(rawReplStrg[j]); } } else { - m_SubstBuffer.push_back(text[j]); + m_SubstBuffer.push_back(rawReplStrg[j]); } } @@ -358,7 +339,40 @@ const char* DeelxRegexSearch::SubstituteByPosition(Document* doc, const char* te // ============================================================================ -void replaceAll(std::string& source,const std::string& from,const std::string& to) +/****************************************************************************** +* +* UnSlash functions +* Mostly taken from SciTE, (c) Neil Hodgson, http://www.scintilla.org +* +/ + +/** +* Is the character an octal digit? +*/ +static bool IsOctalDigit(char ch) { + return ch >= '0' && ch <= '7'; +} +// ---------------------------------------------------------------------------- + +/** +* If the character is an hexa digit, get its value. +*/ +static int GetHexDigit(char ch) { + if (ch >= '0' && ch <= '9') { + return ch - '0'; + } + if (ch >= 'A' && ch <= 'F') { + return ch - 'A' + 10; + } + if (ch >= 'a' && ch <= 'f') { + return ch - 'a' + 10; + } + return -1; +} +// ---------------------------------------------------------------------------- + + +static void replaceAll(std::string& source,const std::string& from,const std::string& to) { std::string newString; newString.reserve(source.length() * 2); // avoids a few memory allocations @@ -411,11 +425,6 @@ std::string& DeelxRegexSearch::convertReplExpr(std::string& replStr) char ch = replStr[i]; if (ch == '\\') { ch = replStr[++i]; // next char - if (ch == '\\') { - // skip 2nd backslash ("\\") - if (i < replStr.length()) { ch = replStr[++i]; } - else { break; } - } if (ch >= '1' && ch <= '9') { // former behavior convenience: // change "\\" to deelx's group reference ($) @@ -445,11 +454,60 @@ std::string& DeelxRegexSearch::convertReplExpr(std::string& replStr) tmpStr.push_back('\v'); break; case '\\': - tmpStr.push_back('\\'); + tmpStr.push_back('\\'); // preserve escd "\" + tmpStr.push_back('\\'); break; + case 'x': + case 'u': + { + bool bShort = (ch == 'x'); + char buf[8] = { '\0' }; + char *pch = buf; + WCHAR val[2] = L""; + int hex; + val[0] = 0; + ++i; + hex = GetHexDigit(replStr[i]); + if (hex >= 0) { + ++i; + val[0] = (WCHAR)hex; + hex = GetHexDigit(replStr[i]); + if (hex >= 0) { + ++i; + val[0] *= 16; + val[0] += (WCHAR)hex; + if (!bShort) { + hex = GetHexDigit(replStr[i]); + if (hex >= 0) { + ++i; + val[0] *= 16; + val[0] += (WCHAR)hex; + hex = GetHexDigit(replStr[i]); + if (hex >= 0) { + ++i; + val[0] *= 16; + val[0] += (WCHAR)hex; + } + } + } + } + if (val[0]) { + val[1] = 0; + WideCharToMultiByte(CP_UTF8, 0, val, -1, buf, ARRAYSIZE(val), NULL, NULL); + tmpStr.push_back(*pch++); + while (*pch) + tmpStr.push_back(*pch++); + } + else + tmpStr.push_back(ch); // unknown ctrl seq + } + else + tmpStr.push_back(ch); // unknown ctrl seq + } + break; + default: - // unknown ctrl seq - tmpStr.push_back(ch); + tmpStr.push_back(ch); // unknown ctrl seq break; } } diff --git a/src/Dialogs.c b/src/Dialogs.c index 00a4d40e6..891719f60 100644 --- a/src/Dialogs.c +++ b/src/Dialogs.c @@ -1092,7 +1092,10 @@ INT_PTR CALLBACK FileMRUDlgProc(HWND hwnd,UINT umsg,WPARAM wParam,LPARAM lParam) if (bPreserveCaretPos) CheckDlgButton(hwnd, IDC_PRESERVECARET, BST_CHECKED); - //if (!bSaveRecentFiles) DialogEnableWindow(hwnd,IDC_PRESERVECARET, FALSE); + //if (!bSaveRecentFiles) + // DialogEnableWindow(hwnd,IDC_PRESERVECARET, FALSE); + + CenterDlgInParent(hwnd); } @@ -1288,8 +1291,13 @@ INT_PTR CALLBACK FileMRUDlgProc(HWND hwnd,UINT umsg,WPARAM wParam,LPARAM lParam) ListView_InsertItem(GetDlgItem(hwnd,IDC_FILEMRU),&lvi); } - ListView_SetItemState(GetDlgItem(hwnd,IDC_FILEMRU),0,LVIS_FOCUSED,LVIS_FOCUSED); - ListView_SetColumnWidth(GetDlgItem(hwnd,IDC_FILEMRU),0,LVSCW_AUTOSIZE_USEHEADER); + UINT cnt = ListView_GetItemCount(GetDlgItem(hwnd, IDC_FILEMRU)); + if (cnt > 0) { + UINT idx = ListView_GetTopIndex(GetDlgItem(hwnd, IDC_FILEMRU)); + ListView_SetItemState(GetDlgItem(hwnd, IDC_FILEMRU), idx, LVIS_FOCUSED, LVIS_FOCUSED); + ListView_SetColumnWidth(GetDlgItem(hwnd, IDC_FILEMRU), idx, LVSCW_AUTOSIZE_USEHEADER); + ListView_SetItemState(GetDlgItem(hwnd, IDC_FILEMRU), idx, LVIS_SELECTED, LVIS_SELECTED); + } lpit->hThread = CreateThread(NULL,0,FileMRUIconThread,(LPVOID)lpit,0,&dwtid); } diff --git a/src/Edit.c b/src/Edit.c index 8c85ed466..123736637 100644 --- a/src/Edit.c +++ b/src/Edit.c @@ -4346,7 +4346,9 @@ void __fastcall EditSetSearchFlags(HWND hwnd, LPEDITFINDREPLACE lpefr) lpefr->fuFlags |= (SCFIND_REGEXP | SCFIND_POSIX); } - lpefr->bTransformBS = (IsDlgButtonChecked(hwnd, IDC_FINDTRANSFORMBS) == BST_CHECKED) ? TRUE : FALSE; + if (!(lpefr->bWildcardSearch || (lpefr->fuFlags & SCFIND_REGEXP))) + lpefr->bTransformBS = (IsDlgButtonChecked(hwnd, IDC_FINDTRANSFORMBS) == BST_CHECKED) ? TRUE : FALSE; + lpefr->bNoFindWrap = (IsDlgButtonChecked(hwnd, IDC_NOWRAP) == BST_CHECKED) ? TRUE : FALSE; } @@ -4412,8 +4414,9 @@ int __fastcall EditGetFindStrg(HWND hwnd, LPCEDITFINDREPLACE lpefr, LPSTR szFind StringCchCopyA(szFind, cchCnt, lpefr->szFind); - if (lpefr->bTransformBS) - TransformBackslashes(szFind, (lpefr->fuFlags & SCFIND_REGEXP), Encoding_SciGetCodePage(hwnd)); + BOOL bIsRegEx = (lpefr->fuFlags & SCFIND_REGEXP); + if (lpefr->bTransformBS || bIsRegEx) + TransformBackslashes(szFind, bIsRegEx, Encoding_SciGetCodePage(hwnd),NULL); int slen = StringCchLenA(szFind, FNDRPL_BUFFER); @@ -4424,12 +4427,13 @@ int __fastcall EditGetFindStrg(HWND hwnd, LPCEDITFINDREPLACE lpefr, LPSTR szFind if (lpefr->bWildcardSearch) EscapeWildcards(szFind, lpefr); - //@@@~TransformMetaChars(szFind, (lpefr->fuFlags & SCFIND_REGEXP), (int)SendMessage(hwnd, SCI_GETEOLMODE, 0, 0)); } return slen; } + + //============================================================================= // // EditFindInTarget() @@ -4622,18 +4626,22 @@ INT_PTR CALLBACK EditFindReplaceDlgProcW(HWND hwnd,UINT umsg,WPARAM wParam,LPARA if (lpefr->fuFlags & SCFIND_WORDSTART) CheckDlgButton(hwnd,IDC_FINDSTART,BST_CHECKED); + if (lpefr->bTransformBS) + CheckDlgButton(hwnd, IDC_FINDTRANSFORMBS, BST_CHECKED); + if (lpefr->fuFlags & SCFIND_REGEXP) CheckDlgButton(hwnd,IDC_FINDREGEXP,BST_CHECKED); - if (lpefr->bTransformBS) - CheckDlgButton(hwnd,IDC_FINDTRANSFORMBS,BST_CHECKED); - - if (lpefr->bWildcardSearch) - { + if (lpefr->bWildcardSearch) { CheckDlgButton(hwnd,IDC_WILDCARDSEARCH,BST_CHECKED); CheckDlgButton(hwnd,IDC_FINDREGEXP,BST_UNCHECKED); } + if ((lpefr->fuFlags & SCFIND_REGEXP) || (lpefr->bWildcardSearch)) { + CheckDlgButton(hwnd, IDC_FINDTRANSFORMBS, BST_CHECKED); + DialogEnableWindow(hwnd, IDC_FINDTRANSFORMBS, FALSE); + } + if (lpefr->bNoFindWrap) CheckDlgButton(hwnd,IDC_NOWRAP,BST_CHECKED); @@ -4725,80 +4733,97 @@ INT_PTR CALLBACK EditFindReplaceDlgProcW(HWND hwnd,UINT umsg,WPARAM wParam,LPARA switch (LOWORD(wParam)) { case IDC_FINDTEXT: case IDC_REPLACETEXT: - { - BOOL bEnableF = (GetWindowTextLengthW(GetDlgItem(hwnd, IDC_FINDTEXT)) || - CB_ERR != SendDlgItemMessage(hwnd, IDC_FINDTEXT, CB_GETCURSEL, 0, 0)); + { + BOOL bEnableF = (GetWindowTextLengthW(GetDlgItem(hwnd, IDC_FINDTEXT)) || + CB_ERR != SendDlgItemMessage(hwnd, IDC_FINDTEXT, CB_GETCURSEL, 0, 0)); - BOOL bEnableR = (GetWindowTextLengthW(GetDlgItem(hwnd, IDC_REPLACETEXT)) || - CB_ERR != SendDlgItemMessage(hwnd, IDC_REPLACETEXT, CB_GETCURSEL, 0, 0)); + BOOL bEnableR = (GetWindowTextLengthW(GetDlgItem(hwnd, IDC_REPLACETEXT)) || + CB_ERR != SendDlgItemMessage(hwnd, IDC_REPLACETEXT, CB_GETCURSEL, 0, 0)); - BOOL bEnableIS = !(BOOL)SendMessage(hwndEdit, SCI_GETSELECTIONEMPTY, 0, 0); + BOOL bEnableIS = !(BOOL)SendMessage(hwndEdit, SCI_GETSELECTIONEMPTY, 0, 0); - DialogEnableWindow(hwnd, IDOK, bEnableF); - DialogEnableWindow(hwnd, IDC_FINDPREV, bEnableF); - DialogEnableWindow(hwnd, IDC_REPLACE, bEnableF); - DialogEnableWindow(hwnd, IDC_REPLACEALL, bEnableF); - DialogEnableWindow(hwnd, IDC_REPLACEINSEL, bEnableF && bEnableIS); - DialogEnableWindow(hwnd, IDC_SWAPSTRG, bEnableF || bEnableR); + DialogEnableWindow(hwnd, IDOK, bEnableF); + DialogEnableWindow(hwnd, IDC_FINDPREV, bEnableF); + DialogEnableWindow(hwnd, IDC_REPLACE, bEnableF); + DialogEnableWindow(hwnd, IDC_REPLACEALL, bEnableF); + DialogEnableWindow(hwnd, IDC_REPLACEINSEL, bEnableF && bEnableIS); + DialogEnableWindow(hwnd, IDC_SWAPSTRG, bEnableF || bEnableR); - if (HIWORD(wParam) == CBN_CLOSEUP) { - LONG lSelEnd; - SendDlgItemMessage(hwnd, LOWORD(wParam), CB_GETEDITSEL, 0, (LPARAM)&lSelEnd); - SendDlgItemMessage(hwnd, LOWORD(wParam), CB_SETEDITSEL, 0, MAKELPARAM(lSelEnd, lSelEnd)); - } + if (HIWORD(wParam) == CBN_CLOSEUP) { + LONG lSelEnd; + SendDlgItemMessage(hwnd, LOWORD(wParam), CB_GETEDITSEL, 0, (LPARAM)&lSelEnd); + SendDlgItemMessage(hwnd, LOWORD(wParam), CB_SETEDITSEL, 0, MAKELPARAM(lSelEnd, lSelEnd)); + } - if (bDoCheckAllOccurrences) { - EditSetSearchFlags(hwnd, lpefr); - if (bFlagsChanged || (StringCchCompareXA(lastFind, lpefr->szFind) != 0)) { - BeginWaitCursor(); - StringCchCopyA(lastFind, COUNTOF(lastFind), lpefr->szFind); - RegExResult_t match = NO_MATCH; - match = EditFindHasMatch(hwndEdit, lpefr, (iSaveMarkOcc > 0), FALSE); - if (regexMatch != match) { - regexMatch = match; - InvalidateRect(GetDlgItem(hwnd, IDC_FINDTEXT), NULL, TRUE); - } - // we have to set Sci's regex instance to first find (have substitution in place) - EditFindHasMatch(hwndEdit, lpefr, FALSE, TRUE); - bFlagsChanged = FALSE; - EndWaitCursor(); + if (bDoCheckAllOccurrences) { + EditSetSearchFlags(hwnd, lpefr); + if (bFlagsChanged || (StringCchCompareXA(lastFind, lpefr->szFind) != 0)) { + BeginWaitCursor(); + StringCchCopyA(lastFind, COUNTOF(lastFind), lpefr->szFind); + RegExResult_t match = NO_MATCH; + match = EditFindHasMatch(hwndEdit, lpefr, (iSaveMarkOcc > 0), FALSE); + if (regexMatch != match) { + regexMatch = match; + InvalidateRect(GetDlgItem(hwnd, IDC_FINDTEXT), NULL, TRUE); } + // we have to set Sci's regex instance to first find (have substitution in place) + EditFindHasMatch(hwndEdit, lpefr, FALSE, TRUE); + bFlagsChanged = FALSE; + EndWaitCursor(); } } - break; + } + break; case IDC_FINDREGEXP: - if (IsDlgButtonChecked(hwnd, IDC_FINDREGEXP) == BST_CHECKED) { - CheckDlgButton(hwnd, IDC_FINDTRANSFORMBS, BST_UNCHECKED); + if (IsDlgButtonChecked(hwnd, IDC_FINDREGEXP) == BST_CHECKED) + { + CheckDlgButton(hwnd, IDC_FINDTRANSFORMBS, BST_CHECKED); + DialogEnableWindow(hwnd, IDC_FINDTRANSFORMBS, FALSE); + CheckDlgButton(hwnd, IDC_WILDCARDSEARCH, BST_UNCHECKED); // Can not use wildcard search together with regexp lpefr->fuFlags |= (SCFIND_REGEXP | SCFIND_POSIX); - lpefr->bTransformBS = FALSE; lpefr->bWildcardSearch = FALSE; } else { - if (IsDlgButtonChecked(hwnd, IDC_WILDCARDSEARCH) == BST_CHECKED) + if (IsDlgButtonChecked(hwnd, IDC_WILDCARDSEARCH) == BST_CHECKED) { lpefr->fuFlags |= (SCFIND_REGEXP | SCFIND_POSIX); - else + CheckDlgButton(hwnd, IDC_FINDTRANSFORMBS, BST_CHECKED); + DialogEnableWindow(hwnd, IDC_FINDTRANSFORMBS, FALSE); + } + else { lpefr->fuFlags ^= (SCFIND_REGEXP | SCFIND_POSIX); + DialogEnableWindow(hwnd, IDC_FINDTRANSFORMBS, TRUE); + CheckDlgButton(hwnd, IDC_FINDTRANSFORMBS, (lpefr->bTransformBS) ? BST_CHECKED : BST_UNCHECKED); + } } bFlagsChanged = TRUE; PostMessage(hwnd, WM_COMMAND, MAKELONG(IDC_FINDTEXT, 1), 0); break; case IDC_WILDCARDSEARCH: - if (IsDlgButtonChecked(hwnd, IDC_WILDCARDSEARCH) == BST_CHECKED) { + if (IsDlgButtonChecked(hwnd, IDC_WILDCARDSEARCH) == BST_CHECKED) + { + CheckDlgButton(hwnd, IDC_FINDTRANSFORMBS, BST_CHECKED); + DialogEnableWindow(hwnd, IDC_FINDTRANSFORMBS, FALSE); + CheckDlgButton(hwnd, IDC_FINDREGEXP, BST_UNCHECKED); - lpefr->bWildcardSearch = TRUE; lpefr->fuFlags |= (SCFIND_REGEXP | SCFIND_POSIX); + lpefr->bWildcardSearch = TRUE; } else { - lpefr->bWildcardSearch = FALSE; - if (IsDlgButtonChecked(hwnd, IDC_FINDREGEXP) == BST_CHECKED) { + if (IsDlgButtonChecked(hwnd, IDC_FINDREGEXP) == BST_CHECKED) + { lpefr->fuFlags |= (SCFIND_REGEXP | SCFIND_POSIX); - //lpefr->fuFlags ^= SCFIND_POSIX; + CheckDlgButton(hwnd, IDC_FINDTRANSFORMBS, BST_CHECKED); + DialogEnableWindow(hwnd, IDC_FINDTRANSFORMBS, FALSE); } - else + else { + DialogEnableWindow(hwnd, IDC_FINDTRANSFORMBS, TRUE); + CheckDlgButton(hwnd, IDC_FINDTRANSFORMBS, (lpefr->bTransformBS) ? BST_CHECKED : BST_UNCHECKED); lpefr->fuFlags ^= (SCFIND_REGEXP | SCFIND_POSIX); + } + lpefr->bWildcardSearch = FALSE; } bFlagsChanged = TRUE; PostMessage(hwnd, WM_COMMAND, MAKELONG(IDC_FINDTEXT, 1), 0); @@ -4806,11 +4831,11 @@ INT_PTR CALLBACK EditFindReplaceDlgProcW(HWND hwnd,UINT umsg,WPARAM wParam,LPARA case IDC_FINDTRANSFORMBS: if (IsDlgButtonChecked(hwnd, IDC_FINDTRANSFORMBS) == BST_CHECKED) { - CheckDlgButton(hwnd, IDC_FINDREGEXP, BST_UNCHECKED); lpefr->bTransformBS = TRUE; } - else + else { lpefr->bTransformBS = FALSE; + } bFlagsChanged = TRUE; PostMessage(hwnd, WM_COMMAND, MAKELONG(IDC_FINDTEXT, 1), 0); break; @@ -5044,6 +5069,7 @@ INT_PTR CALLBACK EditFindReplaceDlgProcW(HWND hwnd,UINT umsg,WPARAM wParam,LPARA SendMessage(hwndMain, WM_COMMAND, MAKELONG(IDM_EDIT_SAVEFIND, 1), 0); SetDlgItemTextA2W(CP_UTF8, hwnd, IDC_FINDTEXT, lpefr->szFindUTF8); CheckDlgButton(hwnd, IDC_FINDREGEXP, BST_UNCHECKED); + CheckDlgButton(hwnd, IDC_WILDCARDSEARCH, BST_UNCHECKED); CheckDlgButton(hwnd, IDC_FINDTRANSFORMBS, BST_UNCHECKED); PostMessage(hwnd, WM_NEXTDLGCTL, (WPARAM)(GetDlgItem(hwnd, IDC_FINDTEXT)), 1); break; @@ -5310,7 +5336,6 @@ BOOL EditFindPrev(HWND hwnd, LPCEDITFINDREPLACE lpefr, BOOL bExtendSelection) { char* __fastcall EditGetReplaceString(HWND hwnd, LPCEDITFINDREPLACE lpefr, int* iReplaceMsg) { char* pszReplace = NULL; // replace text of arbitrary size - *iReplaceMsg = (lpefr->fuFlags & SCFIND_REGEXP) ? SCI_REPLACETARGETRE : SCI_REPLACETARGET; if (StringCchCompareNA(lpefr->szReplace, FNDRPL_BUFFER, "^c", -1) == 0) { *iReplaceMsg = SCI_REPLACETARGET; pszReplace = EditGetClipboardText(hwnd, TRUE, NULL, NULL); @@ -5319,8 +5344,11 @@ char* __fastcall EditGetReplaceString(HWND hwnd, LPCEDITFINDREPLACE lpefr, int* pszReplace = StrDupA(lpefr->szReplace); if (!pszReplace) pszReplace = StrDupA(""); - if (lpefr->bTransformBS) - TransformBackslashes(pszReplace, (lpefr->fuFlags & SCFIND_REGEXP), Encoding_SciGetCodePage(hwnd)); + + BOOL bIsRegEx = (lpefr->fuFlags & SCFIND_REGEXP); + if (lpefr->bTransformBS || bIsRegEx) + TransformBackslashes(pszReplace, bIsRegEx, Encoding_SciGetCodePage(hwnd), iReplaceMsg); + } return pszReplace; } diff --git a/src/Helpers.c b/src/Helpers.c index 78022a501..a1fdc472a 100644 --- a/src/Helpers.c +++ b/src/Helpers.c @@ -2408,32 +2408,65 @@ unsigned int UnSlash(char *s,UINT cpEdit) { /** * Convert C style \0oo into their indicated characters. - * This is used to get control characters into the regular expresion engine. + * This is used to get control characters into the regular expresion engine + * w/o interfering with group referencing ('\0'). */ -unsigned int UnSlashLowOctal(char *s) { - char *sStart = s; - char *o = s; +unsigned int UnSlashLowOctal(char* s) { + char* sStart = s; + char* o = s; while (*s) { - if ((s[0] == '\\') && (s[1] == '0') && IsOctalDigit(s[2]) && IsOctalDigit(s[3])) { + if ((s[0] == '\\') && (s[1] == '\\')) { // esc seq + *o = *s; ++o; ++s; *o = *s; + } + else if ((s[0] == '\\') && (s[1] == '0') && IsOctalDigit(s[2]) && IsOctalDigit(s[3])) { *o = (char)(8 * (s[2] - '0') + (s[3] - '0')); s += 3; } else { *o = *s; } - o++; + ++o; if (*s) - s++; + ++s; } *o = '\0'; return (unsigned int)(o - sStart); } -void TransformBackslashes(char* pszInput,BOOL bRegEx,UINT cpEdit) + +/** + * check, if we have regex sub-group referencing + */ +int CheckRegExReplTarget(char* pszInput) { - if (bRegEx) + while (*pszInput) { + if ((*pszInput == '$') || (*pszInput == '\\')) { + ++pszInput; + if ((*pszInput >= '0') && (*pszInput <= '9')) { + return SCI_REPLACETARGETRE; + } + } + ++pszInput; + } + return SCI_REPLACETARGET; +} + + +void TransformBackslashes(char* pszInput, BOOL bRegEx, UINT cpEdit, int* iReplaceMsg) +{ + int replTarget = SCI_REPLACETARGET; + + if (bRegEx) { UnSlashLowOctal(pszInput); - else - UnSlash(pszInput,cpEdit); + if (iReplaceMsg) + replTarget = CheckRegExReplTarget(pszInput); + } + + if (SCI_REPLACETARGET == replTarget) + UnSlash(pszInput, cpEdit); + + if (iReplaceMsg) + *iReplaceMsg = replTarget; + } diff --git a/src/Helpers.h b/src/Helpers.h index 4d4b62630..1488867f0 100644 --- a/src/Helpers.h +++ b/src/Helpers.h @@ -269,7 +269,7 @@ HWND CreateThemedDialogParam(HINSTANCE,LPCTSTR,HWND,DLGPROC,LPARAM); //==== UnSlash Functions ====================================================== -void TransformBackslashes(char*,BOOL,UINT); +void TransformBackslashes(char*,BOOL,UINT,int*); void TransformMetaChars(char*,BOOL,int); //==== MinimizeToTray Functions - see comments in Helpers.c =================== diff --git a/src/Notepad3.rc b/src/Notepad3.rc index 436ef3893..7548eb4d6 100644 Binary files a/src/Notepad3.rc and b/src/Notepad3.rc differ