stream_lc.h

来自「a little DFA compiler.」· C头文件 代码 · 共 434 行

H
434
字号
/* Author: Marcus Boerger <helly@users.sourceforge.net>*//* $Id: stream_lc.h 767 2007-06-26 15:21:10Z helly $ */#ifndef _stream_lc_h#define _stream_lc_h#include <iosfwd>#include <fstream>#include <assert.h>#include <stdio.h>namespace re2c{template<class _E, class _Tr = std::char_traits<_E> >class basic_null_streambuf	: public std::basic_streambuf<_E, _Tr>{public:	basic_null_streambuf()		: std::basic_streambuf<_E, _Tr>()	{	}	};typedef basic_null_streambuf<char> null_streambuf;template<class _E, class _Tr = std::char_traits<_E> >class basic_null_stream	: public std::basic_ostream<_E, _Tr>{public:	basic_null_stream()		: std::basic_ostream<_E, _Tr>(null_buf = new basic_null_streambuf<_E, _Tr>())	{	}		virtual ~basic_null_stream()	{		delete null_buf;	}	basic_null_stream& put(_E)	{		// nothing to do		return *this;	}		basic_null_stream& write(const _E *, std::streamsize)	{		// nothing to do		return *this;	}protected:	basic_null_streambuf<_E, _Tr> * null_buf;};typedef basic_null_stream<char> null_stream;class line_number{public:	virtual ~line_number()	{	}	virtual uint get_line() const = 0;};template<class _E, class _Tr = std::char_traits<_E> >class basic_filebuf_lc	: public std::basic_streambuf<_E, _Tr>	, public line_number{public:	typedef std::basic_streambuf<_E, _Tr> _Mybase;	typedef basic_filebuf_lc<_E, _Tr> _Myt;	typedef _E char_type;	typedef _Tr traits_type;	typedef typename _Tr::int_type int_type;	typedef typename _Tr::pos_type pos_type;	typedef typename _Tr::off_type off_type;	basic_filebuf_lc(FILE *_fp = 0)		: _Mybase()		, fp(_fp)		, must_close(false)		, fline(1)	{	}	virtual ~basic_filebuf_lc()	{		sync();		if (must_close)		{			close();		}	}	uint get_line() const	{		return fline + 1;	}	bool is_open() const	{		return fp != 0;	}	_Myt* open(const char *filename, std::ios_base::openmode mode = std::ios_base::out)	{		if (fp != 0)		{			return 0;		}		const char * fmode = (mode & std::ios_base::out)		                   ? "wt"		                   : "rt";		if ((fp = fopen(filename, fmode)) == 0)		{			return 0;		}		must_close = true;		return this;	}	_Myt* open(FILE * _fp)	{		if (fp != 0)		{			return 0;		}		fp = _fp;		must_close = false;		return this;	}	_Myt* close()	{		sync();		if (fp == 0 || fclose(fp) != 0)		{			fp = 0;			return 0;		}		else		{			fp = 0;			return this;		}	}protected:	virtual int_type overflow(int_type c = _Tr::eof())	{		if (c == '\n')		{			++fline;		}		if (_Tr::eq_int_type(_Tr::eof(), c))		{			return _Tr::not_eof(c);		}		else		{			buffer += _Tr::to_char_type(c);			return c;		}	}	virtual int_type pbackfail(int_type c = _Tr::eof())	{		assert(0);		c = 0;		return _Tr::eof();	}	virtual int_type underflow() // don't point past it	{		int c;		if (buffer.length())		{			return buffer[0];		}		if (fp == 0 || ((c = fgetc(fp)) == EOF))		{			return _Tr::eof();		}		buffer += (char)c;		return c;	}	virtual int_type uflow() // point past it	{		int c;		if (buffer.length())		{			c = buffer[0];			buffer.erase(0, 1);			return c;		}		if (fp == 0 || ((c = fgetc(fp)) == EOF))		{			return _Tr::eof();		}		else if (c == '\n')		{			++fline;		}		return c;	}#if 0	virtual std::streamsize xsgetn(_E* buf, std::streamsize n)	{		std::streamsize r = 0;		while(n--)		{			int_type c = underflow();			if (_Tr::eq_int_type(_Tr::eof(), c))			{				break;			}			buf[r++] = c;		}		buf[r] = '\0';		return r;	}#endif	virtual pos_type seekoff(off_type off, std::ios_base::seekdir whence,		std::ios_base::openmode = (std::ios_base::openmode)(std::ios_base::in | std::ios_base::out))	{		return fseek(fp, (long)off, whence);	}	virtual pos_type seekpos(pos_type fpos,		std::ios_base::openmode = (std::ios_base::openmode)(std::ios_base::in | std::ios_base::out))	{		return fseek(fp, (long)fpos, SEEK_SET);	}	virtual _Mybase * setbuf(_E *, std::streamsize)	{		assert(0);		return this;	}	virtual int sync()	{		if (buffer.length() != 0) {			fwrite(buffer.c_str(), sizeof(_E), buffer.length(), fp);		}		buffer.clear();		return fp == 0			|| _Tr::eq_int_type(_Tr::eof(), overflow())			|| 0 <= fflush(fp) ? 0 : -1;	}	virtual std::streamsize xsputn(const _E *buf, std::streamsize cnt)	{		if (buffer.length() != 0) {			fwrite(buffer.c_str(), sizeof(_E), buffer.length(), fp);		}		buffer.clear();		/*fline += std::count(buf, buf + cnt, '\n');*/		for (std::streamsize pos = 0; pos < cnt; ++pos) 		{			if (buf[pos] == '\n')			{				++fline;			}		}		if (cnt != 0) {			return fwrite(buf, sizeof(_E), cnt, fp);		} else {			return 0;		}	}private:	FILE * fp;	bool   must_close;	uint   fline;	std::basic_string<_E, _Tr> buffer;};typedef basic_filebuf_lc<char> filebuf_lc;template<	class _E, 	class _BaseStream,	std::ios_base::openmode  _DefOpenMode,	class _Tr = std::char_traits<_E> >class basic_fstream_lc	: public _BaseStream	, public line_number{public:	typedef basic_fstream_lc<_E, _BaseStream, _DefOpenMode, _Tr> _Myt;	typedef std::basic_ios<_E, _Tr> _Myios;	typedef _BaseStream _Mybase;	typedef basic_filebuf_lc<_E, _Tr> _Mybuf;	basic_fstream_lc()		: _Mybase(mybuf = new _Mybuf())	{	}	virtual ~basic_fstream_lc()	{		delete mybuf;	}	bool is_open() const	{		return mybuf->is_open();	}	_Myt& open(const char * filename, std::ios_base::openmode mode = _DefOpenMode)	{		if ((mode & _DefOpenMode) == 0 || mybuf->open(filename, mode) == 0)		{			_Myios::setstate(std::ios_base::failbit);		}		return *this;	}		_Myt& open(FILE *fp)	{		if (mybuf->open(fp) == 0)		{			_Myios::setstate(std::ios_base::failbit);		}		return *this;	}		void close()	{		if (mybuf->close() == 0)		{			_Myios::setstate(std::ios_base::failbit);		}	}		uint get_line() const	{		return mybuf->get_line();	}protected:	mutable _Mybuf *mybuf;};template<class _E, class _Tr = std::char_traits<_E> >class basic_ofstream_lc	: public basic_fstream_lc<_E, std::basic_ostream<_E, _Tr>, std::ios_base::out, _Tr>{};typedef basic_ofstream_lc<char> ofstream_lc;template<class _E, class _Tr = std::char_traits<_E> >class basic_ifstream_lc	: public basic_fstream_lc<_E, std::basic_istream<_E, _Tr>, std::ios_base::in, _Tr>{};typedef basic_ifstream_lc<char> ifstream_lc;class file_info{public:	static std::string escape(const std::string& _str)	{		std::string str(_str);		size_t l = str.length();		for (size_t p = 0; p < l; ++p)		{			if (str[p] == '\\')			{				str.insert(++p, "\\");				++l;			}		}		return str;	}	file_info()		: ln(NULL)	{	}	file_info(const std::string& _fname, const line_number* _ln, bool _escape = true)		: fname(_escape ? escape(_fname) : _fname)		, ln(_ln)	{	}	file_info(const file_info& oth, const line_number* _ln = NULL)		: fname(oth.fname)		, ln(_ln)	{	}	file_info& operator = (const file_info& oth)	{		*(const_cast<std::string*>(&this->fname)) = oth.fname;		ln = oth.ln;		return *this;	}	const std::string  fname;	const line_number* ln;};std::ostream& operator << (std::ostream& o, const file_info& li);} // end namespace re2c#endif /* _stream_lc_h */

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?