From 20d28e80a5c861a9d5f449ea911ab75b4f37ad0d Mon Sep 17 00:00:00 2001 From: Jef Date: Tue, 24 Sep 2024 14:54:57 +0200 Subject: Initial community commit --- Src/Wasabi/bfc/file/filename.cpp | 2 + Src/Wasabi/bfc/file/filename.h | 26 +++++ Src/Wasabi/bfc/file/readdir.cpp | 129 ++++++++++++++++++++ Src/Wasabi/bfc/file/readdir.h | 48 ++++++++ Src/Wasabi/bfc/file/recursedir.cpp | 67 +++++++++++ Src/Wasabi/bfc/file/recursedir.h | 73 ++++++++++++ Src/Wasabi/bfc/file/splitpath.c | 213 ++++++++++++++++++++++++++++++++++ Src/Wasabi/bfc/file/splitpath.h | 26 +++++ Src/Wasabi/bfc/file/tmpnamestr.h | 18 +++ Src/Wasabi/bfc/file/wildcharsenum.cpp | 64 ++++++++++ Src/Wasabi/bfc/file/wildcharsenum.h | 34 ++++++ 11 files changed, 700 insertions(+) create mode 100644 Src/Wasabi/bfc/file/filename.cpp create mode 100644 Src/Wasabi/bfc/file/filename.h create mode 100644 Src/Wasabi/bfc/file/readdir.cpp create mode 100644 Src/Wasabi/bfc/file/readdir.h create mode 100644 Src/Wasabi/bfc/file/recursedir.cpp create mode 100644 Src/Wasabi/bfc/file/recursedir.h create mode 100644 Src/Wasabi/bfc/file/splitpath.c create mode 100644 Src/Wasabi/bfc/file/splitpath.h create mode 100644 Src/Wasabi/bfc/file/tmpnamestr.h create mode 100644 Src/Wasabi/bfc/file/wildcharsenum.cpp create mode 100644 Src/Wasabi/bfc/file/wildcharsenum.h (limited to 'Src/Wasabi/bfc/file') diff --git a/Src/Wasabi/bfc/file/filename.cpp b/Src/Wasabi/bfc/file/filename.cpp new file mode 100644 index 00000000..b3d24990 --- /dev/null +++ b/Src/Wasabi/bfc/file/filename.cpp @@ -0,0 +1,2 @@ +#include "precomp_wasabi_bfc.h" +#include "filename.h" diff --git a/Src/Wasabi/bfc/file/filename.h b/Src/Wasabi/bfc/file/filename.h new file mode 100644 index 00000000..8442f1b8 --- /dev/null +++ b/Src/Wasabi/bfc/file/filename.h @@ -0,0 +1,26 @@ +#ifndef _FILENAME_H +#define _FILENAME_H + +#include +#include +#include + +// a simple class to drag-and-drop filenames around + +#define DD_FILENAME L"DD_Filename v1" + +// another implementation that uses the central playstring table +class FilenamePS : private Playstring +{ +public: + FilenamePS(const wchar_t *str) : Playstring(str) {} + const wchar_t *getFilename() { return getValue(); } + operator const wchar_t *() { return getFilename(); } + static const wchar_t *dragitem_getDatatype() { return DD_FILENAME; } + +protected: + FilenamePS(const FilenamePS &fn) {} + FilenamePS& operator =(const FilenamePS &ps) { return *this; } +}; + +#endif diff --git a/Src/Wasabi/bfc/file/readdir.cpp b/Src/Wasabi/bfc/file/readdir.cpp new file mode 100644 index 00000000..e3bc48ef --- /dev/null +++ b/Src/Wasabi/bfc/file/readdir.cpp @@ -0,0 +1,129 @@ +#include "precomp_wasabi_bfc.h" +#include "readdir.h" + +#ifdef _WIN32 +#include +#endif + +#if !defined(WIN32) && !defined(LINUX) +#error port me +#endif + +//PORT +ReadDir::ReadDir( const wchar_t *_path, const wchar_t *_match, bool _skipdots ) : skipdots( _skipdots ), first( 1 ), path( _path ), match( _match ) +{ + files = INVALID_HANDLE_VALUE; + if ( match.isempty() ) + match = MATCHALLFILES; + ZERO( data ); + +} + +ReadDir::~ReadDir() +{ + //PORT +#ifdef WIN32 + if ( files != INVALID_HANDLE_VALUE ) FindClose( files ); +#endif +#ifdef LINUX + if ( d != NULL ) closedir( d ); +#endif +} + +int ReadDir::next() +{ + //PORT +#ifdef WIN32 + for ( ;;) + { + if ( first ) + { + wchar_t fullpath[ MAX_PATH ]; + PathCombineW( fullpath, path.getValue(), match.getValue() ); + files = FindFirstFileW( fullpath, &data ); + } + if ( files == INVALID_HANDLE_VALUE ) return 0; + if ( first ) + { + first = 0; + if ( skipdots && ( isDotDir() || isDotDotDir() ) ) continue; + return 1; + } + if ( !FindNextFileW( files, &data ) ) return 0; + + if ( skipdots && ( isDotDir() || isDotDotDir() ) ) continue; + return 1; + } +#endif//WIN32 +#ifdef LINUX + + path.AddBackslash(); + if ( first || d == NULL ) + { + if ( !( d = opendir( path ) ) ) return 0; + first = 0; + } + + while ( 1 ) + { + de = readdir( d ); + if ( !de ) + { + closedir( d ); + d = NULL; + return 0; + } + + StringW full; + full.printf( L"%s%s", path.v(), de->d_name ); + + if ( stat( full, &st ) == -1 ) + continue; + + if ( skipdots && ( isDotDir() || isDotDotDir() ) ) continue; + + if ( !Std::match( match, de->d_name ) ) continue; + + return 1; + } + +#endif +} + +const wchar_t *ReadDir::getFilename() +{ + if ( first ) if ( !next() ) return NULL; + //PORT + return data.cFileName; + +} + +int ReadDir::isDir() +{ + //PORT + if ( files == INVALID_HANDLE_VALUE ) return 0; + return !!( data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ); +} + +int ReadDir::isReadonly() +{ + //PORT + if ( files == INVALID_HANDLE_VALUE ) return 0; + return !!( data.dwFileAttributes & FILE_ATTRIBUTE_READONLY ); + +} + +int ReadDir::isDotDir() +{ + //PORT + if ( files == INVALID_HANDLE_VALUE ) return 0; + return ( data.cFileName[ 0 ] == '.' && data.cFileName[ 1 ] == 0 ); +} + +int ReadDir::isDotDotDir() +{ + //PORT + + if ( files == INVALID_HANDLE_VALUE ) return 0; + return ( data.cFileName[ 0 ] == '.' && data.cFileName[ 1 ] == '.' && data.cFileName[ 2 ] == 0 ); +} diff --git a/Src/Wasabi/bfc/file/readdir.h b/Src/Wasabi/bfc/file/readdir.h new file mode 100644 index 00000000..edfc9d87 --- /dev/null +++ b/Src/Wasabi/bfc/file/readdir.h @@ -0,0 +1,48 @@ +#ifndef _READDIR_H +#define _READDIR_H + + + +#include +#include + +/* intended use: + ReadDir dir(path); + while (dir.next()) { + const char *fn = dir.getFilename(); + } +*/ + +class ReadDir +{ +public: + ReadDir(const wchar_t *path, const wchar_t *match=NULL, bool skipdots=true); + ~ReadDir(); + + int next(); // done when returns 0 + const wchar_t *getFilename(); + int isDir(); // if current file is a dir + int isReadonly(); // if current file is readonly + + int isDotDir(); // if given dir iteself is being enumerated (usually ".") + int isDotDotDir(); // if parent dir of cur dir is showing (usually "..") + + const wchar_t *getPath() { return path; } + +private: + StringW path, match; + int skipdots, first; +//PORT +#ifdef WIN32 + HANDLE files; + WIN32_FIND_DATAW data; // (shrug) so we have two? so what? + //StringW filename; +#endif +#ifdef LINUX + DIR *d; + struct dirent *de; + struct stat st; +#endif +}; + +#endif diff --git a/Src/Wasabi/bfc/file/recursedir.cpp b/Src/Wasabi/bfc/file/recursedir.cpp new file mode 100644 index 00000000..ca836a28 --- /dev/null +++ b/Src/Wasabi/bfc/file/recursedir.cpp @@ -0,0 +1,67 @@ +#include "precomp_wasabi_bfc.h" +#include "recursedir.h" + +RecurseDir::RecurseDir( const wchar_t *_path, const wchar_t *_match ) : + path( _path ), match( _match ) +{ + if ( match.isempty() ) match = Wasabi::Std::matchAllFiles(); + + curdir = new ReadDir( path, match ); +} + +RecurseDir::~RecurseDir() +{ + dirstack.deleteAll(); +} + +int RecurseDir::next() +{ + for ( ;;) + { + if ( curdir == NULL ) + { // pop one off the stack + curdir = dirstack.getLast(); + if ( curdir == NULL ) return 0; // done + dirstack.removeLastItem(); + } + int r = curdir->next(); + if ( r <= 0 ) + { + delete curdir; curdir = NULL; + continue; // get another one + } + + // ok, we have a file to look at + if ( curdir->isDir() ) + { // descend into it + StringW newpath = curdir->getPath(); + newpath.AppendPath( curdir->getFilename() ); + + dirstack.addItem( curdir ); // push the old one + curdir = new ReadDir( newpath, match ); // start new one + + continue; + } + + return r; + } +} + +const wchar_t *RecurseDir::getPath() +{ + if ( curdir == NULL ) + return NULL; + return curdir->getPath(); +} + +const wchar_t *RecurseDir::getFilename() +{ + if ( curdir == NULL ) + return NULL; + return curdir->getFilename(); +} + +const wchar_t *RecurseDir::getOriginalPath() +{ + return path; +} diff --git a/Src/Wasabi/bfc/file/recursedir.h b/Src/Wasabi/bfc/file/recursedir.h new file mode 100644 index 00000000..2c40c7ac --- /dev/null +++ b/Src/Wasabi/bfc/file/recursedir.h @@ -0,0 +1,73 @@ +#ifndef _RECURSEDIR_H +#define _RECURSEDIR_H + +#include +#include +#include +#include + +class ReadDir; + +/** + Read the contents of a directory, recursively. + Also possible to use search match patterns. + + @short Recursive directory reading. + @author Nullsoft + @ver 1.0 + @see ReadDir +*/ +class RecurseDir { +public: + /** + Sets the directory to read and the match pattern. + If no match pattern is set, it will match against + all files. + + @param path The path of the directory to read. + @param match The match pattern to use. + */ + RecurseDir(const wchar_t *path, const wchar_t *match=NULL); + + /** + Deletes the directory stack. + */ + ~RecurseDir(); + + /** + Advance to the next file. + + @ret 0, No more files to read; > 0, Files left to read. + */ + int next(); + + /** + Restart from the top of the directory tree. + + @ret 0 + */ + int restart(); + + /** + Get the current directory path. + + @ret The path. + */ + const wchar_t *getPath(); + + /** + Get the filename for the current file. + + @ret The filename. + */ + const wchar_t *getFilename(); + + const wchar_t *getOriginalPath(); + +private: + StringW path, match; + ReadDir *curdir; + PtrList dirstack; +}; + +#endif diff --git a/Src/Wasabi/bfc/file/splitpath.c b/Src/Wasabi/bfc/file/splitpath.c new file mode 100644 index 00000000..d9c3fbc5 --- /dev/null +++ b/Src/Wasabi/bfc/file/splitpath.c @@ -0,0 +1,213 @@ +/* + * Copyright 2000 Martin Fuchs + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +// 03/29/2004, f. gastellu : added _makepath and _wmakepath + +#include "splitpath.h" +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef WANT_UNICODE + +void _wsplitpath(const WCHAR* path, WCHAR* drv, WCHAR* dir, WCHAR* name, WCHAR* ext) +{ + const WCHAR* end; /* end of processed string */ + const WCHAR* p; /* search pointer */ + const WCHAR* s; /* copy pointer */ + + /* extract drive name */ + if (path[0] && path[1]==':') { + if (drv) { + *drv++ = *path++; + *drv++ = *path++; + *drv = L'\0'; + } + } else if (drv) + *drv = L'\0'; + + /* search for end of string or stream separator */ + for(end=path; *end && *end!=L':'; ) + end++; + + /* search for begin of file extension */ + for(p=end; p>path && *--p!=L'\\' && *p!=L'/'; ) + if (*p == L'.') { + end = p; + break; + } + + if (ext) + for(s=end; *ext=*s++; ) + ext++; + + /* search for end of directory name */ + for(p=end; p>path; ) + if (*--p=='\\' || *p=='/') { + p++; + break; + } + + if (name) { + for(s=p; spath && *--p!='\\' && *p!='/'; ) + if (*p == '.') { + end = p; + break; + } + + if (ext) + for(s=end; (*ext=*s++); ) + ext++; + + /* search for end of directory name */ + for(p=end; p>path; ) + if (*--p=='\\' || *p=='/') { + p++; + break; + } + + if (name) { + for(s=p; s + +class TmpNameStrW : public StringW +{ +public: + TmpNameStrW() + { + wchar_t tmp[WA_MAX_PATH]=L""; + TMPNAM(tmp); + setValue(tmp); + } +}; + + +#endif diff --git a/Src/Wasabi/bfc/file/wildcharsenum.cpp b/Src/Wasabi/bfc/file/wildcharsenum.cpp new file mode 100644 index 00000000..ae3e24e2 --- /dev/null +++ b/Src/Wasabi/bfc/file/wildcharsenum.cpp @@ -0,0 +1,64 @@ +// NONPORTABLE NONPORTABLE NONPORTABLE +#include "precomp_wasabi_bfc.h" +#ifdef WIN32 +#include +#endif +#include "wildcharsenum.h" +#include +#include +#include + +WildcharsEnumerator::WildcharsEnumerator(const wchar_t *_selection) : selection(_selection) +{ + // Then scan. + rescan(); +} + +WildcharsEnumerator::~WildcharsEnumerator() { + finddatalist.deleteAll(); +} + +int WildcharsEnumerator::getNumFiles() +{ + return finddatalist.getNumItems(); +} + +const wchar_t *WildcharsEnumerator::enumFile(int n) { + StringW path = finddatalist.enumItem(n)->path; + if (!path.isempty()) + { + enumFileString = StringPathCombine(path.getValue(), finddatalist.enumItem(n)->filename.getValue()); + return enumFileString; + } + return finddatalist.enumItem(n)->filename; +} + +void WildcharsEnumerator::rescan() +{ + finddatalist.removeAll(); + ParamParser pp(selection, L";"); + for (int is = 0; is < pp.getNumItems(); is++) + { + StringW _selection = pp.enumItem(is); + + PathParserW parse(_selection); + StringW path = L""; + StringW mask = L""; + + for (int i=0;i +#include + +class find_entry { +public: + find_entry(const wchar_t *_path, const wchar_t *_filename) : path(_path), filename(_filename) {} + ~find_entry() {} + StringW path; + StringW filename; +}; + +class WildcharsEnumerator +{ +public: + WildcharsEnumerator(const wchar_t *_selection); + virtual ~WildcharsEnumerator(); + + int getNumFiles(); + const wchar_t *enumFile(int n); + void rescan(); + + static int isWildchars(const wchar_t *filename); + +private: + StringW selection; + PtrList finddatalist; + StringW singfiledup; + StringW enumFileString; +}; + +#endif -- cgit