]> git.donarmstrong.com Git - lilypond.git/blob - flower/dstream.cc
release: 0.1.9
[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     {
61         (*silent_assoc_p_)[idx] = false;
62     }
63   local_silence_b_ = (*silent_assoc_p_)[idx];
64   if (current_classname_str_ != idx && !local_silence_b_) 
65     {
66         current_classname_str_=idx;
67         if (!(*silent_assoc_p_)["Dstream"])
68             *os_l_ << "[" << current_classname_str_ << ":]"; // messy.
69     }
70   return *this;
71 }
72
73 bool
74 Dstream::silence (String s)
75 {
76   if (!silent_assoc_p_->elt_b (s))
77         return false;
78   return (*silent_assoc_p_)[s];
79 }
80
81 Dstream &
82 Dstream::operator<<(String s)
83 {
84   output (s);
85   return *this;
86 }
87
88 Dstream &
89 Dstream::operator<<(void const *v_l)
90 {
91   output (String_convert::pointer_str (v_l));
92   return *this;
93 }
94
95 Dstream &
96 Dstream::operator<<(char const *ch_l)
97 {
98   output (ch_l);
99   return *this;
100 }
101
102 void
103 Dstream::output (String s)
104 {
105   if (local_silence_b_|| !os_l_)
106         return ;
107   
108   for (char const *cp = s  ; *cp; cp++)
109         switch (*cp) 
110           {
111             case '{':
112             case '[':
113             case '(': indent_level_i_ += INDTAB;
114                 *os_l_ << *cp;          
115                 break;
116                 
117             case ')':
118             case ']':
119             case '}':
120                 indent_level_i_ -= INDTAB;
121                 *os_l_ << *cp           ;
122                 
123                 assert  (indent_level_i_>=0) ;
124                 break;
125                 
126             case '\n':
127                 *os_l_ << '\n' << String (' ', indent_level_i_) << flush;
128                 break;        
129             default:
130                 *os_l_ << *cp;
131                 break;
132               }
133   return ;    
134 }
135
136
137 Dstream::Dstream (ostream *r, char const * cfg_nm)
138 {
139   os_l_ = r;
140   silent_assoc_p_ = new Assoc<String,bool>;
141   indent_level_i_ = 0;
142   if (!os_l_)
143         return;
144   
145   char const * fn =cfg_nm ? cfg_nm : ".dstreamrc";
146   {
147         ifstream ifs (fn);      // can't open
148         if (!ifs)
149             return;
150     }
151
152   Text_db cfg (fn);
153   while (! cfg.eof()){       
154          Text_record  r (cfg++);
155          if (r.size() != 2) 
156            {
157              r.message ("not enough fields in Dstream init.");
158              continue;
159            }
160          (*silent_assoc_p_)[r[0]] = (bool)(int)(Scalar (r[1]));
161     }
162
163 }
164
165
166 Dstream::~Dstream()
167 {    
168   delete silent_assoc_p_;
169   assert (!indent_level_i_) ;
170 }
171
172 void
173 Dstream::clear_silence() 
174 {
175   for (Assoc_iter<String, bool> i (*silent_assoc_p_); i.ok(); i++) 
176     {
177         i.val() = 0;
178     }
179 }