File: convenientstreams.h

package info (click to toggle)
qepcad 1.74%2Bds-5
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 4,848 kB
  • sloc: ansic: 27,242; cpp: 2,995; makefile: 1,287; perl: 91
file content (113 lines) | stat: -rw-r--r-- 3,607 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
/***************************************************************
 * This file defines two very convenient stream classes:
 *
 * cacIstream  - Comments and continuations istream,
 *               i.e. # & \\n mean what you think
 *
 * slwcistream - Single-line buffered, respecting #'s for 
 *               comments and \\n for continuations
 * Chris Brown, 11 April, 2007
 ***************************************************************/
#ifndef _CONVENIENT_STREAMS_
#define _CONVENIENT_STREAMS_
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <string>
#include <sstream>
using namespace std;


/***************************************************************
 * slwcistream - Single-line buffered, respecting #'s for 
 * comments and \\n for continuations
 ***************************************************************/
class slwcistream : public istringstream
{
public:
  enum option {none = 0, skipleadingws = 1};
  slwcistream(istream& in, option opt = none)
  {
    string s = "";
    signed char c = in.get();
    if (opt == skipleadingws) 
      while(c != EOF && (isspace(c) || (c == '\\' && isspace(in.peek())))) c = in.get();
    // States  : 0 = normal, 1 = in comment, 2 = just read a backslash
    int state = 0;
    do {
      if (c == EOF) break;
      if (state == 2 && c == '\n') { state = 0; continue; }
      if (c == '\n') break;
      if (state == 1 && c == '\\' && in.peek() == '\n') { in.get(); state = 0; continue; }
      if (state == 1) continue;
      if (state == 0 && c == '#') { state = 1; continue; }
      if (state == 0 && c == '\\') { state = 2; continue; }
      s += c;
      state = 0;
    }while((c = in.get()));
    str(s);
  }
};


/***************************************************************
 * cacIstream - Comments and continuations istream, 
 * i.e. # and \\n mean what you think
 ***************************************************************/


class cacInBuff : public streambuf
{  
protected:
  static const int buffSize = 10;
  static const int extra = 4;
  char buff[buffSize];
  istream *trueIn;
public:
  cacInBuff(istream &_in) { trueIn = &_in; char *tmp = buff+extra; setg(tmp,tmp,tmp); }
  inline virtual int_type underflow();
};

class cacIstream : public istream
{
protected:
  cacInBuff buff;
public:
  cacIstream(istream &_in) : buff(_in), istream(&buff) { }
};

/***************************************************************
 * Implementation of realineInBuff member functions
 ***************************************************************/
cacInBuff::int_type cacInBuff::underflow()
{
  if (gptr() >= egptr())
  {
    int leftover = min((long int)extra, (long int)(gptr() - eback()));
    memmove(buff + (extra-leftover), gptr() - leftover, leftover);

    char *s = buff + extra;     // the string I'm reading in
    int ls = 0;                 // the actual size of s

    // States  : 0 = normal, 1 = in comment, 2 = just read a backslash
    istream & in = *trueIn;
    int state = 0;
    signed char c;
    while(ls < buffSize - extra && (c = in.get()))
    {
      if (c == EOF) break;
      else if (state == 2 && c == '\n') { state = 0; continue; }
      else if (c == '\n') ;
      else if (state == 1 && c == '\\' && in.peek() == '\n') { in.get(); state = 0; continue; }
      else if (state == 1) continue;
      else if (state == 0 && c == '#') { state = 1; continue; }
      else if (state == 0 && c == '\\') { state = 2; continue; }
      s[ls++] = c;
      state = 0;
    }
    if (ls == 0) return EOF;
    setg(buff + (extra-leftover), buff + extra, buff + extra + ls);
  }
  return *gptr();
}
#endif