]> git.donarmstrong.com Git - lilypond.git/blob - flower/lib/dstream.cc
release: 0.0.42
[lilypond.git] / flower / lib / dstream.cc
1
2
3 #include <fstream.h>
4 #include "assoc.hh"
5 #include "dstream.hh"
6 #include "scalar.hh"
7 #include "text-db.hh"
8 #include "string-convert.hh"
9
10 /// indent of each level 
11 const INDTAB = 2;
12
13 /*
14   should use Regexp library.
15   */
16 static String
17 strip_pretty(String pretty_str)
18 {
19     int i = pretty_str.index_i('(');
20     if (i>=0)
21         pretty_str = pretty_str.left_str(i);
22     
23     int l = pretty_str.index_last_i(' '); // strip until last ' '
24     if (l>=0)
25         pretty_str = pretty_str.nomid_str(0,l+1);
26     return pretty_str;
27 }
28
29 static String
30 strip_member(String pret)
31 {
32     int l=pret.index_last_i(':')-1;
33     if (l>=0)
34         pret = pret.left_str(l );
35     return pret;
36 }
37
38 Dstream&
39 Dstream::identify_as(String name)
40 {
41     if (!os)
42         return *this;
43     
44     String mem(strip_pretty(name));
45     String cl(strip_member(mem));
46     String idx = cl;
47     
48     if (silent->elt_query(mem))
49         idx  = mem;
50     else if (silent->elt_query(cl))
51         idx = cl;
52     else {
53         (*silent)[idx] = false;
54     }
55     local_silence = (*silent)[idx];
56     if (classname != idx && !local_silence) {
57         classname=idx;
58         if (!(*silent)["Dstream"])
59             *os << "[" << classname << ":]"; // messy.
60     }
61     return *this;
62 }
63
64 bool
65 Dstream::silence(String s)
66 {
67     if (!silent->elt_query(s))
68         return false;
69     return (*silent)[s];
70 }
71
72 /** Output a string via the Dstream. This is the only output
73  interface. It delegates all conversion to String class.  */
74 Dstream &
75 Dstream::operator<<(String s)
76 {
77     output(s);
78     return *this;
79 }
80
81 Dstream &
82 Dstream::operator<<(const void *v_l)
83 {
84     output(String_convert::pointer_str(v_l));
85     return *this;
86 }
87
88 Dstream &
89 Dstream::operator<<(const char *ch_l)
90 {
91     output(ch_l);
92     return *this;
93 }
94
95 void
96 Dstream::output(String s)
97 {
98     if (local_silence|| !os)
99         return ;
100     
101     for (const char *cp = s  ; *cp; cp++)
102         switch(*cp) {
103             case '{':
104             case '[':
105             case '(': indentlvl += INDTAB;
106                 *os << *cp;             
107                 break;
108                 
109             case ')':
110             case ']':
111             case '}':
112                 indentlvl -= INDTAB;
113                 *os << *cp              ;
114                 
115                 assert  (indentlvl>=0) ;
116                 break;
117                 
118             case '\n':
119                 *os << '\n' << String (' ', indentlvl) << flush;
120                 break;        
121             default:
122                 *os << *cp;
123                 break;
124             }
125     return ;    
126 }
127
128
129 Dstream::Dstream(ostream *r, const char * cfg_nm )
130 {
131     os = r;
132     silent = new Assoc<String,bool>;
133     indentlvl = 0;
134     if (!os)
135         return;
136     
137     const char * fn =cfg_nm ? cfg_nm : ".dstreamrc";
138     {
139         ifstream ifs(fn);       // can't open
140         if (!ifs)
141             return;
142     }
143
144     Text_db cfg(fn);
145     while (! cfg.eof()){             
146          Text_record  r(  cfg++);
147          if (r.size() != 2) {
148              r.message("not enough fields in Dstream init.");
149              continue;
150          }
151          (*silent)[r[0]] = (bool)(int)(Scalar(r[1]));
152     }
153
154 }
155
156
157 Dstream::~Dstream()
158 {    
159     delete silent;
160     assert(!indentlvl) ;
161 }