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