void FindWindow::ReplaceAll(void) { // This function is called from the FinderThread function, so locking is // required when accessing any member variables. Lock(); BString errorLog; BString findText(fFindBox->Text()); BString replaceText(fReplaceBox->Text()); if (!fIsRegEx) { findText.CharacterEscape("^$()%.[]*+-?", '\\'); } BString replaceTerms; replaceTerms << "'" << findText << "' '" << replaceText << "'"; ShellHelper shell; shell << "pwd; find "; shell.AddEscapedArg(fWorkingDir); BString sStr("'s/"); sStr << findText.String() << "/"; sStr << replaceText.String() << "/"; sStr << "'"; shell << " -type f | xargs sed -i " << sStr.String(); STRACE(2,("Shell command: %s\n",shell.AsString().String())); Unlock(); BString out; shell.RunInPipe(out,false); STRACE(2,("Command output: %s\n",out.String())); if (errorLog.CountChars() > 0) { BString errorString = B_TRANSLATE("The following files had problems replacing the search terms:\n"); errorString << errorLog; ShowAlert(errorString.String()); } PostMessage(M_FIND); }
void FindWindow::Replace(void) // Was REPLACEALL { // This function is called from the FinderThread function, so locking is // required when accessing any member variables. // Just make sure you escape single quotes and underscores before constructing // the sed command ShowAlert(B_TRANSLATE("luare based replace all has been removed until it can be migrated from Lua"), "OK", NULL, NULL, B_STOP_ALERT); return; Lock(); BString errorLog; for (int32 i = 0; i < fResultList->CountItems(); i++) { BString findText(fFindBox->Text()), replaceText(fReplaceBox->Text()); if (!fIsRegEx) { findText.CharacterEscape("^$()%.[]*+-?", '%'); replaceText.CharacterEscape("%", '%'); } findText.CharacterEscape("'", '\\'); replaceText.CharacterEscape("'", '\\'); BString replaceTerms; replaceTerms << "'" << findText << "' '" << replaceText << "'"; GrepListItem *gitem = (GrepListItem*)fResultList->ItemAt(i); DPath file(gitem->GetRef()); ShellHelper shell; shell << "luare" << replaceTerms; shell.AddEscapedArg(file.GetFullPath()); shell.AddEscapedArg(file.GetFullPath()); printf("replace command: %s\n", shell.AsString().String()); int32 outvalue = shell.Run(); if (outvalue) { // append file name to list of files with error conditions and notify // user of problems at the end so as not to annoy them. errorLog << "\t" << file.GetFileName() << "\n"; } // Allow window updates from time to time if (i % 5 == 0) { Unlock(); Lock(); } } Unlock(); if (errorLog.CountChars() > 0) { BString errorString = B_TRANSLATE("The following files had problems replacing the search terms:\n"); errorString << errorLog; BAlert *alert = new BAlert(B_TRANSLATE_SYSTEM_NAME("Paladin"), errorString.String(), B_TRANSLATE("OK")); alert->Go(); } PostMessage(M_FIND); }
void FindWindow::FindResults(void) { // This function is called from the FinderThread function, so locking is // required when accessing any member variables. Lock(); bool canReplace = fReplaceButton->IsEnabled(); EnableReplace(false); for (int32 i = fResultList->CountItems() - 1; i >= 0; i--) { // We don't want to hog the window lock, but we also don't want // tons of context switches, either. Yielding the lock every 5 items // should give us sufficient responsiveness. if (i % 5 == 0) { Unlock(); Lock(); } BListItem *item = fResultList->RemoveItem(i); delete item; } Unlock(); ShellHelper shell; shell << "cd "; shell.AddEscapedArg(fWorkingDir); shell << "; pwd; find . -type f "; shell << "|xargs grep -n -H -s --binary-files=without-match "; // TODO check for PCRE invocation and pass in pcre flag to grep if so // TODO Ensure RE escaping also happens (E.g. open/close paran etc.) shell.AddEscapedArg(fFindBox->Text()); if (fThreadQuitFlag) return; BString out; shell.RunInPipe(out, false); if (fThreadQuitFlag) return; BObjectList<BString> resultList(20, true); TokenizeToList(out.String(), resultList); Lock(); for (int32 i = 0; i < resultList.CountItems(); i++) { // We don't want to hog the window lock, but we also don't want // tons of context switches, either. Yielding the lock every 5 items // should give us sufficient responsiveness. if (i % 5 == 0) { Unlock(); Lock(); } BString entryString(resultList.ItemAt(i)->String()); BString filename(entryString); int32 pos = filename.FindFirst(":"); if (pos < 0) continue; filename.Truncate(pos); if (filename.StartsWith("./")) filename.Remove(0,2); STRACE(2,("Truncated file name from grep: %s\n",filename.String())); BString lineString; entryString.CopyInto(lineString, pos + 1, entryString.CountChars() - pos); int32 pos2 = lineString.FindFirst(":"); BString locationString; lineString.CopyInto(locationString, pos2 + 1, lineString.CountChars() - pos2); lineString.Truncate(pos2); DPath entryPath(fWorkingDir); entryPath << filename; BString fullPath(fWorkingDir); fullPath << "/" << filename; STRACE(2,("Full path: %s\n",fullPath.String())); DPath relPath(filename); fResultList->AddItem(new GrepListItem(fullPath,filename, entryPath.GetRef(), atol(lineString.String()), locationString.String())); } EnableReplace(true); if (fResultList->CountItems() == 0) fResultList->AddItem(new BStringItem(B_TRANSLATE("No matches found"))); Unlock(); }