From: guido Date: Wed, 14 Sep 2005 10:56:40 +0000 (+0000) Subject: new PathSearch functionality X-Git-Url: https://gitweb.dealii.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=fbe9087e2148c494052d8a506d614072a58b45e5;p=dealii-svn.git new PathSearch functionality git-svn-id: https://svn.dealii.org/trunk@11417 0785d39b-7218-0410-832d-ea1e28bc413d --- diff --git a/deal.II/base/include/base/path_search.h b/deal.II/base/include/base/path_search.h index 9bdc6137ab..14489dd7e1 100644 --- a/deal.II/base/include/base/path_search.h +++ b/deal.II/base/include/base/path_search.h @@ -37,15 +37,16 @@ * Additional file classes can be added easily by using add_class(). * * Usage: First, you construct a PathSearch object for a certain file class, - * e.g. meshes. Then, you use the open() method to obtain a reference - * to an istream object. - * @verbatim + * e.g. meshes. Then, you use the find() method to obtain a full path + * name and you can open the file. + * @code * #include * * PathSearch search("MESH"); - * istream& in = search.open("grid"); + * std::string full_name = search.find("grid"); + * std::ifstream in(full_name.c_str()); * ... - * @endverbatim + * @endcode * * This piece of code will first traverse all paths in the list set up * for file class MESH. If it manages to open a file, it @@ -55,10 +56,11 @@ * * If you want to restrict your search to a certain mesh format, * .inp for instance, then either use "grid.inp" in - * the code above or use the alternative open function - * @verbatim - * istream& in = search.open("grid", ".inp"); - * @endverbatim + * the code above or use the alternative find(const std::string&,const + * std::string&,const char*) function + * @code + * std::string full_name = search.find("grid", ".inp"); + * @endcode * * Path lists are by default starting with the current directory * ("./"), followed optionally by a standard directory of @@ -71,10 +73,6 @@ * dot. These characters are not added automatically (allowing you to * do some real file name editing). * - * If you want to open another file with the same object, the previous - * one is automatically closed for you. The close() method is needed - * only if you need to open the same file externally. - * * @todo Add support for environment variables like in kpathsea. * * @author Guido Kanschat, Luca Heltai 2005 @@ -83,7 +81,8 @@ class PathSearch { public: /** - * Position for adding a new item to a list. + * Position for adding a new item + * to a list. */ enum Position { @@ -107,40 +106,76 @@ class PathSearch const unsigned int debug=0); /** - * Open a file in the class - * specified by the constructor. + * Find a file in the class + * specified by the constructor + * and return its complete path + * name (including a possible + * suffix). + * + * File search works by actually + * trying to open the file. If @p + * fopen is successful with the + * provided @p open_mode, then + * the file is found, otherwise + * the search continues. + * + * @warning Be careful with @p + * open_mode! In particular, use + * "w" with great care! + * If the file does not exist, it + * cannot be found. If it does + * exist, the @p fopen function + * will truncate it to zero + * length. + * + * @param filename The base + * name of the file to be found, + * without path components and + * suffix. + * @param open_mode The mode + * handed over to the @p fopen + * function. */ - std::istream& open (const std::string& filename); + std::string find (const std::string& filename, + const char* open_mode = "r"); /** - * Open a file in the class - * specified by the - * constructor. Do not use the - * standard suffix list, but only - * try to apply the suffix given. - */ - std::istream& open (const std::string& filename, - const std::string& suffix); - - /** Explicitly close the file - opened by the previous call - to one of the open() - functions. This is needed - only if you need to open the - same file externally. Opening - another file with the same - PathSearch object - automatically closes the old - one. */ - void close(); - - /** - * Return the actual name of the - * file opened by the previous - * call to one of the open() - * functions. + * Find a file in the class + * specified by the constructor + * and return its complete path + * name. Do not use the standard + * suffix list, but only try to + * apply the suffix given. + * + * File search works by actually + * trying to open the file. If @p + * fopen is successful with the + * provided @p open_mode, then + * the file is found, otherwise + * the search continues. + * + * @warning Be careful with @p + * open_mode! In particular, use + * "w" with great care! + * If the file does not exist, it + * cannot be found. If it does + * exist, the @p fopen function + * will truncate it to zero + * length. + * + * @param filename The base + * name of the file to be found, + * without path components and + * suffix. + * @param suffix The suffix to be + * used for opening. + * @param open_mode The mode + * handed over to the @p fopen + * function. */ - const std::string& name() const; + std::string find (const std::string& filename, + const std::string& suffix, + const char* open_mode = "r"); /** * Show the paths and suffixes @@ -174,13 +209,19 @@ class PathSearch * This class was not * registered in the path * search mechanism. + * @ingroup Exceptions */ DeclException1(ExcNoClass, std::string, << "The class " << arg1 << " must be registered before referring it in PathSearch"); - + /** + * The PathSearch class could not + * find a file with this name in + * its path list. + * @ingroup Exceptions + */ DeclException2(ExcFileNotFound, std::string, std::string, << "The file \"" << arg1 @@ -244,17 +285,6 @@ class PathSearch */ std::vector& my_suffix_list; - /** - * The file stream after open was called. - */ - std::auto_ptr stream; - - /** - * The actual name of the file - * that was opened previously. - */ - std::string real_name; - /** * Debug flag. No output if zero. */ @@ -270,15 +300,6 @@ class PathSearch /* ----------------------------- inline functions ------------------------- */ -inline -const std::string& -PathSearch::name () const -{ - return real_name; -} - - - template inline void diff --git a/deal.II/base/source/path_search.cc b/deal.II/base/source/path_search.cc index 95768ae65e..9d025f15a8 100644 --- a/deal.II/base/source/path_search.cc +++ b/deal.II/base/source/path_search.cc @@ -15,6 +15,7 @@ #include #include +#include #include //TODO:[GK] Clean up open functions, reuse code! @@ -89,72 +90,45 @@ PathSearch::PathSearch(const std::string& cls, {} -std::istream& -PathSearch::open (const std::string& filename, - const std::string& suffix) +std::string +PathSearch::find (const std::string& filename, + const std::string& suffix, + const char* open_mode) { std::vector::const_iterator path; const std::vector::const_iterator endp = my_path_list.end(); + std::string real_name; + if (debug > 2) deallog << "PathSearch[" << cls << "] " << my_path_list.size() << " directories " << std::endl; - // Try without suffix first - for (path = my_path_list.begin(); path != endp; ++path) - { - real_name = *path + filename; - if (debug > 1) - deallog << "PathSearch[" << cls << "] trying " - << real_name << std::endl; - stream.reset(new std::ifstream(real_name.c_str())); - if (stream->is_open()) - { - if (debug > 0) - deallog << "PathSearch[" << cls << "] opened " - << real_name << std::endl; - return *stream; - } - } - - // Now try with given suffix + // Try to open file for (path = my_path_list.begin(); path != endp; ++path) { real_name = *path + filename + suffix; if (debug > 1) deallog << "PathSearch[" << cls << "] trying " << real_name << std::endl; - stream.reset(new std::ifstream(real_name.c_str())); - if (stream->is_open()) + FILE* fp = fopen(real_name.c_str(), open_mode); + if (fp != 0) { if (debug > 0) deallog << "PathSearch[" << cls << "] opened " << real_name << std::endl; - return *stream; + fclose(fp); + return real_name; } } AssertThrow(false, ExcFileNotFound(filename, cls)); - return *stream; + return std::string(""); } -void -PathSearch::close() -{ - if(stream->is_open()) { - stream->close(); - if (debug > 0) - deallog << "PathSearch[" << cls << "] closed " - << real_name << std::endl; - } else { - if (debug > 0) - deallog << "PathSearch[" << cls - << "] nothing opened" << std::endl; - } -} - -std::istream& -PathSearch::open (const std::string& filename) +std::string +PathSearch::find (const std::string& filename, + const char* open_mode) { std::vector::const_iterator suffix; std::vector::const_iterator path; @@ -169,24 +143,18 @@ PathSearch::open (const std::string& filename) for (suffix = my_suffix_list.begin(); suffix != ends; ++suffix) { - for (path = my_path_list.begin(); path != endp; ++path) + try { - real_name = *path + filename + *suffix; - if (debug > 1) - deallog << "PathSearch[" << cls << "] trying " - << real_name << std::endl; - stream.reset(new std::ifstream(real_name.c_str())); - if (stream->is_open()) - { - if (debug > 0) - deallog << "PathSearch[" << cls << "] opened " - << real_name << std::endl; - return *stream; - } + return find(filename, *suffix, open_mode); + } + catch (ExcFileNotFound) + { + continue; } + } AssertThrow(false, ExcFileNotFound(filename, cls)); - return *stream; + return std::string(""); } diff --git a/deal.II/deal.II/source/grid/grid_in.cc b/deal.II/deal.II/source/grid/grid_in.cc index c7e452a877..2ffae5cdb5 100644 --- a/deal.II/deal.II/source/grid/grid_in.cc +++ b/deal.II/deal.II/source/grid/grid_in.cc @@ -1002,9 +1002,14 @@ void GridIn::read (const std::string& filename, { // Search file class for meshes PathSearch search("MESH"); + std::string name; // Open the file and remember its name - std::istream& in = search.open(filename.c_str()); - const std::string& name = search.name(); + if (format == Default) + name = search.find(filename); + else + name = search.find(filename, default_suffix(format)); + + std::ifstream in(name.c_str()); if (format == Default) { diff --git a/tests/base/path_search.cc b/tests/base/path_search.cc index 45e0b65966..ab1de37088 100644 --- a/tests/base/path_search.cc +++ b/tests/base/path_search.cc @@ -31,20 +31,16 @@ int main() cc.add_suffix(".c"); cc.add_suffix(".cc"); - cc.open("block_vector.cc"); - deallog << cc.name() << std::endl; - cc.open("block_vector"); - deallog << cc.name() << std::endl; + deallog << cc.find("block_vector.cc") << std::endl; + deallog << cc.find("block_vector") << std::endl; cc.add_suffix(".h", PathSearch::after_none); - cc.open("block_vector"); - deallog << cc.name() << std::endl; - + deallog << cc.find("block_vector") << std::endl; cc.show(deallog); PathSearch mesh("MESH", 3); mesh.show(deallog); - std::istream& in = mesh.open("backstep"); - deallog << mesh.name() << std::endl; + std::ifstream in(mesh.find("backstep").c_str()); + deallog << mesh.find("backstep") << std::endl; std::string line; for (unsigned int i=0;i<4;++i) {