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