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 + -
显示快捷键?