]> git.donarmstrong.com Git - lilypond.git/blob - flower/dstream.cc
release: 0.0.37
[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_str(pret.index_i('(')));
17     int l = cl.index_last_i(' ');
18     cl = cl.right_str(cl.len() - l - 1);
19     return cl;
20 }
21
22 static String
23 strip_member(String pret)
24 {
25     String cl(pret.left_str(pret.index_last_i(':')-1));
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 /** only output possibility. Delegates all conversion to String class.
63  */
64 Dstream &
65 Dstream::operator<<(String s)
66 {
67     if (local_silence|| !os)
68         return *this;
69     
70     for (const char *cp = s  ; *cp; cp++)
71         switch(*cp) 
72             {
73             case '{':
74             case '[':
75             case '(': indentlvl += INDTAB;
76                 *os << *cp;             
77                 break;
78                 
79             case ')':
80             case ']':
81             case '}':
82                 indentlvl -= INDTAB;
83                 *os << *cp              ;
84                 
85                 assert  (indentlvl>=0) ;
86                 break;
87                 
88             case '\n':
89                 *os << '\n' << String (' ', indentlvl) << flush;
90                 break;        
91             default:
92                 *os << *cp;
93                 break;
94             }
95     return *this;    
96 }
97
98
99 Dstream::Dstream(ostream *r, const char * cfg_nm )
100 {
101     os = r;
102     silent = new Assoc<String,bool>;
103     indentlvl = 0;
104     if (!os)
105         return;
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)(int)(Scalar(r[1]));
122     }
123
124 }
125
126
127 Dstream::~Dstream()
128 {
129     delete silent;
130 }