]> granicus.if.org Git - re2c/commitdiff
- Add the new header
authorhelly <helly@642ea486-5414-0410-9d7f-a0204ed87703>
Sat, 21 Jan 2006 15:52:58 +0000 (15:52 +0000)
committerhelly <helly@642ea486-5414-0410-9d7f-a0204ed87703>
Sat, 21 Jan 2006 15:52:58 +0000 (15:52 +0000)
stream_lc.h [new file with mode: 0755]

diff --git a/stream_lc.h b/stream_lc.h
new file mode 100755 (executable)
index 0000000..41ca65b
--- /dev/null
@@ -0,0 +1,348 @@
+/*
+ Author: Marcus Boerger <helly@users.sourceforge.net>
+*/
+
+/* $Id$ */
+
+#ifndef _stream_lc_h
+#define _stream_lc_h
+
+#include <iosfwd>
+#include <fstream>
+#include <assert.h>
+
+namespace re2c
+{
+
+template<class _E>
+class basic_null_streambuf
+       : public std::basic_streambuf<_E>
+{
+public:
+       basic_null_streambuf()
+               : std::basic_streambuf<_E>()
+       {
+       }       
+};
+
+typedef basic_null_streambuf<char> null_streambuf;
+
+template<class _E>
+class basic_null_stream
+       : public std::basic_ostream<_E>
+{
+public:
+       basic_null_stream()
+               : std::basic_ostream<_E>(&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>  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)
+               , oline(1)
+       {
+       }
+
+       virtual ~basic_filebuf_lc()
+       {
+               sync();
+               if (must_close)
+               {
+                       close();
+               }
+       }
+
+       uint get_line() const
+       {
+               return oline + 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)
+                                  ? "w"
+                                  : "r";
+               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')
+               {
+                       ++oline;
+               }
+               if (_Tr::eq_int_type(_Tr::eof(), c))
+               {
+                       return _Tr::not_eof(c);
+               }
+               else
+               {
+                       return fputc(_Tr::to_char_type(c), fp) ? c : _Tr::eof();
+               }
+       }
+
+       virtual int_type pbackfail(int_type c = _Tr::eof())
+       {
+               c = 0;
+               assert(0);
+               return 0;
+       }
+
+       virtual int_type underflow()
+       {
+               assert(0);
+               return 0;
+       }
+
+       virtual int_type uflow()
+       {
+               assert(0);
+               return 0;
+       }
+
+       virtual pos_type seekoff(off_type, std::ios_base::seekdir,
+               std::ios_base::openmode = (std::ios_base::openmode)(std::ios_base::in | std::ios_base::out))
+       {
+               assert(0);
+               return pos_type(~0);
+       }
+
+       virtual pos_type seekpos(pos_type,
+               std::ios_base::openmode = (std::ios_base::openmode)(std::ios_base::in | std::ios_base::out))
+       {
+               assert(0);
+               return pos_type(~0);
+       }
+
+       virtual _Mybase * setbuf(_E *, std::streamsize)
+       {
+               assert(0);
+               return this;
+       }
+
+       virtual int sync()
+       {
+               return fp == 0
+                       || _Tr::eq_int_type(_Tr::eof(), overflow())
+                       || 0 <= fflush(fp) ? 0 : -1;
+       }
+
+       virtual void imbue(const std::locale&)
+       {
+               assert(0);
+       }
+
+       std::streamsize xsputn(const _E *buf, std::streamsize cnt)
+       {
+               oline += std::count(buf, buf + cnt, '\n');
+               return fwrite(buf, sizeof(_E), cnt, fp);
+       }
+
+private:
+
+       FILE * fp;
+       bool   must_close;
+       uint   oline;
+};
+
+typedef basic_filebuf_lc<char> filebuf_lc;
+
+template<class _E, class _Tr = std::char_traits<_E> >
+class basic_ofstream_lc
+       : public std::basic_ostream<_E, _Tr>
+       , public line_number
+{
+public:
+       typedef std::basic_ios<    _E, _Tr> _Myios;
+       typedef std::basic_ostream<_E, _Tr> _Mybase;
+       typedef basic_ofstream_lc< _E, _Tr> _Myt;
+       typedef basic_filebuf_lc<  _E, _Tr> _Mybuf;
+
+       basic_ofstream_lc()
+               : _Mybase(&mybuf)  
+       {
+       }
+
+       virtual ~basic_ofstream_lc()
+       {
+       }
+
+       bool is_open() const
+       {
+               return mybuf.is_open();
+       }
+
+       void open(const char * filename, std::ios_base::openmode mode = std::ios_base::out)
+       {
+               if ((mode & std::ios_base::out) == 0 || mybuf.open(filename, mode) == 0)
+               {
+                       _Myios::setstate(std::ios_base::failbit);
+               }
+       }
+       
+       void open(FILE *fp)
+       {
+               if (mybuf.open(fp) == 0)
+               {
+                       _Myios::setstate(std::ios_base::failbit);
+               }
+       }
+       
+       void close()
+       {
+               if (mybuf.close() == 0)
+               {
+                       _Myios::setstate(std::ios_base::failbit);
+               }
+       }
+       
+       uint get_line() const
+       {
+               return mybuf.get_line();
+       }
+
+protected:
+       mutable _Mybuf mybuf;
+};
+
+typedef basic_ofstream_lc<char> ofstream_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)
+       {
+               new (this) file_info(oth.fname, oth.ln, false);
+               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 */