Refactored a new class FileIterator from Grepper that will make adding
node monitoring easier. Also, FileIterator will be split to make the code cleaner with regards to folder or selection mode. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@26752 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -0,0 +1,225 @@
|
||||
/*
|
||||
* Copyright (c) 2008 Stephan Aßmus <[email protected]>
|
||||
* Copyright (c) 1998-2007 Matthijs Hollemans
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "FileIterator.h"
|
||||
|
||||
#include <new>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <Directory.h>
|
||||
#include <NodeInfo.h>
|
||||
#include <Path.h>
|
||||
|
||||
#include "Model.h"
|
||||
|
||||
using std::nothrow;
|
||||
|
||||
// TODO: stippi: Check if this is a the best place to maintain a global
|
||||
// list of files and folders for node monitoring. It should probably monitor
|
||||
// every file that was grepped, as well as every visited (sub) folder.
|
||||
// For the moment I don't know the life cycle of the FileIterator object.
|
||||
|
||||
|
||||
FileIterator::FileIterator(Model* model)
|
||||
: fDirectories(10),
|
||||
fCurrentDir(new (nothrow) BDirectory(&model->fDirectory)),
|
||||
fCurrentRef(0),
|
||||
fModel(model)
|
||||
{
|
||||
if (!fCurrentDir || !fDirectories.AddItem(fCurrentDir)) {
|
||||
// init error
|
||||
delete fCurrentDir;
|
||||
fCurrentDir = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
FileIterator::~FileIterator()
|
||||
{
|
||||
for (int32 i = fDirectories.CountItems() - 1; i >= 0; i--)
|
||||
delete (BDirectory*)fDirectories.ItemAt(i);
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
FileIterator::IsValid() const
|
||||
{
|
||||
return fCurrentDir != NULL;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
FileIterator::GetNextName(char* buffer)
|
||||
{
|
||||
BEntry entry;
|
||||
struct stat fileStat;
|
||||
|
||||
while (true) {
|
||||
// Traverse the directory to get a new BEntry.
|
||||
// _GetNextEntry returns false if there are no
|
||||
// more entries, and we exit the loop.
|
||||
|
||||
if (!_GetNextEntry(entry))
|
||||
return false;
|
||||
|
||||
// If the entry is a subdir, then add it to the
|
||||
// list of directories and continue the loop.
|
||||
// If the entry is a file and we can grep it
|
||||
// (i.e. it is a text file), then we're done
|
||||
// here. Otherwise, continue with the next entry.
|
||||
|
||||
if (entry.GetStat(&fileStat) == B_OK) {
|
||||
if (S_ISDIR(fileStat.st_mode)) {
|
||||
// subdir
|
||||
_ExamineSubdir(entry);
|
||||
} else {
|
||||
// file or a (non-traversed) symbolic link
|
||||
if (_ExamineFile(entry, buffer))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// #pragma mark - private
|
||||
|
||||
|
||||
bool
|
||||
FileIterator::_GetNextEntry(BEntry& entry)
|
||||
{
|
||||
if (fDirectories.CountItems() == 1)
|
||||
return _GetTopEntry(entry);
|
||||
else
|
||||
return _GetSubEntry(entry);
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
FileIterator::_GetTopEntry(BEntry& entry)
|
||||
{
|
||||
// If the user selected one or more files, we must look
|
||||
// at the "refs" inside the message that was passed into
|
||||
// our add-on's process_refs(). If the user didn't select
|
||||
// any files, we will simply read all the entries from the
|
||||
// current working directory.
|
||||
|
||||
entry_ref fileRef;
|
||||
|
||||
if (fModel->fSelectedFiles.FindRef("refs", fCurrentRef, &fileRef) == B_OK) {
|
||||
entry.SetTo(&fileRef, fModel->fRecurseLinks);
|
||||
++fCurrentRef;
|
||||
return true;
|
||||
} else if (fCurrentRef > 0) {
|
||||
// when we get here, we have processed
|
||||
// all the refs from the message
|
||||
return false;
|
||||
} else if (fCurrentDir != NULL) {
|
||||
// examine the whole directory
|
||||
return fCurrentDir->GetNextEntry(&entry,
|
||||
fModel->fRecurseLinks) == B_OK;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
FileIterator::_GetSubEntry(BEntry& entry)
|
||||
{
|
||||
if (!fCurrentDir)
|
||||
return false;
|
||||
|
||||
if (fCurrentDir->GetNextEntry(&entry, fModel->fRecurseLinks) == B_OK)
|
||||
return true;
|
||||
|
||||
// If we get here, there are no more entries in
|
||||
// this subdir, so return to the parent directory.
|
||||
|
||||
fDirectories.RemoveItem(fCurrentDir);
|
||||
delete fCurrentDir;
|
||||
fCurrentDir = (BDirectory*)fDirectories.LastItem();
|
||||
|
||||
return _GetNextEntry(entry);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
FileIterator::_ExamineSubdir(BEntry& entry)
|
||||
{
|
||||
if (!fModel->fRecurseDirs)
|
||||
return;
|
||||
|
||||
if (fModel->fSkipDotDirs) {
|
||||
char nameBuf[B_FILE_NAME_LENGTH];
|
||||
if (entry.GetName(nameBuf) == B_OK) {
|
||||
if (*nameBuf == '.')
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
BDirectory* dir = new (nothrow) BDirectory(&entry);
|
||||
if (dir == NULL || dir->InitCheck() != B_OK
|
||||
|| !fDirectories.AddItem(dir)) {
|
||||
// clean up
|
||||
delete dir;
|
||||
return;
|
||||
}
|
||||
|
||||
fCurrentDir = dir;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
FileIterator::_ExamineFile(BEntry& entry, char* buffer)
|
||||
{
|
||||
BPath path;
|
||||
if (entry.GetPath(&path) != B_OK)
|
||||
return false;
|
||||
|
||||
strcpy(buffer, path.Path());
|
||||
|
||||
if (!fModel->fTextOnly)
|
||||
return true;
|
||||
|
||||
BNode node(&entry);
|
||||
BNodeInfo nodeInfo(&node);
|
||||
char mimeTypeString[B_MIME_TYPE_LENGTH];
|
||||
|
||||
if (nodeInfo.GetType(mimeTypeString) == B_OK) {
|
||||
BMimeType mimeType(mimeTypeString);
|
||||
BMimeType superType;
|
||||
|
||||
if (mimeType.GetSupertype(&superType) == B_OK) {
|
||||
if (strcmp("text", superType.Type()) == 0
|
||||
|| strcmp("message", superType.Type()) == 0) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
* Copyright (c) 2008 Stephan Aßmus <[email protected]>
|
||||
* Copyright (c) 1998-2007 Matthijs Hollemans
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
#ifndef FILE_ITERATOR_H
|
||||
#define FILE_ITERATOR_H
|
||||
|
||||
#include <List.h>
|
||||
|
||||
class BEntry;
|
||||
class BDirectory;
|
||||
class Model;
|
||||
|
||||
// TODO: split into Folder and MessageFileIterator (_GetTopEntry)
|
||||
|
||||
// Provides an interface to retrieve the next file that should be grepped
|
||||
// for the search string.
|
||||
class FileIterator {
|
||||
public:
|
||||
FileIterator(Model* model);
|
||||
virtual ~FileIterator();
|
||||
|
||||
virtual bool IsValid() const;
|
||||
|
||||
// Returns the full path name of the next file.
|
||||
virtual bool GetNextName(char* buffer);
|
||||
|
||||
private:
|
||||
// Looks for the next entry.
|
||||
bool _GetNextEntry(BEntry& entry);
|
||||
|
||||
// Looks for the next entry in the top-level dir.
|
||||
bool _GetTopEntry(BEntry& entry);
|
||||
|
||||
// Looks for the next entry in a subdir.
|
||||
bool _GetSubEntry(BEntry& entry);
|
||||
|
||||
// Determines whether we can add a subdir.
|
||||
void _ExamineSubdir(BEntry& entry);
|
||||
|
||||
// Determines whether we can grep a file.
|
||||
bool _ExamineFile(BEntry& entry, char* buffer);
|
||||
|
||||
private:
|
||||
// Contains pointers to BDirectory objects.
|
||||
BList fDirectories;
|
||||
|
||||
// The directory we are currently looking at.
|
||||
BDirectory* fCurrentDir;
|
||||
|
||||
// The ref number we are currently looking at.
|
||||
int32 fCurrentRef;
|
||||
|
||||
// The directory or files to grep on.
|
||||
Model* fModel;
|
||||
};
|
||||
|
||||
#endif // FILE_ITERATOR_H
|
||||
@@ -5,7 +5,15 @@
|
||||
#ifndef GLOBAL_DEFS_H
|
||||
#define GLOBAL_DEFS_H
|
||||
|
||||
|
||||
#define APP_SIGNATURE "application/x-vnd.mahlzeit.trackergrep"
|
||||
#define APP_NAME "TextSearch"
|
||||
|
||||
#define PREFS_FILE "TextSearchSettings"
|
||||
#define HISTORY_LIMIT 20
|
||||
|
||||
#define TRACKER_SIGNATURE "application/x-vnd.Be-TRAK"
|
||||
#define PE_SIGNATURE "application/x-vnd.beunited.pe"
|
||||
|
||||
|
||||
#endif // GLOBAL_DEFS_H
|
||||
|
||||
@@ -38,6 +38,7 @@
|
||||
#include <String.h>
|
||||
#include <UTF8.h>
|
||||
|
||||
#include "FileIterator.h"
|
||||
#include "GlobalDefs.h"
|
||||
#include "Grepper.h"
|
||||
#include "Translation.h"
|
||||
@@ -112,10 +113,7 @@ GrepWindow::GrepWindow(BMessage* message)
|
||||
|
||||
GrepWindow::~GrepWindow()
|
||||
{
|
||||
if (fModel->fState == STATE_SEARCH) {
|
||||
fGrepper->Cancel();
|
||||
}
|
||||
|
||||
delete fGrepper;
|
||||
delete fModel;
|
||||
}
|
||||
|
||||
@@ -708,8 +706,21 @@ GrepWindow::_OnStartCancel()
|
||||
|
||||
fOldPattern = fSearchText->Text();
|
||||
|
||||
fGrepper = new Grepper(fOldPattern.String(), fModel);
|
||||
fGrepper->Start();
|
||||
FileIterator* iterator = new (nothrow) FileIterator(fModel);
|
||||
fGrepper = new (nothrow) Grepper(fOldPattern.String(), fModel,
|
||||
iterator);
|
||||
if (fGrepper != NULL && fGrepper->IsValid())
|
||||
fGrepper->Start();
|
||||
else {
|
||||
// roll back in case of problems
|
||||
if (fGrepper == NULL)
|
||||
delete iterator;
|
||||
delete fGrepper;
|
||||
fGrepper = NULL;
|
||||
fModel->fState = STATE_CANCEL;
|
||||
// TODO: better notification to user
|
||||
fprintf(stderr, "Out of memory.\n");
|
||||
}
|
||||
} else if (fModel->fState == STATE_SEARCH) {
|
||||
fModel->fState = STATE_CANCEL;
|
||||
fGrepper->Cancel();
|
||||
|
||||
@@ -33,6 +33,8 @@
|
||||
#include <Path.h>
|
||||
#include <UTF8.h>
|
||||
|
||||
#include "FileIterator.h"
|
||||
|
||||
using std::nothrow;
|
||||
|
||||
// TODO: stippi: Check if this is a the best place to maintain a global
|
||||
@@ -88,24 +90,13 @@ strdup_from_utf8(uint32 encode, const char* src, int32 length)
|
||||
}
|
||||
|
||||
|
||||
Grepper::Grepper(const char* pattern, Model* model)
|
||||
: fDirectories(new (nothrow) BList(10)),
|
||||
fCurrentDir(new (nothrow) BDirectory(&model->fDirectory)),
|
||||
fCurrentRef(0),
|
||||
fPattern(NULL),
|
||||
Grepper::Grepper(const char* pattern, Model* model, FileIterator* iterator)
|
||||
: fPattern(NULL),
|
||||
fModel(model),
|
||||
fIterator(iterator),
|
||||
fThreadId(-1),
|
||||
fMustQuit(false)
|
||||
{
|
||||
if (!fCurrentDir || !fDirectories || !fDirectories->AddItem(fCurrentDir)) {
|
||||
// init error
|
||||
delete fCurrentDir;
|
||||
fCurrentDir = NULL;
|
||||
delete fDirectories;
|
||||
fDirectories = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
if (fModel->fEncoding) {
|
||||
char *src = strdup_from_utf8(fModel->fEncoding, pattern,
|
||||
strlen(pattern));
|
||||
@@ -119,26 +110,17 @@ Grepper::Grepper(const char* pattern, Model* model)
|
||||
Grepper::~Grepper()
|
||||
{
|
||||
Cancel();
|
||||
|
||||
free(fPattern);
|
||||
|
||||
// If the thread terminated normally, then there is only
|
||||
// one object in the list: the initial directory. But if
|
||||
// the user aborted the search, there may be more.
|
||||
|
||||
if (fDirectories) {
|
||||
for (int32 i = fDirectories->CountItems() - 1; i >= 0; i--)
|
||||
delete static_cast<BDirectory*>(fDirectories->ItemAt(i));
|
||||
|
||||
delete fDirectories;
|
||||
}
|
||||
delete fIterator;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
Grepper::IsValid() const
|
||||
{
|
||||
return fPattern != NULL && fDirectories != NULL && fCurrentDir != NULL;
|
||||
if (fIterator == NULL || !fIterator->IsValid())
|
||||
return false;
|
||||
return fPattern != NULL && fModel != NULL;
|
||||
}
|
||||
|
||||
|
||||
@@ -192,7 +174,7 @@ Grepper::_GrepperThread()
|
||||
sprintf(fileName, "/boot/var/tmp/SearchText%ld", fThreadId);
|
||||
tempFile.SetTo(fileName);
|
||||
|
||||
while (!fMustQuit && _GetNextName(fileName)) {
|
||||
while (!fMustQuit && fIterator->GetNextName(fileName)) {
|
||||
message.MakeEmpty();
|
||||
message.what = MSG_REPORT_FILE_NAME;
|
||||
message.AddString("filename", fileName);
|
||||
@@ -344,153 +326,3 @@ Grepper::_EscapeSpecialChars(char* buffer, ssize_t bufferSize)
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
Grepper::_GetNextName(char* buffer)
|
||||
{
|
||||
BEntry entry;
|
||||
struct stat fileStat;
|
||||
|
||||
while (true) {
|
||||
// Traverse the directory to get a new BEntry.
|
||||
// _GetNextEntry returns false if there are no
|
||||
// more entries, and we exit the loop.
|
||||
|
||||
if (!_GetNextEntry(entry))
|
||||
return false;
|
||||
|
||||
// If the entry is a subdir, then add it to the
|
||||
// list of directories and continue the loop.
|
||||
// If the entry is a file and we can grep it
|
||||
// (i.e. it is a text file), then we're done
|
||||
// here. Otherwise, continue with the next entry.
|
||||
|
||||
if (entry.GetStat(&fileStat) == B_OK) {
|
||||
if (S_ISDIR(fileStat.st_mode)) {
|
||||
// subdir
|
||||
_ExamineSubdir(entry);
|
||||
} else {
|
||||
// file or a (non-traversed) symbolic link
|
||||
if (_ExamineFile(entry, buffer))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
Grepper::_GetNextEntry(BEntry& entry)
|
||||
{
|
||||
if (fDirectories->CountItems() == 1)
|
||||
return _GetTopEntry(entry);
|
||||
else
|
||||
return _GetSubEntry(entry);
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
Grepper::_GetTopEntry(BEntry& entry)
|
||||
{
|
||||
// If the user selected one or more files, we must look
|
||||
// at the "refs" inside the message that was passed into
|
||||
// our add-on's process_refs(). If the user didn't select
|
||||
// any files, we will simply read all the entries from the
|
||||
// current working directory.
|
||||
|
||||
entry_ref fileRef;
|
||||
|
||||
if (fModel->fSelectedFiles.FindRef("refs",
|
||||
fCurrentRef, &fileRef) == B_OK) {
|
||||
entry.SetTo(&fileRef, fModel->fRecurseLinks);
|
||||
++fCurrentRef;
|
||||
return true;
|
||||
} else if (fCurrentRef > 0) {
|
||||
// when we get here, we have processed
|
||||
// all the refs from the message
|
||||
return false;
|
||||
} else {
|
||||
// examine the whole directory
|
||||
return fCurrentDir->GetNextEntry(&entry,
|
||||
fModel->fRecurseLinks) == B_OK;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
Grepper::_GetSubEntry(BEntry& entry)
|
||||
{
|
||||
if (!fCurrentDir)
|
||||
return false;
|
||||
|
||||
if (fCurrentDir->GetNextEntry(&entry, fModel->fRecurseLinks) == B_OK)
|
||||
return true;
|
||||
|
||||
// If we get here, there are no more entries in
|
||||
// this subdir, so return to the parent directory.
|
||||
|
||||
fDirectories->RemoveItem(fCurrentDir);
|
||||
delete fCurrentDir;
|
||||
fCurrentDir = (BDirectory*)fDirectories->LastItem();
|
||||
|
||||
return _GetNextEntry(entry);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Grepper::_ExamineSubdir(BEntry& entry)
|
||||
{
|
||||
if (!fModel->fRecurseDirs)
|
||||
return;
|
||||
|
||||
if (fModel->fSkipDotDirs) {
|
||||
char nameBuf[B_FILE_NAME_LENGTH];
|
||||
if (entry.GetName(nameBuf) == B_OK) {
|
||||
if (*nameBuf == '.')
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
BDirectory* dir = new (nothrow) BDirectory(&entry);
|
||||
if (dir == NULL || dir->InitCheck() != B_OK
|
||||
|| !fDirectories->AddItem(dir)) {
|
||||
// clean up
|
||||
delete dir;
|
||||
return;
|
||||
}
|
||||
|
||||
fCurrentDir = dir;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
Grepper::_ExamineFile(BEntry& entry, char* buffer)
|
||||
{
|
||||
BPath path;
|
||||
if (entry.GetPath(&path) != B_OK)
|
||||
return false;
|
||||
|
||||
strcpy(buffer, path.Path());
|
||||
|
||||
if (!fModel->fTextOnly)
|
||||
return true;
|
||||
|
||||
BNode node(&entry);
|
||||
BNodeInfo nodeInfo(&node);
|
||||
char mimeTypeString[B_MIME_TYPE_LENGTH];
|
||||
|
||||
if (nodeInfo.GetType(mimeTypeString) == B_OK) {
|
||||
BMimeType mimeType(mimeTypeString);
|
||||
BMimeType superType;
|
||||
|
||||
if (mimeType.GetSupertype(&superType) == B_OK) {
|
||||
if (strcmp("text", superType.Type()) == 0
|
||||
|| strcmp("message", superType.Type()) == 0) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -24,10 +24,13 @@
|
||||
|
||||
#include "Model.h"
|
||||
|
||||
class FileIterator;
|
||||
|
||||
// Executes "grep" in a background thread.
|
||||
class Grepper {
|
||||
public:
|
||||
Grepper(const char* pattern, Model* model);
|
||||
Grepper(const char* pattern, Model* model,
|
||||
FileIterator* iterator);
|
||||
virtual ~Grepper();
|
||||
|
||||
bool IsValid() const;
|
||||
@@ -49,44 +52,19 @@ private:
|
||||
// to prevent the shell from misinterpreting them.
|
||||
bool _EscapeSpecialChars(char* buffer,
|
||||
ssize_t bufferSize);
|
||||
|
||||
// Returns the full path name of the next file.
|
||||
bool _GetNextName(char* buffer);
|
||||
|
||||
// Looks for the next entry.
|
||||
bool _GetNextEntry(BEntry& entry);
|
||||
|
||||
// Looks for the next entry in the top-level dir.
|
||||
bool _GetTopEntry(BEntry& entry);
|
||||
|
||||
// Looks for the next entry in a subdir.
|
||||
bool _GetSubEntry(BEntry& entry);
|
||||
|
||||
// Determines whether we can add a subdir.
|
||||
void _ExamineSubdir(BEntry& entry);
|
||||
|
||||
// Determines whether we can grep a file.
|
||||
bool _ExamineFile(BEntry& entry, char* buffer);
|
||||
|
||||
private:
|
||||
// Contains pointers to BDirectory objects.
|
||||
BList* fDirectories;
|
||||
|
||||
// The directory we are currently looking at.
|
||||
BDirectory* fCurrentDir;
|
||||
|
||||
// The ref number we are currently looking at.
|
||||
int32 fCurrentRef;
|
||||
|
||||
private:
|
||||
// The (escaped) search pattern.
|
||||
char* fPattern;
|
||||
|
||||
// The directory or files to grep on.
|
||||
Model* fModel;
|
||||
|
||||
// The supplier of files to grep
|
||||
FileIterator* fIterator;
|
||||
|
||||
// Our thread's ID.
|
||||
thread_id fThreadId;
|
||||
|
||||
|
||||
// Whether our thread must quit.
|
||||
volatile bool fMustQuit;
|
||||
};
|
||||
|
||||
@@ -3,6 +3,7 @@ SubDir HAIKU_TOP src apps text_search ;
|
||||
SetSubDirSupportedPlatformsBeOSCompatible ;
|
||||
|
||||
Application TextSearch :
|
||||
FileIterator.cpp
|
||||
GrepApp.cpp
|
||||
GrepListView.cpp
|
||||
Grepper.cpp
|
||||
|
||||
@@ -32,12 +32,7 @@
|
||||
#include <Rect.h>
|
||||
#include <String.h>
|
||||
|
||||
|
||||
#define PREFS_FILE "TrackerGrepSettings"
|
||||
#define HISTORY_LIMIT 20
|
||||
|
||||
#define TRACKER_SIGNATURE "application/x-vnd.Be-TRAK"
|
||||
#define PE_SIGNATURE "application/x-vnd.beunited.pe"
|
||||
#include "GlobalDefs.h"
|
||||
|
||||
|
||||
enum {
|
||||
@@ -89,6 +84,7 @@ public:
|
||||
void AddToHistory(const char* text);
|
||||
void FillHistoryMenu(BMenu* menu);
|
||||
|
||||
public:
|
||||
// The directory we were invoked from.
|
||||
entry_ref fDirectory;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user