]> git.donarmstrong.com Git - lilypond.git/blob - flower/dstream.cc
release: 1.3.0
[lilypond.git] / flower / dstream.cc
1 /*
2   dstream.cc -- implement Dstream
3
4   source file of the Flower Library
5
6   (c) 1996, 1997--1999 Han-Wen Nienhuys <hanwen@cs.uu.nl>
7 */
8
9 #include <fstream.h>
10 #include "dictionary-iter.hh"
11 #include "dstream.hh"
12
13 #include "text-db.hh"
14 #include "string-convert.hh"
15 #include "rational.hh"
16
17 /// amount of indentation for each level.
18 const int 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_dict_p_->elem_b (mem))
56     idx  = mem;
57   else if (silent_dict_p_->elem_b (cl))
58     idx = cl;
59   else
60     {
61       (*silent_dict_p_)[idx] = default_silence_b_;
62     }
63   local_silence_b_ = (*silent_dict_p_)[idx];
64   if (current_classname_str_ != idx && !local_silence_b_)
65     {
66       current_classname_str_=idx;
67       if (!(*silent_dict_p_)["Dstream"])
68         *os_l_ << "[" << current_classname_str_ << ":]"; // messy.
69     }
70   return *this;
71 }
72
73 bool
74 Dstream::silent_b (String s) const
75 {
76   if (!silent_dict_p_->elem_b (s))
77     return false;
78   return (*silent_dict_p_)[s];
79 }
80
81 Dstream &
82 Dstream::operator<<(void const *v_l)
83 {
84   output (String_convert::pointer_str (v_l));
85   return *this;
86 }
87
88 Dstream &
89 Dstream::operator <<(String s)
90 {
91   output (s);
92   return *this;
93 }
94
95 Dstream &
96 Dstream::operator <<(const char * s)
97 {
98   output (String (s));
99   return *this;
100 }
101
102 Dstream &
103 Dstream::operator <<(char c)
104 {
105   output (to_str (c));
106   return *this;
107 }
108
109 Dstream&
110 Dstream::operator << (Real r)
111 {
112   output (to_str  (r));
113   return *this;
114 }
115 Dstream &
116 Dstream::operator <<(Rational c)
117 {
118   output (c.str ());
119   return *this;
120 }
121 Dstream &
122 Dstream::operator <<(int i)
123 {
124   output (to_str(i));
125   return *this;
126 }
127   
128 void
129 Dstream::output (String s)
130 {
131   if (local_silence_b_|| !os_l_)
132     return ;
133
134   for (char const *cp = s.ch_C (); *cp; cp++)
135     switch (*cp)
136       {
137       case '{':
138       case '[':
139       case '(': indent_level_i_ += INDTAB;
140         *os_l_ << *cp;
141         break;
142
143       case ')':
144       case ']':
145       case '}':
146         indent_level_i_ -= INDTAB;
147         *os_l_ << *cp           ;
148
149         assert  (indent_level_i_>=0) ;
150         break;
151
152       case '\n':
153         *os_l_ << '\n' << to_str (' ', indent_level_i_) << flush;
154         break;
155       default:
156         *os_l_ << *cp;
157         break;
158       }
159   return ;
160 }
161
162
163 Dstream::Dstream (ostream *r, char const * cfg_nm)
164 {
165   os_l_ = r;
166   silent_dict_p_ = new Dictionary<bool>;
167   default_silence_b_ = false;
168   indent_level_i_ = 0;
169   if (!os_l_)
170     return;
171
172   char const * fn =cfg_nm ? cfg_nm : ".dstreamrc";
173   {
174     ifstream ifs (fn);  // can 't open
175     if (!ifs)
176       return;
177   }
178
179   Text_db cfg (fn);
180   while (!cfg.eof_b ()){
181     Text_record  r (cfg++);
182     if (r.size() != 2)
183       {
184         r.message (_ ("not enough fields in Dstream init"));
185         continue;
186       }
187     (*silent_dict_p_)[r[0]] = r[1] == "1";
188   }
189
190   if ((*silent_dict_p_).elem_b ("Dstream_default_silence"))
191     default_silence_b_ = (*silent_dict_p_)["Dstream_default_silence"];
192 }
193
194
195 Dstream::~Dstream()
196 {
197   delete silent_dict_p_;
198   assert (!indent_level_i_) ;
199 }
200
201 void
202 Dstream::clear_silence()
203 {
204   for (Dictionary_iter<bool> i (*silent_dict_p_); i.ok(); i++)
205     {
206       i.val_ref() = false;
207     }
208 }
209