1 /* "CodeWorker": a scripting language for parsing and generating text. 2 3 Copyright (C) 1996-1997, 1999-2002 C�dric Lemaire 4 5 This library is free software; you can redistribute it and/or 6 modify it under the terms of the GNU Lesser General Public 7 License as published by the Free Software Foundation; either 8 version 2.1 of the License, or (at your option) any later version. 9 10 This library is distributed in the hope that it will be useful, 11 but WITHOUT ANY WARRANTY; without even the implied warranty of 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 Lesser General Public License for more details. 14 15 You should have received a copy of the GNU Lesser General Public 16 License along with this library; if not, write to the Free Software 17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 19 To contact the author: codeworker@free.fr 20 */ 21 22 #ifndef _ScpStream_h_ 23 #define _ScpStream_h_ 24 25 #ifndef WIN32 26 # include <cstdio> 27 # if defined(__cplusplus) // && __GNUC_PREREQ (4, 3) 28 # include <cstring> 29 # include <cstdlib> 30 # endif 31 #endif 32 33 #include <string> 34 #include <iostream> 35 #include <fstream> 36 #include <ctime> 37 38 #ifndef WIN32 39 # include <cstdio> // for Debian/gcc 2.95.4 40 #endif 41 42 #include <list> 43 #include <map> 44 #include <set> 45 46 namespace CodeWorker { 47 48 #ifdef IN 49 #undef IN 50 #endif 51 #ifdef OUT 52 #undef OUT 53 #endif 54 55 class ScpStream; 56 57 typedef bool (*END_STREAM_CALLBACK)(ScpStream& theStream, void* data); 58 59 class ScpStream { 60 public: 61 static int IN; 62 static int OUT; 63 static int INOUT; 64 static int APPEND; 65 static int PATH; 66 67 static std::string ENDL; 68 69 struct SizeAttributes { 70 int _iSize; 71 int _iReadCursor; 72 int _iWriteCursor; 73 char _cEndChar; 74 SizeAttributes* _pShiftedStream; 75 SizeAttributesSizeAttributes76 inline SizeAttributes() : _iSize(-1), _iReadCursor(-1), _iWriteCursor(-1), _pShiftedStream(NULL), _cEndChar('\0') {} SizeAttributesSizeAttributes77 inline SizeAttributes(const SizeAttributes& copy) : _iSize(copy._iSize), _iReadCursor(copy._iReadCursor), _iWriteCursor(copy._iWriteCursor), _cEndChar(copy._cEndChar) { 78 if (copy._pShiftedStream != NULL) { 79 _pShiftedStream = new SizeAttributes(*(copy._pShiftedStream)); 80 } else _pShiftedStream = NULL; 81 } ~SizeAttributesSizeAttributes82 inline ~SizeAttributes() { delete _pShiftedStream; } emptySizeAttributes83 inline bool empty() const { return (_iSize < 0); } 84 }; 85 86 private: 87 char* _tcStream; 88 int _iCacheMemory; 89 int _iSize; 90 int _iReadCursor; 91 int _iWriteCursor; 92 bool _bInsertText; 93 std::string _sIndentation; 94 95 int _iMode; 96 std::string _sFilename; 97 mutable ScpStream* _pParentStream; 98 ScpStream* _pShiftedStream; 99 int _iShiftedStreamPosition; 100 ScpStream* _pPrecStream; 101 ScpStream* _pNextStream; 102 103 // for the line directive 104 int _iLineCounter; 105 int _iLinePosition; 106 107 mutable std::map<std::string, int> _mapOfFloatingLocations; 108 std::set<std::string> _setOfTextsToInsertOnce; 109 110 static std::list<std::string> _listOfIncludePaths; 111 static std::map<std::string, std::string> _listOfVirtualFiles; 112 113 END_STREAM_CALLBACK _pfStreamReaderCallback; 114 void* _pStreamReaderCBKData; 115 END_STREAM_CALLBACK _pfStreamWriterCallback; 116 void* _pStreamWriterCBKData; 117 118 public: 119 ScpStream(int iCacheMemory = 2000000); 120 ScpStream(const std::string& sFilename, int iMode, int iCacheMemory = 2000000, int iLength = -1); 121 ScpStream(const std::string& sFilename, FILE* f, int iCacheMemory = 2000000); 122 ScpStream(const std::string& sText); 123 ScpStream(ScpStream& shiftedStream, int iShiftedStreamPosition); 124 ~ScpStream(); 125 126 static ScpStream* createFile(const std::string& sFilename); 127 static bool existInputFileFromIncludePath(const char* tcFileName, std::string& sCompleteFileName); 128 static bool existInputFile(const char* sFileName); 129 static ScpStream* openInputFileFromIncludePath(const char* tcFileName, std::string& sCompleteFileName); 130 static ScpStream* openInputFile(const char* sFileName); 131 readBuffer()132 inline const char* readBuffer() const { _tcStream[_iSize] = '\0';return _tcStream; } setFilename(const std::string & sFilename)133 inline void setFilename(const std::string& sFilename) { _sFilename = sFilename; } getFilename()134 inline const std::string& getFilename() const { return _sFilename; } size()135 inline int size() const { return _iSize; } empty()136 inline bool empty() const { return (_iSize == 0); } insertMode()137 inline bool insertMode() const { return _bInsertText; } insertMode(bool bInsertMode)138 inline void insertMode(bool bInsertMode) { _bInsertText = bInsertMode; } getParentStream()139 inline ScpStream* getParentStream() const { return _pParentStream; } setParentStream(ScpStream * pStream)140 inline void setParentStream(ScpStream* pStream) { _pParentStream = pStream; } getStreamReaderCallback()141 inline END_STREAM_CALLBACK getStreamReaderCallback() const { return _pfStreamReaderCallback; } 142 void setStreamReaderCallback(END_STREAM_CALLBACK pfCBK, void* pData = NULL); getStreamWriterCallback()143 inline END_STREAM_CALLBACK getStreamWriterCallback() const { return _pfStreamWriterCallback; } 144 void setStreamWriterCallback(END_STREAM_CALLBACK pfCBK, void* pData = NULL); 145 getIndentation()146 inline const std::string& getIndentation() const { return _sIndentation; } 147 void incrementIndentation(int iLevel = 1); 148 bool decrementIndentation(int iLevel = 1); 149 150 std::string getMessagePrefix(bool bCountCols = false) const; 151 152 int readChar(); 153 int peekChar(); getInputLocation()154 inline int getInputLocation() const { return _iReadCursor; } setInputLocation(int iLocation)155 inline void setInputLocation(int iLocation) { if (iLocation <= _iSize) _iReadCursor = iLocation; } getOutputLocation()156 inline int getOutputLocation() const { return _iWriteCursor; } setOutputLocation(int iLocation)157 inline void setOutputLocation(int iLocation) { if (iLocation <= _iSize) _iWriteCursor = iLocation; } 158 SizeAttributes resize(int iNewSize); 159 void restoreSize(const SizeAttributes& sizeAttrs); 160 void setLineDirective(int iLine); 161 int getLineCount() const; 162 int getOutputLineCount() const; 163 int getColCount() const; 164 int getOutputColCount() const; 165 bool goBack(); 166 bool skipBlanks(); 167 bool skipSpaces(); 168 bool skipLineBlanks(); 169 bool skipCppComments(); 170 bool skipCppExceptDoxygenComments(); 171 bool skipEmpty(); 172 bool skipEmptyCppExceptDoxygen(); 173 bool skipEmptyAda(); 174 bool skipEmptyHTML(); 175 bool skipEmptyLaTeX(); 176 bool skipLine(); 177 bool readChars(int iLength, std::string& sText); 178 bool readWord(std::string& sWord); 179 bool readIdentifier(std::string& sIdentifier); 180 bool readInt(int& iResult); 181 bool readHexadecimal(int& iResult); 182 bool readDouble(double& dValue); 183 bool readStringOrCharLiteral(std::string& sText); 184 bool readCharLiteral(int& iChar); 185 bool readString(std::string& sText); 186 bool readAdaString(std::string& sText); 187 bool readPythonString(std::string& sText); 188 bool readLine(std::string& sLine); 189 bool readLastChars(int iLength, std::string& sLastChars); 190 bool readUptoChar(char cEnd, std::string& sText); 191 bool readUptoChar(const std::string& sEnd, std::string& sText); 192 193 bool isEqualTo(unsigned char ch); 194 bool isEqualTo(const char* sText); 195 bool isEqualToIgnoreCase(unsigned char ch); 196 bool isEqualToIgnoreCase(const char* sText); 197 bool isEqualToIdentifier(const char* sText); isEqualTo(const std::string & sText)198 inline bool isEqualTo(const std::string& sText) { return isEqualTo(sText.c_str()); } isEqualToIgnoreCase(const std::string & sText)199 inline bool isEqualToIgnoreCase(const std::string& sText) { return isEqualToIgnoreCase(sText.c_str()); } 200 bool findString(const char* sText); 201 bool findString(const char* sText, int iBoundary); findString(const std::string & sText)202 inline bool findString(const std::string& sText) { return findString(sText.c_str()); } findString(const std::string & sText,int iBoundary)203 inline bool findString(const std::string& sText, int iBoundary) { return findString(sText.c_str(), iBoundary); } 204 allFloatingLocations()205 inline const std::map<std::string, int>& allFloatingLocations() const { return _mapOfFloatingLocations; } 206 bool newFloatingLocation(const std::string& sKey); 207 void setFloatingLocation(const std::string& sKey, int iLocation); 208 int getFloatingLocation(const std::string& sKey, ScpStream*& pOwner) const; 209 int removeFloatingLocation(const std::string& sKey, ScpStream*& pOwner); 210 211 ScpStream& operator <<(char cValue); 212 ScpStream& operator <<(unsigned char cValue); 213 ScpStream& operator <<(int iValue); 214 ScpStream& operator <<(long lValue); 215 ScpStream& operator <<(unsigned long lValue); 216 ScpStream& operator <<(double dValue); 217 ScpStream& operator <<(const char* tcValue); 218 ScpStream& operator <<(const std::string& sValue); 219 ScpStream& operator <<(const ScpStream& theStream); 220 void writeString(const std::string& sString); 221 void writeQuotedChar(char c); 222 void writeBinaryData(const char* tcBinary, int iLength); 223 std::string getLastWrittenChars(int iNbChars) const; 224 bool writeTextOnce(const std::string& sText); 225 ScpStream& flush(); 226 ScpStream& endl(); 227 bool close(); 228 229 bool equals(const ScpStream& theStream, int& iPosition) const; 230 bool equalsFromInputLocations(const ScpStream& theStream, int& iPosition) const; 231 bool insertText(const std::string& sText, int iLocation, int iAreaToRecover = 0); 232 bool insertTextOnce(const std::string& sText, int iLocation, int iAreaToRecover = 0); 233 bool insertStream(const ScpStream& theStream, int iLocation, int iAreaToRecover = 0); 234 bool copy(const ScpStream& theStream, int iLocation, int iLength = -1); 235 void saveIntoFile(const std::string& sFilename, bool bCreateFileIfUnknown) const; 236 void appendFile(const std::string& sFilename, bool bCreateFileIfUnknown) const; 237 238 bool indentAsCpp(); 239 getListOfIncludePaths()240 static const std::list<std::string>& getListOfIncludePaths() { return _listOfIncludePaths; } setListOfIncludePaths(const std::list<std::string> & listOfIncludePaths)241 static void setListOfIncludePaths(const std::list<std::string>& listOfIncludePaths) { _listOfIncludePaths = listOfIncludePaths; } 242 243 static bool createVirtualFile(const std::string& sHandle, const std::string& sContent); 244 static std::string createVirtualTemporaryFile(const std::string& sContent); 245 static bool existVirtualFile(const std::string& sHandle); 246 static bool loadVirtualFile(const std::string& sHandle, std::string& sContent); 247 static bool appendVirtualFile(const std::string& sHandle, const std::string& sContent); 248 static bool deleteVirtualFile(const std::string& sHandle); 249 250 static std::ifstream* openSTLInputFile(const char* sInputFile); 251 private: 252 void writeText(const char* tcText); 253 }; 254 255 256 bool createDirectoriesForFile(const std::string& sFileName); 257 258 std::fstream* openIOFile(const char* sInputFile, bool bCreateDirectories = false); 259 260 261 std::ifstream* openInputFileFromIncludePath(const char* sFileName, std::string& sCompleteFileName); 262 int getLocation(std::istream& stream); 263 void setLocation(std::istream& stream, int iCursor); 264 void setLocationAtXLines(std::istream& stream, int iCursor); 265 int getLineCount(std::istream& stream); 266 int getColCount(std::istream& stream); 267 bool previousLine(std::istream& stream); 268 int getColCount(std::istream& stream); 269 bool getColEmptyHeader(std::istream& stream, std::string& sHeader); 270 void goBack(std::istream& stream); 271 int readChar(std::istream& stream); 272 int peekChar(std::istream& stream); 273 bool skipBlanks(std::istream& stream); 274 bool skipLineBlanks(std::istream& stream); 275 bool skipCppComments(std::istream& stream); 276 bool skipEmpty(std::istream& stream); 277 bool skipEmptyHTML(std::istream& stream); 278 bool skipEmptyLaTeX(std::istream& stream); 279 bool readWord(std::istream& stream, std::string& sWord); 280 bool readIdentifier(std::istream& stream, std::string& sIdentifier); 281 bool readLine(std::istream& stream, std::string& sLine); 282 bool readInt(std::istream& stream, int& iResult); 283 bool readLong(std::istream& stream, long& iResult); 284 bool readBoolean(std::istream& stream, bool& bResult); 285 bool readDouble(std::istream& stream, double& dResult); 286 bool readCharLiteral(std::istream& stream, int& iChar); 287 bool readStringOrCharLiteral(std::istream& stream, std::string& sText); 288 bool readString(std::istream& stream, std::string& sResult); 289 bool readDate(std::istream& stream, tm& myDate); 290 bool readFormattedText(std::istream& stream, const std::string& sFormat, std::string& sResult); 291 bool readPointer(std::istream& stream, unsigned long& iPointer); 292 bool readUptoChar(std::istream& myStream, char cEnd, std::string& sText); 293 bool readUptoChar(std::istream& myStream, const std::string& sEnd, std::string& sText); 294 bool isEqualTo(std::istream& stream, unsigned char ch); 295 bool isEqualTo(std::istream& stream, const char* sText); 296 bool isEqualToIdentifier(std::istream& stream, const char* sText); 297 bool findString(std::istream& stream, const char* sText); 298 std::string getLastReadChars(std::istream& stream, int iNbChars); 299 300 301 std::ofstream* openOutputFile(const char* sOutputFile, bool bCreateDirectories = false); 302 std::ofstream* openAppendFile(const char* sAppendFile); 303 void writeChar(std::ostream& stream, char c); 304 void writeText(std::ostream& stream, const char* sText); 305 void writeComments(std::ostream& stream, const char* sComment); 306 void writeBorderedComments(std::ostream& stream, const char* sComment); 307 void carriageReturn(std::ostream& stream); 308 void writeInt(std::ostream& stream, int iValue); 309 void writeBoolean(std::ostream& stream, bool bValue); 310 void writeDouble(std::ostream& stream, double dValue); 311 void writeString(std::ostream& stream, const char* sText); 312 void writeDate(std::ostream& stream, const tm& myDate); 313 void writePointer(std::ostream& stream, unsigned long iPointer); 314 315 void copyToStream(std::istream& inputStream, std::ostream& outputStream, int iStart, int iLength = -1); 316 317 bool isPathTerminator_(char c); 318 void toSlashes_(char *str); 319 std::string canonize_(const char* tcPathname, char* dest1); 320 321 } 322 323 #endif 324