+/*
+ dstream.cc -- implement Dstream
+
+ source file of the Flower Library
+
+ (c) 1996, 1997--1999 Han-Wen Nienhuys <hanwen@cs.uu.nl>
+*/
+
#include <fstream.h>
-#include "assoc.hh"
+#include "dictionary-iter.hh"
#include "dstream.hh"
-#include "scalar.hh"
-#include "textdb.hh"
-/// indent of each level
-const INDTAB = 3;
+#include "text-db.hh"
+#include "string-convert.hh"
+#include "rational.hh"
+
+/// amount of indentation for each level.
+const int INDTAB = 2;
/*
should use Regexp library.
*/
static String
-strip_pretty(String pret)
+strip_pretty (String pretty_str)
{
- String cl(pret.left(pret.pos('(')-1));
- int l = cl.lastPos(' ');
- cl = cl.right(cl.len() -l);
- return cl;
+ int i = pretty_str.index_i ('(');
+ if (i>=0)
+ pretty_str = pretty_str.left_str (i);
+
+ int l = pretty_str.index_last_i (' '); // strip until last ' '
+ if (l>=0)
+ pretty_str = pretty_str.nomid_str (0,l+1);
+ return pretty_str;
}
static String
-strip_member(String pret)
+strip_member (String pret)
{
- String cl(pret.left(pret.lastPos(':')-2));
- return cl;
+ int l=pret.index_last_i (':')-1;
+ if (l>=0)
+ pret = pret.left_str (l);
+ return pret;
}
Dstream&
-Dstream::identify_as(String name)
+Dstream::identify_as (String name)
{
- if (!os)
- return *this;
-
- String mem(strip_pretty(name));
- String cl(strip_member(mem));
- String idx = cl;
-
- if (silent->elt_query(mem))
- idx = mem;
- else if (silent->elt_query(cl))
- idx = cl;
- else {
- (*silent)[idx] = false;
+ if (!os_l_)
+ return *this;
+
+ String mem (strip_pretty (name));
+ String cl (strip_member (mem));
+ String idx = cl;
+
+ if (silent_dict_p_->elem_b (mem))
+ idx = mem;
+ else if (silent_dict_p_->elem_b (cl))
+ idx = cl;
+ else
+ {
+ (*silent_dict_p_)[idx] = default_silence_b_;
}
- local_silence = (*silent)[idx];
- if (classname != idx && !local_silence) {
- classname=idx;
- *os << "[" << classname << ":]";
+ local_silence_b_ = (*silent_dict_p_)[idx];
+ if (current_classname_str_ != idx && !local_silence_b_)
+ {
+ current_classname_str_=idx;
+ if (!(*silent_dict_p_)["Dstream"])
+ *os_l_ << "[" << current_classname_str_ << ":]"; // messy.
}
- return *this;
+ return *this;
}
bool
-Dstream::silence(String s)
+Dstream::silent_b (String s) const
{
- if (!silent->elt_query(s))
- return false;
- return (*silent)[s];
+ if (!silent_dict_p_->elem_b (s))
+ return false;
+ return (*silent_dict_p_)[s];
}
-///
+
Dstream &
-Dstream::operator<<(String s)
+Dstream::operator<<(void const *v_l)
{
- if (local_silence|| !os)
- return *this;
-
- for (const char *cp = s ; *cp; cp++)
- switch(*cp)
- {
- case '{':
- case '[':
- case '(': indentlvl += INDTAB;
- *os << *cp;
- break;
-
- case ')':
- case ']':
- case '}':
- indentlvl -= INDTAB;
- *os << *cp ;
-
- assert (indentlvl>=0) ;
- break;
-
- case '\n':
- *os << '\n' << String (' ', indentlvl) << flush;
- break;
- default:
- *os << *cp;
- break;
- }
- return *this;
+ output (String_convert::pointer_str (v_l));
+ return *this;
}
-/** only output possibility. Delegates all conversion to String class.
- */
+Dstream &
+Dstream::operator <<(String s)
+{
+ output (s);
+ return *this;
+}
-Dstream::Dstream(ostream *r, const char * cfg_nm )
+Dstream &
+Dstream::operator <<(const char * s)
{
- os = r;
- silent = new Assoc<String,bool>;
- if (!os)
- return;
- indentlvl = 0;
-
- const char * fn =cfg_nm ? cfg_nm : ".dstreamrc";
- {
- ifstream ifs(fn); // can't open
- if (!ifs)
- return;
- }
+ output (String (s));
+ return *this;
+}
- Text_db cfg(fn);
- while (! cfg.eof()){
- Text_record r( cfg++);
- if (r.sz() != 2) {
- r.message("not enough fields in Dstream init.");
- continue;
- }
- (*silent)[r[0]] = Scalar(r[1]).to_bool();
- }
+Dstream &
+Dstream::operator <<(char c)
+{
+ output (to_str (c));
+ return *this;
+}
+Dstream&
+Dstream::operator << (Real r)
+{
+ output (to_str (r));
+ return *this;
+}
+Dstream &
+Dstream::operator <<(Rational c)
+{
+ output (c.str ());
+ return *this;
+}
+Dstream &
+Dstream::operator <<(int i)
+{
+ output (to_str(i));
+ return *this;
+}
+
+void
+Dstream::output (String s)
+{
+ if (local_silence_b_|| !os_l_)
+ return ;
+
+ for (char const *cp = s.ch_C (); *cp; cp++)
+ switch (*cp)
+ {
+ case '{':
+ case '[':
+ case '(': indent_level_i_ += INDTAB;
+ *os_l_ << *cp;
+ break;
+
+ case ')':
+ case ']':
+ case '}':
+ indent_level_i_ -= INDTAB;
+ *os_l_ << *cp ;
+
+ assert (indent_level_i_>=0) ;
+ break;
+
+ case '\n':
+ *os_l_ << '\n' << to_str (' ', indent_level_i_) << flush;
+ break;
+ default:
+ *os_l_ << *cp;
+ break;
+ }
+ return ;
+}
+
+
+Dstream::Dstream (ostream *r, char const * cfg_nm)
+{
+ os_l_ = r;
+ silent_dict_p_ = new Dictionary<bool>;
+ default_silence_b_ = false;
+ indent_level_i_ = 0;
+ if (!os_l_)
+ return;
+
+ char const * fn =cfg_nm ? cfg_nm : ".dstreamrc";
+ {
+ ifstream ifs (fn); // can 't open
+ if (!ifs)
+ return;
+ }
+
+ Text_db cfg (fn);
+ while (!cfg.eof_b ()){
+ Text_record r (cfg++);
+ if (r.size() != 2)
+ {
+ r.message (_ ("not enough fields in Dstream init"));
+ continue;
+ }
+ (*silent_dict_p_)[r[0]] = r[1] == "1";
+ }
+
+ if ((*silent_dict_p_).elem_b ("Dstream_default_silence"))
+ default_silence_b_ = (*silent_dict_p_)["Dstream_default_silence"];
}
Dstream::~Dstream()
{
- delete silent;
+ delete silent_dict_p_;
+ assert (!indent_level_i_) ;
}
+
+void
+Dstream::clear_silence()
+{
+ for (Dictionary_iter<bool> i (*silent_dict_p_); i.ok(); i++)
+ {
+ i.val_ref() = false;
+ }
+}
+