Permalink
Browse files

Move Replacement String Parsing from EditorCtrl to separate class.

  • Loading branch information...
1 parent 6b122dd commit 7a21cb6946de7ed4cedf015b3c2da0c6ff15f296 @adamv adamv committed Oct 25, 2009
Showing with 237 additions and 186 deletions.
  1. +4 −166 src/EditorCtrl.cpp
  2. +0 −20 src/EditorCtrl.h
  3. +196 −0 src/ReplaceStringParser.cpp
  4. +29 −0 src/ReplaceStringParser.h
  5. +8 −0 src/e.vcproj
View
@@ -45,6 +45,8 @@
#include "Strings.h"
#include "pcre.h"
+#include "ReplaceStringParser.h"
+
// Document Icons
#include "document.xpm"
@@ -5053,172 +5055,8 @@ cxFindResult EditorCtrl::FindPrevious(const wxString& text, int options) {
}
wxString EditorCtrl::ParseReplaceString(const wxString& replacetext, const map<unsigned int,interval>& captures, const vector<char>* source) const {
- RepParseState state(replacetext, captures, source);
-
- const wxChar *start = replacetext.c_str();
- DoRepParse(state, start, start + replacetext.size());
-
- return state.newtext;
-}
-
-void EditorCtrl::DoRepParse(RepParseState& state, const wxChar* start, const wxChar* end) const {
- wxASSERT(start <= end);
-
- for ( const wxChar *p = start; p < end; ++p ) {
- size_t index = (size_t)-1;
-
- if (*p == wxT('$')) {
- if (wxIsdigit(*++p)) {
- // back reference
- wxChar *end;
- index = (size_t)wxStrtoul(p, &end, 10);
- p = end - 1; // -1 to compensate for p++ in the loop
- }
-
- // do we have a back reference?
- if (index != (size_t)-1) {
- // yes, get its text
- map<unsigned int,interval>::const_iterator iv = state.captures.find(index);
- if ( iv != state.captures.end() ) {
- wxString reftext;
- if (state.source) {
- reftext = wxString(&*state.source->begin() + iv->second.start, wxConvUTF8, iv->second.end - iv->second.start);
- }
- else {
- cxLOCKDOC_READ(m_doc)
- reftext = doc.GetTextPart(iv->second.start, iv->second.end);
- cxENDLOCK
- }
-
- // Case foldings
- if (state.caseChar && !reftext.empty()) {
- if (state.lowcase) reftext[0] = wxTolower(reftext[0]);
- else if (state.upcase) reftext[0] = wxToupper(reftext[0]);
- else wxASSERT(false);
-
- state.caseChar = false;
- state.lowcase = false;
- state.upcase = false;
- }
- else if (state.caseText) {
- if (state.lowcase) reftext.MakeLower();
- else if (state.upcase) reftext.MakeUpper();
- else wxASSERT(false);
- }
-
- state.newtext += reftext;
- }
- }
- }
- else if (*p == wxT('\\')) {
- ++p;
- if (p < end) {
- if (*p == wxT('n')) state.newtext += wxT('\n');
- else if (*p == wxT('t')) state.newtext += m_indent;
- else if (*p == wxT('l')) {
- state.caseChar = true;
- state.lowcase = true;
- state.upcase = false;
- }
- else if (*p == wxT('u')) {
- state.caseChar = true;
- state.lowcase = false;
- state.upcase = true;
- }
- else if (*p == wxT('L')) {
- state.caseText = true;
- state.lowcase = true;
- state.upcase = false;
- }
- else if (*p == wxT('U')) {
- state.caseText = true;
- state.lowcase = false;
- state.upcase = true;
- }
- else if (*p == wxT('E')) {
- state.caseText = false;
- state.caseChar = false;
- state.lowcase = false;
- state.upcase = false;
- }
- else state.newtext += *p;
- }
- else {
- state.newtext += '\\';
- break;
- }
- }
- else if (*p == wxT('(') && *(p+1) == wxT('?')) {
- // Parse condition
- const wxChar* p2 = p+2;
- const wxChar* inStart = NULL;
- const wxChar* inEnd = NULL;
- const wxChar* otStart = NULL;
- const wxChar* otEnd = NULL;
- bool success = false;
-
- if (wxIsdigit(*p2)) {
- // Get capture index
- wxChar *iend;
- unsigned int index = wxStrtoul(p2, &iend, 10);
- p2 = iend;
-
- if (*p2 != wxT(':')) goto error;
- ++p2;
-
- inStart = p2;
- inEnd = p2;
-
- // find insertion end
- unsigned int pcount = 0;
- while(1) {
- if (!inEnd) goto error;
- else if (*inEnd == wxT('\\')) ++inEnd; // ignore escaped chars
- else if (*inEnd == wxT('(')) ++pcount; // count parens
- else if (*inEnd == wxT(')')) if (pcount) --pcount; else break;
- else if (*inEnd == wxT(':')) {
- // find 'otherwise' end
- otStart = otEnd = inEnd + 1;
- pcount = 0;
- while(1) {
- if (!otEnd) goto error;
- else if (*otEnd == wxT('\\')) ++otEnd; // ignore escaped chars
- else if (*otEnd == wxT('(')) ++pcount; // count parens
- else if (*otEnd == wxT(')')) {if (pcount) --pcount; else break;}
- ++otEnd;
- }
- break;
- }
- ++inEnd;
- }
-
- // parse the part that meet condition
- map<unsigned int,interval>::const_iterator iv = state.captures.find(index);
- if (iv != state.captures.end()) {
- DoRepParse(state, inStart, inEnd);
- }
- else if (otStart) {
- DoRepParse(state, otStart, otEnd);
- }
- success = true;
- }
-
-error:
- if (success) p = otEnd ? otEnd : inEnd;
- else state.newtext += *p; // ordinary character
-
- }
- else {
- if (state.caseChar || state.caseText) {
- if (state.lowcase) state.newtext += wxTolower(*p);
- else if (state.upcase) state.newtext += wxToupper(*p);
- else wxASSERT(false);
-
- state.caseChar = false;
- }
- else state.newtext += *p; // ordinary character
- }
- }
+ ReplaceStringParser parser(m_doc, m_indent, replacetext, captures, source);
+ return parser.Parse();
}
search_result EditorCtrl::RegExFind(const pcre* re, const pcre_extra* study, unsigned int start_pos, map<unsigned int,interval> *captures, unsigned int end_pos, int search_options) const {
View
@@ -375,25 +375,6 @@ class EditorCtrl : public KeyHookable<wxControl>,
virtual void UpdateParentPanels();
private:
- // Classes
- class RepParseState {
- public:
- RepParseState(const wxString& reptext, const map<unsigned int,interval>& caps, const vector<char>* source=NULL):
- replacetext(reptext), captures(caps), source(source), upcase(false), lowcase(false), caseChar(false), caseText(false)
- {
- newtext.reserve(replacetext.size());
- };
- // member variables
- const wxString& replacetext;
- const map<unsigned int,interval>& captures;
- const vector<char>* source;
- wxString newtext;
- bool upcase;
- bool lowcase;
- bool caseChar;
- bool caseText;
- };
-
// Embedded class: DragDropTarget
class DragDropTarget : public wxDropTarget {
public:
@@ -497,7 +478,6 @@ class EditorCtrl : public KeyHookable<wxControl>,
wxString GetCurrentLine();
bool DoFind(const wxString& text, unsigned int start_pos, int options=0, bool dir_forward = true);
- void DoRepParse(RepParseState& state, const wxChar* start, const wxChar* end) const;
void GetCompletionMatches(interval wordIv, wxArrayString& result, bool precharbase) const;
Oops, something went wrong.

0 comments on commit 7a21cb6

Please sign in to comment.