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