[NEW_FEATURE] (Author: Dave Brotherstone) Add PCRE (Perl Compatible Regular Expressions) support.
git-svn-id: svn://svn.tuxfamily.org/svnroot/notepadplus/repository/trunk@863 f5eea248-9336-0410-98b8-ebc06183d4e3
This commit is contained in:
parent
73ffaa8554
commit
7e0ed0ebf3
|
@ -1864,6 +1864,10 @@ void NppParameters::feedFindHistoryParameters(TiXmlNode *node)
|
|||
(findHistoryRoot->ToElement())->Attribute(TEXT("transparency"), &_findHistory._transparency);
|
||||
if (_findHistory._transparency <= 0 || _findHistory._transparency > 200)
|
||||
_findHistory._transparency = 150;
|
||||
|
||||
boolStr = (findHistoryRoot->ToElement())->Attribute(TEXT("dotMatchesNewline"));
|
||||
if (boolStr)
|
||||
_findHistory._dotMatchesNewline = !lstrcmp(TEXT("yes"), boolStr);
|
||||
}
|
||||
|
||||
void NppParameters::feedShortcut(TiXmlNode *node)
|
||||
|
@ -4633,6 +4637,7 @@ bool NppParameters::writeFindHistory()
|
|||
(findHistoryRoot->ToElement())->SetAttribute(TEXT("searchMode"), _findHistory._searchMode);
|
||||
(findHistoryRoot->ToElement())->SetAttribute(TEXT("transparencyMode"), _findHistory._transparencyMode);
|
||||
(findHistoryRoot->ToElement())->SetAttribute(TEXT("transparency"), _findHistory._transparency);
|
||||
(findHistoryRoot->ToElement())->SetAttribute(TEXT("dotMatchesNewline"), _findHistory._dotMatchesNewline?TEXT("yes"):TEXT("no"));
|
||||
|
||||
TiXmlElement hist_element(TEXT(""));
|
||||
|
||||
|
|
|
@ -961,7 +961,8 @@ struct FindHistory {
|
|||
_isMatchWord(false), _isMatchCase(false),_isWrap(true),_isDirectionDown(true),\
|
||||
_isFifRecuisive(true), _isFifInHiddenFolder(false), _isDlgAlwaysVisible(false),\
|
||||
_isFilterFollowDoc(false), _isFolderFollowDoc(false),\
|
||||
_searchMode(normal), _transparencyMode(onLossingFocus), _transparency(150)
|
||||
_searchMode(normal), _transparencyMode(onLossingFocus), _transparency(150),
|
||||
_dotMatchesNewline(false)
|
||||
|
||||
{};
|
||||
int _nbMaxFindHistoryPath;
|
||||
|
@ -978,6 +979,7 @@ struct FindHistory {
|
|||
bool _isMatchCase;
|
||||
bool _isWrap;
|
||||
bool _isDirectionDown;
|
||||
bool _dotMatchesNewline;
|
||||
|
||||
bool _isFifRecuisive;
|
||||
bool _isFifInHiddenFolder;
|
||||
|
|
|
@ -343,16 +343,12 @@ void FindReplaceDlg::fillFindHistory()
|
|||
::SendDlgItemMessage(_hSelf, IDNORMAL, BM_SETCHECK, findHistory._searchMode == FindHistory::normal, 0);
|
||||
::SendDlgItemMessage(_hSelf, IDEXTENDED, BM_SETCHECK, findHistory._searchMode == FindHistory::extended, 0);
|
||||
::SendDlgItemMessage(_hSelf, IDREGEXP, BM_SETCHECK, findHistory._searchMode == FindHistory::regExpr, 0);
|
||||
::SendDlgItemMessage(_hSelf, IDREDOTMATCHNL, BM_SETCHECK, findHistory._dotMatchesNewline, 0);
|
||||
if (findHistory._searchMode == FindHistory::regExpr)
|
||||
{
|
||||
//regex doesnt allow wholeword
|
||||
::SendDlgItemMessage(_hSelf, IDWHOLEWORD, BM_SETCHECK, BST_UNCHECKED, 0);
|
||||
::EnableWindow(::GetDlgItem(_hSelf, IDWHOLEWORD), (BOOL)false);
|
||||
|
||||
//regex doesnt allow upward search
|
||||
::SendDlgItemMessage(_hSelf, IDDIRECTIONDOWN, BM_SETCHECK, BST_CHECKED, 0);
|
||||
::SendDlgItemMessage(_hSelf, IDDIRECTIONUP, BM_SETCHECK, BST_UNCHECKED, 0);
|
||||
::EnableWindow(::GetDlgItem(_hSelf, IDDIRECTIONUP), (BOOL)false);
|
||||
}
|
||||
|
||||
if (nppParams->isTransparentAvailable())
|
||||
|
@ -993,6 +989,10 @@ BOOL CALLBACK FindReplaceDlg::run_dlgProc(UINT message, WPARAM wParam, LPARAM lP
|
|||
}
|
||||
return TRUE;
|
||||
//Option actions
|
||||
case IDREDOTMATCHNL:
|
||||
findHistory._dotMatchesNewline = _options._dotMatchesNewline = isCheckedOrNot(IDREDOTMATCHNL);
|
||||
return TRUE;
|
||||
|
||||
case IDWHOLEWORD :
|
||||
findHistory._isMatchWord = _options._isWholeWord = isCheckedOrNot(IDWHOLEWORD);
|
||||
return TRUE;
|
||||
|
@ -1008,16 +1008,19 @@ BOOL CALLBACK FindReplaceDlg::run_dlgProc(UINT message, WPARAM wParam, LPARAM lP
|
|||
{
|
||||
_options._searchType = FindRegex;
|
||||
findHistory._searchMode = FindHistory::regExpr;
|
||||
::EnableWindow(GetDlgItem(_hSelf, IDREDOTMATCHNL), true);
|
||||
}
|
||||
else if (isCheckedOrNot(IDEXTENDED))
|
||||
{
|
||||
_options._searchType = FindExtended;
|
||||
findHistory._searchMode = FindHistory::extended;
|
||||
::EnableWindow(GetDlgItem(_hSelf, IDREDOTMATCHNL), false);
|
||||
}
|
||||
else
|
||||
{
|
||||
_options._searchType = FindNormal;
|
||||
findHistory._searchMode = FindHistory::normal;
|
||||
findHistory._searchMode = FindHistory::normal;
|
||||
::EnableWindow(GetDlgItem(_hSelf, IDREDOTMATCHNL), false);
|
||||
}
|
||||
|
||||
bool isRegex = (_options._searchType == FindRegex);
|
||||
|
@ -1027,14 +1030,10 @@ BOOL CALLBACK FindReplaceDlg::run_dlgProc(UINT message, WPARAM wParam, LPARAM lP
|
|||
_options._isWholeWord = false;
|
||||
::SendDlgItemMessage(_hSelf, IDWHOLEWORD, BM_SETCHECK, _options._isWholeWord?BST_CHECKED:BST_UNCHECKED, 0);
|
||||
|
||||
//regex doesnt allow upward search
|
||||
::SendDlgItemMessage(_hSelf, IDDIRECTIONDOWN, BM_SETCHECK, BST_CHECKED, 0);
|
||||
::SendDlgItemMessage(_hSelf, IDDIRECTIONUP, BM_SETCHECK, BST_UNCHECKED, 0);
|
||||
_options._whichDirection = DIR_DOWN;
|
||||
}
|
||||
|
||||
::EnableWindow(::GetDlgItem(_hSelf, IDWHOLEWORD), (BOOL)!isRegex);
|
||||
::EnableWindow(::GetDlgItem(_hSelf, IDDIRECTIONUP), (BOOL)!isRegex);
|
||||
|
||||
return TRUE; }
|
||||
|
||||
case IDWRAP :
|
||||
|
@ -1266,7 +1265,11 @@ bool FindReplaceDlg::processFindNext(const TCHAR *txt2find, const FindOption *op
|
|||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
else if (posFind == -2) // Invalid Regular expression
|
||||
{
|
||||
::MessageBox(_hParent, TEXT("Invalid regular expression"), TEXT("Find"), MB_ICONERROR | MB_OK);
|
||||
return false;
|
||||
}
|
||||
int start = posFind;
|
||||
int end = int((*_ppEditView)->execute(SCI_GETTARGETEND));
|
||||
|
||||
|
@ -1329,6 +1332,11 @@ bool FindReplaceDlg::processReplace(const TCHAR *txt2find, const TCHAR *txt2repl
|
|||
(*_ppEditView)->execute(SCI_SETSEL, start, start + replacedLen);
|
||||
}
|
||||
}
|
||||
else if (posFind == -2) // Invalid Regular expression
|
||||
{
|
||||
::MessageBox(_hParent, TEXT("Invalid regular expression"), TEXT("Find"), MB_ICONERROR | MB_OK);
|
||||
return false;
|
||||
}
|
||||
|
||||
delete [] pTextFind;
|
||||
delete [] pTextReplace;
|
||||
|
@ -1509,11 +1517,12 @@ int FindReplaceDlg::processRange(ProcessOperation op, const TCHAR *txt2find, con
|
|||
(*_ppEditView)->execute(SCI_SETSEARCHFLAGS, flags);
|
||||
targetStart = (*_ppEditView)->searchInTarget(pTextFind, stringSizeFind, startRange, endRange);
|
||||
|
||||
if ((targetStart != -1) && (op == ProcessFindAll)) //add new filetitle if this file results in hits
|
||||
if ((targetStart >= 0) && (op == ProcessFindAll)) //add new filetitle if this file results in hits
|
||||
{
|
||||
_pFinder->addFileNameTitle(fileName);
|
||||
}
|
||||
while (targetStart != -1)
|
||||
|
||||
while (targetStart != -1 && targetStart != -2)
|
||||
{
|
||||
//int posFindBefore = posFind;
|
||||
targetStart = int((*_ppEditView)->execute(SCI_GETTARGETSTART));
|
||||
|
@ -1866,6 +1875,8 @@ void FindReplaceDlg::saveInMacro(int cmd, int cmdType)
|
|||
::SendMessage(_hParent, WM_FRSAVE_STR, IDFINDWHAT, reinterpret_cast<LPARAM>(_options._str2Search.c_str()));
|
||||
booleans |= _options._isWholeWord?IDF_WHOLEWORD:0;
|
||||
booleans |= _options._isMatchCase?IDF_MATCHCASE:0;
|
||||
booleans |= _options._dotMatchesNewline?IDF_REDOTMATCHNL:0;
|
||||
|
||||
::SendMessage(_hParent, WM_FRSAVE_INT, IDNORMAL, _options._searchType);
|
||||
if (cmd == IDCMARKALL)
|
||||
{
|
||||
|
@ -1911,6 +1922,7 @@ void FindReplaceDlg::execSavedCommand(int cmd, int intValue, generic_string stri
|
|||
_env->_isInSelection = ((intValue & IDF_IN_SELECTION_CHECK)> 0);
|
||||
_env->_isWrapAround = ((intValue & IDF_WRAP)> 0);
|
||||
_env->_whichDirection = ((intValue & IDF_WHICH_DIRECTION)> 0);
|
||||
_env->_dotMatchesNewline = ((intValue & IDF_REDOTMATCHNL)> 0);
|
||||
break;
|
||||
case IDNORMAL:
|
||||
_env->_searchType = (SearchType)intValue;
|
||||
|
@ -2063,6 +2075,7 @@ void FindReplaceDlg::initOptionsFromDlg()
|
|||
_options._isWrapAround = isCheckedOrNot(IDWRAP);
|
||||
_options._isInSelection = isCheckedOrNot(IDC_IN_SELECTION_CHECK);
|
||||
|
||||
_options._dotMatchesNewline = isCheckedOrNot(IDREDOTMATCHNL);
|
||||
_options._doPurge = isCheckedOrNot(IDC_PURGE_CHECK);
|
||||
_options._doMarkLine = isCheckedOrNot(IDC_MARKLINE_CHECK);
|
||||
|
||||
|
|
|
@ -30,6 +30,8 @@
|
|||
#include "DockingDlgInterface.h"
|
||||
#endif //DOCKINGDLGINTERFACE_H
|
||||
|
||||
#include "BoostRegexSearch.h"
|
||||
|
||||
#define FIND_RECURSIVE 1
|
||||
#define FIND_INHIDDENDIR 2
|
||||
|
||||
|
@ -78,10 +80,12 @@ struct FindOption
|
|||
generic_string _directory;
|
||||
bool _isRecursive;
|
||||
bool _isInHiddenDir;
|
||||
bool _dotMatchesNewline;
|
||||
FindOption() : _isWholeWord(true), _isMatchCase(true), _searchType(FindNormal),\
|
||||
_isWrapAround(true), _whichDirection(DIR_DOWN), _incrementalType(NotIncremental),
|
||||
_doPurge(false), _doMarkLine(false),
|
||||
_isInSelection(false), _isRecursive(true), _isInHiddenDir(false),
|
||||
_isInSelection(false), _isRecursive(true), _isInHiddenDir(false),
|
||||
_dotMatchesNewline(false),
|
||||
_filters(TEXT("")), _directory(TEXT("")) {};
|
||||
};
|
||||
|
||||
|
@ -93,7 +97,8 @@ public:
|
|||
static int buildSearchFlags(const FindOption * option) {
|
||||
return (option->_isWholeWord ? SCFIND_WHOLEWORD : 0) |
|
||||
(option->_isMatchCase ? SCFIND_MATCHCASE : 0) |
|
||||
(option->_searchType == FindRegex ? SCFIND_REGEXP|SCFIND_POSIX : 0);
|
||||
(option->_searchType == FindRegex ? SCFIND_REGEXP|SCFIND_POSIX : 0) |
|
||||
((option->_searchType == FindRegex && option->_dotMatchesNewline) ? SCFIND_REGEXP_DOTMATCHESNL : 0);
|
||||
};
|
||||
static void displaySectionCentered(int posStart, int posEnd, ScintillaEditView * pEditView, bool isDownwards = true);
|
||||
|
||||
|
|
|
@ -51,11 +51,11 @@ BEGIN
|
|||
CONTROL "Match &whole word only",IDWHOLEWORD,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,88,140,15
|
||||
CONTROL "Match &case",IDMATCHCASE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,100,140,15
|
||||
CONTROL "Wra&p around",IDWRAP,"Button",BS_AUTOCHECKBOX | BS_MULTILINE | WS_TABSTOP,12,112,110,15
|
||||
GROUPBOX "Search Mode",IDC_MODE_STATIC,6,131,156,48
|
||||
GROUPBOX "Search Mode",IDC_MODE_STATIC,6,131,159,48
|
||||
CONTROL "&Normal",IDNORMAL,"Button",BS_AUTORADIOBUTTON | WS_GROUP,12,143,126,10
|
||||
CONTROL "E&xtended (\\n, \\r, \\t, \\0, \\x...)",IDEXTENDED,
|
||||
"Button",BS_AUTORADIOBUTTON,12,155,145,10
|
||||
CONTROL "Re&gular expression",IDREGEXP,"Button",BS_AUTORADIOBUTTON,12,167,139,10
|
||||
CONTROL "Re&gular expression",IDREGEXP,"Button",BS_AUTORADIOBUTTON,12,167,78,10
|
||||
CONTROL "&Up",IDDIRECTIONUP,"Button",BS_AUTORADIOBUTTON | WS_GROUP | WS_TABSTOP,177,143,64,12
|
||||
CONTROL "&Down",IDDIRECTIONDOWN,"Button",BS_AUTORADIOBUTTON | WS_TABSTOP,177,155,63,12
|
||||
GROUPBOX "Direction",IDC_DIR_STATIC,172,131,74,48,WS_GROUP
|
||||
|
@ -74,6 +74,7 @@ BEGIN
|
|||
CONTROL "On losing focus",IDC_TRANSPARENT_LOSSFOCUS_RADIO,"Button",BS_AUTORADIOBUTTON | WS_TABSTOP,268,143,86,10
|
||||
CONTROL "Always",IDC_TRANSPARENT_ALWAYS_RADIO,"Button",BS_AUTORADIOBUTTON | WS_TABSTOP,268,155,83,10
|
||||
CONTROL "",IDC_PERCENTAGE_SLIDER,"msctls_trackbar32",TBS_BOTH | TBS_NOTICKS | NOT WS_VISIBLE | WS_TABSTOP,271,166,53,10
|
||||
CONTROL "&. matches newline",IDREDOTMATCHNL,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,93,167,67,9
|
||||
END
|
||||
|
||||
IDB_INCREMENTAL_BG BITMAP "..\\icons\\incrementalBg.bmp"
|
||||
|
|
|
@ -107,6 +107,8 @@
|
|||
|
||||
#define IDC_FRCOMMAND_INIT 1700
|
||||
#define IDC_FRCOMMAND_EXEC 1701
|
||||
#define IDC_FRCOMMAND_BOOLEANS 1702
|
||||
#define IDC_FRCOMMAND_BOOLEANS 1702
|
||||
|
||||
#define IDREDOTMATCHNL 1703
|
||||
#define IDF_REDOTMATCHNL 1024
|
||||
#endif //FINDREPLACE_DLG_H
|
||||
|
|
|
@ -19,14 +19,14 @@
|
|||
#include "xmlMatchedTagsHighlighter.h"
|
||||
#include "ScintillaEditView.h"
|
||||
|
||||
int XmlMatchedTagsHighlighter::getFirstTokenPosFrom(int targetStart, int targetEnd, const char *token, pair<int, int> & foundPos)
|
||||
int XmlMatchedTagsHighlighter::getFirstTokenPosFrom(int targetStart, int targetEnd, const char *token, bool isRegex, pair<int, int> & foundPos)
|
||||
{
|
||||
//int start = currentPos;
|
||||
//int end = (direction == DIR_LEFT)?0:_pEditView->getCurrentDocLen();
|
||||
|
||||
_pEditView->execute(SCI_SETTARGETSTART, targetStart);
|
||||
_pEditView->execute(SCI_SETTARGETEND, targetEnd);
|
||||
_pEditView->execute(SCI_SETSEARCHFLAGS, SCFIND_REGEXP|SCFIND_POSIX);
|
||||
_pEditView->execute(SCI_SETSEARCHFLAGS, isRegex ? (SCFIND_REGEXP|SCFIND_POSIX) : 0);
|
||||
int posFind = _pEditView->execute(SCI_SEARCHINTARGET, (WPARAM)strlen(token), (LPARAM)token);
|
||||
if (posFind != -1)
|
||||
{
|
||||
|
@ -42,8 +42,8 @@ TagCateg XmlMatchedTagsHighlighter::getTagCategory(XmlMatchedTagsPos & tagsPos,
|
|||
|
||||
int docLen = _pEditView->getCurrentDocLen();
|
||||
|
||||
int gtPos = getFirstTokenPosFrom(curPos, 0, ">", foundPos);
|
||||
int ltPos = getFirstTokenPosFrom(curPos, 0, "<", foundPos);
|
||||
int gtPos = getFirstTokenPosFrom(curPos, 0, ">", false, foundPos);
|
||||
int ltPos = getFirstTokenPosFrom(curPos, 0, "<", false, foundPos);
|
||||
if (ltPos != -1)
|
||||
{
|
||||
if ((gtPos != -1) && (ltPos < gtPos))
|
||||
|
@ -63,8 +63,8 @@ TagCateg XmlMatchedTagsHighlighter::getTagCategory(XmlMatchedTagsPos & tagsPos,
|
|||
|
||||
// so now we are sure we have tag sign '<'
|
||||
// We'll see on the right
|
||||
int gtPosOnR = getFirstTokenPosFrom(curPos, docLen, ">", foundPos);
|
||||
int ltPosOnR = getFirstTokenPosFrom(curPos, docLen, "<", foundPos);
|
||||
int gtPosOnR = getFirstTokenPosFrom(curPos, docLen, ">", false, foundPos);
|
||||
int ltPosOnR = getFirstTokenPosFrom(curPos, docLen, "<", false, foundPos);
|
||||
|
||||
if (gtPosOnR == -1)
|
||||
return invalidTag;
|
||||
|
@ -112,7 +112,7 @@ bool XmlMatchedTagsHighlighter::getMatchedTagPos(int searchStart, int searchEnd,
|
|||
bool direction = searchEnd > searchStart;
|
||||
|
||||
pair<int, int> foundPos;
|
||||
int ltPosOnR = getFirstTokenPosFrom(searchStart, searchEnd, tag2find, foundPos);
|
||||
int ltPosOnR = getFirstTokenPosFrom(searchStart, searchEnd, tag2find, true, foundPos);
|
||||
if (ltPosOnR == -1)
|
||||
return false;
|
||||
|
||||
|
@ -150,7 +150,7 @@ bool XmlMatchedTagsHighlighter::getMatchedTagPos(int searchStart, int searchEnd,
|
|||
e = tagsPos.tagCloseStart;
|
||||
}
|
||||
|
||||
int ltTag = getFirstTokenPosFrom(s, e, oppositeTag2find, oppositeTagPos);
|
||||
int ltTag = getFirstTokenPosFrom(s, e, oppositeTag2find, true, oppositeTagPos);
|
||||
|
||||
if (ltTag == -1)
|
||||
{
|
||||
|
@ -174,7 +174,7 @@ bool XmlMatchedTagsHighlighter::getMatchedTagPos(int searchStart, int searchEnd,
|
|||
{
|
||||
for(;;)
|
||||
{
|
||||
ltTag = getFirstTokenPosFrom(ltTag, e, oppositeTag2find, oppositeTagPos);
|
||||
ltTag = getFirstTokenPosFrom(ltTag, e, oppositeTag2find, true, oppositeTagPos);
|
||||
|
||||
if (ltTag == -1)
|
||||
{
|
||||
|
@ -204,7 +204,7 @@ bool XmlMatchedTagsHighlighter::getMatchedTagPos(int searchStart, int searchEnd,
|
|||
{
|
||||
for(;;)
|
||||
{
|
||||
ltTag = getFirstTokenPosFrom(ltTag, e, oppositeTag2find, oppositeTagPos);
|
||||
ltTag = getFirstTokenPosFrom(ltTag, e, oppositeTag2find, true, oppositeTagPos);
|
||||
if (ltTag == -1)
|
||||
{
|
||||
if (direction == search2Left)
|
||||
|
|
|
@ -41,7 +41,7 @@ private:
|
|||
|
||||
ScintillaEditView *_pEditView;
|
||||
|
||||
int getFirstTokenPosFrom(int targetStart, int targetEnd, const char *token, std::pair<int, int> & foundPos);
|
||||
int getFirstTokenPosFrom(int targetStart, int targetEnd, const char *token, bool isRegex, std::pair<int, int> & foundPos);
|
||||
TagCateg getTagCategory(XmlMatchedTagsPos & tagsPos, int curPos);
|
||||
bool getMatchedTagPos(int searchStart, int searchEnd, const char *tag2find, const char *oppositeTag2find, vector<int> oppositeTagFound, XmlMatchedTagsPos & tagsPos);
|
||||
bool getXmlMatchedTagsPos(XmlMatchedTagsPos & tagsPos);
|
||||
|
|
|
@ -228,7 +228,7 @@
|
|||
FavorSizeOrSpeed="1"
|
||||
OmitFramePointers="false"
|
||||
WholeProgramOptimization="false"
|
||||
AdditionalIncludeDirectories="..\src\WinControls\AboutDlg;..\..\scintilla\include;..\include;..\src\WinControls;..\src\WinControls\ImageListSet;..\src\WinControls\OpenSaveFileDialog;..\src\WinControls\SplitterContainer;..\src\WinControls\StaticDialog;..\src\WinControls\TabBar;..\src\WinControls\ToolBar;..\src\MISC\Process;..\src\ScitillaComponent;..\src\MISC;..\src\MISC\SysMsg;..\src\WinControls\StatusBar;..\src;..\src\WinControls\StaticDialog\RunDlg;..\src\tinyxml;..\src\WinControls\ColourPicker;..\src\Win32Explr;..\src\MISC\RegExt;..\src\WinControls\TrayIcon;..\src\WinControls\shortcut;..\src\WinControls\Grid;..\src\WinControls\ContextMenu;..\src\MISC\PluginsManager;..\src\WinControls\Preference;..\src\WinControls\WindowsDlg;..\src\WinControls\TaskList;..\src\WinControls\DockingWnd;..\src\WinControls\ToolTip;..\src\MISC\Exception;..\src\MISC\Common;..\src\tinyxml\tinyXmlA;..\src\WinControls\AnsiCharPanel;..\src\WinControls\ClipboardHistory;..\src\WinControls\FindCharsInRange;..\src\WinControls\VerticalFileSwitcher;..\src\WinControls\ProjectPanel"
|
||||
AdditionalIncludeDirectories="..\src\WinControls\AboutDlg;..\..\scintilla\include;..\include;..\src\WinControls;..\src\WinControls\ImageListSet;..\src\WinControls\OpenSaveFileDialog;..\src\WinControls\SplitterContainer;..\src\WinControls\StaticDialog;..\src\WinControls\TabBar;..\src\WinControls\ToolBar;..\src\MISC\Process;..\src\ScitillaComponent;..\src\MISC;..\src\MISC\SysMsg;..\src\WinControls\StatusBar;..\src;..\src\WinControls\StaticDialog\RunDlg;..\src\tinyxml;..\src\WinControls\ColourPicker;..\src\Win32Explr;..\src\MISC\RegExt;..\src\WinControls\TrayIcon;..\src\WinControls\shortcut;..\src\WinControls\Grid;..\src\WinControls\ContextMenu;..\src\MISC\PluginsManager;..\src\WinControls\Preference;..\src\WinControls\WindowsDlg;..\src\WinControls\TaskList;..\src\WinControls\DockingWnd;..\src\WinControls\ToolTip;..\src\MISC\Exception;..\src\MISC\Common;..\src\tinyxml\tinyXmlA;..\src\WinControls\AnsiCharPanel;..\src\WinControls\ClipboardHistory;..\src\WinControls\FindCharsInRange;..\src\WinControls\VerticalFileSwitcher;..\src\WinControls\ProjectPanel;..\src\WinControls\DocumentMap"
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USE_64BIT_TIME_T;TIXML_USE_STL;TIXMLA_USE_STL;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_WARNINGS;_CRT_NON_CONFORMING_SWPRINTFS=1"
|
||||
GeneratePreprocessedFile="0"
|
||||
StringPooling="true"
|
||||
|
|
|
@ -0,0 +1,94 @@
|
|||
#ifndef ANSIDOCUMENTITERATOR_H_12481491281240
|
||||
#define ANSIDOCUMENTITERATOR_H_12481491281240
|
||||
|
||||
class AnsiDocumentIterator : public std::iterator<std::bidirectional_iterator_tag, char>
|
||||
{
|
||||
public:
|
||||
AnsiDocumentIterator() :
|
||||
m_doc(0),
|
||||
m_pos(0),
|
||||
m_end(0)
|
||||
{
|
||||
}
|
||||
|
||||
AnsiDocumentIterator(Document* doc, int pos, int end) :
|
||||
m_doc(doc),
|
||||
m_pos(pos),
|
||||
m_end(end)
|
||||
{
|
||||
// Check for debug builds
|
||||
PLATFORM_ASSERT(m_pos <= m_end);
|
||||
|
||||
// Ensure for release.
|
||||
if (m_pos > m_end)
|
||||
{
|
||||
m_pos = m_end;
|
||||
}
|
||||
}
|
||||
|
||||
AnsiDocumentIterator(const AnsiDocumentIterator& copy) :
|
||||
m_doc(copy.m_doc),
|
||||
m_pos(copy.m_pos),
|
||||
m_end(copy.m_end)
|
||||
{
|
||||
// Check for debug builds
|
||||
PLATFORM_ASSERT(m_pos <= m_end);
|
||||
|
||||
// Ensure for release.
|
||||
if (m_pos > m_end)
|
||||
{
|
||||
m_pos = m_end;
|
||||
}
|
||||
}
|
||||
|
||||
bool operator == (const AnsiDocumentIterator& other) const
|
||||
{
|
||||
return (ended() == other.ended()) && (m_doc == other.m_doc) && (m_pos == other.m_pos);
|
||||
}
|
||||
|
||||
bool operator != (const AnsiDocumentIterator& other) const
|
||||
{
|
||||
return !(*this == other);
|
||||
}
|
||||
|
||||
char operator * () const
|
||||
{
|
||||
return charAt(m_pos);
|
||||
}
|
||||
|
||||
AnsiDocumentIterator& operator ++ ()
|
||||
{
|
||||
PLATFORM_ASSERT(m_pos < m_end);
|
||||
|
||||
m_pos++;
|
||||
return *this;
|
||||
}
|
||||
|
||||
AnsiDocumentIterator& operator -- ()
|
||||
{
|
||||
m_pos--;
|
||||
return *this;
|
||||
}
|
||||
|
||||
int pos() const
|
||||
{
|
||||
return m_pos;
|
||||
}
|
||||
|
||||
private:
|
||||
char charAt(int position) const
|
||||
{
|
||||
return m_doc->CharAt(position);
|
||||
}
|
||||
|
||||
bool ended() const
|
||||
{
|
||||
return m_pos == m_end;
|
||||
}
|
||||
|
||||
int m_pos;
|
||||
int m_end;
|
||||
Document* m_doc;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -0,0 +1,323 @@
|
|||
/**
|
||||
* Copyright (c) since 2009 Simon Steele - http://untidy.net/
|
||||
* Based on the work of Simon Steele for Programmer's Notepad 2 (http://untidy.net)
|
||||
* Converted from boost::xpressive to boost::regex and performance improvements
|
||||
* (principally caching the compiled regex), and support for UTF8 encoded text
|
||||
* (c) 2012 Dave Brotherstone - Changes for boost::regex
|
||||
*
|
||||
*
|
||||
*/
|
||||
#include <stdlib.h>
|
||||
#include <iterator>
|
||||
#include "scintilla.h"
|
||||
#include "Platform.h"
|
||||
#include "SplitVector.h"
|
||||
#include "Partitioning.h"
|
||||
#include "RunStyles.h"
|
||||
#include "CellBuffer.h"
|
||||
#include "CharClassify.h"
|
||||
#include "Decoration.h"
|
||||
#include "ILexer.h"
|
||||
#include "Document.h"
|
||||
#include "UniConversion.h"
|
||||
#include "UTF8DocumentIterator.h"
|
||||
#include "AnsiDocumentIterator.h"
|
||||
#include "BoostRegexSearch.h"
|
||||
#include <boost/regex.hpp>
|
||||
#define CP_UTF8 65001
|
||||
#define SC_CP_UTF8 65001
|
||||
|
||||
|
||||
|
||||
#ifdef SCI_NAMESPACE
|
||||
using namespace Scintilla;
|
||||
#endif
|
||||
|
||||
using namespace boost;
|
||||
|
||||
|
||||
typedef basic_regex<char> charregex_t;
|
||||
typedef boost::wregex wcharregex_t;
|
||||
// , std::vector<boost::sub_match<DocumentIterator> >::allocator_type
|
||||
typedef match_results<UTF8DocumentIterator> utf8match_t;
|
||||
typedef match_results<AnsiDocumentIterator> ansimatch_t;
|
||||
|
||||
class BoostRegexSearch : public RegexSearchBase
|
||||
{
|
||||
public:
|
||||
BoostRegexSearch() : substituted(NULL), lastCompileFlags(-1) {}
|
||||
|
||||
virtual ~BoostRegexSearch()
|
||||
{
|
||||
if (substituted)
|
||||
{
|
||||
delete [] substituted;
|
||||
substituted = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
virtual long FindText(Document* doc, int minPos, int maxPos, const char *s,
|
||||
bool caseSensitive, bool word, bool wordStart, int flags, int *length);
|
||||
|
||||
|
||||
|
||||
virtual const char *SubstituteByPosition(Document* doc, const char *text, int *length);
|
||||
|
||||
private:
|
||||
wchar_t *utf8ToWchar(const char *utf8);
|
||||
char *wcharToUtf8(const wchar_t *w);
|
||||
|
||||
charregex_t m_charre;
|
||||
wcharregex_t m_wcharre;
|
||||
|
||||
utf8match_t m_utf8match;
|
||||
ansimatch_t m_ansimatch;
|
||||
|
||||
char *substituted;
|
||||
std::string m_lastRegexString;
|
||||
std::string m_lastRegexUtf8string;
|
||||
int lastCompileFlags;
|
||||
};
|
||||
|
||||
#ifdef SCI_NAMESPACE
|
||||
namespace Scintilla
|
||||
{
|
||||
#endif
|
||||
|
||||
RegexSearchBase *CreateRegexSearch(CharClassify* /* charClassTable */)
|
||||
{
|
||||
return new BoostRegexSearch();
|
||||
}
|
||||
|
||||
#ifdef SCI_NAMESPACE
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Find text in document, supporting both forward and backward
|
||||
* searches (just pass minPos > maxPos to do a backward search)
|
||||
*/
|
||||
|
||||
|
||||
long BoostRegexSearch::FindText(Document* doc, int minPos, int maxPos, const char *s,
|
||||
bool caseSensitive, bool /*word*/, bool /*wordStart*/, int searchFlags, int *length)
|
||||
{
|
||||
int startPos, endPos, increment;
|
||||
|
||||
if (minPos > maxPos)
|
||||
{
|
||||
startPos = maxPos;
|
||||
endPos = minPos;
|
||||
increment = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
startPos = minPos;
|
||||
endPos = maxPos;
|
||||
increment = 1;
|
||||
}
|
||||
|
||||
// Range endpoints should not be inside DBCS characters, but just in case, move them.
|
||||
startPos = doc->MovePositionOutsideChar(startPos, 1, false);
|
||||
endPos = doc->MovePositionOutsideChar(endPos, 1, false);
|
||||
|
||||
|
||||
int compileFlags(regex_constants::ECMAScript);
|
||||
if (!caseSensitive)
|
||||
{
|
||||
compileFlags |= regex_constants::icase;
|
||||
}
|
||||
bool isUtf8 = (doc->CodePage() == SC_CP_UTF8);
|
||||
|
||||
try
|
||||
{
|
||||
|
||||
if (compileFlags != lastCompileFlags
|
||||
|| (isUtf8 && m_lastRegexUtf8string != s)
|
||||
|| (!isUtf8 && m_lastRegexString != s)) // Test to see if we're called with the same
|
||||
// regex as last time, if we are, then we don't need to recompile it
|
||||
{
|
||||
if (isUtf8)
|
||||
{
|
||||
const wchar_t* wchars = utf8ToWchar(s);
|
||||
m_wcharre = wcharregex_t(wchars, static_cast<regex_constants::syntax_option_type>(compileFlags));
|
||||
delete [] wchars;
|
||||
m_lastRegexUtf8string = s;
|
||||
}
|
||||
else
|
||||
{ // Ansi
|
||||
m_charre = charregex_t(s, static_cast<regex_constants::syntax_option_type>(compileFlags));
|
||||
m_lastRegexString = s;
|
||||
}
|
||||
lastCompileFlags = compileFlags;
|
||||
}
|
||||
}
|
||||
|
||||
catch(regex_error& /*ex*/)
|
||||
{
|
||||
// -1 is normally used for not found, -2 is used here for invalid regex
|
||||
return -2;
|
||||
}
|
||||
|
||||
// Work out the range of lines we're searching across, moving beyond an empty end-of-line
|
||||
int lineRangeStart = doc->LineFromPosition(startPos);
|
||||
int lineRangeEnd = doc->LineFromPosition(endPos);
|
||||
if ((increment == 1) &&
|
||||
(startPos >= doc->LineEnd(lineRangeStart)) &&
|
||||
(lineRangeStart < lineRangeEnd))
|
||||
{
|
||||
// the start position is at end of line or between line end characters.
|
||||
lineRangeStart++;
|
||||
startPos = doc->LineStart(lineRangeStart);
|
||||
}
|
||||
|
||||
regex_constants::match_flag_type flags(regex_constants::match_default);
|
||||
|
||||
|
||||
|
||||
// Work out the flags:
|
||||
if (startPos != doc->LineStart(lineRangeStart))
|
||||
{
|
||||
flags |= regex_constants::match_not_bol;
|
||||
}
|
||||
|
||||
if (endPos != doc->LineEnd(lineRangeEnd))
|
||||
{
|
||||
flags |= regex_constants::match_not_eol;
|
||||
}
|
||||
|
||||
if (0 == (searchFlags & SCFIND_REGEXP_DOTMATCHESNL))
|
||||
{
|
||||
flags |= regex_constants::match_not_dot_newline;
|
||||
}
|
||||
|
||||
int pos(-1);
|
||||
int lenRet(0);
|
||||
|
||||
|
||||
if (doc->CodePage() == SC_CP_UTF8)
|
||||
{
|
||||
UTF8DocumentIterator end(doc, endPos, endPos);
|
||||
bool success = boost::regex_search(UTF8DocumentIterator(doc, startPos, endPos), end, m_utf8match, m_wcharre, flags);
|
||||
if (success)
|
||||
{
|
||||
pos = m_utf8match[0].first.pos();
|
||||
lenRet = m_utf8match[0].second.pos() - pos;
|
||||
|
||||
if (increment == -1)
|
||||
{
|
||||
// Check for the last match on this line.
|
||||
int repetitions = 100; // Break out of infinite loop
|
||||
int previousPos = pos;
|
||||
while (success && ((pos + lenRet) <= endPos))
|
||||
{
|
||||
if (previousPos >= pos && 0 >= (--repetitions))
|
||||
break;
|
||||
previousPos = pos;
|
||||
success = regex_search(UTF8DocumentIterator(doc, pos + 1, endPos), end, m_utf8match, m_wcharre, flags);
|
||||
// success = regex_search(DocumentIterator(doc, pos + 1, endPos), end, match, re, static_cast<regex_constants::match_flag_type>(flags));
|
||||
if (success)
|
||||
{
|
||||
if ((pos + lenRet) <= minPos)
|
||||
{
|
||||
pos = m_utf8match[0].first.pos();
|
||||
lenRet = m_utf8match[0].second.pos() - pos;
|
||||
}
|
||||
else
|
||||
{
|
||||
success = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
*length = lenRet;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
AnsiDocumentIterator end(doc, endPos, endPos);
|
||||
|
||||
bool success = boost::regex_search(AnsiDocumentIterator(doc, startPos, endPos), end, m_ansimatch, m_charre, flags);
|
||||
if (success)
|
||||
{
|
||||
pos = m_ansimatch[0].first.pos();
|
||||
lenRet = m_ansimatch.length();
|
||||
|
||||
if (increment == -1)
|
||||
{
|
||||
// Check for the last match on this line.
|
||||
int repetitions = 100; // Break out of infinite loop
|
||||
int previousPos = pos;
|
||||
while (success && ((pos + lenRet) <= endPos))
|
||||
{
|
||||
if (previousPos >= pos && 0 >= (--repetitions))
|
||||
break;
|
||||
previousPos = pos;
|
||||
success = regex_search(AnsiDocumentIterator(doc, pos + 1, endPos), end, m_ansimatch, m_charre, flags);
|
||||
// success = regex_search(DocumentIterator(doc, pos + 1, endPos), end, match, re, static_cast<regex_constants::match_flag_type>(flags));
|
||||
if (success)
|
||||
{
|
||||
if ((pos + lenRet) <= minPos)
|
||||
{
|
||||
pos = m_ansimatch[0].first.pos();
|
||||
lenRet = m_ansimatch[0].length();
|
||||
}
|
||||
else
|
||||
{
|
||||
success = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
*length = lenRet;
|
||||
}
|
||||
}
|
||||
|
||||
return pos;
|
||||
}
|
||||
|
||||
|
||||
const char *BoostRegexSearch::SubstituteByPosition(Document* doc, const char *text, int *length) {
|
||||
delete []substituted;
|
||||
substituted = NULL;
|
||||
if (doc->CodePage() == SC_CP_UTF8)
|
||||
{
|
||||
const wchar_t* wtext = utf8ToWchar(text);
|
||||
std::wstring replaced = m_utf8match.format(wtext, boost::format_all);
|
||||
delete[] wtext;
|
||||
substituted = wcharToUtf8(replaced.c_str());
|
||||
*length = strlen(substituted);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::string replaced = m_ansimatch.format(text, boost::format_all);
|
||||
*length = replaced.size();
|
||||
substituted = new char[*length + 1];
|
||||
strcpy(substituted, replaced.c_str());
|
||||
}
|
||||
return substituted;
|
||||
}
|
||||
|
||||
wchar_t *BoostRegexSearch::utf8ToWchar(const char *utf8)
|
||||
{
|
||||
int utf8Size = strlen(utf8);
|
||||
int wcharSize = UTF16Length(utf8, utf8Size);
|
||||
wchar_t *w = new wchar_t[wcharSize + 1];
|
||||
UTF16FromUTF8(utf8, utf8Size, w, wcharSize + 1);
|
||||
w[wcharSize] = 0;
|
||||
|
||||
return w;
|
||||
}
|
||||
|
||||
char* BoostRegexSearch::wcharToUtf8(const wchar_t *w)
|
||||
{
|
||||
int wcharSize = wcslen(w);
|
||||
int charSize = UTF8Length(w, wcharSize);
|
||||
char *c = new char[charSize + 1];
|
||||
UTF8FromUTF16(w, wcharSize, c, charSize);
|
||||
c[charSize] = 0;
|
||||
return c;
|
||||
}
|
|
@ -0,0 +1,88 @@
|
|||
@ECHO OFF
|
||||
:: Perform the pre-steps to build boost and set the boost path for the build file
|
||||
|
||||
:: TODO - Shift stuff to get the boost path / check/display usage
|
||||
|
||||
SET BOOSTPATH=%1
|
||||
|
||||
IF NOT EXIST "%BOOSTPATH%\boost\regex.hpp" (
|
||||
GOTO BOOSTNOTFOUND
|
||||
)
|
||||
|
||||
IF NOT EXIST "%BOOSTPATH%\bjam\bin\bjam.exe" (
|
||||
ECHO Building BJAM, the boost build tool
|
||||
PUSHD %BOOSTPATH%\tools\build\v2
|
||||
CALL bootstrap.bat
|
||||
|
||||
%BOOSTPATH%\tools\build\v2\b2 --prefix=%BOOSTPATH%\bjam install
|
||||
)
|
||||
|
||||
IF NOT ERRORLEVEL 0 (
|
||||
GOTO BUILDERROR
|
||||
)
|
||||
|
||||
ECHO.
|
||||
ECHO Building Boost::regex
|
||||
|
||||
CD %BOOSTPATH%\libs\regex\build
|
||||
|
||||
%BOOSTPATH%\bjam\bin\bjam variant=release threading=multi link=static runtime-link=static
|
||||
IF NOT ERRORLEVEL 0 (
|
||||
GOTO BUILDERROR
|
||||
)
|
||||
|
||||
%BOOSTPATH%\bjam\bin\bjam variant=debug threading=multi link=static runtime-link=static
|
||||
IF NOT ERRORLEVEL 0 (
|
||||
GOTO BUILDERROR
|
||||
)
|
||||
|
||||
IF EXIST "%BOOSTPATH%\bin.v2\libs\regex\build\msvc-8.0" (
|
||||
SET BOOSTVSVERPATH=%BOOSTPATH%\bin.v2\libs\regex\build\msvc-8.0
|
||||
) ELSE IF EXIST "%BOOSTPATH%\bin.v2\libs\regex\build\msvc-9.0" (
|
||||
SET BOOSTVSVERPATH=%BOOSTPATH%\bin.v2\libs\regex\build\msvc-9.0
|
||||
) ELSE IF EXIST "%BOOSTPATH%\bin.v2\libs\regex\build\msvc-10.0" (
|
||||
SET BOOSTVSVERPATH=%BOOSTPATH%\bin.v2\libs\regex\build\msvc-10.0
|
||||
)
|
||||
|
||||
ECHO # Autogenerated file, run BuildBoost.bat [path_to_boost] to generate > %~dp0%\boostpath.mak
|
||||
ECHO BOOSTPATH=%BOOSTPATH% >> %~dp0%\boostpath.mak
|
||||
ECHO BOOSTVSVERPATH=%BOOSTVSVERPATH% >> %~dp0%\boostpath.mak
|
||||
|
||||
POPD
|
||||
|
||||
ECHO Boost::regex built.
|
||||
ECHO.
|
||||
ECHO Now you need to build scintilla.
|
||||
ECHO First, edit the scintilla\win32\scintilla.mak, and make sure there's a line in there that says
|
||||
ECHO.
|
||||
ECHO !INCLUDE ../boostregex/nppSpecifics.mak
|
||||
ECHO.
|
||||
ECHO just after all the LOBJS have been defined (it's around line 211)
|
||||
ECHO If not, add it in.
|
||||
ECHO Then, from the scintilla\win32 directory
|
||||
ECHO.
|
||||
ECHO nmake -f scintilla.mak
|
||||
ECHO.
|
||||
ECHO.
|
||||
|
||||
GOTO EOF
|
||||
|
||||
:BOOSTNOTFOUND
|
||||
ECHO Boost Path not valid. Run BuildBoost.bat with the directory where you unpacked your boost zip
|
||||
ECHO Boost is available free from www.boost.org
|
||||
ECHO.
|
||||
ECHO e.g.
|
||||
ECHO buildboost.bat d:\libs\boost_1_48_0
|
||||
|
||||
GOTO EOF
|
||||
|
||||
|
||||
:BUILDERROR
|
||||
ECHO There was an error building boost. Please see the messages above for details.
|
||||
ECHO - Have you got a clean extract from a recent boost version, such as 1.48?
|
||||
ECHO - Download a fresh copy from www.boost.org and extract it to a directory,
|
||||
ECHO and run the batch again with the name of that directory
|
||||
|
||||
:EOF
|
||||
|
||||
|
|
@ -0,0 +1,57 @@
|
|||
#include "UTF8DocumentIterator.h"
|
||||
|
||||
|
||||
void UTF8DocumentIterator::readCharacter()
|
||||
{
|
||||
unsigned char currentChar = m_doc->CharAt(m_pos);
|
||||
if (currentChar & 0x80)
|
||||
{
|
||||
int mask = 0x40;
|
||||
int nBytes = 1;
|
||||
|
||||
do
|
||||
{
|
||||
mask >>= 1;
|
||||
++nBytes;
|
||||
} while (currentChar & mask);
|
||||
|
||||
int result = currentChar & m_firstByteMask[nBytes];
|
||||
int pos = m_pos;
|
||||
m_utf8Length = 1;
|
||||
// work out the unicode point, and count the actual bytes.
|
||||
// If a byte does not start with 10xxxxxx then it's not part of the
|
||||
// the code. Therefore invalid UTF-8 encodings are dealt with, simply by stopping when
|
||||
// the UTF8 extension bytes are no longer valid.
|
||||
while ((--nBytes) && (pos < m_end) && (0x80 == ((currentChar = m_doc->CharAt(++pos)) & 0xC0)))
|
||||
{
|
||||
result = (result << 6) | (currentChar & 0x3F);
|
||||
++m_utf8Length;
|
||||
}
|
||||
|
||||
if (result >= 0x10000)
|
||||
{
|
||||
result -= 0x10000;
|
||||
m_utf16Length = 2;
|
||||
// UTF-16 Pair
|
||||
m_character[0] = 0xD800 + (result >> 10);
|
||||
m_character[1] = 0xDC00 + (result & 0x3FF);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
m_utf16Length = 1;
|
||||
m_character[0] = static_cast<wchar_t>(result);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_utf8Length = 1;
|
||||
m_utf16Length = 1;
|
||||
m_characterIndex = 0;
|
||||
m_character[0] = static_cast<wchar_t>(currentChar);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
const unsigned char UTF8DocumentIterator::m_firstByteMask[7] = { 0x7F, 0x3F, 0x1F, 0x0F, 0x07, 0x03, 0x01 };
|
||||
|
|
@ -0,0 +1,149 @@
|
|||
#ifndef UTF8DOCUMENTITERATOR_H_3452843291318441149
|
||||
#define UTF8DOCUMENTITERATOR_H_3452843291318441149
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <iterator>
|
||||
#include "Platform.h"
|
||||
#include "SplitVector.h"
|
||||
#include "Partitioning.h"
|
||||
#include "RunStyles.h"
|
||||
#include "CellBuffer.h"
|
||||
#include "CharClassify.h"
|
||||
#include "Decoration.h"
|
||||
#include <ILexer.h>
|
||||
#include <Document.h>
|
||||
|
||||
class UTF8DocumentIterator : public std::iterator<std::bidirectional_iterator_tag, wchar_t>
|
||||
{
|
||||
public:
|
||||
UTF8DocumentIterator() :
|
||||
m_doc(0),
|
||||
m_pos(0),
|
||||
m_end(0),
|
||||
m_characterIndex(0),
|
||||
m_utf8Length(0),
|
||||
m_utf16Length(0)
|
||||
{
|
||||
}
|
||||
|
||||
UTF8DocumentIterator(Document* doc, int pos, int end) :
|
||||
m_doc(doc),
|
||||
m_pos(pos),
|
||||
m_end(end),
|
||||
m_characterIndex(0)
|
||||
{
|
||||
// Check for debug builds
|
||||
PLATFORM_ASSERT(m_pos <= m_end);
|
||||
|
||||
// Ensure for release.
|
||||
if (m_pos > m_end)
|
||||
{
|
||||
m_pos = m_end;
|
||||
}
|
||||
readCharacter();
|
||||
}
|
||||
|
||||
UTF8DocumentIterator(const UTF8DocumentIterator& copy) :
|
||||
m_doc(copy.m_doc),
|
||||
m_pos(copy.m_pos),
|
||||
m_end(copy.m_end),
|
||||
m_characterIndex(copy.m_characterIndex),
|
||||
m_utf8Length(copy.m_utf8Length),
|
||||
m_utf16Length(copy.m_utf16Length)
|
||||
{
|
||||
// Check for debug builds
|
||||
PLATFORM_ASSERT(m_pos <= m_end);
|
||||
m_character[0] = copy.m_character[0];
|
||||
m_character[1] = copy.m_character[1];
|
||||
|
||||
// Ensure for release.
|
||||
if (m_pos > m_end)
|
||||
{
|
||||
m_pos = m_end;
|
||||
}
|
||||
}
|
||||
|
||||
bool operator == (const UTF8DocumentIterator& other) const
|
||||
{
|
||||
return (ended() == other.ended()) && (m_doc == other.m_doc) && (m_pos == other.m_pos);
|
||||
}
|
||||
|
||||
bool operator != (const UTF8DocumentIterator& other) const
|
||||
{
|
||||
return !(*this == other);
|
||||
}
|
||||
|
||||
wchar_t operator * () const
|
||||
{
|
||||
return m_character[m_characterIndex];
|
||||
}
|
||||
|
||||
UTF8DocumentIterator& operator = (int other)
|
||||
{
|
||||
m_pos = other;
|
||||
return *this;
|
||||
}
|
||||
|
||||
UTF8DocumentIterator& operator ++ ()
|
||||
{
|
||||
PLATFORM_ASSERT(m_pos < m_end);
|
||||
if (2 == m_utf16Length && 0 == m_characterIndex)
|
||||
{
|
||||
m_characterIndex = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_pos += m_utf8Length;
|
||||
m_characterIndex = 0;
|
||||
readCharacter();
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
UTF8DocumentIterator& operator -- ()
|
||||
{
|
||||
if (m_utf16Length == 2 && m_characterIndex == 1)
|
||||
{
|
||||
m_characterIndex = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
--m_pos;
|
||||
// Skip past the UTF-8 extension bytes
|
||||
while (0x80 == (m_doc->CharAt(m_pos) & 0xC0))
|
||||
--m_pos;
|
||||
|
||||
readCharacter();
|
||||
if (m_utf16Length == 2)
|
||||
{
|
||||
m_characterIndex = 1;
|
||||
}
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
int pos() const
|
||||
{
|
||||
return m_pos;
|
||||
}
|
||||
|
||||
private:
|
||||
void readCharacter();
|
||||
|
||||
|
||||
bool ended() const
|
||||
{
|
||||
return m_pos == m_end;
|
||||
}
|
||||
|
||||
int m_pos;
|
||||
wchar_t m_character[2];
|
||||
int m_characterIndex;
|
||||
int m_end;
|
||||
int m_utf8Length;
|
||||
int m_utf16Length;
|
||||
Document* m_doc;
|
||||
static const unsigned char m_firstByteMask[];
|
||||
};
|
||||
|
||||
#endif // UTF8DOCUMENTITERATOR_H_3452843291318441149
|
|
@ -0,0 +1,44 @@
|
|||
# This makefile should be included in the main scintilla.mak file,
|
||||
# just after where LOBJS is defined (around line
|
||||
#
|
||||
# The following line should be added around line 211 of scintilla.mak
|
||||
# !INCLUDE nppSpecifics.mak
|
||||
|
||||
# Set your boost path (the root of where you've unpacked your boost zip).
|
||||
# Boost is available from www.boost.org
|
||||
|
||||
!IF EXIST(..\boostregex\boostpath.mak)
|
||||
|
||||
!INCLUDE ..\boostregex\boostpath.mak
|
||||
|
||||
SOBJS=\
|
||||
$(SOBJS)\
|
||||
$(DIR_O)\BoostRegexSearch.obj\
|
||||
$(DIR_O)\UTF8DocumentIterator.obj
|
||||
|
||||
LOBJS=\
|
||||
$(LOBJS)\
|
||||
$(DIR_O)\BoostRegexSearch.obj\
|
||||
$(DIR_O)\UTF8DocumentIterator.obj
|
||||
|
||||
|
||||
INCLUDEDIRS=$(INCLUDEDIRS) -I$(BOOSTPATH)
|
||||
|
||||
CXXFLAGS=$(CXXFLAGS) -DSCI_OWNREGEX
|
||||
!IFDEF DEBUG
|
||||
LDFLAGS=$(LDFLAGS) -LIBPATH:$(BOOSTVSVERPATH)\debug\link-static\runtime-link-static\threading-multi
|
||||
!ELSE
|
||||
LDFLAGS=$(LDFLAGS) -LIBPATH:$(BOOSTVSVERPATH)\release\link-static\runtime-link-static\threading-multi
|
||||
!ENDIF
|
||||
|
||||
|
||||
|
||||
$(DIR_O)\UTF8DocumentIterator.obj:: ../boostregex/UTF8DocumentIterator.cxx
|
||||
$(CC) $(CXXFLAGS) -c ../boostregex/UTF8DocumentIterator.cxx
|
||||
|
||||
$(DIR_O)\BoostRegexSearch.obj:: ../boostregex/BoostRegexSearch.cxx ../src/CharClassify.h ../src/RESearch.h
|
||||
$(CC) $(CXXFLAGS) -c ../boostregex/BoostRegexSearch.cxx
|
||||
|
||||
!ENDIF
|
||||
|
||||
|
|
@ -205,6 +205,8 @@ LOBJS=\
|
|||
$(DIR_O)\WordList.obj \
|
||||
$(DIR_O)\XPM.obj \
|
||||
$(LEXOBJS)
|
||||
|
||||
!INCLUDE ../boostregex/nppSpecifics.mak
|
||||
|
||||
$(DIR_O)\ScintRes.res : ScintRes.rc
|
||||
$(RC) -fo$@ $**
|
||||
|
|
Loading…
Reference in New Issue