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