]> git.donarmstrong.com Git - lilypond.git/blob - flower/dstream.cc
release: 0.0.20
[lilypond.git] / flower / dstream.cc
1 #include <fstream.h>
2 #include "assoc.hh"
3 #include "dstream.hh"
4 #include "scalar.hh"
5 #include "textdb.hh"
6
7 /// indent of each level 
8 const INDTAB = 3;
9
10 /*
11   should use Regexp library.
12   */
13 static String
14 strip_pretty(String pret)
15 {
16     String cl(pret.left(pret.pos('(')-1));
17     int l = cl.lastPos(' ');
18     cl = cl.right(cl.len() -l);
19     return cl;
20 }
21
22 static String
23 strip_member(String pret)
24 {
25     String cl(pret.left(pret.lastPos(':')-2));
26     return cl;
27 }
28
29 Dstream&
30 Dstream::identify_as(String name)
31 {
32     if (!os)
33         return *this;
34     
35     String mem(strip_pretty(name));
36     String cl(strip_member(mem));
37     String idx = cl;
38     
39     if (silent->elt_query(mem))
40         idx  = mem;
41     else if (silent->elt_query(cl))
42         idx = cl;
43     else {
44         (*silent)[idx] = false;
45     }
46     local_silence = (*silent)[idx];
47     if (classname != idx && !local_silence) {
48         classname=idx;
49         *os << "[" << classname << ":]";
50     }
51     return *this;
52 }
53
54 bool
55 Dstream::silence(String s)
56 {
57     if (!silent->elt_query(s))
58         return false;
59     return (*silent)[s];
60 }
61 ///
62 Dstream &
63 Dstream::operator<<(String s)
64 {
65     if (local_silence|| !os)
66         return *this;
67     
68     for (const char *cp = s  ; *cp; cp++)
69         switch(*cp) 
70             {
71             case '{':
72             case '[':
73             case '(': indentlvl += INDTAB;
74                 *os << *cp;             
75                 break;
76                 
77             case ')':
78             case ']':
79             case '}':
80                 indentlvl -= INDTAB;
81                 *os << *cp              ;
82                 
83                 assert  (indentlvl>=0) ;
84                 break;
85                 
86             case '\n':
87                 *os << '\n' << String (' ', indentlvl) << flush;
88                 break;        
89             default:
90                 *os << *cp;
91                 break;
92             }
93     return *this;    
94 }
95
96 /** only output possibility. Delegates all conversion to String class.
97  */
98
99 Dstream::Dstream(ostream *r, const char * cfg_nm )
100 {
101     os = r;
102     silent = new Assoc<String,bool>;
103     if (!os)
104         return;
105     indentlvl = 0;
106     
107     const char * fn =cfg_nm ? cfg_nm : ".dstreamrc";
108     {
109         ifstream ifs(fn);       // can't open
110         if (!ifs)
111             return;
112     }
113
114     Text_db cfg(fn);
115     while (! cfg.eof()){             
116          Text_record  r(  cfg++);
117          if (r.size() != 2) {
118              r.message("not enough fields in Dstream init.");
119              continue;
120          }
121          (*silent)[r[0]] = bool(Scalar(r[1]));
122     }
123
124 }
125
126
127 Dstream::~Dstream()
128 {
129     delete silent;
130 }