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