summaryrefslogtreecommitdiff
path: root/flower/dstream.cc
blob: 6cfc62eb3ded390c3a96555f3a1a9f36e4a6f4ac (about) (plain)
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
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
#include <fstream.h>
#include "assoc.hh"
#include "dstream.hh"
#include "string.hh"
#include "textdb.hh"

/// indent of each level 
const INDTAB = 3;

/*
  should use Regexp library.
  */
static String
strip_pretty(String pret)
{
    String cl(pret.left(pret.pos('(')-1));
    int l = cl.lastPos(' ');
    cl = cl.right(cl.len() -l);
    return cl;
}

static String
strip_member(String pret)
{
    String cl(pret.left(pret.lastPos(':')-2));
    return cl;
}

Dstream&
Dstream::identify_as(String name)
{
    if (!os)
	return *this;
    
    String mem(strip_pretty(name));
    String cl(strip_member(mem));
    String idx = cl;
    
    if (silent->elt_query(mem))
	idx  = mem;
    else if (silent->elt_query(cl))
	idx = cl;
    else {
	(*silent)[idx] = false;
    }
    local_silence = (*silent)[idx];
    if (classname != idx && !local_silence) {
	classname=idx;
	*os << "[" << classname << ":]";
    }
    return *this;
}

bool
Dstream::silence(String s)
{
    if (!silent->elt_query(s))
	return false;
    return (*silent)[s];
}
///
Dstream &
Dstream::operator<<(String s)
{
    if (local_silence|| !os)
	return *this;
    
    for (const char *cp = s  ; *cp; cp++)
	switch(*cp) 
	    {
	    case '{':
	    case '[':
	    case '(': indentlvl += INDTAB;
		*os << *cp;		
		break;
		
	    case ')':
	    case ']':
	    case '}':
		indentlvl -= INDTAB;
		*os << *cp		;
		
		assert  (indentlvl>=0) ;
		break;
		
	    case '\n':
		*os << '\n' << String (' ', indentlvl) << flush;
		break;	      
	    default:
		*os << *cp;
		break;
	    }
    return *this;    
}

/** only output possibility. Delegates all conversion to String class.
 */

Dstream::Dstream(ostream *r, const char * cfg_nm )
{
    os = r;
    silent = new Assoc<String,bool>;
    if (!os)
	return;
    indentlvl = 0;
    
    const char * fn =cfg_nm ? cfg_nm : ".dstreamrc";
    {
	ifstream ifs(fn);	// can't open
	if (!ifs)
	    return;
    }

    Text_db cfg(fn);
    while (! cfg.eof()){	     
	 Text_record  r(  cfg++);
	 if (r.sz() != 2) {
	     r.message("not enough fields in Dstream init.");
	     continue;
	 }
	 (*silent)[r[0]] = r[1].to_bool();
    }

}


Dstream::~Dstream()
{
    delete silent;
}