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