lilypond-0.1.14
[lilypond.git] / flower / dstream.cc
blob16d83d6890245c929f90c506ca3cb225abeb52d6
1 /*
2 dstream.cc -- implement Dstream
4 source file of the Flower Library
6 (c) 1996,1997 Han-Wen Nienhuys <hanwen@stack.nl>
7 */
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"
17 /// indent of each level
18 const INDTAB = 2;
21 should use Regexp library.
23 static String
24 strip_pretty (String pretty_str)
26 int i = pretty_str.index_i ('(');
27 if (i>=0)
28 pretty_str = pretty_str.left_str (i);
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;
36 static String
37 strip_member (String pret)
39 int l=pret.index_last_i (':')-1;
40 if (l>=0)
41 pret = pret.left_str (l);
42 return pret;
45 Dstream&
46 Dstream::identify_as (String name)
48 if (!os_l_)
49 return *this;
51 String mem (strip_pretty (name));
52 String cl (strip_member (mem));
53 String idx = cl;
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
61 (*silent_assoc_p_)[idx] = false;
63 local_silence_b_ = (*silent_assoc_p_)[idx];
64 if (current_classname_str_ != idx && !local_silence_b_)
66 current_classname_str_=idx;
67 if (!(*silent_assoc_p_)["Dstream"])
68 *os_l_ << "[" << current_classname_str_ << ":]"; // messy.
70 return *this;
73 bool
74 Dstream::silence (String s)
76 if (!silent_assoc_p_->elt_b (s))
77 return false;
78 return (*silent_assoc_p_)[s];
81 Dstream &
82 Dstream::operator<<(String s)
84 output (s);
85 return *this;
88 Dstream &
89 Dstream::operator<<(void const *v_l)
91 output (String_convert::pointer_str (v_l));
92 return *this;
95 Dstream &
96 Dstream::operator<<(char const *ch_l)
98 output (ch_l);
99 return *this;
102 void
103 Dstream::output (String s)
105 if (local_silence_b_|| !os_l_)
106 return ;
108 for (char const *cp = s ; *cp; cp++)
109 switch (*cp)
111 case '{':
112 case '[':
113 case '(': indent_level_i_ += INDTAB;
114 *os_l_ << *cp;
115 break;
117 case ')':
118 case ']':
119 case '}':
120 indent_level_i_ -= INDTAB;
121 *os_l_ << *cp ;
123 assert (indent_level_i_>=0) ;
124 break;
126 case '\n':
127 *os_l_ << '\n' << String (' ', indent_level_i_) << flush;
128 break;
129 default:
130 *os_l_ << *cp;
131 break;
133 return ;
137 Dstream::Dstream (ostream *r, char const * cfg_nm)
139 os_l_ = r;
140 silent_assoc_p_ = new Assoc<String,bool>;
141 indent_level_i_ = 0;
142 if (!os_l_)
143 return;
145 char const * fn =cfg_nm ? cfg_nm : ".dstreamrc";
147 ifstream ifs (fn); // can't open
148 if (!ifs)
149 return;
152 Text_db cfg (fn);
153 while (! cfg.eof()){
154 Text_record r (cfg++);
155 if (r.size() != 2)
157 r.message ("not enough fields in Dstream init.");
158 continue;
160 (*silent_assoc_p_)[r[0]] = (bool)(int)(Scalar (r[1]));
166 Dstream::~Dstream()
168 delete silent_assoc_p_;
169 assert (!indent_level_i_) ;
172 void
173 Dstream::clear_silence()
175 for (Assoc_iter<String, bool> i (*silent_assoc_p_); i.ok(); i++)
177 i.val() = false;