00001 #ifndef DVUTIL_INCLUDESTREAM_H 00002 #define DVUTIL_INCLUDESTREAM_H 00003 // $Id: includestream.h,v 1.8 2005/12/18 17:10:27 dvermeir Exp $ 00004 00005 #include <string> 00006 #include <list> 00007 #include <iostream> 00008 #include "filterstreambuf.h" 00009 00010 namespace Dv { 00011 namespace Util { 00012 /** 00013 * A stream that can include other files. 00014 * An includestream is an @a istream that replaces lines 00015 * of the form 00016 * @code 00017 * #include "file" 00018 * #include <file> 00019 * @endcode 00020 * by the contents of the @c file. If @c file is between 00021 * double quotes and is not absolute, it is interpreted as relative 00022 * to the current directory. Otherwise (i.e. if it is of 00023 * the form @c <file> , it will be searched for (if it is 00024 * not absolute) in a list of directories. 00025 * @warning 00026 * <ol> 00027 * <li>An exception (@a runtime_error ) is thrown upon an 00028 * include error (syntax, file not found, ..) 00029 * <li>No check is made (yet) for recursive include directives. 00030 * </ol> 00031 */ 00032 class includestream: public std::istream { 00033 public: 00034 /** Type of optional second argument: a list of directories 00035 * to search for included files. 00036 */ 00037 typedef std::list<std::string> directories; 00038 private: 00039 /** 00040 * Implements Filter interface for filterstreambuf 00041 */ 00042 class IncludeFilter { 00043 public: 00044 /** Constructor. 00045 * @param is underlying input stream (need not be a file stream). 00046 * @param dirs pointer (may be 0) to a list of directories 00047 * to search if an include directive is of the @c <file> form. 00048 */ 00049 IncludeFilter(std::istream& is, directories* dirs); 00050 /** Constructor. 00051 * @param is underlying input stream (need not be a file stream). 00052 * @param dir a single directory 00053 * to search if an include directive is of the @a <file> form. 00054 */ 00055 IncludeFilter(std::istream& is, const std::string& dir); 00056 /** Destructor. */ 00057 ~IncludeFilter(); 00058 int put(int c) { return EOF; } 00059 int get(); 00060 int sync() { return -1; } 00061 void close() {} 00062 std::ios::iostate state() const; 00063 /** @return directories that will be searched when processing 00064 * include directives of the form @c <file>. 00065 */ 00066 const directories& dirs() const { return dirs_; } 00067 private: 00068 /** Underlying istream from where the filter takes its input. */ 00069 directories dirs_; 00070 /** Current input line. */ 00071 std::string line_; 00072 /** Current position in input line, std::string::npost if none. */ 00073 std::string::size_type pos_; 00074 /** Stack of open files. */ 00075 std::list<std::istream*> is_; 00076 /** Auxiliary function: pop @a &is from @a dirs_ . 00077 * @param is stream to pop. 00078 */ 00079 void pop(std::istream& is); 00080 }; 00081 00082 public: 00083 /** 00084 * Uses open stream. 00085 * @param stream from which original input is taken 00086 * @param dirs pointer (may be 0) to a list of directories 00087 * to search if an include directive is of the @c <file> form. 00088 * @warning No check for recursive include is made (yet). 00089 */ 00090 includestream(std::istream& stream, directories* dirs = 0); 00091 /** 00092 * Uses open stream. 00093 * @param stream from which original input is taken 00094 * @param dir a single directory 00095 * to search if an include directive is of the @a <file> form. 00096 * @warning No check for recursive include is made (yet). 00097 */ 00098 includestream(std::istream& stream, const std::string& dir); 00099 /** Destructor. */ 00100 ~includestream(); 00101 00102 /** Try to find a file @a d/filename for some directory @a d 00103 * in @a dirs. Return zero-length string if not found. The 00104 * directories are tried in order. 00105 * @param filename (relative) path of filename. If filename 00106 * is absolute, i.e. starts with @a / , only its existence 00107 * (without considering @a dirs ) is checked. 00108 * @param dirs list of directories to try 00109 * @return full pathname of first existing file @a d/filename 00110 * for some @a d in @a dirs, or zero-length string. If @a filename 00111 * starts with @a '/' , only the existence of @a filename is 00112 * checked. 00113 */ 00114 static std::string find(const std::string& filename, const directories& dirs); 00115 private: 00116 IncludeFilter filter_; 00117 }; 00118 } 00119 } 00120 00121 #endif
dvutil-1.0.10 | [ 5 December, 2009] |