char* rx_compile(const gcstring& s) { static CacheMap<10, gcstring, char*> cache; if (char** p = cache.get(s)) return *p; return cache.put(s, RxCompile(s.ptr(), s.size()).compile()); }
static int SetGlobalString(long what, const char *string) { STARTFUNC("SetGlobalString"); LOG << "What: " << what << " String: " << string << ENDLINE; switch (what) { case FLAG_DefaultModeName: strlcpy(DefaultModeName, string, sizeof(DefaultModeName)); break; case FLAG_CompletionFilter: if ((CompletionFilter = RxCompile(string)) == NULL) return -1; break; case FLAG_PrintDevice: strlcpy(PrintDevice, string, sizeof(PrintDevice)); break; case FLAG_CompileCommand: strlcpy(CompileCommand, string, sizeof(CompileCommand)); break; case FLAG_WindowFont: strlcpy(WindowFont, string, sizeof(WindowFont)); break; case FLAG_HelpCommand: strlcpy(HelpCommand, string, sizeof(HelpCommand)); break; case FLAG_GUICharacters: AppendGUICharacters (string); break; #ifdef CONFIG_OBJ_CVS case FLAG_CvsCommand: strlcpy(CvsCommand, string, sizeof(CvsCommand)); break; case FLAG_CvsLogMode: strlcpy(CvsLogMode, string, sizeof(CvsLogMode)); break; #endif #ifdef CONFIG_OBJ_SVN case FLAG_SvnCommand: strlcpy(SvnCommand, string, sizeof(SvnCommand)); break; case FLAG_SvnLogMode: strlcpy(SvnLogMode, string, sizeof(SvnLogMode)); break; #endif case FLAG_RGBColor: SetRGBColor(string); break; case FLAG_XShellCommand: strlcpy(XShellCommand, string, sizeof(XShellCommand)); break; default: //printf("Unknown global string: %ld\n", what); ENDFUNCRC(-1); } ENDFUNCRC(0); }
// FindFunction -- search for line matching 'RoutineRegexp' // starting from current line + 'delta'. 'way' should be +1 or -1. int EBuffer::FindFunction(int delta, int way) { RxNode *regx; int line; PELine L; RxMatchRes res; if (BFS(this, BFS_RoutineRegexp) == 0) { View->MView->Win->Choice(GPC_ERROR, "Error", 1, "O&K", "No routine regexp."); return -1; } regx = RxCompile(BFS(this, BFS_RoutineRegexp)); if (regx == 0) { View->MView->Win->Choice(GPC_ERROR, "Error", 1, "O&K", "Failed to compile regexp '%s'", BFS(this, BFS_RoutineRegexp)); return -1; } //** Scan backwards from the current cursor position, Msg(S_BUSY, "Matching %s", BFS(this, BFS_RoutineRegexp)); line = VToR(CP.Row) + delta; while (line >= 0 && line < RCount) { L = RLine(line); if (RxExec(regx, L->Chars, L->Count, L->Chars, &res) == 1) break; line += way; } if (line < 0) line = 0; if (line >= RCount) line = RCount - 1; RxFree(regx); return line; }
static int SetModeString(EMode *mode, int what, const char *string) { int j = what; #ifdef CONFIG_SYNTAX_HILIT if (j == BFI_Colorizer) { mode->fColorize = FindColorizer(string); } else #endif if (j == BFI_EventMap) { mode->fEventMap = FindEventMap(string); #ifdef CONFIG_INDENT } else if (j == BFI_IndentMode) { mode->Flags.num[j] = GetIndentMode(string); #endif } else if (j == BFS_WordChars) { SetWordChars(mode->Flags.WordChars, string); } else if (j == BFS_CapitalChars) { SetWordChars(mode->Flags.CapitalChars, string); } else if (j == BFS_FileNameRx) { if (mode->MatchName) free(mode->MatchName); if (mode->MatchNameRx) RxFree(mode->MatchNameRx); mode->MatchName = strdup(string); mode->MatchNameRx = RxCompile(string); } else if (j == BFS_FirstLineRx) { if (mode->MatchLine) free(mode->MatchLine); if (mode->MatchLineRx) RxFree(mode->MatchLineRx); mode->MatchLine = strdup(string); mode->MatchLineRx = RxCompile(string); } else { if (mode->Flags.str[j & 0xFF]) free(mode->Flags.str[j & 0xFF]); mode->Flags.str[j & 0xFF] = strdup(string); } return 0; }
int EBuffer::FoldCreateByRegexp(const char *Regexp) { /*FOLD00*/ RxNode *R; int err = 1; if (Modify() == 0) return 0; R = RxCompile(Regexp); if (R != NULL) { PELine X; int first = -1; int L; for (L = 0; L < RCount; L++) { RxMatchRes RM; X = RLine(L); if (RxExec(R, X->Chars, X->Count, X->Chars, &RM) == 1) { if (first >= 0) { int i; for (i = L; i > 0; i--) { PELine Y; Y = RLine(i); if ((Y->Count == 0) || strrchr(Y->Chars, '}')) { if ((L - i) > 2) { while ((i > 0) && (RLine(i - 1)->Count == 0)) i--; if ((first >= 0) && i && (FoldCreate(i) == 0)) err = 0; } break; } } } else first = L; if (FoldCreate(L) == 0) { err = 0; break; } } } RxFree(R); } return err; }
int EBuffer::ScanForRoutines() { RxNode *regx; int line; PELine L; RxMatchRes res; if (BFS(this, BFS_RoutineRegexp) == 0) { View->MView->Win->Choice(GPC_ERROR, "Error", 1, "O&K", "No routine regexp."); return 0; } regx = RxCompile(BFS(this, BFS_RoutineRegexp)); if (regx == 0) { View->MView->Win->Choice(GPC_ERROR, "Error", 1, "O&K", "Failed to compile regexp '%s'", BFS(this, BFS_RoutineRegexp)); return 0; } if (rlst.Lines) { free(rlst.Lines); rlst.Lines = 0; } rlst.Lines = 0; rlst.Count = 0; Msg(S_BUSY, "Matching %s", BFS(this, BFS_RoutineRegexp)); for (line = 0; line < RCount; line++) { L = RLine(line); if (RxExec(regx, L->Chars, L->Count, L->Chars, &res) == 1) { rlst.Count++; rlst.Lines = (int *) realloc((void *) rlst.Lines, sizeof(int) * (rlst.Count | 0x1F)); rlst.Lines[rlst.Count - 1] = line; Msg(S_BUSY, "Routines: %d", rlst.Count); } } RxFree(regx); return 1; }
int AddSvnIgnoreRegexp (const char *regexp) { if (SvnIgnoreRegexpCount>=MAXREGEXP) return 0; if ((SvnIgnoreRegexp[SvnIgnoreRegexpCount]=RxCompile (regexp))==NULL) return 0; SvnIgnoreRegexpCount++; return 1; }
static int ReadColorize(CurPos &cp, EColorize *Colorize, const char *ModeName) { unsigned char obj; unsigned short len; long LastState = -1; while ((obj = GetObj(cp, len)) != 0xFF) { switch (obj) { case CF_COLOR: if (ReadHilitColors(cp, Colorize, ModeName) == -1) return -1; break; case CF_KEYWORD: { const char *colorstr; if ((colorstr = GetCharStr(cp, len)) == 0) return -1; unsigned int Col; unsigned int ColBg, ColFg; if (sscanf(colorstr, "%1X %1X", &ColFg, &ColBg) != 2) return 0; Col = ColFg | (ColBg << 4); int color = ChColor(Col); if (ReadKeywords(cp, &Colorize->Keywords, color) == -1) return -1; } break; case CF_HSTATE: { long stateno; long color; if (Colorize->hm == 0) Colorize->hm = new HMachine(); assert(Colorize->hm != 0); if (GetNum(cp, stateno) == 0) return -1; assert(stateno == LastState + 1); obj = GetObj(cp, len); assert(obj == CF_INT); if (GetNum(cp, color) == 0) return -1; HState newState; newState.InitState(); newState.color = color; Colorize->hm->AddState(newState); LastState = stateno; } break; case CF_HTRANS: { HTrans newTrans; long nextState; long matchFlags; const char *match; long color; if (GetNum(cp, nextState) == 0) return -1; obj = GetObj(cp, len); assert(obj == CF_INT); if (GetNum(cp, matchFlags) == 0) return -1; obj = GetObj(cp, len); assert(obj == CF_INT); if (GetNum(cp, color) == 0) return -1; obj = GetObj(cp, len); assert(matchFlags & MATCH_REGEXP ? obj == CF_REGEXP : obj == CF_STRING); if ((match = GetCharStr(cp, len)) == 0) return -1; newTrans.InitTrans(); newTrans.matchFlags = matchFlags; newTrans.nextState = nextState; newTrans.color = color; if (newTrans.matchFlags & MATCH_REGEXP) { newTrans.regexp = RxCompile(match); newTrans.matchLen = 0; } else if ((newTrans.matchFlags & MATCH_SET) || (newTrans.matchFlags & MATCH_NOTSET)) { newTrans.matchLen = 1; newTrans.match = (char *)malloc(256/8); assert(newTrans.match != NULL); SetWordChars(newTrans.match, match); } else { newTrans.match = strdup(match); newTrans.matchLen = strlen(match); } Colorize->hm->AddTrans(newTrans); } break; case CF_HWTYPE: { long nextKwdMatchedState; long nextKwdNotMatchedState; long nextKwdNoCharState; long options; const char *wordChars; obj = GetObj(cp, len); assert(obj == CF_INT); if (GetNum(cp, nextKwdMatchedState) == 0) return -1; obj = GetObj(cp, len); assert(obj == CF_INT); if (GetNum(cp, nextKwdNotMatchedState) == 0) return -1; obj = GetObj(cp, len); assert(obj == CF_INT); if (GetNum(cp, nextKwdNoCharState) == 0) return -1; obj = GetObj(cp, len); assert(obj == CF_INT); if (GetNum(cp, options) == 0) return -1; obj = GetObj(cp, len); assert(obj == CF_STRING); if ((wordChars = GetCharStr(cp, len)) == 0) return -1; Colorize->hm->LastState()->options = options; Colorize->hm->LastState()->nextKwdMatchedState = nextKwdMatchedState; Colorize->hm->LastState()->nextKwdNotMatchedState = nextKwdNotMatchedState; Colorize->hm->LastState()->nextKwdNoCharState = nextKwdNoCharState; if (wordChars && *wordChars) { Colorize->hm->LastState()->wordChars = (char *)malloc(256/8); assert(Colorize->hm->LastState()->wordChars != NULL); SetWordChars(Colorize->hm->LastState()->wordChars, wordChars); } } break; case CF_HWORDS: { const char *colorstr; int color; if ((colorstr = GetCharStr(cp, len)) == 0) return -1; color = hcPlain_Keyword; if (strcmp(colorstr, "-") != 0) { const char *Value = colorstr; int Col; if (*Value == '-') { Value++; if (sscanf(Value, "%1X", &Col) != 1) return -1; Col |= (hcPlain_Background & 0xF0); } else if (Value[1] == '-') { if (sscanf(Value, "%1X", &Col) != 1) return -1; Col <<= 4; Col |= (hcPlain_Background & 0x0F); } else { unsigned int ColBg, ColFg; if (sscanf(colorstr, "%1X %1X", &ColFg, &ColBg) != 2) return 0; Col = ColFg | (ColBg << 4); } color = Col; } if (ReadKeywords(cp, &Colorize->hm->LastState()->keywords, color) == -1) return -1; } break; case CF_SETVAR: { long what; if (GetNum(cp, what) == 0) return -1; switch (GetObj(cp, len)) { case CF_STRING: { const char *val = GetCharStr(cp, len); if (len == 0) return -1; if (SetColorizeString(Colorize, what, val) != 0) return -1; } break; /* case CF_INT: { long num; if (GetNum(cp, num) == 0) return -1; if (SetModeNumber(Mode, what, num) != 0) return -1; } break;*/ default: return -1; } } break; case CF_END: return 0; default: return -1; } } return -1; }
int EBuffer::Find(SearchReplaceOptions &opt) { int slen = strlen(opt.strSearch); int Options = opt.Options; int rlen = strlen(opt.strReplace); RxNode *R = NULL; opt.resCount = -1; opt.lastInsertLen = 0; if (slen == 0) return 0; if (Options & SEARCH_BLOCK) { if (CheckBlock() == 0) return 0; } if (Options & SEARCH_RE) { R = RxCompile(opt.strSearch); if (R == 0) { View->MView->Win->Choice(GPC_ERROR, "Find", 1, "O&K", "Invalid regular expression."); return 0; } } if (Options & SEARCH_GLOBAL) { if (Options & SEARCH_BLOCK) { if (Options & SEARCH_BACK) { if (SetPosR(BE.Col, BE.Row) == 0) goto error; } else { if (SetPosR(BB.Col, BB.Row) == 0) goto error; } } else { if (Options & SEARCH_BACK) { if (RCount < 1) goto error; if (SetPosR(LineLen(RCount - 1), RCount - 1) == 0) goto error; } else { if (SetPosR(0, 0) == 0) goto error; } } } opt.resCount = 0; while (1) { if (Options & SEARCH_RE) { if (FindRx(R, opt) == 0) goto end; } else { if (FindStr(opt.strSearch, slen, opt) == 0) goto end; } opt.resCount++; if (opt.Options & SEARCH_REPLACE) { char ask = 'A'; if (!(Options & SEARCH_NASK)) { char ch; while (1) { Draw(VToR(CP.Row), 1); Redraw(); switch (View->MView->Win->Choice(0, "Replace", 5, "&Yes", "&All", "&Once", "&Skip", "&Cancel", "Replace with %s?", opt.strReplace)) { case 0: ch = 'Y'; break; case 1: ch = 'A'; break; case 2: ch = 'O'; break; case 3: ch = 'N'; break; case 4: case -1: default: ch = 'Q'; break; } if (ch == 'Y') { ask = 'Y'; goto ok_rep; } if (ch == 'N') { ask = 'N'; goto ok_rep; } if (ch == 'Q') { ask = 'Q'; goto ok_rep; } if (ch == 'A') { ask = 'A'; goto ok_rep; } if (ch == 'O') { ask = 'O'; goto ok_rep; } } ok_rep: if (ask == 'N') goto try_join; if (ask == 'Q') goto end; if (ask == 'A') Options |= SEARCH_NASK; } if (Options & SEARCH_RE) { PELine L = RLine(Match.Row); int P, R; char *PR = 0; int LR = 0; R = Match.Row; P = Match.Col; P = CharOffset(L, P); if (0 == RxReplace(opt.strReplace, L->Chars, L->Count, MatchRes, &PR, &LR)) { if (DelText(R, Match.Col, MatchLen) == 0) goto error; if (PR && LR > 0) if (InsText(R, Match.Col, LR, PR) == 0) goto error; if (PR) free(PR); rlen = LR; } } else { if (DelText(Match.Row, Match.Col, MatchLen) == 0) goto error; if (InsText(Match.Row, Match.Col, rlen, opt.strReplace) == 0) goto error; // Cursor remains at start of inserted string. If there is recursive // replace pattern, fte can go it infinite loop. // Workaround: Move cursor to end of inserted string opt.lastInsertLen = strlen(opt.strReplace); } if (!(Options & SEARCH_BACK)) { MatchLen = rlen; MatchCount = rlen; } if (ask == 'O') goto end; } try_join: if (Options & SEARCH_JOIN) { char ask = 'A'; if (!(Options & SEARCH_NASK)) { char ch; while (1) { Draw(VToR(CP.Row), 1); Redraw(); switch (View->MView->Win->Choice(0, "Join Line", 5, "&Yes", "&All", "&Once", "&Skip", "&Cancel", "Join lines %d and %d?", 1 + VToR(CP.Row), 1 + VToR(CP.Row) + 1)) { case 0: ch = 'Y'; break; case 1: ch = 'A'; break; case 2: ch = 'O'; break; case 3: ch = 'N'; break; case 4: case -1: default: ch = 'Q'; break; } if (ch == 'Y') { ask = 'Y'; goto ok_join; } if (ch == 'N') { ask = 'N'; goto ok_join; } if (ch == 'Q') { ask = 'Q'; goto ok_join; } if (ch == 'A') { ask = 'A'; goto ok_join; } if (ch == 'O') { ask = 'O'; goto ok_join; } } ok_join: if (ask == 'N') goto try_split; if (ask == 'Q') goto end; if (ask == 'A') Options |= SEARCH_NASK; } if (JoinLine(Match.Row, Match.Col) == 0) goto error; if (ask == 'O') goto end; } try_split: if (Options & SEARCH_SPLIT) { char ask = 'A'; if (!(Options & SEARCH_NASK)) { char ch; while (1) { Draw(VToR(CP.Row), 1); Redraw(); switch(View->MView->Win->Choice(0, "Split Line", 5, "&Yes", "&All", "&Once", "&Skip", "&Cancel", "Split line %d?", VToR(CP.Row))) { case 0: ch = 'Y'; break; case 1: ch = 'A'; break; case 2: ch = 'O'; break; case 3: ch = 'S'; break; case 4: case -1: default: ch = 'Q'; break; } if (ch == 'Y') { ask = 'Y'; goto ok_split; } else if (ch == 'N') { ask = 'N'; goto ok_split; } else if (ch == 'Q') { ask = 'Q'; goto ok_split; } else if (ch == 'A') { ask = 'A'; goto ok_split; } else if (ch == 'O') { ask = 'O'; goto ok_split; } } ok_split: if (ask == 'N') goto try_delete; if (ask == 'Q') goto end; if (ask == 'A') Options |= SEARCH_NASK; } if (SplitLine(Match.Row, Match.Col + strlen(opt.strReplace)) == 0) goto error; if (ask == 'O') goto end; } try_delete: if (Options & SEARCH_DELETE) { char ask = 'A'; if (!(Options & SEARCH_NASK)) { char ch; while (1) { Draw(VToR(CP.Row), 1); Redraw(); switch (View->MView->Win->Choice(0, "Delete Line", 5, "&Yes", "&All", "&Once", "&Skip", "&Cancel", "Delete line %d?", VToR(CP.Row))) { case 0: ch = 'Y'; break; case 1: ch = 'A'; break; case 2: ch = 'O'; break; case 3: ch = 'N'; break; case 4: case -1: default: ch = 'Q'; break; } if (ch == 'Y') { ask = 'Y'; goto ok_delete; } if (ch == 'N') { ask = 'N'; goto ok_delete; } if (ch == 'Q') { ask = 'Q'; goto ok_delete; } if (ch == 'A') { ask = 'A'; goto ok_delete; } if (ch == 'O') { ask = 'O'; goto ok_delete; } } ok_delete: if (ask == 'N') goto next; if (ask == 'Q') goto end; if (ask == 'A') Options |= SEARCH_NASK; } if (Match.Row == RCount - 1) { if (DelText(Match.Row, 0, LineLen()) == 0) goto error; } else if (DelLine(Match.Row) == 0) goto error; if (ask == 'O') goto end; if (!(Options & SEARCH_ALL)) break; goto last; } next: if (!(Options & SEARCH_ALL)) break; Options |= SEARCH_NEXT; last: ; } end: // end of search if (R) RxFree(R); if (Options & SEARCH_ALL) Msg(S_INFO, "%d match(es) found.", opt.resCount); else { if (opt.resCount == 0) { Msg(S_INFO, "[%s] not found", opt.strSearch); return 0; } } return 1; error: if (R) { RxFree(R); } View->MView->Win->Choice(GPC_ERROR, "Find", 1, "O&K", "Error in search/replace."); return 0; }