From: fred Date: Wed, 5 Mar 1997 19:56:25 +0000 (+0000) Subject: flower-1.1.6 X-Git-Tag: release/1.5.59~6243 X-Git-Url: https://git.donarmstrong.com/?a=commitdiff_plain;h=e4bd5d213662460ffd80a7fc25e57b6c5c03915c;p=lilypond.git flower-1.1.6 --- diff --git a/flower/NEWS b/flower/NEWS index faa08528d7..836eccbee0 100644 --- a/flower/NEWS +++ b/flower/NEWS @@ -1,7 +1,15 @@ +pl 1.1.6 + - all of 1.1.4-1 and 1.1.5 +Bugfix + - null_terminated -> is_binary test + pl 1.1.5 - memmem interface, conditional compilation - snprintf +pl 1.1.4-1 + - included in new make structure + pl 1.1.4 - great file-renaming. - String cleanup (binary <-> null terminate), several bugfixes diff --git a/flower/Sources.make b/flower/Sources.make deleted file mode 100644 index 4e08bec735..0000000000 --- a/flower/Sources.make +++ /dev/null @@ -1,21 +0,0 @@ - -cc=choleski.cc data-file.cc dstream.cc lgetopt.cc libc-extension.cc matdebug.cc\ - matrix.cc\ - path.cc scalar.cc smat.cc string.cc string-convert.cc stringutil.cc\ - text-db.cc text-stream.cc unionfind.cc vector.cc - -templatecc=cursor.tcc list.tcc plist.tcc interval.tcc\ - pcursor.tcc - -inl=link.inl list.inl cursor.inl plist.inl string-data.inl string-handle.inl - -hh=assoc.hh assoc-iter.hh choleski.hh compare.hh cursor.hh data-file.hh \ - dstream.hh\ - fproto.hh handle.hh interval.hh iterate.hh lgetopt.hh \ - libc-extension.hh link.hh list.hh\ - matrix.hh path.hh pcursor.hh plist.hh rational.hh real.hh scalar.hh\ - smat.hh string.hh string-convert.hh string-handle.hh string-data.hh\ - text-db.hh text-stream.hh unionfind.hh pqueue.hh\ - varray.hh vector.hh vsmat.hh - -extra=stringtest.cc diff --git a/flower/Variables.make b/flower/Variables.make deleted file mode 100644 index 23a14e903a..0000000000 --- a/flower/Variables.make +++ /dev/null @@ -1,45 +0,0 @@ -MAJVER=1 -MINVER=1 -PATCHLEVEL=5 - -PACKAGENAME=flower - -#PROFILEFLAG=-pg -#DEBUGFLAG= -g -OPTIFLAG= -DNPRINT -O2 -DSTRING_UTILS_INLINED # -DNDEBUG - -######################################### - -ifdef PROFILEFLAG - DEFINES+=$(OPTIFLAG) $(PROFILEFLAG) - EXTRALIB+=-pg -endif - -ifndef DEBUGFLAG - DEFINES+=$(OPTIFLAG) -else - DEFINES+=$(DEBUGFLAG) -endif - - -CXXFLAGS+=$(DEFINES) -Wall -W -CXXVER=$(CXX) --version - -VERSION=$(MAJVER).$(MINVER).$(PATCHLEVEL) -DNAME=$(PACKAGENAME)-$(VERSION) - -include Sources.make -OBJECTDIR=objects -CCDIR=. -obs=$(addprefix $(OBJECTDIR)/,$(cc:.cc=.o)) - -staticlib=libflower.a -ALLSOURCES=$(hh) $(cc) $(inl) $(templatecc) $(extra) -DFILES=$(ALLSOURCES) Makefile Variables.make make_version\ - Sources.make TODO README NEWS -DDIR=$(DNAME) - -depfile=deps/$(subst .o,.dep,$(notdir $@)) -DODEP=rm -f $(depfile); DEPENDENCIES_OUTPUT="$(depfile) $(OBJECTDIR)/$(notdir $@)" -OUTPUT_OPTION=$< -o $@ -SUBDIRS=deps objects diff --git a/flower/assoc-iter.hh b/flower/assoc-iter.hh deleted file mode 100644 index 34b88df22d..0000000000 --- a/flower/assoc-iter.hh +++ /dev/null @@ -1,39 +0,0 @@ -/* - associter.hh -- part of flowerlib - - (c) 1996 Han-Wen Nienhuys -*/ - -#ifndef ASSOCITER_HH -#define ASSOCITER_HH - -#include "assoc.hh" - -/// an iterator for the #Assoc# class -template -struct Assoc_iter { - int i; - Assoc &assoc_; - /// we don't want to be bothered by const correctness - Assoc_iter(const Assoc &a) : - assoc_((Assoc &)a) - { - i= next(0); - } - int next(int j) { - while (j < assoc_.arr.size() && assoc_.arr[j].free) - j++; - return j; - } - bool ok() const { - return i < assoc_.arr.size(); - } - void OK()const { - assert(!ok() || !assoc_.arr[i].free); - } - void operator++(int) { i++; i = next(i); } - K key() { return assoc_.arr[i].key; } - V &val() { return assoc_.arr[i].val; } -}; - -#endif diff --git a/flower/assoc.hh b/flower/assoc.hh deleted file mode 100644 index 99e20914b7..0000000000 --- a/flower/assoc.hh +++ /dev/null @@ -1,78 +0,0 @@ -#ifndef ASSOC_HH -#define ASSOC_HH - -#include "varray.hh" -#include - -/** - A helper for Assoc - */ -template -struct Assoc_ent_ { - bool free; - K key; - V val; -}; - - -/** mindblowingly stupid Associative array implementation. - Hungarian: map - */ -template -struct Assoc { - Array< Assoc_ent_ > arr; - - /* ************** */ - - int find(K key) const { - for (int i = 0; i < arr.size(); i++) { - if (!arr[i].free && key == arr[i].key) - return i; - } - return -1; - } - int find_creat(K key) { - int free = -1; - for (int i = 0; i < arr.size(); i++) { - if (key == arr[i].key) { - return i; - } else if (arr[i].free ) { - free = i; - } - } - if (free >= 0){ - arr[free].free = false; - arr[free].key = key; - return free; - } - - Assoc_ent_ ae; - ae.free = false; - ae.key = key; - arr.push(ae); - return arr.size() -1; - } -public: - bool elt_query(K key) const { - return find(key) >= 0; - } - void del(K key) { - assert(elt_query(key)); - int i= find(key); - arr[i].free = true; - } - void - add(K key, V val) { - int i = find_creat(key); - arr[i].val = val; - } - V& operator[](K key) { - return arr[find_creat(key)].val; - } - const V& operator[](K key) const { - assert(elt_query(key)); - return arr[find(key)].val; - } -}; - -#endif diff --git a/flower/choleski.cc b/flower/choleski.cc deleted file mode 100644 index 1d64f949ac..0000000000 --- a/flower/choleski.cc +++ /dev/null @@ -1,91 +0,0 @@ -#include "choleski.hh" -const Real EPS = 1e-7; // so sue me. Hard coded - -Vector -Choleski_decomposition::solve(Vector rhs)const -{ - int n= rhs.dim(); - assert(n == L.dim()); - Vector y(n); - - // forward substitution - for (int i=0; i < n; i++) { - Real sum(0.0); - for (int j=0; j < i; j++) - sum += y(j) * L(i,j); - y(i) = (rhs(i) - sum)/L(i,i); - } - for (int i=0; i < n; i++) - y(i) /= D(i); - - // backward subst - Vector &x(rhs); // using input as return val. - for (int i=n-1; i >= 0; i--) { - Real sum(0.0); - for (int j=i+1; j < n; j++) - sum += L(j,i)*x(j); - x(i) = (y(i) - sum)/L(i,i); - } - return x; -} - -/* - Standard matrix algorithm. - */ - -Choleski_decomposition::Choleski_decomposition(Matrix P) - : L(P.dim()), D(P.dim()) -{ - int n = P.dim(); - assert((P-P.transposed()).norm()/P.norm() < EPS); - - L.unit(); - for (int k= 0; k < n; k++) { - for (int j = 0; j < k; j++){ - Real sum(0.0); - for (int l=0; l < j; l++) - sum += L(k,l)*L(j,l)*D(l); - L(k,j) = (P(k,j) - sum)/D(j); - } - Real sum=0.0; - - for (int l=0; l < k; l++) - sum += sqr(L(k,l))*D(l); - Real d = P(k,k) - sum; - D(k) = d; - } - -#ifdef NDEBUG - assert((original()-P).norm() / P.norm() < EPS); -#endif -} - -Matrix -Choleski_decomposition::original() const -{ - Matrix T(L.dim()); - T.set_diag(D); - return L*T*L.transposed(); -} - -Matrix -Choleski_decomposition::inverse() const -{ - int n=L.dim(); - Matrix invm(n); - Vector e_i(n); - for (int i = 0; i < n; i++) { - e_i.set_unit(i); - Vector inv(solve(e_i)); - for (int j = 0 ; j?, >) -#else -#define gpp_minmax(type, prefix) -#endif - -/** handy notations for a signed comparison. - make the operators{<,<=,==,>=,>} and the MAX and MIN of two. - Please fill a & in the type argument if necessary. - */ -#define template_instantiate_compare(type, function, prefix) \ -prefix one_operator(type, function, >)\ -prefix one_operator(type, function, >=)\ -prefix one_operator(type, function, ==)\ -prefix one_operator(type, function, !=)\ -prefix one_operator(type, function, <)\ -prefix one_operator(type, function, <=)\ -gpp_minmax(type, prefix)\ -prefix inline type max(type t1, type t2) { return (t1 > t2 )? t1 : t2; }\ -prefix inline type min(type t1, type t2) { return (t1 < t2 )? t1 : t2; }\ - \ -prefix bool operator<(type t1, type t2) /* stupid fix to allow ; */ - - - -#define instantiate_compare(type, func) template_instantiate_compare(type,func, ) - - - -#endif - diff --git a/flower/cursor.hh b/flower/cursor.hh deleted file mode 100644 index 0ea99037f9..0000000000 --- a/flower/cursor.hh +++ /dev/null @@ -1,113 +0,0 @@ -// cursor.hh - -#ifndef __CURSOR_HH -#define __CURSOR_HH - -#include "link.hh" -template class List; - -/** iterator to List. - add and insert extend the list - items are always stored as copies in List, but: - List : copies of String stored - List : copies of String* stored! - - the operations add and insert actually delegate the work to List class. - */ -template -class Cursor -{ - public: - /** create cursor, set at top. The const part isn't true, actually, #list# - surely isn't const, but I get tired of the warning messages. */ - Cursor( const List& list, Link* pointer = 0 ); - - Cursor( const Cursor& cursor ); - - T& thing(); - - /// return current T - T& operator *() { return thing(); } - operator T() { return thing(); } - Cursor operator =( const Cursor& c ); - - /// make cursor with #no# items back - Cursor operator -( int no) const; - - /// make cursor with #no# items further - Cursor operator +( int no) const; - int operator -(Cursor op) const; - Cursor operator -=(int); - Cursor operator +=(int); - - /// return current and move one down - Cursor operator ++( int ); - - /// return current and move one up - Cursor operator --( int ); - - /// point to link? - bool ok(); - - /// ++ items left? - bool forward(); - - /// -- items left? - bool backward(); - - /** put (copy) after me in List. - analogously to editor. ok() interpreted as at end - of line. - - PRE: !ok, POST: added to bottom() - - PRE: ok, POST: added after me - - cursor points to same object, cursor.next() is newly added - object. - */ - void add( const T& thing ); - - /** put (copy) before me in List. - analogously to editor. ok() interpreted as at begin of - line. - - PRE: !ok, POST: add to top() - - PRE: ok, POST: add before me - - cursor points to same object, cursor.previous() - is newly inserted object. - */ - - void insert( const T& thing ); - /// - void backspace(); - - /// - void del(); - - /// access the list this came from - List& list() const ; - Link* pointer(); - static int compare(Cursor a,Cursorb) { return a-b; } -private: - List& list_; - Link* pointer_; -}; - - -/* - comparisons. - */ -#include "compare.hh" - - -template_instantiate_compare(Cursor, Cursor::compare, template); - -#include "pcursor.hh" -#include "list.hh" -#include "cursor.inl" -#include "iterate.hh" - -#endif // CURSOR_HH diff --git a/flower/cursor.inl b/flower/cursor.inl deleted file mode 100644 index 54d3703e60..0000000000 --- a/flower/cursor.inl +++ /dev/null @@ -1,113 +0,0 @@ - // cursor.inl -*-c++-*- -#ifndef CURSOR_INL -#define CURSOR_INL -#include - - -template -inline -Cursor::Cursor( const List& list, Link* pointer ) : - list_((List&) list ) -{ - if ( list.size() ) - pointer_ = pointer ? pointer : list.top_; - else - pointer_ = pointer; -} - -template -inline -Cursor::Cursor( const Cursor& cursor ) : - list_( cursor.list_ ) -{ - pointer_ = cursor.pointer_; -} - -template -inline T& -Cursor::thing() -{ - assert( pointer_ ); - return pointer_->thing(); -} - -template -Cursor -Cursor::operator =( const Cursor& c ) -{ - assert( &list_ == &c.list_ ); - pointer_ = c.pointer_; - return *this; -} - -template -inline void -Cursor::add( const T& th ) -{ - list_.add( th, *this ); -} - -template -inline void -Cursor::insert( const T& th ) -{ - list_.insert( th, *this ); -} - -template -inline List& -Cursor::list() const -{ - return list_; -} - -template -inline Link* -Cursor::pointer() -{ - return pointer_; -} - -template -inline bool -Cursor::backward() -{ - return ( pointer_ != 0 ); -} - -template -inline bool -Cursor::forward() -{ - return ( pointer_ != 0 ); -} - -template -inline bool -Cursor::ok() -{ - return ( pointer_ != 0 ); -} - - -template -inline Cursor -Cursor::operator ++( int ) -{ - Cursor r (*this); - assert( pointer_ ); - pointer_ = pointer_->next(); - return r; -} - -template -inline Cursor -Cursor::operator --( int ) -{ - Cursor r (*this); - assert( pointer_ ); - pointer_ = pointer_->previous(); - return r; -} - -#endif diff --git a/flower/cursor.tcc b/flower/cursor.tcc deleted file mode 100644 index 3d2116c46f..0000000000 --- a/flower/cursor.tcc +++ /dev/null @@ -1,107 +0,0 @@ -#ifndef CURSOR_CC -#define CURSOR_CC - -#include "cursor.hh" -#include - -template - void -Cursor::backspace() -{ - Cursor c(*this); - c--; - list_.remove( *this ); -} - -template - void -Cursor::del() -{ - Cursor c(*this); - c++; - list_.remove( *this ); - *this = c; -} - - -template -Cursor -Cursor::operator -=( int j ) -{ - while (j--) - (*this)--; - return *this; -} -template -Cursor -Cursor::operator +=( int j ) -{ - while (j++) - (*this)++; - return *this; -} - -template -Cursor -Cursor::operator +( int i ) const -{ - Cursor r = *this; - - if (i<0) - return r -(-i); - - while (i--) - r++; - - return r; -} - -template -Cursor -Cursor::operator -( int i ) const -{ - Cursor r = *this; - if (i<0) - return r +(-i); - - while (i--) - r--; - - return r; -} -/* - warning: can't use Cursor::operator == (Cursor), - since it uses Cursor::operator-(Cursor) - */ -template -int -Cursor::operator-(Cursor rhs) const -{ - assert(rhs.list == list); - int dif = 0; - - // search from *this on further up (positive difference) - Cursor c(*this); - while (c.ok() && c.pointer_ != rhs.pointer_) { - c--; - dif++; - } - - if (c.ok()) - goto gotcha; // so, sue me. - - // search in direction of bottom. (negative diff) - dif =0; - c=*this; - while (c.ok() && c.pointer_ !=rhs.pointer_) { - dif --; - c++; - } - assert(c.ok()); - -gotcha: - assert((*this - dif).pointer_ == c.pointer_); - return dif; -} - -#endif diff --git a/flower/data-file.cc b/flower/data-file.cc deleted file mode 100644 index 0dad79c91f..0000000000 --- a/flower/data-file.cc +++ /dev/null @@ -1,95 +0,0 @@ -#include -#include - -#include "data-file.hh" - -void -Data_file::gobble_white() -{ - char c; - - while ((c=data_get()) == ' ' ||c == '\t') - if (eof()) - break; - - data_unget(c); -} - -String -Data_file::get_word() -{// should handle escape seq's - String s; - - while (1) - { - char c = data_get(); - - if (isspace(c) || eof()) - { - data_unget(c); - break; - } - - - if (c == '\"') - { - rawmode= true; - - while ((c = data_get()) != '\"') - if (eof()) - error("EOF in a string"); - else - s += c; - - - rawmode= false; - } - else - s += c; - } - - return s; -} - -/** get a char - Only class member who uses text_file::get - */ -char -Data_file::data_get() { - char c = get(); - if (!rawmode && c == '#') // gobble comment - { - while ((c = get()) != '\n' && !eof()) - ; - return '\n'; - } - - return c; -} - -/// read line, gobble '\n' -String Data_file::get_line() -{ - char c; - String s; - - while ((c = data_get()) != '\n' && !eof()) - s += c; - return s; -} - -/// gobble stuff before first entry on a line. -void -Data_file::gobble_leading_white() -{ - // eat blank lines. - while (!eof()) { - char c = data_get(); - if (!isspace(c)) { - data_unget(c); - break; - } - } -} - - diff --git a/flower/data-file.hh b/flower/data-file.hh deleted file mode 100644 index dae9e56347..0000000000 --- a/flower/data-file.hh +++ /dev/null @@ -1,59 +0,0 @@ -/* - data-file.hh -- declare Data_file - - source file of the LilyPond music typesetter - - (c) 1997 Han-Wen Nienhuys -*/ - - -#ifndef DATAFILE_HH -#define DATAFILE_HH - -#include "text-stream.hh" - -/// read a data file -class Data_file : private Text_stream -{ - - public: - bool rawmode; - - Text_stream::line; - Text_stream::eof; - Text_stream::get_name; - - char data_get(); - void data_unget(char c) { - unget(c); - } - - /// read line, eat #\n# - String get_line(); - - /// read a word till next space, leave space. Also does quotes - String get_word(); - - /// gobble horizontal white stuff. - void gobble_white(); - - /// gobble empty stuff before first field. - void gobble_leading_white(); - Data_file(String s) : Text_stream(s) { - //*mlog << "(" << s << flush; - rawmode= false; - } - - ~Data_file() { - // *mlog << ")"< -#include "assoc.hh" -#include "dstream.hh" -#include "scalar.hh" -#include "text-db.hh" -#include "string-convert.hh" - -/// indent of each level -const INDTAB = 2; - -/* - should use Regexp library. - */ -static String -strip_pretty(String pretty_str) -{ - 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) -{ - int l=pret.index_last_i(':')-1; - if (l>=0) - pret = pret.left_str(l ); - return pret; -} - -Dstream& -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; - } - local_silence = (*silent)[idx]; - if (classname != idx && !local_silence) { - classname=idx; -// *os << "[" << classname << ":]"; // messy. - } - return *this; -} - -bool -Dstream::silence(String s) -{ - if (!silent->elt_query(s)) - return false; - return (*silent)[s]; -} - -/** Output a string via the Dstream. This is the only output - interface. It delegates all conversion to String class. */ -Dstream & -Dstream::operator<<(String s) -{ - output(s); - return *this; -} - -Dstream & -Dstream::operator<<(const void *v_l) -{ - output(String_convert::pointer_str(v_l)); - return *this; -} - -Dstream & -Dstream::operator<<(const char *ch_l) -{ - output(ch_l); - return *this; -} - -void -Dstream::output(String s) -{ - if (local_silence|| !os) - return ; - - 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 ; -} - - -Dstream::Dstream(ostream *r, const char * cfg_nm ) -{ - os = r; - silent = new Assoc; - indentlvl = 0; - if (!os) - return; - - const char * fn =cfg_nm ? cfg_nm : ".dstreamrc"; - { - ifstream ifs(fn); // can't open - if (!ifs) - return; - } - - Text_db cfg(fn); - while (! cfg.eof()){ - Text_record r( cfg++); - if (r.size() != 2) { - r.message("not enough fields in Dstream init."); - continue; - } - (*silent)[r[0]] = (bool)(int)(Scalar(r[1])); - } - -} - - -Dstream::~Dstream() -{ - delete silent; - assert(!indentlvl) ; -} diff --git a/flower/dstream.hh b/flower/dstream.hh deleted file mode 100644 index 5375304d85..0000000000 --- a/flower/dstream.hh +++ /dev/null @@ -1,54 +0,0 @@ - -#ifndef DSTREAM_HH -#define DSTREAM_HH - -#include "string.hh" - -const char eol= '\n'; - -template -struct Assoc; - -/** debug stream. - a class for providing debug output of nested structures, - with indents according to \{\}()[]. - - One can turn on and off specific messages using the Assoc silent. - This can be done automatically: - - #define DEBUG dstream_.identify_as(__PRETTY_FUNCTION__) - - DEBUG << "a message\n"; - - Init for the class names which should be silent can be given in a rc file. - - */ -class Dstream -{ - ostream *os; - int indentlvl; - bool local_silence; - String classname; - void output(String s); - Assoc *silent; -public: - - bool silence(String); - - /** - if rcfile == 0, then do not read any rc file. - */ - - Dstream(ostream *r, const char * rcfile); - virtual ~Dstream(); - Dstream &identify_as(String s); - - Dstream &operator << (String s); - /** - Output memory locations. - */ - Dstream &operator << (void const *); - Dstream &operator << (char const *); -}; -#endif - diff --git a/flower/fproto.hh b/flower/fproto.hh deleted file mode 100644 index 8c6fda680e..0000000000 --- a/flower/fproto.hh +++ /dev/null @@ -1,44 +0,0 @@ -/* - fproto.hh -- typenames in flowerlib - - (c) 1996 Han-Wen Nienhuys -*/ - -#ifndef FPROTO_HH -#define FPROTO_HH - -#include "flower-config.hh" - -template struct Array; -template struct sstack; -template struct Assoc; -template struct List; -template struct PointerList; -template struct IPointerList; -template struct Cursor; -template struct PCursor; -template struct Link; -template struct Handle; -templatestruct Interval_t; -#include "real.hh" - -typedef Interval_t Interval; - -struct Choleski_decomposition; - -struct Long_option_init; -struct Getopt_long; -struct Matrix; -struct String_data; -struct String_handle; -struct String_convert; -struct String; -struct virtual_smat; -struct Vector ; -struct Text_stream; -struct Data_file; -struct Text_db; -struct Scalar; -typedef unsigned char Byte; -#endif // FPROTO_HH - diff --git a/flower/handle.hh b/flower/handle.hh deleted file mode 100644 index 63c17ef1d2..0000000000 --- a/flower/handle.hh +++ /dev/null @@ -1,58 +0,0 @@ -#ifndef HANDLE_HH -#define HANDLE_HH - -/// reference counting handle -template -class Handle { - T *obj; - int *refs; - - /// let go of ref. Delete if necessary - void down() { - if (!(*refs--)) { - delete obj; - delete refs; - } - obj = 0; - refs = 0; - } - /// point to new object. - void up(T *t, int *r) { - if (!r) { - refs = new int; - *refs = 1; - } else { - refs =r; - *refs++; - } - obj = t; - } - /// POST: *refs == 1 - void copy() { - if(*refs != 1){ - T * newobj = new T(*obj ); - down(); - up(newobj); - } - } - Handle(Handle const &src) { - up(src.obj, src.refs); - } - Handle(T & o) { - up (&o); - } - void operator=(Handle const& src) { - if (this == &src) - return; - down(); - up(src.o, src.refs); - } - operator const T&() { - return *obj; - } - operator T&() { - copy(); - return *obj; - } -} -#endif diff --git a/flower/interval.hh b/flower/interval.hh deleted file mode 100644 index aae16381db..0000000000 --- a/flower/interval.hh +++ /dev/null @@ -1,125 +0,0 @@ -/* - interval.hh -- part of flowerlib - - (c) 1996 Han-Wen Nienhuys -*/ - -#ifndef INTERVAL_HH -#define INTERVAL_HH - -#include -#include "fproto.hh" -#include "real.hh" - - -/** a T interval. - this represents the closed interval [left,right]. - No invariants. T must be a totally ordered ring - */ -template -struct Interval_t { - T left, right; - - /* ************** */ - - T center() { return (left + right) / T(2);} - void translate(T t) { - left += t; - right += t; - } - T& idx(int j) { - if (j==-1) - return left; - else if (j==1) - return right; - else - assert(false); - return left; - } - T& operator[](int j) { - return idx(j); - } - T operator[](int j) const { - return ((Interval_t *)this)->idx(j); - } - T &max() { return right;} - T max()const { return right;} - T min()const{ return left; } - T &min(){ return left; } - /** - PRE - *this and h are comparable - */ - void unite(Interval_t h); - void intersect(Interval_t h); - - T length() const; - void set_empty() ; - bool empty() const { return left > right; } - Interval_t() { - set_empty(); - } - Interval_t(T m, T M) { - left =m; - right = M; - } - Interval_t &operator += (T r) { - left += r; - right +=r; - return *this; - } - String str() const; - bool elt_q(T r); -}; - - -/** - inclusion ordering. Crash if not comparable. - */ -template -int Interval__compare(const Interval_t&,Interval_t const&); - -/* - INLINE - */ - -#include "compare.hh" - -template_instantiate_compare(Interval_t&, Interval__compare, template); - - -template -inline Interval_t -intersection(Interval_t a, Interval_t const&b) -{ - a.intersect(b); - return a; - -} - - -template -inline -Interval_t operator +(T a,Interval_t i ) -{ - i += a; - return i; -} - -template -inline -Interval_t operator +(Interval_t i,T a ){ - return a+i; -} - -typedef Interval_t Interval; - - -#define Interval__instantiate(T) template struct Interval_t;\ - template int Interval__compare(const Interval_t&,Interval_t const&) - - -#endif // INTERVAL_HH - - - diff --git a/flower/interval.tcc b/flower/interval.tcc deleted file mode 100644 index 6e7b0b1279..0000000000 --- a/flower/interval.tcc +++ /dev/null @@ -1,106 +0,0 @@ -#include -#include -#include "interval.hh" -#include "string.hh" - - -template -int -_Interval__compare(const Interval_t&a,Interval_t const&b) -{ - if (a.left == b.left && a.right == b.right) - return 0; - - if (a.left <= b.left && a.right >= b.right) - return 1; - - if (a.left >= b.left && a.right <= b.right) - return -1; - - return -2; -} - - -template -int -Interval__compare(const Interval_t&a,Interval_t const&b) -{ - int i = _Interval__compare(a,b); - if (i < -1) - assert(false); - return i; -} - -#ifdef AIX -const Real INFTY = 1e8; // ARGh. AIX sucks -#else -const Real INFTY = HUGE_VAL; -#endif - -template -void -Interval_t::set_empty() -{ - left = INFTY; - right = -INFTY; -} - -template -T -Interval_t::length() const { - assert(right >= left); - return right-left; -} - -template -void -Interval_t::unite(Interval_t h) -{ - if (h.leftright) - right = h.right; -} - -/** - smallest Interval which includes *this and #h# - */ - -template -void -Interval_t::intersect(Interval_t h) -{ -#if defined (__GNUG__) && ! defined (__STRICT_ANSI__) - left = h.left >? left; - right = h.right -Interval_t -intersect(Interval_t x, Interval_t const &y) -{ - x.intersect(y); - return x; -} - -template -String -Interval_t::str() const -{ - if (empty()) - return "[empty]"; - String s("["); - - return s + left + "," + right +"]"; -} - -template -bool -Interval_t::elt_q(T r) -{ - return r >= left && r <= right; -} diff --git a/flower/iterate.hh b/flower/iterate.hh deleted file mode 100644 index 1e924f0790..0000000000 --- a/flower/iterate.hh +++ /dev/null @@ -1,22 +0,0 @@ -/* - iterate.hh -- define some list macros - - source file of the flowerlib - - (c) 1997 Han-Wen Nienhuys -*/ - - -#ifndef ITERATE_HH -#define ITERATE_HH - - - -#define iterator(set) typeof((set).top()) -#define iterator_bot(set) typeof((set).bottom()) - -// should use top() -#define iter_top(set,var) iterator(set) var(set) -#define iter_bot(set,var) iterator(set) var(set.bottom()) - -#endif // ITERATE_HH diff --git a/flower/lgetopt.cc b/flower/lgetopt.cc deleted file mode 100644 index a56c64c6db..0000000000 --- a/flower/lgetopt.cc +++ /dev/null @@ -1,222 +0,0 @@ -/* - process command line, GNU style. - - this is (Copyleft) 1996, Han-Wen Nienhuys, - */ -#include -#include -#include -#include "lgetopt.hh" - -long -Getopt_long::intarg() -{ - long l; - if (sscanf(optarg, "%ld", &l) != 1) - report(E_ILLEGALARG); - - return l; -} - -Long_option_init * -Getopt_long::parselong() -{ - const char *optnm = argv[optind] + 2 ; - assert(*optnm); - - char *endopt = strchr(optnm, '='); - int searchlen = (endopt) ? endopt - optnm : strlen(optnm); - - beet=0; - for (int i=0; i< table_len; i++) { - const char *ln = the_opts[i].longname; - - if (ln && !strncmp(ln, optnm, searchlen)) { - beet = the_opts+i; - break; - } - } - - if (!beet) { - report(E_UNKNOWNOPTION); - return 0; - } - optind++; - optindind = 0; - - - if (beet->take_arg) { - if (endopt) - optarg = endopt +1; // a '=' - else { - optarg = argv[optind]; - optind++; - } - if (!optarg) - report(E_ARGEXPECT); - - } else { - optarg = 0; - if (endopt) - report(E_NOARGEXPECT); - } - - return beet; -} - - -ostream & -Long_option_init::printon(ostream &errorout) -{ - if (shortname) - errorout <<"-" << shortname; - if (shortname && longname) - errorout << ", "; - if (longname) - errorout << "`--" << longname << "'"; - return errorout; -} - -// report an error, GNU style. -void -Getopt_long::report(Errorcod c) -{ - error = c; - if (!errorout) - return; - - *errorout << argv[0] << ": "; - switch (c) { - case E_ARGEXPECT: - *errorout<< "option "; - beet->printon(*errorout); - *errorout << "requires an argument"<longname << "' does not allow an argument"<printon(*errorout); - *errorout << '\n'; - default: - assert(false); - } - exit(2); -} - -Long_option_init * -Getopt_long::parseshort() -{ - char c=argv[optind][optindind]; - beet=0; - assert(c); - - for (int i=0; i < table_len; i++) - if (the_opts[i].shortname == c) { - beet = the_opts+i; - break; - } - - if (!beet){ - report(E_UNKNOWNOPTION); - return 0; - } - - optindind++; - if (!beet->take_arg){ - optarg = 0; - return beet; - } - optarg = argv[optind] + optindind; - - optind ++; - optindind = 0; - - if (!optarg[0]) { - optarg = argv[optind]; - optind ++; - } - if (!optarg) { - report(E_ARGEXPECT); - } - - return beet; -} - -Long_option_init * -Getopt_long::operator()() { - if (!next()) - return 0; - - if (optindind) - return parseshort(); - - if (argv[optind][0] != '-') - return 0; - - if (argv[optind][1] == '-') {// what to do with "command -- bla" - return parselong(); - } else { - optindind = 1; - return parseshort(); - } -} - -Getopt_long::Getopt_long(int c, char **v, Long_option_init *lo) -{ - the_opts = lo; - errorout = &cerr; - argv = v; - argc = c; - optind = 1; - optindind = 0; - - // reached end of option table? - int i; - for (i = 0; the_opts[i].longname ||the_opts[i].shortname; i++) - ; - table_len = i; -} - -bool -Getopt_long::next() -{ - - error = E_NOERROR; - while (optind < argc && !argv[optind][optindind]) { - optind++; - optindind = 0; - } - return (optind < argc); -} - -char * -Getopt_long::current_arg() -{ - if (optind >= argc) - return 0; - char * a = argv[optind]; - return a + optindind; -} - -char * -Getopt_long::get_next_arg() -{ - char * a = current_arg(); - if ( a) { - optind ++; - optindind = 0; - } - return a; -} diff --git a/flower/lgetopt.hh b/flower/lgetopt.hh deleted file mode 100644 index 3b2b0348b3..0000000000 --- a/flower/lgetopt.hh +++ /dev/null @@ -1,94 +0,0 @@ -#ifndef LGETOPT_HH -#define LGETOPT_HH - -#include - - -class ostream; - -/** - a struct this for initialising the commandline options. - */ -struct Long_option_init { - bool take_arg; - const char* longname; - char shortname; - - ostream &printon(ostream &errorout); -}; - - -/** C++ for version of long_getopt. For processing GNU style command - line arguments. No pointer (return values, arguments) contents are - copied. */ -class Getopt_long { -public: - /** errorcodes: no error, argument expected, no argument expected, - unknown option, illegal argument (eg. int expected). */ - enum Errorcod { E_NOERROR = 0, E_ARGEXPECT, E_NOARGEXPECT, E_UNKNOWNOPTION, - E_ILLEGALARG } ; - - -private: - - /// the option info. - Long_option_init *the_opts; - int table_len; - - /// if doing short option, argv[optind][optindind] is processed next. - int optindind; - - /// the option found - Long_option_init *beet; - - /// get ready for processing next error. - bool next(); - Long_option_init *parselong(); - Long_option_init *parseshort(); - - ostream *errorout; - - /// report an error and abort - void report(Errorcod c); -public: - - /// argument. Set to 0 if not present - char* optarg; - - /// current error status - Errorcod error; - - /// return an integer (with err. detect) - long intarg(); - /// argv[optind] will be processed next. - int optind; - - /// the arguments - char **argv; - - /// the arg. count - int argc; - - /* *************** */ - - /** - What to do with errors. - report messages on #*os#, and abort. - if #os# is null, then do not report nor abort, just set #error# - */ - - void seterror(ostream *os); - - /// construct: pass arguments and option info. - Getopt_long(int c, char **v, Long_option_init *lo); - - /** get the next option. - @return pointer to next option found. - 0 if error occurred, or next argument is no option. - */ - Long_option_init *operator()(); - - char *current_arg(); - char * get_next_arg(); -}; -#endif diff --git a/flower/lib/choleski.cc b/flower/lib/choleski.cc new file mode 100644 index 0000000000..1d64f949ac --- /dev/null +++ b/flower/lib/choleski.cc @@ -0,0 +1,91 @@ +#include "choleski.hh" +const Real EPS = 1e-7; // so sue me. Hard coded + +Vector +Choleski_decomposition::solve(Vector rhs)const +{ + int n= rhs.dim(); + assert(n == L.dim()); + Vector y(n); + + // forward substitution + for (int i=0; i < n; i++) { + Real sum(0.0); + for (int j=0; j < i; j++) + sum += y(j) * L(i,j); + y(i) = (rhs(i) - sum)/L(i,i); + } + for (int i=0; i < n; i++) + y(i) /= D(i); + + // backward subst + Vector &x(rhs); // using input as return val. + for (int i=n-1; i >= 0; i--) { + Real sum(0.0); + for (int j=i+1; j < n; j++) + sum += L(j,i)*x(j); + x(i) = (y(i) - sum)/L(i,i); + } + return x; +} + +/* + Standard matrix algorithm. + */ + +Choleski_decomposition::Choleski_decomposition(Matrix P) + : L(P.dim()), D(P.dim()) +{ + int n = P.dim(); + assert((P-P.transposed()).norm()/P.norm() < EPS); + + L.unit(); + for (int k= 0; k < n; k++) { + for (int j = 0; j < k; j++){ + Real sum(0.0); + for (int l=0; l < j; l++) + sum += L(k,l)*L(j,l)*D(l); + L(k,j) = (P(k,j) - sum)/D(j); + } + Real sum=0.0; + + for (int l=0; l < k; l++) + sum += sqr(L(k,l))*D(l); + Real d = P(k,k) - sum; + D(k) = d; + } + +#ifdef NDEBUG + assert((original()-P).norm() / P.norm() < EPS); +#endif +} + +Matrix +Choleski_decomposition::original() const +{ + Matrix T(L.dim()); + T.set_diag(D); + return L*T*L.transposed(); +} + +Matrix +Choleski_decomposition::inverse() const +{ + int n=L.dim(); + Matrix invm(n); + Vector e_i(n); + for (int i = 0; i < n; i++) { + e_i.set_unit(i); + Vector inv(solve(e_i)); + for (int j = 0 ; j +#include + +#include "data-file.hh" + +void +Data_file::gobble_white() +{ + char c; + + while ((c=data_get()) == ' ' ||c == '\t') + if (eof()) + break; + + data_unget(c); +} + +String +Data_file::get_word() +{// should handle escape seq's + String s; + + while (1) + { + char c = data_get(); + + if (isspace(c) || eof()) + { + data_unget(c); + break; + } + + + if (c == '\"') + { + rawmode= true; + + while ((c = data_get()) != '\"') + if (eof()) + error("EOF in a string"); + else + s += c; + + + rawmode= false; + } + else + s += c; + } + + return s; +} + +/** get a char + Only class member who uses text_file::get + */ +char +Data_file::data_get() { + char c = get(); + if (!rawmode && c == '#') // gobble comment + { + while ((c = get()) != '\n' && !eof()) + ; + return '\n'; + } + + return c; +} + +/// read line, gobble '\n' +String Data_file::get_line() +{ + char c; + String s; + + while ((c = data_get()) != '\n' && !eof()) + s += c; + return s; +} + +/// gobble stuff before first entry on a line. +void +Data_file::gobble_leading_white() +{ + // eat blank lines. + while (!eof()) { + char c = data_get(); + if (!isspace(c)) { + data_unget(c); + break; + } + } +} + + diff --git a/flower/lib/dstream.cc b/flower/lib/dstream.cc new file mode 100644 index 0000000000..e6fdbc0e4d --- /dev/null +++ b/flower/lib/dstream.cc @@ -0,0 +1,158 @@ +#include +#include "assoc.hh" +#include "dstream.hh" +#include "scalar.hh" +#include "text-db.hh" +#include "string-convert.hh" + +/// indent of each level +const INDTAB = 2; + +/* + should use Regexp library. + */ +static String +strip_pretty(String pretty_str) +{ + 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) +{ + int l=pret.index_last_i(':')-1; + if (l>=0) + pret = pret.left_str(l ); + return pret; +} + +Dstream& +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; + } + local_silence = (*silent)[idx]; + if (classname != idx && !local_silence) { + classname=idx; +// *os << "[" << classname << ":]"; // messy. + } + return *this; +} + +bool +Dstream::silence(String s) +{ + if (!silent->elt_query(s)) + return false; + return (*silent)[s]; +} + +/** Output a string via the Dstream. This is the only output + interface. It delegates all conversion to String class. */ +Dstream & +Dstream::operator<<(String s) +{ + output(s); + return *this; +} + +Dstream & +Dstream::operator<<(const void *v_l) +{ + output(String_convert::pointer_str(v_l)); + return *this; +} + +Dstream & +Dstream::operator<<(const char *ch_l) +{ + output(ch_l); + return *this; +} + +void +Dstream::output(String s) +{ + if (local_silence|| !os) + return ; + + 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 ; +} + + +Dstream::Dstream(ostream *r, const char * cfg_nm ) +{ + os = r; + silent = new Assoc; + indentlvl = 0; + if (!os) + return; + + const char * fn =cfg_nm ? cfg_nm : ".dstreamrc"; + { + ifstream ifs(fn); // can't open + if (!ifs) + return; + } + + Text_db cfg(fn); + while (! cfg.eof()){ + Text_record r( cfg++); + if (r.size() != 2) { + r.message("not enough fields in Dstream init."); + continue; + } + (*silent)[r[0]] = (bool)(int)(Scalar(r[1])); + } + +} + + +Dstream::~Dstream() +{ + delete silent; + assert(!indentlvl) ; +} diff --git a/flower/lib/include/assoc-iter.hh b/flower/lib/include/assoc-iter.hh new file mode 100644 index 0000000000..34b88df22d --- /dev/null +++ b/flower/lib/include/assoc-iter.hh @@ -0,0 +1,39 @@ +/* + associter.hh -- part of flowerlib + + (c) 1996 Han-Wen Nienhuys +*/ + +#ifndef ASSOCITER_HH +#define ASSOCITER_HH + +#include "assoc.hh" + +/// an iterator for the #Assoc# class +template +struct Assoc_iter { + int i; + Assoc &assoc_; + /// we don't want to be bothered by const correctness + Assoc_iter(const Assoc &a) : + assoc_((Assoc &)a) + { + i= next(0); + } + int next(int j) { + while (j < assoc_.arr.size() && assoc_.arr[j].free) + j++; + return j; + } + bool ok() const { + return i < assoc_.arr.size(); + } + void OK()const { + assert(!ok() || !assoc_.arr[i].free); + } + void operator++(int) { i++; i = next(i); } + K key() { return assoc_.arr[i].key; } + V &val() { return assoc_.arr[i].val; } +}; + +#endif diff --git a/flower/lib/include/assoc.hh b/flower/lib/include/assoc.hh new file mode 100644 index 0000000000..99e20914b7 --- /dev/null +++ b/flower/lib/include/assoc.hh @@ -0,0 +1,78 @@ +#ifndef ASSOC_HH +#define ASSOC_HH + +#include "varray.hh" +#include + +/** + A helper for Assoc + */ +template +struct Assoc_ent_ { + bool free; + K key; + V val; +}; + + +/** mindblowingly stupid Associative array implementation. + Hungarian: map + */ +template +struct Assoc { + Array< Assoc_ent_ > arr; + + /* ************** */ + + int find(K key) const { + for (int i = 0; i < arr.size(); i++) { + if (!arr[i].free && key == arr[i].key) + return i; + } + return -1; + } + int find_creat(K key) { + int free = -1; + for (int i = 0; i < arr.size(); i++) { + if (key == arr[i].key) { + return i; + } else if (arr[i].free ) { + free = i; + } + } + if (free >= 0){ + arr[free].free = false; + arr[free].key = key; + return free; + } + + Assoc_ent_ ae; + ae.free = false; + ae.key = key; + arr.push(ae); + return arr.size() -1; + } +public: + bool elt_query(K key) const { + return find(key) >= 0; + } + void del(K key) { + assert(elt_query(key)); + int i= find(key); + arr[i].free = true; + } + void + add(K key, V val) { + int i = find_creat(key); + arr[i].val = val; + } + V& operator[](K key) { + return arr[find_creat(key)].val; + } + const V& operator[](K key) const { + assert(elt_query(key)); + return arr[find(key)].val; + } +}; + +#endif diff --git a/flower/lib/include/choleski.hh b/flower/lib/include/choleski.hh new file mode 100644 index 0000000000..f5e9fb4f5a --- /dev/null +++ b/flower/lib/include/choleski.hh @@ -0,0 +1,46 @@ +#ifndef CHOLESKI_HH +#define CHOLESKI_HH + +#include "matrix.hh" + +/** + Choleski decomposition of a matrix + structure for using the LU decomposition of a positive definite matrix. + + #P# is split into + + LD transpose(L) + */ +struct Choleski_decomposition { + + /// lower triangle of Choleski decomposition + Matrix L; + + /// diagonal + Vector D; + + /** Create decomposition of P. + PRE + P needs to be symmetric positive definite + */ + + Choleski_decomposition(Matrix P); + + /** + solve Px = rhs + */ + Vector solve(Vector rhs) const; + + Vector operator * (Vector rhs) const { return solve (rhs); } + /** + return the inverse of the matrix P. + */ + Matrix inverse() const; + /** + return P, calc'ed from L and D + */ + Matrix original() const; + + +}; +#endif diff --git a/flower/lib/include/compare.hh b/flower/lib/include/compare.hh new file mode 100644 index 0000000000..203ba014e7 --- /dev/null +++ b/flower/lib/include/compare.hh @@ -0,0 +1,55 @@ +/* + flowerlib + + (c) 1996 Han-Wen Nienhuys + */ +#ifndef COMPARE_HH +#define COMPARE_HH + +#define one_operator(type, function, op) \ +inline bool \ +operator op (type t1, type t2) {\ + return function(t1, t2) op 0;\ +}\ + +#define gpp_minmax_operator(type, op, opp) \ +inline type \ +operator op(type t1, type t2)\ +{\ + return (t1 opp t2) ? t1 : t2;\ +}\ + + +#if defined (__GNUG__) && ! defined (__STRICT_ANSI__) +#define gpp_minmax(type, prefix)\ + prefix gpp_minmax_operator(type, ?, >) +#else +#define gpp_minmax(type, prefix) +#endif + +/** handy notations for a signed comparison. + make the operators{<,<=,==,>=,>} and the MAX and MIN of two. + Please fill a & in the type argument if necessary. + */ +#define template_instantiate_compare(type, function, prefix) \ +prefix one_operator(type, function, >)\ +prefix one_operator(type, function, >=)\ +prefix one_operator(type, function, ==)\ +prefix one_operator(type, function, !=)\ +prefix one_operator(type, function, <)\ +prefix one_operator(type, function, <=)\ +gpp_minmax(type, prefix)\ +prefix inline type max(type t1, type t2) { return (t1 > t2 )? t1 : t2; }\ +prefix inline type min(type t1, type t2) { return (t1 < t2 )? t1 : t2; }\ + \ +prefix bool operator<(type t1, type t2) /* stupid fix to allow ; */ + + + +#define instantiate_compare(type, func) template_instantiate_compare(type,func, ) + + + +#endif + diff --git a/flower/lib/include/cursor.hh b/flower/lib/include/cursor.hh new file mode 100644 index 0000000000..0ea99037f9 --- /dev/null +++ b/flower/lib/include/cursor.hh @@ -0,0 +1,113 @@ +// cursor.hh + +#ifndef __CURSOR_HH +#define __CURSOR_HH + +#include "link.hh" +template class List; + +/** iterator to List. + add and insert extend the list + items are always stored as copies in List, but: + List : copies of String stored + List : copies of String* stored! + + the operations add and insert actually delegate the work to List class. + */ +template +class Cursor +{ + public: + /** create cursor, set at top. The const part isn't true, actually, #list# + surely isn't const, but I get tired of the warning messages. */ + Cursor( const List& list, Link* pointer = 0 ); + + Cursor( const Cursor& cursor ); + + T& thing(); + + /// return current T + T& operator *() { return thing(); } + operator T() { return thing(); } + Cursor operator =( const Cursor& c ); + + /// make cursor with #no# items back + Cursor operator -( int no) const; + + /// make cursor with #no# items further + Cursor operator +( int no) const; + int operator -(Cursor op) const; + Cursor operator -=(int); + Cursor operator +=(int); + + /// return current and move one down + Cursor operator ++( int ); + + /// return current and move one up + Cursor operator --( int ); + + /// point to link? + bool ok(); + + /// ++ items left? + bool forward(); + + /// -- items left? + bool backward(); + + /** put (copy) after me in List. + analogously to editor. ok() interpreted as at end + of line. + + PRE: !ok, POST: added to bottom() + + PRE: ok, POST: added after me + + cursor points to same object, cursor.next() is newly added + object. + */ + void add( const T& thing ); + + /** put (copy) before me in List. + analogously to editor. ok() interpreted as at begin of + line. + + PRE: !ok, POST: add to top() + + PRE: ok, POST: add before me + + cursor points to same object, cursor.previous() + is newly inserted object. + */ + + void insert( const T& thing ); + /// + void backspace(); + + /// + void del(); + + /// access the list this came from + List& list() const ; + Link* pointer(); + static int compare(Cursor a,Cursorb) { return a-b; } +private: + List& list_; + Link* pointer_; +}; + + +/* + comparisons. + */ +#include "compare.hh" + + +template_instantiate_compare(Cursor, Cursor::compare, template); + +#include "pcursor.hh" +#include "list.hh" +#include "cursor.inl" +#include "iterate.hh" + +#endif // CURSOR_HH diff --git a/flower/lib/include/cursor.inl b/flower/lib/include/cursor.inl new file mode 100644 index 0000000000..54d3703e60 --- /dev/null +++ b/flower/lib/include/cursor.inl @@ -0,0 +1,113 @@ + // cursor.inl -*-c++-*- +#ifndef CURSOR_INL +#define CURSOR_INL +#include + + +template +inline +Cursor::Cursor( const List& list, Link* pointer ) : + list_((List&) list ) +{ + if ( list.size() ) + pointer_ = pointer ? pointer : list.top_; + else + pointer_ = pointer; +} + +template +inline +Cursor::Cursor( const Cursor& cursor ) : + list_( cursor.list_ ) +{ + pointer_ = cursor.pointer_; +} + +template +inline T& +Cursor::thing() +{ + assert( pointer_ ); + return pointer_->thing(); +} + +template +Cursor +Cursor::operator =( const Cursor& c ) +{ + assert( &list_ == &c.list_ ); + pointer_ = c.pointer_; + return *this; +} + +template +inline void +Cursor::add( const T& th ) +{ + list_.add( th, *this ); +} + +template +inline void +Cursor::insert( const T& th ) +{ + list_.insert( th, *this ); +} + +template +inline List& +Cursor::list() const +{ + return list_; +} + +template +inline Link* +Cursor::pointer() +{ + return pointer_; +} + +template +inline bool +Cursor::backward() +{ + return ( pointer_ != 0 ); +} + +template +inline bool +Cursor::forward() +{ + return ( pointer_ != 0 ); +} + +template +inline bool +Cursor::ok() +{ + return ( pointer_ != 0 ); +} + + +template +inline Cursor +Cursor::operator ++( int ) +{ + Cursor r (*this); + assert( pointer_ ); + pointer_ = pointer_->next(); + return r; +} + +template +inline Cursor +Cursor::operator --( int ) +{ + Cursor r (*this); + assert( pointer_ ); + pointer_ = pointer_->previous(); + return r; +} + +#endif diff --git a/flower/lib/include/cursor.tcc b/flower/lib/include/cursor.tcc new file mode 100644 index 0000000000..3be73fe5d2 --- /dev/null +++ b/flower/lib/include/cursor.tcc @@ -0,0 +1,109 @@ +#ifndef CURSOR_CC +#define CURSOR_CC + +#include "cursor.hh" +#include + +template + void +Cursor::backspace() +{ + Cursor c(*this); + if ( c.ok() ) + c--; + list_.remove( *this ); +} + +template + void +Cursor::del() +{ + Cursor c(*this); + if ( c.ok() ) + c++; + list_.remove( *this ); + *this = c; +} + + +template +Cursor +Cursor::operator -=( int j ) +{ + while (j--) + (*this)--; + return *this; +} +template +Cursor +Cursor::operator +=( int j ) +{ + while (j++) + (*this)++; + return *this; +} + +template +Cursor +Cursor::operator +( int i ) const +{ + Cursor r = *this; + + if (i<0) + return r -(-i); + + while (i--) + r++; + + return r; +} + +template +Cursor +Cursor::operator -( int i ) const +{ + Cursor r = *this; + if (i<0) + return r +(-i); + + while (i--) + r--; + + return r; +} +/* + warning: can't use Cursor::operator == (Cursor), + since it uses Cursor::operator-(Cursor) + */ +template +int +Cursor::operator-(Cursor rhs) const +{ + assert(rhs.list == list); + int dif = 0; + + // search from *this on further up (positive difference) + Cursor c(*this); + while (c.ok() && c.pointer_ != rhs.pointer_) { + c--; + dif++; + } + + if (c.ok()) + goto gotcha; // so, sue me. + + // search in direction of bottom. (negative diff) + dif =0; + c=*this; + while (c.ok() && c.pointer_ !=rhs.pointer_) { + dif --; + c++; + } + assert(c.ok()); + +gotcha: + assert((*this - dif).pointer_ == c.pointer_); + return dif; +} + +#endif diff --git a/flower/lib/include/data-file.hh b/flower/lib/include/data-file.hh new file mode 100644 index 0000000000..dae9e56347 --- /dev/null +++ b/flower/lib/include/data-file.hh @@ -0,0 +1,59 @@ +/* + data-file.hh -- declare Data_file + + source file of the LilyPond music typesetter + + (c) 1997 Han-Wen Nienhuys +*/ + + +#ifndef DATAFILE_HH +#define DATAFILE_HH + +#include "text-stream.hh" + +/// read a data file +class Data_file : private Text_stream +{ + + public: + bool rawmode; + + Text_stream::line; + Text_stream::eof; + Text_stream::get_name; + + char data_get(); + void data_unget(char c) { + unget(c); + } + + /// read line, eat #\n# + String get_line(); + + /// read a word till next space, leave space. Also does quotes + String get_word(); + + /// gobble horizontal white stuff. + void gobble_white(); + + /// gobble empty stuff before first field. + void gobble_leading_white(); + Data_file(String s) : Text_stream(s) { + //*mlog << "(" << s << flush; + rawmode= false; + } + + ~Data_file() { + // *mlog << ")"< +struct Assoc; + +/** debug stream. + a class for providing debug output of nested structures, + with indents according to \{\}()[]. + + One can turn on and off specific messages using the Assoc silent. + This can be done automatically: + + #define DEBUG dstream_.identify_as(__PRETTY_FUNCTION__) + + DEBUG << "a message\n"; + + Init for the class names which should be silent can be given in a rc file. + + */ +class Dstream +{ + ostream *os; + int indentlvl; + bool local_silence; + String classname; + void output(String s); + Assoc *silent; +public: + + bool silence(String); + + /** + if rcfile == 0, then do not read any rc file. + */ + + Dstream(ostream *r, const char * rcfile); + virtual ~Dstream(); + Dstream &identify_as(String s); + + Dstream &operator << (String s); + /** + Output memory locations. + */ + Dstream &operator << (void const *); + Dstream &operator << (char const *); +}; +#endif + diff --git a/flower/lib/include/fproto.hh b/flower/lib/include/fproto.hh new file mode 100644 index 0000000000..8c6fda680e --- /dev/null +++ b/flower/lib/include/fproto.hh @@ -0,0 +1,44 @@ +/* + fproto.hh -- typenames in flowerlib + + (c) 1996 Han-Wen Nienhuys +*/ + +#ifndef FPROTO_HH +#define FPROTO_HH + +#include "flower-config.hh" + +template struct Array; +template struct sstack; +template struct Assoc; +template struct List; +template struct PointerList; +template struct IPointerList; +template struct Cursor; +template struct PCursor; +template struct Link; +template struct Handle; +templatestruct Interval_t; +#include "real.hh" + +typedef Interval_t Interval; + +struct Choleski_decomposition; + +struct Long_option_init; +struct Getopt_long; +struct Matrix; +struct String_data; +struct String_handle; +struct String_convert; +struct String; +struct virtual_smat; +struct Vector ; +struct Text_stream; +struct Data_file; +struct Text_db; +struct Scalar; +typedef unsigned char Byte; +#endif // FPROTO_HH + diff --git a/flower/lib/include/handle.hh b/flower/lib/include/handle.hh new file mode 100644 index 0000000000..63c17ef1d2 --- /dev/null +++ b/flower/lib/include/handle.hh @@ -0,0 +1,58 @@ +#ifndef HANDLE_HH +#define HANDLE_HH + +/// reference counting handle +template +class Handle { + T *obj; + int *refs; + + /// let go of ref. Delete if necessary + void down() { + if (!(*refs--)) { + delete obj; + delete refs; + } + obj = 0; + refs = 0; + } + /// point to new object. + void up(T *t, int *r) { + if (!r) { + refs = new int; + *refs = 1; + } else { + refs =r; + *refs++; + } + obj = t; + } + /// POST: *refs == 1 + void copy() { + if(*refs != 1){ + T * newobj = new T(*obj ); + down(); + up(newobj); + } + } + Handle(Handle const &src) { + up(src.obj, src.refs); + } + Handle(T & o) { + up (&o); + } + void operator=(Handle const& src) { + if (this == &src) + return; + down(); + up(src.o, src.refs); + } + operator const T&() { + return *obj; + } + operator T&() { + copy(); + return *obj; + } +} +#endif diff --git a/flower/lib/include/interval.hh b/flower/lib/include/interval.hh new file mode 100644 index 0000000000..aae16381db --- /dev/null +++ b/flower/lib/include/interval.hh @@ -0,0 +1,125 @@ +/* + interval.hh -- part of flowerlib + + (c) 1996 Han-Wen Nienhuys +*/ + +#ifndef INTERVAL_HH +#define INTERVAL_HH + +#include +#include "fproto.hh" +#include "real.hh" + + +/** a T interval. + this represents the closed interval [left,right]. + No invariants. T must be a totally ordered ring + */ +template +struct Interval_t { + T left, right; + + /* ************** */ + + T center() { return (left + right) / T(2);} + void translate(T t) { + left += t; + right += t; + } + T& idx(int j) { + if (j==-1) + return left; + else if (j==1) + return right; + else + assert(false); + return left; + } + T& operator[](int j) { + return idx(j); + } + T operator[](int j) const { + return ((Interval_t *)this)->idx(j); + } + T &max() { return right;} + T max()const { return right;} + T min()const{ return left; } + T &min(){ return left; } + /** + PRE + *this and h are comparable + */ + void unite(Interval_t h); + void intersect(Interval_t h); + + T length() const; + void set_empty() ; + bool empty() const { return left > right; } + Interval_t() { + set_empty(); + } + Interval_t(T m, T M) { + left =m; + right = M; + } + Interval_t &operator += (T r) { + left += r; + right +=r; + return *this; + } + String str() const; + bool elt_q(T r); +}; + + +/** + inclusion ordering. Crash if not comparable. + */ +template +int Interval__compare(const Interval_t&,Interval_t const&); + +/* + INLINE + */ + +#include "compare.hh" + +template_instantiate_compare(Interval_t&, Interval__compare, template); + + +template +inline Interval_t +intersection(Interval_t a, Interval_t const&b) +{ + a.intersect(b); + return a; + +} + + +template +inline +Interval_t operator +(T a,Interval_t i ) +{ + i += a; + return i; +} + +template +inline +Interval_t operator +(Interval_t i,T a ){ + return a+i; +} + +typedef Interval_t Interval; + + +#define Interval__instantiate(T) template struct Interval_t;\ + template int Interval__compare(const Interval_t&,Interval_t const&) + + +#endif // INTERVAL_HH + + + diff --git a/flower/lib/include/interval.tcc b/flower/lib/include/interval.tcc new file mode 100644 index 0000000000..6e7b0b1279 --- /dev/null +++ b/flower/lib/include/interval.tcc @@ -0,0 +1,106 @@ +#include +#include +#include "interval.hh" +#include "string.hh" + + +template +int +_Interval__compare(const Interval_t&a,Interval_t const&b) +{ + if (a.left == b.left && a.right == b.right) + return 0; + + if (a.left <= b.left && a.right >= b.right) + return 1; + + if (a.left >= b.left && a.right <= b.right) + return -1; + + return -2; +} + + +template +int +Interval__compare(const Interval_t&a,Interval_t const&b) +{ + int i = _Interval__compare(a,b); + if (i < -1) + assert(false); + return i; +} + +#ifdef AIX +const Real INFTY = 1e8; // ARGh. AIX sucks +#else +const Real INFTY = HUGE_VAL; +#endif + +template +void +Interval_t::set_empty() +{ + left = INFTY; + right = -INFTY; +} + +template +T +Interval_t::length() const { + assert(right >= left); + return right-left; +} + +template +void +Interval_t::unite(Interval_t h) +{ + if (h.leftright) + right = h.right; +} + +/** + smallest Interval which includes *this and #h# + */ + +template +void +Interval_t::intersect(Interval_t h) +{ +#if defined (__GNUG__) && ! defined (__STRICT_ANSI__) + left = h.left >? left; + right = h.right +Interval_t +intersect(Interval_t x, Interval_t const &y) +{ + x.intersect(y); + return x; +} + +template +String +Interval_t::str() const +{ + if (empty()) + return "[empty]"; + String s("["); + + return s + left + "," + right +"]"; +} + +template +bool +Interval_t::elt_q(T r) +{ + return r >= left && r <= right; +} diff --git a/flower/lib/include/iterate.hh b/flower/lib/include/iterate.hh new file mode 100644 index 0000000000..1e924f0790 --- /dev/null +++ b/flower/lib/include/iterate.hh @@ -0,0 +1,22 @@ +/* + iterate.hh -- define some list macros + + source file of the flowerlib + + (c) 1997 Han-Wen Nienhuys +*/ + + +#ifndef ITERATE_HH +#define ITERATE_HH + + + +#define iterator(set) typeof((set).top()) +#define iterator_bot(set) typeof((set).bottom()) + +// should use top() +#define iter_top(set,var) iterator(set) var(set) +#define iter_bot(set,var) iterator(set) var(set.bottom()) + +#endif // ITERATE_HH diff --git a/flower/lib/include/lgetopt.hh b/flower/lib/include/lgetopt.hh new file mode 100644 index 0000000000..3b2b0348b3 --- /dev/null +++ b/flower/lib/include/lgetopt.hh @@ -0,0 +1,94 @@ +#ifndef LGETOPT_HH +#define LGETOPT_HH + +#include + + +class ostream; + +/** + a struct this for initialising the commandline options. + */ +struct Long_option_init { + bool take_arg; + const char* longname; + char shortname; + + ostream &printon(ostream &errorout); +}; + + +/** C++ for version of long_getopt. For processing GNU style command + line arguments. No pointer (return values, arguments) contents are + copied. */ +class Getopt_long { +public: + /** errorcodes: no error, argument expected, no argument expected, + unknown option, illegal argument (eg. int expected). */ + enum Errorcod { E_NOERROR = 0, E_ARGEXPECT, E_NOARGEXPECT, E_UNKNOWNOPTION, + E_ILLEGALARG } ; + + +private: + + /// the option info. + Long_option_init *the_opts; + int table_len; + + /// if doing short option, argv[optind][optindind] is processed next. + int optindind; + + /// the option found + Long_option_init *beet; + + /// get ready for processing next error. + bool next(); + Long_option_init *parselong(); + Long_option_init *parseshort(); + + ostream *errorout; + + /// report an error and abort + void report(Errorcod c); +public: + + /// argument. Set to 0 if not present + char* optarg; + + /// current error status + Errorcod error; + + /// return an integer (with err. detect) + long intarg(); + /// argv[optind] will be processed next. + int optind; + + /// the arguments + char **argv; + + /// the arg. count + int argc; + + /* *************** */ + + /** + What to do with errors. + report messages on #*os#, and abort. + if #os# is null, then do not report nor abort, just set #error# + */ + + void seterror(ostream *os); + + /// construct: pass arguments and option info. + Getopt_long(int c, char **v, Long_option_init *lo); + + /** get the next option. + @return pointer to next option found. + 0 if error occurred, or next argument is no option. + */ + Long_option_init *operator()(); + + char *current_arg(); + char * get_next_arg(); +}; +#endif diff --git a/flower/lib/include/libc-extension.hh b/flower/lib/include/libc-extension.hh new file mode 100644 index 0000000000..e71037c41e --- /dev/null +++ b/flower/lib/include/libc-extension.hh @@ -0,0 +1,32 @@ +/* + libc-extension.hh -- declare some string.h extensions + + source file of the flowerlib + + (c) 1997 Han-Wen Nienhuys +*/ + + +#ifndef LIBC_EXTENSION_HH +#define LIBC_EXTENSION_HH +#include "fproto.hh" + +char* strnlwr( char* start_l ,int n); +char* strnupr( char* start_l, int n); + +#ifndef HAVE_MEMMEM // GNU extension. +char *memmem(const Byte * haystack, int haystack_len, + const Byte *needle, int needle_len); +#endif HAVE_MEMMEM + +#ifndef HAVE_SNPRINTF // GNU extension. +int snprintf (char *str, size_t n, + const char *format, ... ); +#endif + + +Byte *memrchr(const Byte * p, int n, char c); +Byte *strrev( Byte* byte_l, int length_i ); + + +#endif // LIBC_EXTENSION_HH diff --git a/flower/lib/include/link.hh b/flower/lib/include/link.hh new file mode 100644 index 0000000000..6f9c75a411 --- /dev/null +++ b/flower/lib/include/link.hh @@ -0,0 +1,38 @@ +// link.hh + +#ifndef __LINK_HH +#define __LINK_HH +template +class List; + + +/// class for List +template +class Link +{ +// friend class Cursor; +public: + Link( const T& thing ); + + Link* previous(); + Link* next(); + + /// put new Link item after me in list + void add( const T& thing ); + /// put new Link item before me in list + void insert( const T& thing ); + void remove(List &l); + + T& thing(); + void OK() const; +private: + Link( Link* previous, Link* next, const T& thing ); + + T thing_; + Link* previous_; + Link* next_; +}; + +#include "link.inl" + +#endif // __LINK_HH // diff --git a/flower/lib/include/link.inl b/flower/lib/include/link.inl new file mode 100644 index 0000000000..3926d6bc2a --- /dev/null +++ b/flower/lib/include/link.inl @@ -0,0 +1,102 @@ +// link.inl -*-c++-*- +#ifndef LINK_INL +#define LINK_INL +#include +template +inline +void +Link::OK() const +{ +#ifndef NDEBUG + if (previous_) { + assert(previous_->next_ == this); + } + if (next_) { + assert(next_->previous_ == this); + } +#endif +} + +template +inline +Link::Link( const T& thing ) : + thing_( thing ) +{ + previous_ = next_ = 0; +} + +template +inline +Link::Link( Link* previous, Link* next, const T& thing ) : + thing_( thing ) +{ + previous_ = previous; + next_ = next; +} + +template +inline +Link* +Link::next() +{ + return next_; +} + +template +inline +Link* +Link::previous() +{ + return previous_; +} + +template +inline +void +Link::add( const T& thing ) +{ + + Link* l = new Link( this, next_, thing ); + if ( next_ ) + next_->previous_ = l; + next_ = l; +} + +template +inline void +Link::insert( const T& thing ) +{ + // Link* l = new Link( next_, this, thing ); + // bugfix hwn 16/9/96 + Link* l = new Link( previous_, this, thing ); + if ( previous_ ) + previous_->next_ = l; + previous_ = l; +} + +/* + don't forget to adjust #l#'s top_ and bottom_. + */ +template +inline void +Link::remove(List &l) +{ + if ( previous_ ) + previous_->next_ = next_; + else + l.top_ = next_; + + if ( next_ ) + next_->previous_ = previous_; + else + l.bottom_ = previous_; +} + +template +inline +T& +Link::thing() +{ + return thing_; +} +#endif diff --git a/flower/lib/include/list.hh b/flower/lib/include/list.hh new file mode 100644 index 0000000000..ec59fbff07 --- /dev/null +++ b/flower/lib/include/list.hh @@ -0,0 +1,98 @@ +#ifndef __LIST_HH +#define __LIST_HH + +class ostream; +template class Cursor; +template class Link; + +/** all-purpose doubly linked list. + + List can be seen as all items written down on paper, + from top to bottom + + class Cursor is used to extend List + + items are always stored as copies in List, but: + #List# : copies of #String# stored + #List# : copies of #String*# stored! + (do not use, use \Ref{PointerList} ## instead.) + + {\bf note:} + retrieving "invalid" cursors, i.e. + #top()/bottom()# from empty list, #find()# without success, + results in a nonvalid Cursor ( #!ok()# ) + + + INVARIANTEN! +*/ + +template +class List +{ + public: + List(List const&src); + + /// construct empty list + List(); + virtual ~List(); + + int size() const; + + Cursor bottom() const; // const sucks. + Cursor top() const; + + void OK() const; // check list + + protected: + friend class Cursor; + friend class Link; + + void concatenate(List const &s); + + /** make *this empty. + + POST: + size == 0 + + WARNING: + contents lost, and not deleted. + */ + void set_empty(); + + void add( const T& thing, Cursor &after_me ); + + /// put thing before #before_me# + void insert( const T& thing, Cursor &before_me ); + + /** Remove link pointed to by me. Destructor of contents called + (nop for pointers) + + POST + none; + + + WARNING: do not use #me# after calling + */ + void remove( Cursor me ); + + + /* ************** */ + + int size_; + Link* top_; + Link* bottom_; +}; + +#include "list.inl" +#include "cursor.hh" + +// instantiate a template: explicit instantiation. +#define L_instantiate(a) template class List; template class Cursor; \ + template class Link + + +#endif // __LIST_HH // + + + + diff --git a/flower/lib/include/list.inl b/flower/lib/include/list.inl new file mode 100644 index 0000000000..df0687b7c8 --- /dev/null +++ b/flower/lib/include/list.inl @@ -0,0 +1,56 @@ +// -*-c++-*- + +#ifndef LIST_INL +#define LIST_INL + +template +inline +List::List() +{ + set_empty(); +} + +template +inline void +List::set_empty() +{ + top_ = bottom_ = 0; + size_ = 0; +} + +template +inline void +List::remove( Cursor me ) +{ + if ( me.ok() ){ + Link *lp = me.pointer(); + lp->remove(*this); + delete lp; + size_--; + } +} + +template +inline int +List::size() const +{ + return size_; +} + +template +inline Cursor +List::top()const +{ + return Cursor( *this, top_ ); +} + + +template +inline Cursor +List::bottom()const +{ + return Cursor( *this, bottom_ ); +} + + +#endif diff --git a/flower/lib/include/list.tcc b/flower/lib/include/list.tcc new file mode 100644 index 0000000000..16e12a31f1 --- /dev/null +++ b/flower/lib/include/list.tcc @@ -0,0 +1,112 @@ +#ifndef LIST_CC +#define LIST_CC + +#include "list.hh" + +template +List::List(List const&src) +{ + set_empty(); + // probably el stupido + for (Cursor c(src); c.ok(); c++) + bottom().add(c); +} + +template +void +List::OK() const +{ + int i = size_; + Link *lp = top_; + while (i--) { + assert(lp); + lp->OK(); + lp = lp->next(); + } + assert(!lp); + i = size_; + lp = bottom_; + while (i--) { + assert(lp); + lp->OK(); + lp = lp->previous(); + } + assert(!lp); +} + + +template +List::~List() +{ + Cursor c(*this); + while (c.ok()) + c.del(); +} + +/** + + add after after_me. + + Procedure: + \begin{itemize} + \item if #after_me# is #ok()#, add after #after_me#, else + \item if list !empty simply add to bottom, else + \item list is empty: create first \Ref{Link} and initialize + #bottom_# and #top_#. + \end{itemize} +*/ +template +void +List::add( const T& thing, Cursor &after_me ) +{ + if (!size_) { // not much choice if list is empty + bottom_ = top_ = new Link( thing ); + if (!after_me.ok()) + after_me = bottom(); + } else { // add at aprioprate place + if (!after_me.ok()) + after_me = bottom(); + Link *p =after_me.pointer(); + p->add(thing); + if (p == bottom_) // adjust bottom_ if necessary. + bottom_ = p->next(); + } + + size_++; +} + +template +void +List::insert( const T& thing, Cursor &before_me ) +{ + if (!size_) { + bottom_ = top_ = new Link( thing ); + if (!before_me.ok()) + before_me = top(); + + } else { + if (!before_me.ok()) + before_me = top(); + + Link *p = before_me.pointer() ; + + p->insert(thing); + if (p == top_) + top_ = p->previous(); + } + + size_++; +} + + +template +void +List::concatenate(List const&s) +{ + Cursor b(bottom()); + for (Cursor c(s); c.ok(); c++) { + b.add(c); + b++; + } +} +#endif diff --git a/flower/lib/include/matrix.hh b/flower/lib/include/matrix.hh new file mode 100644 index 0000000000..a633d6657a --- /dev/null +++ b/flower/lib/include/matrix.hh @@ -0,0 +1,135 @@ +#ifndef MATRIX_HH +#define MATRIX_HH + + +#include "vsmat.hh" +#include "vector.hh" + +/** a Real matrix. This is a class for a nonsquare block of #Real#s. The + implementation of sparse matrices is done in the appropriate #smat# + class. Matrix only does the mathematical actions (adding, + multiplying, etc.) + + + TODO + implement ref counting? */ + + +class Matrix { + virtual_smat *dat; + +public: + void OK() const { dat->OK(); } + int cols() const { return dat->cols(); } + int rows() const { return dat->rows(); } + + /** return the size of a matrix. + PRE + the matrix needs to be square. + */ + int dim() const; + + // Matrix() { dat = 0; } + ~Matrix() { delete dat; } + + /// set entries to r + void fill(Real r); + + /// set diagonal to d + void set_diag(Real d); + + void set_diag(Vector d); + /// set unit matrix + void unit() { set_diag(1.0); } + + void operator+=(const Matrix&m); + void operator-=(const Matrix&m); + void operator*=(Real a); + void operator/=(Real a) { (*this) *= 1/a; } + + /** add a row. + add a row to the matrix before row k + + PRE + v.dim() == cols() + 0 <= k <= rows() + */ + void insert_row(Vector v,int k); + /** . + delete a row from this matrix. + + PRE + 0 <= k < rows(); + */ + void delete_row(int k) { dat->delete_row(k); } + void delete_column(int k) { dat->delete_column(k); } + + /** + square n matrix, initialised to null + */ + Matrix(int n); + + /** + n x m matrix, init to 0 + */ + Matrix(int n, int m); + Matrix(const Matrix &m); + + /// dyadic product: v * w.transpose + Matrix(Vector v, Vector w); + void operator=(const Matrix&m); + + /// access an element + Real operator()(int i,int j) const { return dat->elem(i,j); } + + /// access an element + Real &operator()(int i, int j) { return dat->elem(i,j); } + + /// Matrix multiply with vec (from right) + Vector operator *(const Vector &v) const; + + /// set this to m1*m2. + void set_product(const Matrix &m1, const Matrix &m2); + + + Vector left_multiply(Vector const &) const; + + Matrix operator-() const; + + /// transpose this. + void transpose(); + + /// return a transposed copy. + Matrix transposed() const ; + + Real norm() const; + /** swap. + PRE + 0 <= c1,c2 < cols() + */ + void swap_columns(int c1, int c2); + + /** swap. + PRE + 0 <= c1,c2 < rows() + */ + void swap_rows(int c1, int c2); + + + Vector row(int ) const; + Vector col(int) const; + + operator String() const; + void print() const; +}; + +inline Vector +operator *(Vector &v, const Matrix& m) { return m.left_multiply(v); } +Matrix operator *(const Matrix& m1,const Matrix &m2); +Matrix operator /(const Matrix &m1,Real a); +inline Matrix operator -(Matrix m1,const Matrix m2) +{ + m1 -= m2; + return m1; +} +#endif diff --git a/flower/lib/include/path.hh b/flower/lib/include/path.hh new file mode 100644 index 0000000000..bc4d9f3776 --- /dev/null +++ b/flower/lib/include/path.hh @@ -0,0 +1,32 @@ +#ifndef PATH_HH +#define PATH_HH +#include "string.hh" +#include "varray.hh" + + +/** searching directory for file. + + Abstraction of PATH variable. An interface for searching input files. + Search a number of dirs for a file. + + Should use kpathsea? + +*/ + +class File_path : private Array +{ +public: + /// locate a file in the search path + String find(String nm); + + /// construct using prefix. Normally argv[0]. + File_path(String); + + /// add to end of path. + Array::push; + void add(String str) { push(str); } +}; +/// split path into its components +void split_path(String path, String &drive, String &dirs, String &filebase, String &extension); + +#endif diff --git a/flower/lib/include/pcursor.hh b/flower/lib/include/pcursor.hh new file mode 100644 index 0000000000..f1a098f71b --- /dev/null +++ b/flower/lib/include/pcursor.hh @@ -0,0 +1,68 @@ +/* + pcursor.hh -- part of flowerlib + + (c) 1996 Han-Wen Nienhuys&Jan Nieuwenhuizen +*/ + +#ifndef PCURSOR_HH +#define PCURSOR_HH + +#include "plist.hh" +#include "cursor.hh" + +/** cursor to go with PointerList. + don't create PointerList's. + This cursor is just an interface class for Cursor. It takes care of the + appropriate type casts + */ +template +class PCursor : private Cursor { + friend class IPointerList; + + /// delete contents + void junk(); +public: + Cursor::ok; + Cursor::del; + Cursor::backspace; + T remove_p() { + T p = ptr(); + Cursor::del(); + return p; + } + T remove_prev_p() { + assert( ok() ); + (*this)--; + return remove_p(); + } + + PointerList &list() { return (PointerList&)Cursor::list(); } + PCursor operator++(int) { return Cursor::operator++(0);} + PCursor operator--(int) { return Cursor::operator--(0); } + PCursor operator+=(int i) { return Cursor::operator+=(i);} + PCursor operator-=(int i) { return Cursor::operator-=(i); } + PCursor operator -(int no) const { return Cursor::operator-(no);} + int operator -(PCursor op) const { return Cursor::operator-(op);} + PCursor operator +( int no) const {return Cursor::operator+(no);} PCursor(const PointerList & l) : Cursor (l) {} + + PCursor( const Cursor& cursor ) : Cursor(cursor) { } + void* vptr() const { return *((Cursor &) *this); } + + // should return T& ? + T ptr() const { return (T) vptr(); } + T operator ->() const { return ptr(); } + operator T() { return ptr(); } + T operator *() { return ptr(); } + void add(const T& p ) { Cursor::add((void*) p); } + void insert(const T& p ) { Cursor::insert((void*) p);} + static int compare(PCursor a,PCursorb) { + return Cursor::compare(a,b); + } +}; + + + +#include "compare.hh" +template_instantiate_compare(PCursor, PCursor::compare, template); + +#endif diff --git a/flower/lib/include/pcursor.tcc b/flower/lib/include/pcursor.tcc new file mode 100644 index 0000000000..ffb01bcfe8 --- /dev/null +++ b/flower/lib/include/pcursor.tcc @@ -0,0 +1,16 @@ +#include "pcursor.hh" + +template +void +PCursor::junk() +{ +#if !defined(NDEBUG) && defined(PARANOID) + list().OK(); +#endif + + delete ptr(); +#if !defined(NDEBUG)&&defined(PARANOID) + thing() = 0; + list().OK(); +#endif +} diff --git a/flower/lib/include/plist.hh b/flower/lib/include/plist.hh new file mode 100644 index 0000000000..426b861c02 --- /dev/null +++ b/flower/lib/include/plist.hh @@ -0,0 +1,72 @@ +/* + list.hh -- part of flowerlib + + (c) 1996 Han-Wen Nienhuys & Jan Nieuwenhuizen +*/ + +#ifndef PLIST_HH +#define PLIST_HH + +#include "list.hh" + +/** + A list of pointers. + + Use for list of pointers, e.g. PointerList. + This class does no deletion of the pointers, but it knows how to + copy itself (shallow copy). We could have derived it from List, + but this design saves a lot of code dup; for all PointerLists in the + program only one parent List is instantiated. + */ +template +class PointerList : public List +{ + public: + PCursor top() const{ + return PCursor (List::top()); + } + PCursor bottom() const { + return PCursor (List::bottom()); + } + PCursor find(T) const; + void concatenate(PointerList const &s) { List::concatenate(s); } + PointerList() {} +}; + +/** PointerList which deletes pointers given to it. + NOTE: + + The copy constructor doesn't do what you'd want: + Since T might have a virtual ctor, we don't try to do a + + new T(*cursor) + + You have to copy this yourself, or use the macro PointerList__copy + + */ +template +class IPointerList : public PointerList { +public: + IPointerList(const IPointerList&) { set_empty(); } + IPointerList() { } + ~IPointerList(); +}; + +#define IPointerList__copy(T, to, from, op) \ + for (PCursor _pc_(from); _pc_.ok(); _pc_++)\ + to.bottom().add(_pc_->op)\ + \ + + +template +void PL_copy(IPointerList &dst,IPointerList const&src); + + +#define PL_instantiate(a) template class PointerList; \ + template class PCursor; +#define IPL_instantiate(a) PL_instantiate(a); \ + template class IPointerList + +#include "plist.inl" + +#endif diff --git a/flower/lib/include/plist.inl b/flower/lib/include/plist.inl new file mode 100644 index 0000000000..82be364334 --- /dev/null +++ b/flower/lib/include/plist.inl @@ -0,0 +1,21 @@ +/* -*-c++-*- + plist.inl -- part of flowerlib + + (c) 1996 Han-Wen Nienhuys& Jan Nieuwenhuizen +*/ + +#ifndef PLIST_INL +#define PLIST_INL + +template +void +PL_copy(IPointerList &to, IPointerList const&src) +{ + for (PCursor pc(src); pc.ok(); pc++) { + T *q = pc; + T *p=new T(*q) ; + to.bottom().add(p); + } +} + +#endif diff --git a/flower/lib/include/plist.tcc b/flower/lib/include/plist.tcc new file mode 100644 index 0000000000..ac9daedf71 --- /dev/null +++ b/flower/lib/include/plist.tcc @@ -0,0 +1,21 @@ +#include "plist.hh" + +template +IPointerList::~IPointerList() +{ + PCursor c( *this ); + while (c.ok()) { + delete c.remove_p(); + } +} + +template +PCursor +PointerList::find(T what ) const +{ + PCursor i(*this); + for (; i.ok(); i++) + if (i.ptr() == what) + break; + return i; +} diff --git a/flower/lib/include/pqueue.hh b/flower/lib/include/pqueue.hh new file mode 100644 index 0000000000..195232317e --- /dev/null +++ b/flower/lib/include/pqueue.hh @@ -0,0 +1,46 @@ +/* + pqueue.hh -- declare + + source file of the LilyPond music typesetter + + (c) 1997 Han-Wen Nienhuys +*/ + + +#ifndef PQUEUE_HH +#define PQUEUE_HH + +#include "varray.hh" + +/** + Stupid Prioq. Should use Lists and STL. + Smallest is put at the front. + */ + +template +struct PQueue +{ + Array value_arr_; + Array indices_arr_; + + void enter(V v, I idx) { + int j=0; + for (; j < value_arr_.size(); j++) + if (indices_arr_[j] > idx) + break; + + value_arr_.insert(v, j); + indices_arr_.insert(idx, j); + } + int size() { return value_arr_.size(); } + V front_val() { return value_arr_[0]; } + I front_idx() { return indices_arr_[0]; } + V get() { + V retval = front_val(); + value_arr_.del(0); + indices_arr_.del(0); + return retval; + } + +}; +#endif // PQUEUE_HH diff --git a/flower/lib/include/rational.hh b/flower/lib/include/rational.hh new file mode 100644 index 0000000000..30fa2cb6d6 --- /dev/null +++ b/flower/lib/include/rational.hh @@ -0,0 +1 @@ +#include diff --git a/flower/lib/include/real.hh b/flower/lib/include/real.hh new file mode 100644 index 0000000000..0533af2111 --- /dev/null +++ b/flower/lib/include/real.hh @@ -0,0 +1,16 @@ +#ifndef REAL_HH +#define REAL_HH + + +#include +#include +#include + +typedef double Real; + +inline Real +distance(Real x,Real y) +{ + return abs(x-y); +} +#endif diff --git a/flower/lib/include/scalar.hh b/flower/lib/include/scalar.hh new file mode 100644 index 0000000000..5cdfa427da --- /dev/null +++ b/flower/lib/include/scalar.hh @@ -0,0 +1,34 @@ +/* + scalar.hh -- part of LilyPond + + (c) 1996 Han-Wen Nienhuys +*/ + +#ifndef SCALAR_HH +#define SCALAR_HH +#include "string.hh" +#include "real.hh" + +/// Perl -like scalar type. +struct Scalar : public String { + + Scalar(Real r) : String(r) {} + Scalar(int i) : String(i) {} + Scalar(char c) : String(c) {} + Scalar(const char *c) : String(c) {} + Scalar(String s ):String(s) {} + Scalar(Rational ); + operator Rational(); + Scalar() {} + bool isnum(); + operator Real(); + operator int(); + + /** perl -like string to bool conversion. + */ + operator bool() const; + +}; + +#endif // SCALAR_HH + diff --git a/flower/lib/include/smat.hh b/flower/lib/include/smat.hh new file mode 100644 index 0000000000..9b0987c8f4 --- /dev/null +++ b/flower/lib/include/smat.hh @@ -0,0 +1,93 @@ +#ifndef SMAT_HH +#define SMAT_HH +#include "varray.hh" +#include "vsmat.hh" +#include "real.hh" +/// simplest matrix storage. refer to its baseclass for the doco. +class Full_storage : public virtual_smat +{ + /// height, width + int h,w; + /// maxima. + int maxh, maxw; + + /// the storage + Real** els; + void + init() { + els=0; + h=w=maxh=maxw=0; + + } + + bool valid(int i, int j) const { + return (i>=0 && i < h) + && (j < w && j >=0); + } + + + void resize_rows(int); + void resize_cols(int); + +public: + virtual int rows() const { + return h; + } + virtual int cols() const { + return w; + } + + + virtual void set_size(int i, int j) + { + resize(i,j); //this could be more efficient. + } + + virtual void set_size(int i) { + set_size(i,i); + } + virtual void resize(int i, int j); + virtual void resize(int i) { + resize(i,i); + } + + virtual Real& elem(int i,int j) { + assert(valid(i,j)); + return els[i][j]; + } + virtual const Real& elem(int i, int j) const { + assert(valid(i,j)); + return els[i][j]; + } + virtual Array row(int i) const; + virtual Array column(int j) const; + + Full_storage() { + init(); + } + Full_storage(int i, int j) { + init(); + set_size(i,j); + } + Full_storage(Full_storage&); + Full_storage(int i) { + init(); + set_size(i); + } + void OK() const; + void operator=(Full_storage const &); + + virtual void insert_row(int k); + virtual void delete_row(int k); + virtual void delete_column(int k); + + + ~Full_storage(); + virtual bool mult_ok(int i, int j)const; + virtual void mult_next(int &i, int &j) const ; + virtual bool trans_ok(int i, int j) const; + virtual void trans_next(int &i, int &j) const; + virtual virtual_smat * clone(); +}; + +#endif diff --git a/flower/lib/include/string-convert.hh b/flower/lib/include/string-convert.hh new file mode 100644 index 0000000000..bcf461f8f3 --- /dev/null +++ b/flower/lib/include/string-convert.hh @@ -0,0 +1,43 @@ +/* + PROJECT: FlowerSoft C++ library + FILE : string-convert.hh + +*/ + +#ifndef STRING_CONVERT_HH +#define STRING_CONVERT_HH + +/* + ///a class which only has functions. +//#define functor class // cute. docxx fucks up +*/ + +/** + The functor String_convert handles all conversions to/from String (some + time, anyway). + The class is quite empty from data view. + */ +class String_convert { + static int hex2bin_i( String hex_str, String& bin_str_r ); + static int hex2nibble_i( Byte byte ); + static Byte nibble2hex_byte( Byte byte ); +public: + static String bin2dec_str( String bin_str ); + static String bin2hex_str( String bin_str ); + static String dec2bin_str( String str ); + static int bin2_i( String str ); + static String char_str(char c, int n); + static int dec2_i( String dec_str ); + static double dec2_f( String dec_str ); + static String double_str(double f, char const* fmt=0); + static int hex2int_i( String str ); + static String hex2bin_str( String str ); + static String int_str(int i, char const *fmt=0 ); + static String i2hex_str( int i, int length_i, char ch ); + static String i2dec_str( int i, int length_i, char ch ); + static String rational_str(Rational); + static String pointer_str(const void *); + static String longlong_str(long long , char const * fmt = 0); +}; + +#endif // __STRING_CONVERT_HH // diff --git a/flower/lib/include/string-data.hh b/flower/lib/include/string-data.hh new file mode 100644 index 0000000000..ecd7159074 --- /dev/null +++ b/flower/lib/include/string-data.hh @@ -0,0 +1,95 @@ +/* + string-data.hh -- declare String_data + + source file of the LilyPond music typesetter + + (c) 1997 Han-Wen Nienhuys +*/ + + +#ifndef STRINGDATA_HH +#define STRINGDATA_HH + + +/**Internal String struct. + the data itself. Handles simple tasks (resizing, resetting) + */ +class String_data { + // GNU malloc: storage overhead is 8 bytes anyway. + +friend class String_handle; + int maxlen; // maxlen is arraysize-1 + + int length_i_; + Byte* data_byte_p_; + int references; + + /// init to "" + String_data(); + + /// init from src. Conservative allocation. + String_data(String_data const &src); + + ~String_data(); + + /** POST: maxlen >= j. + @param j, maximum stringlength_i_. + contents thrown away. + */ + void setmax(int j); + + /** POST: maxlen >= j. + @param j, maximum stringlength_i_. + contents are kept if it grows. + */ + void remax(int j); + + /// check if writeable. + void OKW(); + + /// check state. + void OK(); + + /// reduce memory usage. + void tighten(); + + // assignment. + void set( Byte const* byte_c_l, int length_i ); + + void set( char const* ch_c_l ); + + /// concatenation. + void append( Byte const* byte_c_l, int length_i ); + + void operator += ( char const* ch_c_l ); + + char const* ch_c_l() const; + + char* ch_l(); + + Byte const* byte_c_l() const; + + // idem, non const + Byte* byte_l(); + + void trunc(int j); + + /** access element. not really safe. Can alter length_i_ without + #String_data# knowing it. */ + Byte &operator [](int j); + Byte operator [](int j) const; + bool is_binary_bo()const; +}; + + + +#ifdef STRING_UTILS_INLINED +#ifndef INLINE +#define INLINE inline +#endif +#include "string-data.inl" + +#endif + + +#endif // STRING_DATA_HH diff --git a/flower/lib/include/string-data.inl b/flower/lib/include/string-data.inl new file mode 100644 index 0000000000..d2b925d0ce --- /dev/null +++ b/flower/lib/include/string-data.inl @@ -0,0 +1,210 @@ +/* -*-C++-*- + String_data.inl -- implement String_data + + source file of Flower lib + + (c) 1997 Han-Wen Nienhuys +*/ + +#ifndef STRINGDATA_INL +#define STRINGDATA_INL + +#include +#include + +#include "string-data.hh" +const int INITIALMAX=8; + +#include + +INLINE void +String_data::OKW() +{ + assert (references == 1); +} + +INLINE void +String_data::OK() +{ + assert(maxlen >= length_i_); + assert(bool(data_byte_p_)); + assert(references >= 1); +} + + +INLINE +String_data::String_data() +{ + references=0; + maxlen = INITIALMAX; + data_byte_p_ = new Byte[maxlen + 1]; + data_byte_p_[0] = 0; + length_i_ = 0; +} + +INLINE +String_data::String_data(String_data const &src) +{ + references=0; + maxlen = length_i_ = src.length_i_; + data_byte_p_ = new Byte[maxlen+1]; // should calc GNU 8byte overhead. + memcpy( data_byte_p_, src.data_byte_p_, length_i_ + 1 ); +} + +INLINE +String_data::~String_data() +{ + assert(references == 0); + delete[] data_byte_p_; +} + +INLINE void +String_data::setmax(int j) +{ + OKW(); + if (j > maxlen) { + delete data_byte_p_; + maxlen = j; + data_byte_p_ = new Byte[maxlen + 1]; + + data_byte_p_[0] = 0; + length_i_ = 0; + } +} + +/* this is all quite hairy: + update of length_i_ + update of maxlen + alloc of buffer + copying of buffer + needs blondification: + split tasks + define change authority +*/ +INLINE void +String_data::remax(int j) +{ + OKW(); + if (j > maxlen) { + Byte *p = new Byte[j + 1]; + memcpy( p, data_byte_p_, ( maxlen = 0 && j <= length_i_); + data_byte_p_[j] = 0; + length_i_ = j; +} + +INLINE bool +String_data::is_binary_bo()const +{ +// return !memchr(data_byte_p_, length_i_, 0); + return ( (int)strlen( (char const*)data_byte_p_ ) != length_i_ ); +} + +INLINE Byte& +String_data::operator [](int j) +{ + assert(j >= 0 && j <= length_i_); + return data_byte_p_[j] ; +} + +INLINE Byte +String_data::operator [](int j) const +{ + assert(j >= 0 && j <= length_i_); + return data_byte_p_[j]; +} + + + + +#endif // __STRING_UTIL_CC // diff --git a/flower/lib/include/string-handle.hh b/flower/lib/include/string-handle.hh new file mode 100644 index 0000000000..5b7a12f648 --- /dev/null +++ b/flower/lib/include/string-handle.hh @@ -0,0 +1,70 @@ +/* + string-handle.hh -- declare String_handle + + source file of the LilyPond music typesetter + + (c) 1997 Han-Wen Nienhuys +*/ + + +#ifndef STRINGHANDLE_HH +#define STRINGHANDLE_HH +#include "fproto.hh" + + +/** + Reference counting for strings. + + handles ref. counting, and provides a very thin interface using + Byte * + + */ +class String_handle { + String_data* data; + + /// decrease ref count. Named kind of like a Tanenbaum semafore + void down(); + + /// increase ref count + void up(String_data *d); + + /** make sure data has only one reference. + POST: data->references == 1 + */ + void copy(); + +public: + String_handle(); + ~String_handle(); + String_handle(String_handle const & src); + + Byte const* byte_c_l() const; + char const* ch_c_l() const; + Byte* byte_l(); + char* ch_l(); + bool is_binary_bo()const; + void operator =(String_handle const &src); + void operator += (char const *s); + Byte operator[](int j) const; + + /** Access elements. WARNING: NOT SAFE + don't use this for loops. Use byte_c_l() + */ + Byte &operator[](int j); + void append( Byte const* byte_c_l, int length_i ); + void set( Byte const* byte_c_l, int length_i ); + void operator = (char const *p); + void trunc(int j); + int length_i() const; +}; + +#ifdef STRING_UTILS_INLINED +#ifndef INLINE +#define INLINE inline +#endif +#include "string-handle.inl" +/* we should be resetting INLINE. oh well. */ +#endif + + +#endif // STRINGHANDLE_HH diff --git a/flower/lib/include/string-handle.inl b/flower/lib/include/string-handle.inl new file mode 100644 index 0000000000..1f1d44ab13 --- /dev/null +++ b/flower/lib/include/string-handle.inl @@ -0,0 +1,156 @@ +/* -*-c++-*- + + stringhandle.inl -- implement String_handle + + source file of Flower lib + + (c) 1997 Han-Wen Nienhuys +*/ + +#ifndef STRINGHANDLE_INL +#define STRINGHANDLE_INL + +#include +#include + +#include "string-data.hh" +#include "string-handle.hh" + +INLINE void +String_handle::down() +{ + if (!(--data->references)) delete data; data = 0; +} + +/// increase ref count +INLINE void +String_handle::up(String_data *d) +{ + data=d; data->references ++; +} + +INLINE void +String_handle::copy() +{ + if (data->references !=1){ + String_data *newdata = new String_data(*data); + down(); + up(newdata); + } +} + +INLINE +String_handle::String_handle() +{ + up(new String_data); +} + +INLINE +String_handle::~String_handle() +{ + down(); +} + +INLINE +String_handle::String_handle(String_handle const & src) +{ + up(src.data); +} + +INLINE Byte* +String_handle::byte_l() +{ + copy(); + return data->byte_l(); +} + +INLINE char* +String_handle::ch_l() +{ + copy(); + return (char*)data->byte_l(); +} + +INLINE Byte +const* String_handle::byte_c_l() const +{ + return data->byte_c_l(); +} + +INLINE char const* +String_handle::ch_c_l() const +{ + return (char const*)data->byte_c_l(); +} + +INLINE void +String_handle::operator =(String_handle const &src) +{ + if (this == &src) + return; + down(); + up(src.data); +} + +INLINE void +String_handle::operator += (char const *s) +{ + copy(); + *data += s; +} + + +INLINE Byte +String_handle::operator[](int j) const +{ + return (*data)[j]; +} + +// !NOT SAFE! +// don't use this for loops. Use byte_c_l() +INLINE Byte & +String_handle::operator[](int j) +{ + copy(); // hmm. Not efficient + return data->byte_l()[j]; +} + +INLINE void +String_handle::append( Byte const* byte_c_l, int length_i ) +{ + copy(); + data->append( byte_c_l, length_i ); +} + +INLINE void +String_handle::set( Byte const* byte_c_l, int length_i ) +{ + copy(); + data->set( byte_c_l, length_i ); +} + +INLINE void +String_handle::operator = (char const *p) +{ + copy(); + data->set( p ); +} + +INLINE void +String_handle::trunc(int j) +{ + copy(); data->trunc(j); +} + +INLINE int +String_handle::length_i() const +{ + return data->length_i_; +} + +INLINE bool +String_handle::is_binary_bo() const { + return data->is_binary_bo(); +} + +#endif diff --git a/flower/lib/include/string.hh b/flower/lib/include/string.hh new file mode 100644 index 0000000000..8cef141169 --- /dev/null +++ b/flower/lib/include/string.hh @@ -0,0 +1,193 @@ +/* + + FILE : string.hh -- declare String + + Rehacked by HWN 3/nov/95 + removed String & 's + introduced Class String_handle + */ + +#ifndef STRING_HH +#define STRING_HH + + +#include +#include +#include + +#include "string-handle.hh" + +/** + + Intuitive string class. provides +\begin{itemize} +\item + ref counting through #String_handle# +\item + conversion from bool, int, double, char* , char. +\item + to be moved to String_convert: + conversion to int, upcase, downcase + +\item + printable. + +\item + indexing (index_i, index_any_i, last_index_i) + +\item + cutting (left_str, right_str, mid_str) + +\item + concat (+=, +) + +\item + signed comparison (<, >, ==, etc) + +\item + No operator[] is provided, since this would be enormously slow. If needed, + convert to char const* . +\end{itemize} + +*/ +class String +{ +protected: + String_handle strh_; + + bool null_terminated(); + +public: + + /** init to empty string. This is needed because other + constructors are provided.*/ + String() { } + String(Rational); + + /// String s = "abc"; + String( char const* source ); + String( Byte const* byte_c_l, int length_i ); + + /// "ccccc" + String( char c, int n = 1 ); + + String( int i , char const *fmt=0); + String ( double f , char const* fmt =0); + /// 'true' or 'false' + String(bool ); + + /// return a "new"-ed copy of contents + Byte* copy_byte_p() const; // return a "new"-ed copy of contents + + char const* ch_c_l() const; + Byte const* byte_c_l() const; + char* ch_l(); + Byte* byte_l(); + + /// deprecated; use ch_c_l() + operator char const* () const { return ch_c_l(); } + + String &operator =( const String & source ); + + /// concatenate s + void operator += (char const* s) { strh_ += s; } + void operator += (String s); + + void append(String); + void prepend(String); + + char operator []( int n ) const { return strh_[n]; } + + /// return n leftmost chars + String left_str( int n ) const; + + /// return n rightmost chars + String right_str( int n ) const; + + /// return uppercase of *this + String upper_str() const; + + /// return lowercase of *this + String lower_str() const; + + /// return the "esrever" of *this + String reversed_str() const; + + + /// return a piece starting at index_i (first char = index_i 0), length n + String mid_str(int index_i, int n ) const; + + /// cut out a middle piece, return remainder + String nomid_str(int index_i, int n ) const; + + /// signed comparison, analogous to memcmp; + static int compare_i(const String& s1,const String& s2); + + /// index of rightmost c + int index_last_i( char c) const; + + /// index of rightmost element of string + int index_last_i( char const* string ) const; + + int index_i(char c ) const; + int index_i(String ) const; + int index_any_i(String ) const; + + void to_upper(); + void to_lower(); + /// provide Stream output + void print_on(ostream& os) const; + + /// the length of the string + int length_i() const; + + // ***** depreciated + int len() const { + return length_i(); + } + + /// convert to an integer + int value_i() const; + + /// convert to a double + double value_f() const; +}; + +#include "compare.hh" + +instantiate_compare(const String &, String::compare_i); + +// because char const* also has an operator ==, this is for safety: +inline bool operator==(String s1, char const* s2){ + return s1 == String(s2); +} +inline bool operator==(char const* s1, String s2) +{ + return String(s1)==s2; +} +inline bool operator!=(String s1, char const* s2 ) { + return s1!=String(s2); +} +inline bool operator!=(char const* s1,String s2) { + return String(s2) !=s1; +} + + +inline String +operator + (String s1, String s2) +{ + s1 += s2; + return s1; +} + +inline ostream & +operator << ( ostream& os, String d ) +{ + d.print_on(os); + return os; +} + + +// String quoteString(String message, String quote); + +#endif diff --git a/flower/lib/include/text-db.hh b/flower/lib/include/text-db.hh new file mode 100644 index 0000000000..3535a84f8f --- /dev/null +++ b/flower/lib/include/text-db.hh @@ -0,0 +1,55 @@ +#ifndef TEXTDB_HH +#define TEXTDB_HH + +#include "data-file.hh" + +/**a "const" Array. Contents can't be changed. do "#" comments, read quote enclosed fields */ + +class Text_record : Array +{ + int line_no; + String filename; + +public: + Text_record() { } // needed because of other ctor + + /// report an error in this line. + message(String s) { + cerr << '\n'<< filename << ": "<< line_no << s << "\n"; + } + String operator[](int j) { + return Array::operator[](j); + } + + Text_record(Array s, String fn, int j) : Array(s) { + filename = fn; line_no = j; + } + Array::size; +}; + +/** abstraction for a datafile. + add a subrec/fieldsep/record separator + */ + +class Text_db : private Data_file +{ + void gobble_leading_white(); +public: + /// get a line with records + Text_record get_record(); + + Text_db(String fn):Data_file(fn) { } + Data_file::error; + bool eof(); + + /// get next line. + Text_record operator++(int) { + return get_record(); + } + /// are we done yet? + operator bool() { + return !eof(); + } +}; + +#endif diff --git a/flower/lib/include/text-stream.hh b/flower/lib/include/text-stream.hh new file mode 100644 index 0000000000..437f8698c7 --- /dev/null +++ b/flower/lib/include/text-stream.hh @@ -0,0 +1,74 @@ + +#ifndef TEXTSTR_HH +#define TEXTSTR_HH + +#include +#include +#include "string.hh" +#include "varray.hh" + +/** + line counting input stream. + a stream for textfiles. linecounting. Thin interface getchar and + ungetchar. (ungetc is unlimited) + + should protect get and unget against improper use +*/ + + +class Text_stream +{ + int line_no; + + // could just have used streams. + FILE *f; + Array pushback; + String name; + + public: + Text_stream(String fn); + String get_name() { return name; } + bool eof() { + return feof(f); + } + bool eol() { + return (peek() == '\n'); + } + char peek() { + char c = get(); + unget(c); + return c; + } + int line(){ + return line_no; + } + + char get() { + char c; + + if (pushback.empty()) + c = getc(f); + else + c = pushback.pop(); + + if (c =='\n') + line_no++; + return c; + } + void unget(char c) { + if (c =='\n') + line_no--; + pushback.push(c); + } + ~Text_stream (){ + if (!eof()) + cerr <<__FUNCTION__<< ": closing unended file"; + + fclose(f); + } + + /// GNU format message. + void message(String s); +}; + +#endif diff --git a/flower/lib/include/unionfind.hh b/flower/lib/include/unionfind.hh new file mode 100644 index 0000000000..fbaa51e731 --- /dev/null +++ b/flower/lib/include/unionfind.hh @@ -0,0 +1,25 @@ +#ifndef UNIONFIND_HH +#define UNIONFIND_HH +#include "varray.hh" + +/* + which points of a graph are connected?. + Union find, a standard algorithm: + + Union_find represents an undirected graph of N points. You can + connect two points using #connect()#. #find(i)# finds a uniquely + determined representant of the equivalence class of points + connected to #i#. + + */ +struct Union_find { + void connect(int i, int j); + int find(int i); + bool equiv(int i, int j) { return find(i) == find(j); } + Union_find(int sz); + +private: + Array classes; + +}; +#endif diff --git a/flower/lib/include/varray.hh b/flower/lib/include/varray.hh new file mode 100644 index 0000000000..febf3e7601 --- /dev/null +++ b/flower/lib/include/varray.hh @@ -0,0 +1,186 @@ +/* + (c) Han-Wen Nienhuys 1995,96 + + Distributed under GNU GPL +*/ + +#ifndef ARRAY_H +#define ARRAY_H +#include + +/// copy a bare (C-)array from #src# to #dest# sized #count# +template +inline void arrcpy(T*dest, T*src, int count) { + for (int i=0; i < count ; i++) + *dest++ = *src++; +} + + +/** + Scaleable array/stack template, for a type T with default constructor. + + + This template implements a scaleable vector. With (or without) range + checking. It may be flaky for objects with complicated con- and + destructors. The type T should have a default constructor. It is + best suited for simple types, such as int, double or String, it + provides a paranoidly safe replacement for the new T[int] construct. + + It uses stack terminology, (push, pop, top), and can be used as a stack. + + + */ +template +class Array { +protected: + /// maximum length of array. + int max; + + /// the data itself + T *thearray; + + /// stretch or shrink array. + void remax(int newmax) { + T* newarr = new T[newmax]; + size_ = (newmax < size_) ? newmax : size_; + arrcpy(newarr, thearray, size_); + + delete[] thearray; + thearray = newarr; + max = newmax; + } + int size_; + +public: + /// check invariants + void OK() const { + assert(max >= size_ && size_ >=0); + if (max) assert(thearray); + } + /** report the size_. + @see {setsize_} + */ + int size() const { return size_; } + + /// POST: size() == 0 + void clear() { size_ = 0; } + + Array() { thearray = 0; max =0; size_ =0; } + + + /** set the size_ to #s#. + POST: size() == s. + Warning: contents are unspecified */ + void set_size(int s) { + if (s >= max) remax(s); + size_ = s; + } + + ~Array() { delete[] thearray; } + + /// return a "new"ed copy of array + T* copy_array() const { + T* Tarray = new T[size_]; + arrcpy(Tarray, thearray, size_); + return Tarray; + } + // depracated + operator T* () const { + return copy_array(); + } + void operator=(Array const & src) { + set_size (src.size_); + arrcpy(thearray,src.thearray, size_); + } + Array(const Array & src) { + thearray = src.copy_array(); + max = size_ = src.size_; + } + + /// tighten array size_. + void precompute () { remax(size_); } + + /// this makes Array behave like an array + T &operator[] (const int i) const { + assert(i >=0&&i=0 && j<= size_); + set_size(size_+1); + for (int i=size_-1; i > j; i--) + thearray[i] = thearray[i-1]; + thearray[j] = k; + } + void del(int i) { + assert(i >=0&& i < size_); + arrcpy(thearray+i, thearray+i+1, size_-i-1); + size_--; + } + // quicksort. + void sort (int (*compare)( T const&,T const&), + int lower = -1, int upper = -1 ) { + if (lower < 0) { + lower = 0 ; + upper = size()-1; + } + if (lower >= upper) + return; + swap(lower, (lower+upper)/2); + int last = lower; + for (int i= lower +1; i <= upper; i++) + if (compare(thearray[i], thearray[lower]) < 0 ) + swap( ++last,i); + swap(lower, last); + sort(compare, lower, last-1); + sort(compare, last+1, upper); + } + void concat(Array const &src) { + int s = size_; + set_size(size_ + src.size_); + arrcpy(thearray+s,src.thearray, src.size_); + } + Array subvec(int lower, int upper) { + assert(lower >= 0 && lower <=upper&& upper <= size_); + Array r; + int s =upper-lower; + r.set_size(s); + arrcpy(r.thearray, thearray + lower, s); + return r; + } +}; + +#endif diff --git a/flower/lib/include/vector.hh b/flower/lib/include/vector.hh new file mode 100644 index 0000000000..4d91397cc6 --- /dev/null +++ b/flower/lib/include/vector.hh @@ -0,0 +1,111 @@ +#ifndef VECTOR_HH +#define VECTOR_HH + +#include +#include "real.hh" +#include "varray.hh" + +class Dstream; +class String; +void set_matrix_debug(Dstream&ds); + +/** a row of numbers. + a vector. Storage is handled in Array, Vector only does the mathematics. + */ +class Vector { + Array dat; +public: + void OK() const { dat.OK();} + int dim() const { return dat.size(); } + Vector() { } + Vector(Array d ); + Vector(const Vector&n); + Vector(int n) { + dat.set_size(n); + fill(0); + } + void insert(Real v, int i) { + dat.insert(v,i); + } + void del(int i) { dat.del(i); } + operator String() const; + void fill(Real r) { + for (int i=0; i < dim(); i++) + dat[i] =r; + } + + void operator +=(Vector v) { + assert(v.dim() == dim()); + for (int i=0; i < dim(); i++) + dat[i] += v.dat[i]; + } + + void operator /=(Real a) { + (*this) *= 1/a; + } + + void operator *=(Real a) { + for (int i=0; i < dim(); i++) + dat[i] *= a; + } + + void operator -=(Vector v) { + assert(v.dim() == dim()); + for (int i=0; i < dim(); i++) + dat[i] -= v(i); + } + + Real &operator()(int i) { return dat[i]; } + Real operator()(int i) const { return dat[i]; } + Real elem(int i) { return dat[i]; } + Real operator *(Vector v) const { + Real ip=0; + assert(v.dim() == dim()); + for (int i=0; i < dim(); i++) + ip += dat[i] *v(i); + return ip; + } + Vector operator-() const; + Real norm() { + return sqrt(norm_sq() ); + } + Real norm_sq() { + return ((*this) * (*this)); + } + operator Array () { return dat; } + void print() const; + /// set to j-th element of unit-base + void set_unit(int j) ; +}; + +inline Vector +operator+(Vector a, Vector const &b) { + a += b; + return a; +} + +inline Vector +operator-(Vector a, Vector const &b) { + a -= b; + return a; +} + +inline Vector +operator*(Vector v, Real a) { + v *= a; + return v; +} + +inline Vector +operator*( Real a,Vector v) { + v *= a; + return v; +} + +inline Vector +operator/(Vector v,Real a) { + v *= 1/a; + return v; +} + +#endif diff --git a/flower/lib/include/vsmat.hh b/flower/lib/include/vsmat.hh new file mode 100644 index 0000000000..283b1e567b --- /dev/null +++ b/flower/lib/include/vsmat.hh @@ -0,0 +1,141 @@ +#ifndef VSMAT_HH +#define VSMAT_HH +#include "varray.hh" +#include "real.hh" +/** base class for interface with matrix storageclasses. There are no + iterators for matrixclasses, since matrices are (like arrays) + explicitly int-indexed. + + Iteration is provided by *_next, *_ok, which update and check both + index variables simultaneously. + + TODO + determine type of product matrix. + +*/ +class virtual_smat { + + +public: + /// check invariants + virtual void OK() const=0; + + /// height of matrix + virtual int rows() const = 0; + + /// width of matrix + virtual int cols() const = 0; + + + /** set the size. contents lost. + PRE + i >=0, j>=0 + */ + virtual void set_size(int i, int j) = 0; + + /**set the size to square dimen. contents lost + PRE + i>=0 + */ + virtual void set_size(int i) = 0; + /**set the size to i. + + keep contents. If enlarged contents unspecified + + PRE + i>=0, j>=0 + + */ + virtual void resize(int i, int j) = 0; + + /** + set the size to square dimen. contents kept + Keep contents. If enlarged contents are unspecified + + PRE + i>=0 + */ + virtual void resize(int i) = 0; + + + /** + access an element. + + Generate an errormessage, if this happens + in the 0-part of a sparse matrix. + */ + + virtual Real& elem(int i,int j) = 0; + + /// access a element, no modify + virtual const Real& elem(int i, int j) const = 0; + +#if 1 + virtual Array row(int i) const = 0; + virtual Array column(int j) const = 0; +#endif + + + /** + add a row to the matrix before row k. Contents + of added row are unspecified + + 0 <= k <= rows() + */ + virtual void insert_row(int k)=0; + + + /** + delete a row from this matrix. + + PRE + 0 <= k < rows(); + */ + virtual void delete_row(int k)=0; + virtual void delete_column(int k)=0; + virtual ~virtual_smat() { } + virtual virtual_smat *clone()=0; + + + + /** + at end of matrix?. when doing loop + + for(i=0; i + */ +#include +#include +#include +#include "lgetopt.hh" + +long +Getopt_long::intarg() +{ + long l; + if (sscanf(optarg, "%ld", &l) != 1) + report(E_ILLEGALARG); + + return l; +} + +Long_option_init * +Getopt_long::parselong() +{ + const char *optnm = argv[optind] + 2 ; + assert(*optnm); + + char *endopt = strchr(optnm, '='); + int searchlen = (endopt) ? endopt - optnm : strlen(optnm); + + beet=0; + for (int i=0; i< table_len; i++) { + const char *ln = the_opts[i].longname; + + if (ln && !strncmp(ln, optnm, searchlen)) { + beet = the_opts+i; + break; + } + } + + if (!beet) { + report(E_UNKNOWNOPTION); + return 0; + } + optind++; + optindind = 0; + + + if (beet->take_arg) { + if (endopt) + optarg = endopt +1; // a '=' + else { + optarg = argv[optind]; + optind++; + } + if (!optarg) + report(E_ARGEXPECT); + + } else { + optarg = 0; + if (endopt) + report(E_NOARGEXPECT); + } + + return beet; +} + + +ostream & +Long_option_init::printon(ostream &errorout) +{ + if (shortname) + errorout <<"-" << shortname; + if (shortname && longname) + errorout << ", "; + if (longname) + errorout << "`--" << longname << "'"; + return errorout; +} + +// report an error, GNU style. +void +Getopt_long::report(Errorcod c) +{ + error = c; + if (!errorout) + return; + + *errorout << argv[0] << ": "; + switch (c) { + case E_ARGEXPECT: + *errorout<< "option "; + beet->printon(*errorout); + *errorout << "requires an argument"<longname << "' does not allow an argument"<printon(*errorout); + *errorout << '\n'; + default: + assert(false); + } + exit(2); +} + +Long_option_init * +Getopt_long::parseshort() +{ + char c=argv[optind][optindind]; + beet=0; + assert(c); + + for (int i=0; i < table_len; i++) + if (the_opts[i].shortname == c) { + beet = the_opts+i; + break; + } + + if (!beet){ + report(E_UNKNOWNOPTION); + return 0; + } + + optindind++; + if (!beet->take_arg){ + optarg = 0; + return beet; + } + optarg = argv[optind] + optindind; + + optind ++; + optindind = 0; + + if (!optarg[0]) { + optarg = argv[optind]; + optind ++; + } + if (!optarg) { + report(E_ARGEXPECT); + } + + return beet; +} + +Long_option_init * +Getopt_long::operator()() { + if (!next()) + return 0; + + if (optindind) + return parseshort(); + + if (argv[optind][0] != '-') + return 0; + + if (argv[optind][1] == '-') {// what to do with "command -- bla" + return parselong(); + } else { + optindind = 1; + return parseshort(); + } +} + +Getopt_long::Getopt_long(int c, char **v, Long_option_init *lo) +{ + the_opts = lo; + errorout = &cerr; + argv = v; + argc = c; + optind = 1; + optindind = 0; + + // reached end of option table? + int i; + for (i = 0; the_opts[i].longname ||the_opts[i].shortname; i++) + ; + table_len = i; +} + +bool +Getopt_long::next() +{ + + error = E_NOERROR; + while (optind < argc && !argv[optind][optindind]) { + optind++; + optindind = 0; + } + return (optind < argc); +} + +char * +Getopt_long::current_arg() +{ + if (optind >= argc) + return 0; + char * a = argv[optind]; + return a + optindind; +} + +char * +Getopt_long::get_next_arg() +{ + char * a = current_arg(); + if ( a) { + optind ++; + optindind = 0; + } + return a; +} diff --git a/flower/lib/libc-extension.cc b/flower/lib/libc-extension.cc new file mode 100644 index 0000000000..f9a255683e --- /dev/null +++ b/flower/lib/libc-extension.cc @@ -0,0 +1,113 @@ +/* + libc-extension.cc -- implement some string.h extensions + + source file of the flowerlib + + (c) 1997 Han-Wen Nienhuys +*/ +#include +#include +#include +#include "libc-extension.hh" + +/* + compensate for lacking libc functions. + */ +char* +strnlwr( char* start_l ,int n) +{ + char * p = start_l + n; + while ( --p >= start_l) { + *p = tolower( *p ); /* a macro on some compilers */ + } + return start_l; +} + +char* +strnupr( char* start_l, int n) +{ + char * p = start_l + n; + while ( --p >= start_l) { + *p = toupper( *p ); /* a macro on some compilers */ + } + return start_l; +} + +#ifndef HAVE_MEMMEM + +/** locate a substring. #memmem# finds the first occurrence of + #needle# in #haystack# + */ + +char * +memmem(const Byte * haystack, int haystack_len, + const Byte *needle,int needle_len) +{ + const Byte * end_haystack = haystack + haystack_len - needle_len; + const Byte * end_needle = needle + needle_len ; + + /* Ahhh ... Some minimal lowlevel stuff. This *is* nice; Varation + is the spice of life */ + while (haystack < end_haystack) { + const Byte *subneedle_l = needle; + const Byte *subhaystack_l = haystack; + while (subneedle_l < end_needle) { + if (*subneedle_l++ != *subhaystack_l++) + goto next; // yeah. I should be prosecuted. + } + + // completed the needle. Gotcha. + return (char*) haystack; + next: + haystack++; + } + return 0; +} +#endif + +Byte * +memrchr(const Byte * p, int n, char c) +{ + const Byte * q = p+n; + while (q > p) { + if (*--q == c) + return (Byte*)q; + } + return 0; +} + + +template +inline void +my_swap(T &t1, T &t2, T &tmp) +{ + tmp = t1; + t1 = t2; + t2 = tmp; +} + +Byte* +strrev( Byte* byte_l, int length_i ) +{ + Byte tmp_byte; + + Byte* left_l = byte_l; + Byte* right_l = byte_l + length_i; + + while ( right_l > left_l ) { + my_swap(*right_l-- , *left_l++ , tmp_byte); + } + return byte_l; +} + +#ifndef HAVE_SNPRINTF +int snprintf ( char *str, size_t n, + const char *format, ... ) +{ + va_list ap; + va_start(ap, format); + int i = vsprintf(str, format, ap); + va_end(ap); + return i; +} +#endif diff --git a/flower/lib/matdebug.cc b/flower/lib/matdebug.cc new file mode 100644 index 0000000000..bcc2843bca --- /dev/null +++ b/flower/lib/matdebug.cc @@ -0,0 +1,63 @@ +#include "dstream.hh" +#include "matrix.hh" + +static Dstream *dout = 0; + +/** + Set the debugging output. Will not delete/swallow argument. + */ +void set_matrix_debug(Dstream&ds) +{ + dout = &ds; +} + +Matrix::operator String() const +{ + String s; +#ifndef NPRINT + s="matrix {\n"; + for (int i=0; i< rows(); i++){ + for (int j = 0; j < cols(); j++) { + s+= String(dat->elem(i,j), "%6f "); + } + s+="\n"; + } + s+="}\n"; +#endif + return s; +} + + +void +Matrix::print() const +{ +#ifndef NPRINT + if (!dout) + return; + *dout << *this; +#endif +} + +Vector::operator String() const +{ + String s; +#ifndef NPRINT + s="vector ["; + for (int i=0; i < dim(); i++) { + s += String(dat[i], "%6f") + String(' '); + } + s+="]"; +#endif + return s; +} + + +void +Vector::print() const +{ +#ifndef NDEBUG + if (!dout) + return; + *dout << *this<<'\n'; +#endif +} diff --git a/flower/lib/matrix.cc b/flower/lib/matrix.cc new file mode 100644 index 0000000000..63bd85a33c --- /dev/null +++ b/flower/lib/matrix.cc @@ -0,0 +1,240 @@ +#include "matrix.hh" + +Real +Matrix::norm() const +{ + Real r =0.0; + for (int i=0, j=0; dat->mult_ok(i,j); dat->mult_next(i,j)) + r += sqr(dat->elem(i,j)); + return sqrt(r); +} + +void +Matrix::fill(Real r) +{ + for (int i=0, j=0; dat->mult_ok(i,j); dat->mult_next(i,j)) + dat->elem(i,j)=r; +} + +void +Matrix::set_diag(Real r) +{ + for (int i=0, j=0; dat->mult_ok(i,j); dat->mult_next(i,j)) + dat->elem(i,j)=(i==j) ? r: 0.0; +} + +void +Matrix::set_diag(Vector d) +{ + for (int i=0, j=0; dat->mult_ok(i,j); dat->mult_next(i,j)) + dat->elem(i,j)=(i==j) ? d(i): 0.0; +} + +void +Matrix::operator+=(const Matrix&m) +{ + assert(m.cols() == cols()); + assert(m.rows() == rows()); + for (int i=0, j=0; dat->mult_ok(i,j); dat->mult_next(i,j)) + dat->elem(i,j) += m(i,j); +} + +void +Matrix::operator-=(const Matrix&m) +{ + assert(m.cols() == cols()); + assert(m.rows() == rows()); + for (int i=0, j=0; dat->mult_ok(i,j); dat->mult_next(i,j)) + dat->elem(i,j) -= m(i,j); +} + + +void +Matrix::operator*=(Real a) +{ + for (int i=0, j=0; dat->mult_ok(i,j); dat->mult_next(i,j)) + dat->elem(i,j) *= a; +} + +void +Matrix::operator=(const Matrix&m) +{ + if (&m == this) + return ; + delete dat; + dat = m.dat->clone(); +} + +Matrix::Matrix(const Matrix &m) +{ + m.OK(); + + dat = m.dat->clone(); +} + + +Matrix::Matrix(int n, int m) +{ + dat = virtual_smat::get_full(n,m); + fill(0); +} + +Matrix::Matrix(int n) +{ + dat = virtual_smat::get_full(n,n); + fill(0); +} + +Matrix::Matrix(Vector v, Vector w) +{ + dat = virtual_smat::get_full(v.dim(), w.dim()); + for (int i=0, j=0; dat->mult_ok(i,j); dat->mult_next(i,j)) + dat->elem(i,j)=v(i)*w(j); +} + + +Vector +Matrix::row(int k) const +{ + int n=cols(); + + + Vector v(n); + for(int i=0; i < n; i++) + v(i)=dat->elem(k,i); + + return v; +} + +Vector +Matrix::col(int k) const +{ + int n=rows(); + Vector v(n); + for(int i=0; i < n; i++) + v(i)=dat->elem(i,k); + return v; +} + +Vector +Matrix::left_multiply(const Vector& v) const +{ + Vector dest(v.dim()); + assert(dat->cols()==v.dim()); + for (int i=0, j=0; dat->mult_ok(i,j); dat->mult_next(i,j)) + dest(i)+= dat->elem(j,i)*v(j); + return dest; +} + +Vector +Matrix::operator *(const Vector& v) const +{ + Vector dest(rows()); + assert(dat->cols()==v.dim()); + for (int i=0, j=0; dat->mult_ok(i,j); dat->mult_next(i,j)) + dest(i)+= dat->elem(i,j)*v(j); + return dest; +} + +Matrix +operator /(Matrix const& m1,Real a) +{ + Matrix m(m1); + m /= a; + return m; +} + +void +Matrix::transpose() // delegate to storage? +{ + for (int i=0, j=0; dat->mult_ok(i,j); dat->mult_next(i,j)) { + if (i >= j) + continue; + Real r=dat->elem(i,j); + dat->elem(i,j) = dat->elem(j,i); + dat->elem(j,i)=r; + } +} + +Matrix +Matrix::operator-() const +{ + OK(); + Matrix m(*this); + m*=-1.0; + return m; +} + +Matrix +Matrix::transposed() const +{ + Matrix m(*this); + m.transpose(); + return m; +} + + +/* should do something smarter: bandmatrix * bandmatrix is also banded matrix. */ +Matrix +operator *(const Matrix &m1, const Matrix &m2) +{ + Matrix result(m1.rows(), m2.cols()); + result.set_product(m1,m2); + return result; +} + +void +Matrix::set_product(const Matrix &m1, const Matrix &m2) +{ + assert(m1.cols()==m2.rows()); + assert(cols()==m2.cols() && rows()==m1.rows()); + + for (int i=0, j=0; dat->mult_ok(i,j); + dat->mult_next(i,j)) { + Real r=0.0; + for (int k = 0; k < m1.cols(); k++) + r += m1(i,k)*m2(k,j); + dat->elem(i,j)=r; + } +} + +void +Matrix::insert_row(Vector v, int k) +{ + assert(v.dim()==cols()); + dat->insert_row(k); + for (int j=0; j < cols(); j++) + dat->elem(k,j)=v(j); +} + + +void +Matrix::swap_columns(int c1, int c2) +{ + assert(c1>=0&& c1 < cols()&&c2 < cols() && c2 >=0); + for (int i=0; i< rows(); i++) { + Real r=dat->elem(i,c1); + dat->elem(i,c1) = dat->elem(i,c2); + dat->elem(i,c2)=r; + } +} + +void +Matrix::swap_rows(int c1, int c2) +{ + assert(c1>=0&& c1 < rows()&&c2 < rows() && c2 >=0); + for (int i=0; i< cols(); i++) { + Real r=dat->elem(c1,i); + dat->elem(c1,i) = dat->elem(c2,i); + dat->elem(c2,i)=r; + } +} + + +int +Matrix::dim() const +{ + assert(cols() == rows()); + return rows(); +} + diff --git a/flower/lib/path.cc b/flower/lib/path.cc new file mode 100644 index 0000000000..c79962f00f --- /dev/null +++ b/flower/lib/path.cc @@ -0,0 +1,77 @@ +/* + path.cc - manipulation of paths and filenames. +*/ +#include +#include "path.hh" + +#ifndef PATHSEP +#define PATHSEP '/' +#endif + +/** + @param path the original full filename + @return 4 components of the path. They can be empty +*/ +void +split_path(String path, + String &drive, String &dirs, String &filebase, String &extension) +{ + // peel off components, one by one. + int di = path.index_i(':'); + if (di >= 0) + { + drive = path.left_str(di + 1); + path = path.right_str(path.len() - di -1); + } + else + drive = ""; + + di = path.index_last_i(PATHSEP); + if (di >=0) + { + dirs = path.left_str(di + 1); + path = path.right_str(path.len()-di -1); + } + else + dirs = ""; + + di = path.index_last_i('.'); + if (di >= 0) + { + filebase = path.left_str(di); + extension =path.right_str(path.len()-di); + } + else + { + extension = ""; + filebase = path; + } +} + +File_path::File_path(String pref) +{ + add("."); + add(pref); +} + + +/** find a file. + It will search in the current dir, in the construction-arg, and + in any other added path, in this order. + */ +String +File_path::find(String nm) +{ + for (int i=0; i < size(); i++) { + String path = (*this)[i]; + path+= "/"+nm; + + + FILE *f = fopen(path, "r"); // ugh! + if (f) { + fclose(f); + return path; + } + } + return ""; +} diff --git a/flower/lib/scalar.cc b/flower/lib/scalar.cc new file mode 100644 index 0000000000..5edd9e997f --- /dev/null +++ b/flower/lib/scalar.cc @@ -0,0 +1,57 @@ +#include +#include +#include "scalar.hh" + +Scalar::Scalar(Rational r) + :String(r) +{ + +} + +Scalar::operator Rational() +{ + int p = index_i('/'); + if (p == -1) + return int(*this); + + String s2 = right_str(len()-p-1); + String s1 = left_str(p); + + return Rational(s1.value_i(), s2.value_i()); +} + +bool +Scalar::isnum() +{ + int conv = false; + if (len()) { + long l =0; + conv = sscanf(strh_.ch_c_l(), "%ld", &l); + } + return len() && conv; +} + +Scalar::operator Real() +{ + assert (isnum()); + return value_f(); +} + +Scalar::operator int() +{ + assert (isnum()); + return value_i(); +} + + +Scalar::operator bool() const +{ + if (!len()) + return false; + if (*this == "0") + return false; + String u (*this); + if ( u.upper_str() == "FALSE") + return false; + return true; +} diff --git a/flower/lib/smat.cc b/flower/lib/smat.cc new file mode 100644 index 0000000000..dcc61ce44e --- /dev/null +++ b/flower/lib/smat.cc @@ -0,0 +1,181 @@ +#include "smat.hh" + +void +Full_storage::operator=(Full_storage const &fs) +{ + resize(fs.h, fs.w); + OK(); + fs.OK(); + for (int i=0; i= h && maxw >= w); + assert(h >= 0 && w >= 0); + assert(els||!maxh); +#endif +} +void +Full_storage::resize_cols(int newh) +{ + if (newh <= maxh) { + h=newh; + return; + } + + Real ** newa=new Real*[newh]; + int j=0; + for (; j < h; j++) + newa[j] = els[j]; + for (; j < newh; j++) + newa[j] = new Real[maxw]; + delete[] els; + els=newa; + + h = maxh = newh; +} + +void +Full_storage::resize_rows(int neww) +{ + if (neww <= maxw) { + w=neww; + return; + } + for (int i=0; i < maxh ; i++) { + Real* newa = new Real[neww]; + for (int k=0; k < w; k++) + newa[k] = els[i][k]; + + delete[] els[i]; + els[i] = newa; + } + w = maxw = neww; +} + +Full_storage::~Full_storage() { + for (int i=0; i < maxh; i++) + delete [] els[i]; + delete[] els; +} + +void +Full_storage::resize(int rows, int cols) +{ + OK(); + resize_cols(rows); + resize_rows(cols); + +} + + +bool +Full_storage::mult_ok(int i, int j) const +{ + return valid(i,j); +} + +bool +Full_storage::trans_ok(int i, int j) const +{ + return valid(i,j); +} + + +void +Full_storage::trans_next(int &i, int &j) const +{ + assert(trans_ok(i,j)); + i++; + if (i >= h) { + i=0; + j ++; + } +} + +void +Full_storage::mult_next(int &i, int &j) const +{ + assert(mult_ok(i,j)); + j++; + if (j >= w) { + j=0; + i++; + } +} + +void +Full_storage::delete_column(int k) +{ + assert(0 <= k &&k k ; i--) + for (int j=0; j +Full_storage::row(int n) const +{ + Array r; + for (int j = 0; j < w; j++) + r.push(els[n][j]); + return r; +} + +Array +Full_storage::column(int n) const +{ + + Array r; + for (int i = 0; i +#include "libc-extension.hh" +#include "string.hh" +#include "string-convert.hh" + +/** + a safe length for stringconversion buffers + + worst case would be %f printing HUGE (or 1/HUGE), which is approx + 2e318, this number would have approx 318 zero's in its string. + + Should enlarge buff dynamically. + @see + man 3 snprintf + */ +static const int STRING_BUFFER_LEN=1024; + +String +String_convert::bin2hex_str( String bin_str ) +{ + String str; + Byte const* byte_c_l = bin_str.byte_c_l(); + for ( int i = 0; i < bin_str.length_i(); i++ ) { + str += (char)nibble2hex_byte( *byte_c_l >> 4 ); + str += (char)nibble2hex_byte( *byte_c_l++ ); + } + return str; +} + +int +String_convert::bin2_i( String bin_str ) +{ + assert( bin_str.length_i() <= 4 ); + + int result_i = 0; + for ( int i = 0; i < bin_str.length_i(); i++ ) { + result_i <<= 8; + result_i += (Byte)bin_str[ i ]; + } + return result_i; +} + +// breendet imp from String +int +String_convert::dec2_i( String dec_str ) +{ + if ( !dec_str.length_i() ) + return 0; + + long l = 0; + int conv = sscanf( dec_str.ch_c_l(), "%ld", &l ); + assert( conv ); + + return (int)l; +} + +String +String_convert::longlong_str(long long ll, char const* fmt) +{ + char buffer[STRING_BUFFER_LEN]; + snprintf(buffer, STRING_BUFFER_LEN, + (fmt ? fmt : "%Ld"), ll ); // assume radix 10 + return String(buffer); + +} +// breendet imp from String +double +String_convert::dec2_f( String dec_str ) +{ + if ( !dec_str.length_i() ) + return 0; + double d = 0; + int conv = sscanf( dec_str.ch_c_l(), "%lf", &d ); + assert( conv ); + return d; +} + +int +String_convert::hex2bin_i( String hex_str, String& bin_str_r ) +{ + if ( hex_str.length_i() % 2 ) + hex_str = "0" + hex_str; + + bin_str_r = ""; + Byte const* byte_c_l= hex_str.byte_c_l(); + int i = 0; + while ( i < hex_str.length_i() ) { + int high_i = hex2nibble_i( *byte_c_l++ ); + int low_i = hex2nibble_i( *byte_c_l++ ); + if ( high_i < 0 || low_i < 0 ) + return 1; // illegal char + bin_str_r += String( (char)( high_i << 4 | low_i ), 1 ); + i += 2; + } + return 0; +} + +String +String_convert::hex2bin_str( String hex_str ) +{ + String str; +// silly, asserts should alway be "on"! +// assert( !hex2bin_i( hex_str, str ) ); + int error_i = hex2bin_i( hex_str, str ); + assert( !error_i ); + return str; +} + +int +String_convert::hex2nibble_i( Byte byte ) +{ + if ( byte >= '0' && byte <= '9' ) + return byte - '0'; + if ( byte >= 'A' && byte <= 'F' ) + return byte - 'A' + 10; + if ( byte >= 'a' && byte <= 'f') + return byte - 'a' + 10; + return -1; +} + +// stupido. Should use int_str() +String +String_convert::i2dec_str( int i, int length_i, char ch ) +{ + char fill_ch = ch; + if ( fill_ch) + fill_ch = '0'; + + // ugh + String dec_str( i ); + + // ugh + return String( fill_ch, length_i - dec_str.length_i() ) + dec_str; +} + + +// stupido. Should use int_str() +String +String_convert::i2hex_str( int i, int length_i, char ch ) +{ + String str; + if ( !i ) + str = "0"; + while ( i ) { + str = String( ( i % 16 )["0123456789abcdef"] ) + str; + i /= 16; + } + if ( str.length_i() < length_i ) + str = String( ch, length_i - str.length_i() ) + str; + return str; +} + +Byte +String_convert::nibble2hex_byte( Byte byte ) +{ + if ( ( byte & 0x0f ) <= 9 ) + return ( byte & 0x0f ) + '0'; + else + return ( byte & 0x0f ) - 10 + 'a'; +} +/** + Convert an integer to a string + + @param + #fmt# is a printf style format, default assumes "%d" as format. + */ +String +String_convert::int_str(int i, char const* fmt) +{ + char buffer[STRING_BUFFER_LEN]; + snprintf(buffer, STRING_BUFFER_LEN, + (fmt ? fmt : "%d"), i ); // assume radix 10 + return String(buffer); +} + +/** + Convert a double to a string. + + @param #fmt# is a printf style format, default assumes "%lf" as format + */ +String +String_convert::double_str(double f, char const* fmt) +{ + char buf[STRING_BUFFER_LEN]; + + snprintf(buf, STRING_BUFFER_LEN, fmt ? fmt : "%f", f); + return buf; +} + +/** + Make a string from a single character. + + @param + #n# is a repetition count, default value is 1 + */ +String +String_convert::char_str(char c, int n) +{ + n = n >= 0 ? n : 0; + char* ch_p = new char[ n ]; + memset( ch_p, c, n ); + String s((Byte*)ch_p, n); + delete ch_p; + return s; +} + +String +String_convert::rational_str(Rational r) +{ + char * n = Itoa(r.numerator()); // LEAK???? + + String s = n; + if (r.denominator() != 1) { + char * d = Itoa(r.denominator()); + s += String( '/' ) + String(d); + //delete d; + } +/* delete n; + */ + return s; +} + +String +String_convert::pointer_str(const void *l) +{ + long long int ill = (long long int )l; + return String_convert::longlong_str(ill, "0x%0Lx"); +} diff --git a/flower/lib/string.cc b/flower/lib/string.cc new file mode 100644 index 0000000000..9aa8bc9a92 --- /dev/null +++ b/flower/lib/string.cc @@ -0,0 +1,365 @@ +/* + + string.cc - implement String + + (c) 1997 Han-Wen Nienhuys & Jan Nieuwenhuizen + + */ + +#include +#include + +#include +#include + +#include "string.hh" +#include "libc-extension.hh" +#include "string-convert.hh" + +#ifdef STRING_DEBUG +void* mymemmove( void* dest, void const* src, size_t n ); +#define memmove mymemmove +#endif + +// return array, alloced with new. +Byte* +String::copy_byte_p() const +{ + Byte const* src = strh_.byte_c_l(); + Byte* dest = new Byte[strh_.length_i() + 1]; + memcpy( dest, src, strh_.length_i() + 1 ); + return dest; +} +void +String::print_on(ostream& os) const +{ + if (!strh_.is_binary_bo()) + os << ch_c_l(); + else + for ( int i = 0; i < length_i(); i++ ) + os << (Byte)(*this)[ i ]; +} + +/* + copying, constructing. + */ +String& +String::operator = (String const&source ) +{ + strh_ = source.strh_; + return *this; +} + + +String::String(Rational r) +{ + *this = String_convert::rational_str(r); +} + +String::String (double f, char const* fmt) +{ + *this= String_convert::double_str(f,fmt); +} + +String::String( char c, int n ) +{ + *this = String_convert::char_str (c,n); +} + +/** + @see + String_convert::int_str + */ +String::String(int i, const char * format ) +{ + *this = String_convert::int_str(i,format); +} + +String::String (bool b) +{ + *this = (char const* ) (b ? "true" : "false"); +} + +String::String( char const* source ) +{ + assert(source); + strh_ = source; +} + +String::String( Byte const* byte_l, int length_i ) +{ + strh_.set( byte_l, length_i ); +} + +void +String::append(String s) +{ + strh_.append( s.byte_c_l(), s.length_i() ); +} +void +String::operator +=(String s) +{ + append(s); +} + +void +String::prepend(String s) +{ + s += *this; + *this = s; +} + +int +String::length_i() const +{ + return strh_.length_i(); +} + +Byte const* +String::byte_c_l() const +{ + return strh_.byte_c_l(); +} + +char const* +String::ch_c_l() const +{ + return strh_.ch_c_l(); +} + +Byte* +String::byte_l() +{ + return strh_.byte_l(); +} + +char* +String::ch_l() +{ + return strh_.ch_l(); +} + +/** + Do a signed comparison, analogous to memcmp; + */ +int +String::compare_i(String const& s1, String const& s2 ) +{ + Byte const* p1 = s1.byte_c_l(); + Byte const* p2 = s2.byte_c_l(); + if ( p1 == p2 ) + return 0; + + int i1 = s1.length_i(); + int i2 = s2.length_i(); + + int result= memcmp( p1, p2, i1 = 0 ) { + index_i += next_i; + next_i = right_str( length_i() - index_i - length ).index_i( string ); + } + return index_i; +} + +/** find a character. + + @return + the index of the leftmost character #c# (0 <= return < length_i()), + or -1 if not found. + + ? should return length_i()?, as in string.left_str(index_i(delimiter)) +*/ +int +String::index_i(char c ) const +{ + char const* me = strh_.ch_c_l(); + char const* p = (char const *) memchr( me,c, length_i()); + if ( p ) + return p - me; + return -1; +} + +/** + find the substring. + + @return + index of leftmost occurrence of #searchfor# + */ +int +String::index_i( String searchfor ) const +{ + char const* me = strh_.ch_c_l(); + char const* p = (char const *) memmem( + me, length_i(), searchfor.ch_c_l(), searchfor.length_i()); + + if ( p ) + return p - me; + else + return -1; +} + +/** find chars of a set. + + @return + the index of the leftmost occurance of an element of #set# + */ +int +String::index_any_i( String set ) const +{ + int n = length_i(); + if ( !n ) + return -1; + + const void * me_l = (const void*) strh_.ch_c_l(); + for (int i=0; i < set.length_i(); i++) { + char * found=(char*) memchr(me_l, set[i], n ); + if (found) { + return found - me_l; + } + } + return -1; +} + +String +String::left_str( int n ) const +{ + if (n >= length_i()) + return *this; + + String retval; + if (n < 1) + return retval; + + retval = *this; + retval.strh_.trunc(n); + return retval; +} + +String +String::right_str( int n ) const +{ + if (n > length_i()) + return *this; + + if ( n < 1) + return ""; + + return String( strh_.byte_c_l() + length_i() - n, n ); +} + + +String +String::nomid_str( int index_i, int n ) const +{ + if ( index_i < 0 ) { + n += index_i; + index_i = 0; + } + if ( n <= 0) + return *this; + + return + left_str( index_i ) + + right_str( length_i() - index_i - n ) ; +} + +/* + proposal: change to "cut()" + */ +String +String::mid_str( int index_i, int n ) const +{ + if (index_i <0) { + n += index_i; + index_i=0; + } + + if ( !length_i() || ( index_i < 0 ) || ( index_i >= length_i() ) || ( n < 1 ) ) + return String(); + + if ( ( n > length_i() ) || ( index_i + n > length_i() ) ) + n = length_i() - index_i; + + return String( byte_c_l() + index_i, n ); +} + +String +String::upper_str() const +{ + String str = *this; + str.to_upper(); + return str; +} +void +String::to_upper() +{ + char *s = (char*)strh_.byte_l(); + strnupr( s ,length_i()); +} + +void +String::to_lower() +{ + char* s = strh_.ch_l(); + strnlwr(s,length_i()); +} + + +String +String::lower_str() const +{ + String str = *this; + str.to_lower(); + return str; +} +String +String::reversed_str() const +{ + String str = *this; + strrev( str.byte_l(), str.length_i() ); + return str; +} + +int +String::value_i() const +{ + return String_convert::dec2_i( *this ); +} + +double +String::value_f() const +{ + return String_convert::dec2_f( *this ); +} + + diff --git a/flower/lib/stringtest.cc b/flower/lib/stringtest.cc new file mode 100644 index 0000000000..0bbde77c99 --- /dev/null +++ b/flower/lib/stringtest.cc @@ -0,0 +1,118 @@ +#ifdef STRING_TEST +/* + stupid test program to verify stringlib + stringtest.cc + */ +#include +#include "string.hh" +#include "varray.hh" +#include "string-convert.hh" + +void +ctors() +{ + cout << "constructors"< a; + a.push("abcd"); + a.push("zxy"); + a.push("abc"); + a.push(""); + a.sort(String::compare_i); + cout << "compares: "< +*/ + +#ifdef STRING_DEBUG +#include +#include +void* +mymemmove( void* dest, void const* src, size_t n ) +{ + return memcpy( dest, src, n ); // wohltempererit: 69006 +} +#define memmove mymemmove +#endif + +#ifdef STRING_UTILS_INLINED +#undef STRING_UTILS_INLINED +#endif + +#ifdef INLINE +#undef INLINE +#endif + +#define INLINE + +#include "string-handle.hh" +#include "string-data.hh" +#include "string-data.inl" +#include "string-handle.inl" diff --git a/flower/lib/text-db.cc b/flower/lib/text-db.cc new file mode 100644 index 0000000000..ebfc992ff2 --- /dev/null +++ b/flower/lib/text-db.cc @@ -0,0 +1,48 @@ +#include "text-db.hh" +bool +Text_db::eof() +{ + Data_file::gobble_leading_white(); + return Data_file::eof(); +} + +void +Text_db::gobble_leading_white() +{ + while (1) { + Data_file::gobble_leading_white(); + if (eof()) + return ; + char c; + if ((c = data_get()) !='\n'){ + data_unget (c); + return ; + } + } +} + + +Text_record +Text_db::get_record() +{ + while (1) { + String s; + Array fields; + assert(!eof()); + + while ((s = get_word()) != "") + { + fields.push(s); + gobble_white(); + } + + + if (get_line() != "") + assert(false); + + assert (fields.size()); + return Text_record(fields, get_name(), line()); + } +} + + diff --git a/flower/lib/text-stream.cc b/flower/lib/text-stream.cc new file mode 100644 index 0000000000..a2d3e4b119 --- /dev/null +++ b/flower/lib/text-stream.cc @@ -0,0 +1,31 @@ +#include "text-stream.hh" + +Text_stream::Text_stream(String fn) +{ + ios::sync_with_stdio(); + if (fn == "") + { + name = ""; + f = stdin; + } + + else + { + name = fn; + f = fopen(fn, "r"); + } + + if (!f) { + cerr <<__FUNCTION__<< ": can't open `" << fn << "'\n"; + exit(1); + } + + line_no = 1; + } + +void +Text_stream::message(String s) +{ + cerr << "\n"< d) + : dat(d) +{ + +} +Vector::Vector(const Vector&n) + : dat(n.dat) +{ +} + +Vector +Vector::operator-() const +{ + Vector v(*this); + v*=-1; + return v; +} + +void +Vector::set_unit(int j) +{ + fill(0.0); + dat[j] = 1.0; +} diff --git a/flower/libc-extension.cc b/flower/libc-extension.cc deleted file mode 100644 index f9a255683e..0000000000 --- a/flower/libc-extension.cc +++ /dev/null @@ -1,113 +0,0 @@ -/* - libc-extension.cc -- implement some string.h extensions - - source file of the flowerlib - - (c) 1997 Han-Wen Nienhuys -*/ -#include -#include -#include -#include "libc-extension.hh" - -/* - compensate for lacking libc functions. - */ -char* -strnlwr( char* start_l ,int n) -{ - char * p = start_l + n; - while ( --p >= start_l) { - *p = tolower( *p ); /* a macro on some compilers */ - } - return start_l; -} - -char* -strnupr( char* start_l, int n) -{ - char * p = start_l + n; - while ( --p >= start_l) { - *p = toupper( *p ); /* a macro on some compilers */ - } - return start_l; -} - -#ifndef HAVE_MEMMEM - -/** locate a substring. #memmem# finds the first occurrence of - #needle# in #haystack# - */ - -char * -memmem(const Byte * haystack, int haystack_len, - const Byte *needle,int needle_len) -{ - const Byte * end_haystack = haystack + haystack_len - needle_len; - const Byte * end_needle = needle + needle_len ; - - /* Ahhh ... Some minimal lowlevel stuff. This *is* nice; Varation - is the spice of life */ - while (haystack < end_haystack) { - const Byte *subneedle_l = needle; - const Byte *subhaystack_l = haystack; - while (subneedle_l < end_needle) { - if (*subneedle_l++ != *subhaystack_l++) - goto next; // yeah. I should be prosecuted. - } - - // completed the needle. Gotcha. - return (char*) haystack; - next: - haystack++; - } - return 0; -} -#endif - -Byte * -memrchr(const Byte * p, int n, char c) -{ - const Byte * q = p+n; - while (q > p) { - if (*--q == c) - return (Byte*)q; - } - return 0; -} - - -template -inline void -my_swap(T &t1, T &t2, T &tmp) -{ - tmp = t1; - t1 = t2; - t2 = tmp; -} - -Byte* -strrev( Byte* byte_l, int length_i ) -{ - Byte tmp_byte; - - Byte* left_l = byte_l; - Byte* right_l = byte_l + length_i; - - while ( right_l > left_l ) { - my_swap(*right_l-- , *left_l++ , tmp_byte); - } - return byte_l; -} - -#ifndef HAVE_SNPRINTF -int snprintf ( char *str, size_t n, - const char *format, ... ) -{ - va_list ap; - va_start(ap, format); - int i = vsprintf(str, format, ap); - va_end(ap); - return i; -} -#endif diff --git a/flower/libc-extension.hh b/flower/libc-extension.hh deleted file mode 100644 index e71037c41e..0000000000 --- a/flower/libc-extension.hh +++ /dev/null @@ -1,32 +0,0 @@ -/* - libc-extension.hh -- declare some string.h extensions - - source file of the flowerlib - - (c) 1997 Han-Wen Nienhuys -*/ - - -#ifndef LIBC_EXTENSION_HH -#define LIBC_EXTENSION_HH -#include "fproto.hh" - -char* strnlwr( char* start_l ,int n); -char* strnupr( char* start_l, int n); - -#ifndef HAVE_MEMMEM // GNU extension. -char *memmem(const Byte * haystack, int haystack_len, - const Byte *needle, int needle_len); -#endif HAVE_MEMMEM - -#ifndef HAVE_SNPRINTF // GNU extension. -int snprintf (char *str, size_t n, - const char *format, ... ); -#endif - - -Byte *memrchr(const Byte * p, int n, char c); -Byte *strrev( Byte* byte_l, int length_i ); - - -#endif // LIBC_EXTENSION_HH diff --git a/flower/link.hh b/flower/link.hh deleted file mode 100644 index 6f9c75a411..0000000000 --- a/flower/link.hh +++ /dev/null @@ -1,38 +0,0 @@ -// link.hh - -#ifndef __LINK_HH -#define __LINK_HH -template -class List; - - -/// class for List -template -class Link -{ -// friend class Cursor; -public: - Link( const T& thing ); - - Link* previous(); - Link* next(); - - /// put new Link item after me in list - void add( const T& thing ); - /// put new Link item before me in list - void insert( const T& thing ); - void remove(List &l); - - T& thing(); - void OK() const; -private: - Link( Link* previous, Link* next, const T& thing ); - - T thing_; - Link* previous_; - Link* next_; -}; - -#include "link.inl" - -#endif // __LINK_HH // diff --git a/flower/link.inl b/flower/link.inl deleted file mode 100644 index 3926d6bc2a..0000000000 --- a/flower/link.inl +++ /dev/null @@ -1,102 +0,0 @@ -// link.inl -*-c++-*- -#ifndef LINK_INL -#define LINK_INL -#include -template -inline -void -Link::OK() const -{ -#ifndef NDEBUG - if (previous_) { - assert(previous_->next_ == this); - } - if (next_) { - assert(next_->previous_ == this); - } -#endif -} - -template -inline -Link::Link( const T& thing ) : - thing_( thing ) -{ - previous_ = next_ = 0; -} - -template -inline -Link::Link( Link* previous, Link* next, const T& thing ) : - thing_( thing ) -{ - previous_ = previous; - next_ = next; -} - -template -inline -Link* -Link::next() -{ - return next_; -} - -template -inline -Link* -Link::previous() -{ - return previous_; -} - -template -inline -void -Link::add( const T& thing ) -{ - - Link* l = new Link( this, next_, thing ); - if ( next_ ) - next_->previous_ = l; - next_ = l; -} - -template -inline void -Link::insert( const T& thing ) -{ - // Link* l = new Link( next_, this, thing ); - // bugfix hwn 16/9/96 - Link* l = new Link( previous_, this, thing ); - if ( previous_ ) - previous_->next_ = l; - previous_ = l; -} - -/* - don't forget to adjust #l#'s top_ and bottom_. - */ -template -inline void -Link::remove(List &l) -{ - if ( previous_ ) - previous_->next_ = next_; - else - l.top_ = next_; - - if ( next_ ) - next_->previous_ = previous_; - else - l.bottom_ = previous_; -} - -template -inline -T& -Link::thing() -{ - return thing_; -} -#endif diff --git a/flower/list.hh b/flower/list.hh deleted file mode 100644 index ec59fbff07..0000000000 --- a/flower/list.hh +++ /dev/null @@ -1,98 +0,0 @@ -#ifndef __LIST_HH -#define __LIST_HH - -class ostream; -template class Cursor; -template class Link; - -/** all-purpose doubly linked list. - - List can be seen as all items written down on paper, - from top to bottom - - class Cursor is used to extend List - - items are always stored as copies in List, but: - #List# : copies of #String# stored - #List# : copies of #String*# stored! - (do not use, use \Ref{PointerList} ## instead.) - - {\bf note:} - retrieving "invalid" cursors, i.e. - #top()/bottom()# from empty list, #find()# without success, - results in a nonvalid Cursor ( #!ok()# ) - - - INVARIANTEN! -*/ - -template -class List -{ - public: - List(List const&src); - - /// construct empty list - List(); - virtual ~List(); - - int size() const; - - Cursor bottom() const; // const sucks. - Cursor top() const; - - void OK() const; // check list - - protected: - friend class Cursor; - friend class Link; - - void concatenate(List const &s); - - /** make *this empty. - - POST: - size == 0 - - WARNING: - contents lost, and not deleted. - */ - void set_empty(); - - void add( const T& thing, Cursor &after_me ); - - /// put thing before #before_me# - void insert( const T& thing, Cursor &before_me ); - - /** Remove link pointed to by me. Destructor of contents called - (nop for pointers) - - POST - none; - - - WARNING: do not use #me# after calling - */ - void remove( Cursor me ); - - - /* ************** */ - - int size_; - Link* top_; - Link* bottom_; -}; - -#include "list.inl" -#include "cursor.hh" - -// instantiate a template: explicit instantiation. -#define L_instantiate(a) template class List; template class Cursor; \ - template class Link - - -#endif // __LIST_HH // - - - - diff --git a/flower/list.inl b/flower/list.inl deleted file mode 100644 index df0687b7c8..0000000000 --- a/flower/list.inl +++ /dev/null @@ -1,56 +0,0 @@ -// -*-c++-*- - -#ifndef LIST_INL -#define LIST_INL - -template -inline -List::List() -{ - set_empty(); -} - -template -inline void -List::set_empty() -{ - top_ = bottom_ = 0; - size_ = 0; -} - -template -inline void -List::remove( Cursor me ) -{ - if ( me.ok() ){ - Link *lp = me.pointer(); - lp->remove(*this); - delete lp; - size_--; - } -} - -template -inline int -List::size() const -{ - return size_; -} - -template -inline Cursor -List::top()const -{ - return Cursor( *this, top_ ); -} - - -template -inline Cursor -List::bottom()const -{ - return Cursor( *this, bottom_ ); -} - - -#endif diff --git a/flower/list.tcc b/flower/list.tcc deleted file mode 100644 index 16e12a31f1..0000000000 --- a/flower/list.tcc +++ /dev/null @@ -1,112 +0,0 @@ -#ifndef LIST_CC -#define LIST_CC - -#include "list.hh" - -template -List::List(List const&src) -{ - set_empty(); - // probably el stupido - for (Cursor c(src); c.ok(); c++) - bottom().add(c); -} - -template -void -List::OK() const -{ - int i = size_; - Link *lp = top_; - while (i--) { - assert(lp); - lp->OK(); - lp = lp->next(); - } - assert(!lp); - i = size_; - lp = bottom_; - while (i--) { - assert(lp); - lp->OK(); - lp = lp->previous(); - } - assert(!lp); -} - - -template -List::~List() -{ - Cursor c(*this); - while (c.ok()) - c.del(); -} - -/** - - add after after_me. - - Procedure: - \begin{itemize} - \item if #after_me# is #ok()#, add after #after_me#, else - \item if list !empty simply add to bottom, else - \item list is empty: create first \Ref{Link} and initialize - #bottom_# and #top_#. - \end{itemize} -*/ -template -void -List::add( const T& thing, Cursor &after_me ) -{ - if (!size_) { // not much choice if list is empty - bottom_ = top_ = new Link( thing ); - if (!after_me.ok()) - after_me = bottom(); - } else { // add at aprioprate place - if (!after_me.ok()) - after_me = bottom(); - Link *p =after_me.pointer(); - p->add(thing); - if (p == bottom_) // adjust bottom_ if necessary. - bottom_ = p->next(); - } - - size_++; -} - -template -void -List::insert( const T& thing, Cursor &before_me ) -{ - if (!size_) { - bottom_ = top_ = new Link( thing ); - if (!before_me.ok()) - before_me = top(); - - } else { - if (!before_me.ok()) - before_me = top(); - - Link *p = before_me.pointer() ; - - p->insert(thing); - if (p == top_) - top_ = p->previous(); - } - - size_++; -} - - -template -void -List::concatenate(List const&s) -{ - Cursor b(bottom()); - for (Cursor c(s); c.ok(); c++) { - b.add(c); - b++; - } -} -#endif diff --git a/flower/make_version b/flower/make_version deleted file mode 100755 index f584d272a9..0000000000 --- a/flower/make_version +++ /dev/null @@ -1,11 +0,0 @@ -#!/bin/sh - -echo '#ifndef FVERSION_HH' -echo '#define FVERSION_HH' - -echo '#define FMAJORVERSION ' $1 -echo '#define FMINORVERSION ' $2 -echo '#define FPATCHLEVEL ' $3 -echo '#define FVERSIONSTR "'$1.$2.$3'"' -echo '#define FCOMPILER "'$4'"' -echo '#endif' diff --git a/flower/matdebug.cc b/flower/matdebug.cc deleted file mode 100644 index bcc2843bca..0000000000 --- a/flower/matdebug.cc +++ /dev/null @@ -1,63 +0,0 @@ -#include "dstream.hh" -#include "matrix.hh" - -static Dstream *dout = 0; - -/** - Set the debugging output. Will not delete/swallow argument. - */ -void set_matrix_debug(Dstream&ds) -{ - dout = &ds; -} - -Matrix::operator String() const -{ - String s; -#ifndef NPRINT - s="matrix {\n"; - for (int i=0; i< rows(); i++){ - for (int j = 0; j < cols(); j++) { - s+= String(dat->elem(i,j), "%6f "); - } - s+="\n"; - } - s+="}\n"; -#endif - return s; -} - - -void -Matrix::print() const -{ -#ifndef NPRINT - if (!dout) - return; - *dout << *this; -#endif -} - -Vector::operator String() const -{ - String s; -#ifndef NPRINT - s="vector ["; - for (int i=0; i < dim(); i++) { - s += String(dat[i], "%6f") + String(' '); - } - s+="]"; -#endif - return s; -} - - -void -Vector::print() const -{ -#ifndef NDEBUG - if (!dout) - return; - *dout << *this<<'\n'; -#endif -} diff --git a/flower/matrix.cc b/flower/matrix.cc deleted file mode 100644 index 63bd85a33c..0000000000 --- a/flower/matrix.cc +++ /dev/null @@ -1,240 +0,0 @@ -#include "matrix.hh" - -Real -Matrix::norm() const -{ - Real r =0.0; - for (int i=0, j=0; dat->mult_ok(i,j); dat->mult_next(i,j)) - r += sqr(dat->elem(i,j)); - return sqrt(r); -} - -void -Matrix::fill(Real r) -{ - for (int i=0, j=0; dat->mult_ok(i,j); dat->mult_next(i,j)) - dat->elem(i,j)=r; -} - -void -Matrix::set_diag(Real r) -{ - for (int i=0, j=0; dat->mult_ok(i,j); dat->mult_next(i,j)) - dat->elem(i,j)=(i==j) ? r: 0.0; -} - -void -Matrix::set_diag(Vector d) -{ - for (int i=0, j=0; dat->mult_ok(i,j); dat->mult_next(i,j)) - dat->elem(i,j)=(i==j) ? d(i): 0.0; -} - -void -Matrix::operator+=(const Matrix&m) -{ - assert(m.cols() == cols()); - assert(m.rows() == rows()); - for (int i=0, j=0; dat->mult_ok(i,j); dat->mult_next(i,j)) - dat->elem(i,j) += m(i,j); -} - -void -Matrix::operator-=(const Matrix&m) -{ - assert(m.cols() == cols()); - assert(m.rows() == rows()); - for (int i=0, j=0; dat->mult_ok(i,j); dat->mult_next(i,j)) - dat->elem(i,j) -= m(i,j); -} - - -void -Matrix::operator*=(Real a) -{ - for (int i=0, j=0; dat->mult_ok(i,j); dat->mult_next(i,j)) - dat->elem(i,j) *= a; -} - -void -Matrix::operator=(const Matrix&m) -{ - if (&m == this) - return ; - delete dat; - dat = m.dat->clone(); -} - -Matrix::Matrix(const Matrix &m) -{ - m.OK(); - - dat = m.dat->clone(); -} - - -Matrix::Matrix(int n, int m) -{ - dat = virtual_smat::get_full(n,m); - fill(0); -} - -Matrix::Matrix(int n) -{ - dat = virtual_smat::get_full(n,n); - fill(0); -} - -Matrix::Matrix(Vector v, Vector w) -{ - dat = virtual_smat::get_full(v.dim(), w.dim()); - for (int i=0, j=0; dat->mult_ok(i,j); dat->mult_next(i,j)) - dat->elem(i,j)=v(i)*w(j); -} - - -Vector -Matrix::row(int k) const -{ - int n=cols(); - - - Vector v(n); - for(int i=0; i < n; i++) - v(i)=dat->elem(k,i); - - return v; -} - -Vector -Matrix::col(int k) const -{ - int n=rows(); - Vector v(n); - for(int i=0; i < n; i++) - v(i)=dat->elem(i,k); - return v; -} - -Vector -Matrix::left_multiply(const Vector& v) const -{ - Vector dest(v.dim()); - assert(dat->cols()==v.dim()); - for (int i=0, j=0; dat->mult_ok(i,j); dat->mult_next(i,j)) - dest(i)+= dat->elem(j,i)*v(j); - return dest; -} - -Vector -Matrix::operator *(const Vector& v) const -{ - Vector dest(rows()); - assert(dat->cols()==v.dim()); - for (int i=0, j=0; dat->mult_ok(i,j); dat->mult_next(i,j)) - dest(i)+= dat->elem(i,j)*v(j); - return dest; -} - -Matrix -operator /(Matrix const& m1,Real a) -{ - Matrix m(m1); - m /= a; - return m; -} - -void -Matrix::transpose() // delegate to storage? -{ - for (int i=0, j=0; dat->mult_ok(i,j); dat->mult_next(i,j)) { - if (i >= j) - continue; - Real r=dat->elem(i,j); - dat->elem(i,j) = dat->elem(j,i); - dat->elem(j,i)=r; - } -} - -Matrix -Matrix::operator-() const -{ - OK(); - Matrix m(*this); - m*=-1.0; - return m; -} - -Matrix -Matrix::transposed() const -{ - Matrix m(*this); - m.transpose(); - return m; -} - - -/* should do something smarter: bandmatrix * bandmatrix is also banded matrix. */ -Matrix -operator *(const Matrix &m1, const Matrix &m2) -{ - Matrix result(m1.rows(), m2.cols()); - result.set_product(m1,m2); - return result; -} - -void -Matrix::set_product(const Matrix &m1, const Matrix &m2) -{ - assert(m1.cols()==m2.rows()); - assert(cols()==m2.cols() && rows()==m1.rows()); - - for (int i=0, j=0; dat->mult_ok(i,j); - dat->mult_next(i,j)) { - Real r=0.0; - for (int k = 0; k < m1.cols(); k++) - r += m1(i,k)*m2(k,j); - dat->elem(i,j)=r; - } -} - -void -Matrix::insert_row(Vector v, int k) -{ - assert(v.dim()==cols()); - dat->insert_row(k); - for (int j=0; j < cols(); j++) - dat->elem(k,j)=v(j); -} - - -void -Matrix::swap_columns(int c1, int c2) -{ - assert(c1>=0&& c1 < cols()&&c2 < cols() && c2 >=0); - for (int i=0; i< rows(); i++) { - Real r=dat->elem(i,c1); - dat->elem(i,c1) = dat->elem(i,c2); - dat->elem(i,c2)=r; - } -} - -void -Matrix::swap_rows(int c1, int c2) -{ - assert(c1>=0&& c1 < rows()&&c2 < rows() && c2 >=0); - for (int i=0; i< cols(); i++) { - Real r=dat->elem(c1,i); - dat->elem(c1,i) = dat->elem(c2,i); - dat->elem(c2,i)=r; - } -} - - -int -Matrix::dim() const -{ - assert(cols() == rows()); - return rows(); -} - diff --git a/flower/matrix.hh b/flower/matrix.hh deleted file mode 100644 index a633d6657a..0000000000 --- a/flower/matrix.hh +++ /dev/null @@ -1,135 +0,0 @@ -#ifndef MATRIX_HH -#define MATRIX_HH - - -#include "vsmat.hh" -#include "vector.hh" - -/** a Real matrix. This is a class for a nonsquare block of #Real#s. The - implementation of sparse matrices is done in the appropriate #smat# - class. Matrix only does the mathematical actions (adding, - multiplying, etc.) - - - TODO - implement ref counting? */ - - -class Matrix { - virtual_smat *dat; - -public: - void OK() const { dat->OK(); } - int cols() const { return dat->cols(); } - int rows() const { return dat->rows(); } - - /** return the size of a matrix. - PRE - the matrix needs to be square. - */ - int dim() const; - - // Matrix() { dat = 0; } - ~Matrix() { delete dat; } - - /// set entries to r - void fill(Real r); - - /// set diagonal to d - void set_diag(Real d); - - void set_diag(Vector d); - /// set unit matrix - void unit() { set_diag(1.0); } - - void operator+=(const Matrix&m); - void operator-=(const Matrix&m); - void operator*=(Real a); - void operator/=(Real a) { (*this) *= 1/a; } - - /** add a row. - add a row to the matrix before row k - - PRE - v.dim() == cols() - 0 <= k <= rows() - */ - void insert_row(Vector v,int k); - /** . - delete a row from this matrix. - - PRE - 0 <= k < rows(); - */ - void delete_row(int k) { dat->delete_row(k); } - void delete_column(int k) { dat->delete_column(k); } - - /** - square n matrix, initialised to null - */ - Matrix(int n); - - /** - n x m matrix, init to 0 - */ - Matrix(int n, int m); - Matrix(const Matrix &m); - - /// dyadic product: v * w.transpose - Matrix(Vector v, Vector w); - void operator=(const Matrix&m); - - /// access an element - Real operator()(int i,int j) const { return dat->elem(i,j); } - - /// access an element - Real &operator()(int i, int j) { return dat->elem(i,j); } - - /// Matrix multiply with vec (from right) - Vector operator *(const Vector &v) const; - - /// set this to m1*m2. - void set_product(const Matrix &m1, const Matrix &m2); - - - Vector left_multiply(Vector const &) const; - - Matrix operator-() const; - - /// transpose this. - void transpose(); - - /// return a transposed copy. - Matrix transposed() const ; - - Real norm() const; - /** swap. - PRE - 0 <= c1,c2 < cols() - */ - void swap_columns(int c1, int c2); - - /** swap. - PRE - 0 <= c1,c2 < rows() - */ - void swap_rows(int c1, int c2); - - - Vector row(int ) const; - Vector col(int) const; - - operator String() const; - void print() const; -}; - -inline Vector -operator *(Vector &v, const Matrix& m) { return m.left_multiply(v); } -Matrix operator *(const Matrix& m1,const Matrix &m2); -Matrix operator /(const Matrix &m1,Real a); -inline Matrix operator -(Matrix m1,const Matrix m2) -{ - m1 -= m2; - return m1; -} -#endif diff --git a/flower/path.cc b/flower/path.cc deleted file mode 100644 index c79962f00f..0000000000 --- a/flower/path.cc +++ /dev/null @@ -1,77 +0,0 @@ -/* - path.cc - manipulation of paths and filenames. -*/ -#include -#include "path.hh" - -#ifndef PATHSEP -#define PATHSEP '/' -#endif - -/** - @param path the original full filename - @return 4 components of the path. They can be empty -*/ -void -split_path(String path, - String &drive, String &dirs, String &filebase, String &extension) -{ - // peel off components, one by one. - int di = path.index_i(':'); - if (di >= 0) - { - drive = path.left_str(di + 1); - path = path.right_str(path.len() - di -1); - } - else - drive = ""; - - di = path.index_last_i(PATHSEP); - if (di >=0) - { - dirs = path.left_str(di + 1); - path = path.right_str(path.len()-di -1); - } - else - dirs = ""; - - di = path.index_last_i('.'); - if (di >= 0) - { - filebase = path.left_str(di); - extension =path.right_str(path.len()-di); - } - else - { - extension = ""; - filebase = path; - } -} - -File_path::File_path(String pref) -{ - add("."); - add(pref); -} - - -/** find a file. - It will search in the current dir, in the construction-arg, and - in any other added path, in this order. - */ -String -File_path::find(String nm) -{ - for (int i=0; i < size(); i++) { - String path = (*this)[i]; - path+= "/"+nm; - - - FILE *f = fopen(path, "r"); // ugh! - if (f) { - fclose(f); - return path; - } - } - return ""; -} diff --git a/flower/path.hh b/flower/path.hh deleted file mode 100644 index bc4d9f3776..0000000000 --- a/flower/path.hh +++ /dev/null @@ -1,32 +0,0 @@ -#ifndef PATH_HH -#define PATH_HH -#include "string.hh" -#include "varray.hh" - - -/** searching directory for file. - - Abstraction of PATH variable. An interface for searching input files. - Search a number of dirs for a file. - - Should use kpathsea? - -*/ - -class File_path : private Array -{ -public: - /// locate a file in the search path - String find(String nm); - - /// construct using prefix. Normally argv[0]. - File_path(String); - - /// add to end of path. - Array::push; - void add(String str) { push(str); } -}; -/// split path into its components -void split_path(String path, String &drive, String &dirs, String &filebase, String &extension); - -#endif diff --git a/flower/pcursor.hh b/flower/pcursor.hh deleted file mode 100644 index ea360078d1..0000000000 --- a/flower/pcursor.hh +++ /dev/null @@ -1,67 +0,0 @@ -/* - pcursor.hh -- part of flowerlib - - (c) 1996 Han-Wen Nienhuys&Jan Nieuwenhuizen -*/ - -#ifndef PCURSOR_HH -#define PCURSOR_HH - -#include "plist.hh" -#include "cursor.hh" - -/** cursor to go with PointerList. - don't create PointerList's. - This cursor is just an interface class for Cursor. It takes care of the - appropriate type casts - */ -template -class PCursor : private Cursor { - friend class IPointerList; - - /// delete contents - void junk(); -public: - Cursor::ok; - Cursor::del; - Cursor::backspace; - T get_p() { - T p = ptr(); - Cursor::del(); - return p; - } - T get_prev() { - (*this)--; - return get_p(); - } - - PointerList &list() { return (PointerList&)Cursor::list(); } - PCursor operator++(int) { return Cursor::operator++(0);} - PCursor operator--(int) { return Cursor::operator--(0); } - PCursor operator+=(int i) { return Cursor::operator+=(i);} - PCursor operator-=(int i) { return Cursor::operator-=(i); } - PCursor operator -(int no) const { return Cursor::operator-(no);} - int operator -(PCursor op) const { return Cursor::operator-(op);} - PCursor operator +( int no) const {return Cursor::operator+(no);} PCursor(const PointerList & l) : Cursor (l) {} - - PCursor( const Cursor& cursor ) : Cursor(cursor) { } - void* vptr() const { return *((Cursor &) *this); } - - // should return T& ? - T ptr() const { return (T) vptr(); } - T operator ->() const { return ptr(); } - operator T() { return ptr(); } - T operator *() { return ptr(); } - void add(const T& p ) { Cursor::add((void*) p); } - void insert(const T& p ) { Cursor::insert((void*) p);} - static int compare(PCursor a,PCursorb) { - return Cursor::compare(a,b); - } -}; - - - -#include "compare.hh" -template_instantiate_compare(PCursor, PCursor::compare, template); - -#endif diff --git a/flower/pcursor.tcc b/flower/pcursor.tcc deleted file mode 100644 index ffb01bcfe8..0000000000 --- a/flower/pcursor.tcc +++ /dev/null @@ -1,16 +0,0 @@ -#include "pcursor.hh" - -template -void -PCursor::junk() -{ -#if !defined(NDEBUG) && defined(PARANOID) - list().OK(); -#endif - - delete ptr(); -#if !defined(NDEBUG)&&defined(PARANOID) - thing() = 0; - list().OK(); -#endif -} diff --git a/flower/plist.hh b/flower/plist.hh deleted file mode 100644 index 426b861c02..0000000000 --- a/flower/plist.hh +++ /dev/null @@ -1,72 +0,0 @@ -/* - list.hh -- part of flowerlib - - (c) 1996 Han-Wen Nienhuys & Jan Nieuwenhuizen -*/ - -#ifndef PLIST_HH -#define PLIST_HH - -#include "list.hh" - -/** - A list of pointers. - - Use for list of pointers, e.g. PointerList. - This class does no deletion of the pointers, but it knows how to - copy itself (shallow copy). We could have derived it from List, - but this design saves a lot of code dup; for all PointerLists in the - program only one parent List is instantiated. - */ -template -class PointerList : public List -{ - public: - PCursor top() const{ - return PCursor (List::top()); - } - PCursor bottom() const { - return PCursor (List::bottom()); - } - PCursor find(T) const; - void concatenate(PointerList const &s) { List::concatenate(s); } - PointerList() {} -}; - -/** PointerList which deletes pointers given to it. - NOTE: - - The copy constructor doesn't do what you'd want: - Since T might have a virtual ctor, we don't try to do a - - new T(*cursor) - - You have to copy this yourself, or use the macro PointerList__copy - - */ -template -class IPointerList : public PointerList { -public: - IPointerList(const IPointerList&) { set_empty(); } - IPointerList() { } - ~IPointerList(); -}; - -#define IPointerList__copy(T, to, from, op) \ - for (PCursor _pc_(from); _pc_.ok(); _pc_++)\ - to.bottom().add(_pc_->op)\ - \ - - -template -void PL_copy(IPointerList &dst,IPointerList const&src); - - -#define PL_instantiate(a) template class PointerList; \ - template class PCursor; -#define IPL_instantiate(a) PL_instantiate(a); \ - template class IPointerList - -#include "plist.inl" - -#endif diff --git a/flower/plist.inl b/flower/plist.inl deleted file mode 100644 index 82be364334..0000000000 --- a/flower/plist.inl +++ /dev/null @@ -1,21 +0,0 @@ -/* -*-c++-*- - plist.inl -- part of flowerlib - - (c) 1996 Han-Wen Nienhuys& Jan Nieuwenhuizen -*/ - -#ifndef PLIST_INL -#define PLIST_INL - -template -void -PL_copy(IPointerList &to, IPointerList const&src) -{ - for (PCursor pc(src); pc.ok(); pc++) { - T *q = pc; - T *p=new T(*q) ; - to.bottom().add(p); - } -} - -#endif diff --git a/flower/plist.tcc b/flower/plist.tcc deleted file mode 100644 index 2ceed2e9c7..0000000000 --- a/flower/plist.tcc +++ /dev/null @@ -1,21 +0,0 @@ -#include "plist.hh" - -template -IPointerList::~IPointerList() -{ - PCursor c( *this ); - while (c.ok()) { - delete c.get_p(); - } -} - -template -PCursor -PointerList::find(T what ) const -{ - PCursor i(*this); - for (; i.ok(); i++) - if (i.ptr() == what) - break; - return i; -} diff --git a/flower/pqueue.hh b/flower/pqueue.hh deleted file mode 100644 index 195232317e..0000000000 --- a/flower/pqueue.hh +++ /dev/null @@ -1,46 +0,0 @@ -/* - pqueue.hh -- declare - - source file of the LilyPond music typesetter - - (c) 1997 Han-Wen Nienhuys -*/ - - -#ifndef PQUEUE_HH -#define PQUEUE_HH - -#include "varray.hh" - -/** - Stupid Prioq. Should use Lists and STL. - Smallest is put at the front. - */ - -template -struct PQueue -{ - Array value_arr_; - Array indices_arr_; - - void enter(V v, I idx) { - int j=0; - for (; j < value_arr_.size(); j++) - if (indices_arr_[j] > idx) - break; - - value_arr_.insert(v, j); - indices_arr_.insert(idx, j); - } - int size() { return value_arr_.size(); } - V front_val() { return value_arr_[0]; } - I front_idx() { return indices_arr_[0]; } - V get() { - V retval = front_val(); - value_arr_.del(0); - indices_arr_.del(0); - return retval; - } - -}; -#endif // PQUEUE_HH diff --git a/flower/rational.hh b/flower/rational.hh deleted file mode 100644 index 30fa2cb6d6..0000000000 --- a/flower/rational.hh +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/flower/real.hh b/flower/real.hh deleted file mode 100644 index 0533af2111..0000000000 --- a/flower/real.hh +++ /dev/null @@ -1,16 +0,0 @@ -#ifndef REAL_HH -#define REAL_HH - - -#include -#include -#include - -typedef double Real; - -inline Real -distance(Real x,Real y) -{ - return abs(x-y); -} -#endif diff --git a/flower/scalar.cc b/flower/scalar.cc deleted file mode 100644 index 5edd9e997f..0000000000 --- a/flower/scalar.cc +++ /dev/null @@ -1,57 +0,0 @@ -#include -#include -#include "scalar.hh" - -Scalar::Scalar(Rational r) - :String(r) -{ - -} - -Scalar::operator Rational() -{ - int p = index_i('/'); - if (p == -1) - return int(*this); - - String s2 = right_str(len()-p-1); - String s1 = left_str(p); - - return Rational(s1.value_i(), s2.value_i()); -} - -bool -Scalar::isnum() -{ - int conv = false; - if (len()) { - long l =0; - conv = sscanf(strh_.ch_c_l(), "%ld", &l); - } - return len() && conv; -} - -Scalar::operator Real() -{ - assert (isnum()); - return value_f(); -} - -Scalar::operator int() -{ - assert (isnum()); - return value_i(); -} - - -Scalar::operator bool() const -{ - if (!len()) - return false; - if (*this == "0") - return false; - String u (*this); - if ( u.upper_str() == "FALSE") - return false; - return true; -} diff --git a/flower/scalar.hh b/flower/scalar.hh deleted file mode 100644 index 5cdfa427da..0000000000 --- a/flower/scalar.hh +++ /dev/null @@ -1,34 +0,0 @@ -/* - scalar.hh -- part of LilyPond - - (c) 1996 Han-Wen Nienhuys -*/ - -#ifndef SCALAR_HH -#define SCALAR_HH -#include "string.hh" -#include "real.hh" - -/// Perl -like scalar type. -struct Scalar : public String { - - Scalar(Real r) : String(r) {} - Scalar(int i) : String(i) {} - Scalar(char c) : String(c) {} - Scalar(const char *c) : String(c) {} - Scalar(String s ):String(s) {} - Scalar(Rational ); - operator Rational(); - Scalar() {} - bool isnum(); - operator Real(); - operator int(); - - /** perl -like string to bool conversion. - */ - operator bool() const; - -}; - -#endif // SCALAR_HH - diff --git a/flower/smat.cc b/flower/smat.cc deleted file mode 100644 index dcc61ce44e..0000000000 --- a/flower/smat.cc +++ /dev/null @@ -1,181 +0,0 @@ -#include "smat.hh" - -void -Full_storage::operator=(Full_storage const &fs) -{ - resize(fs.h, fs.w); - OK(); - fs.OK(); - for (int i=0; i= h && maxw >= w); - assert(h >= 0 && w >= 0); - assert(els||!maxh); -#endif -} -void -Full_storage::resize_cols(int newh) -{ - if (newh <= maxh) { - h=newh; - return; - } - - Real ** newa=new Real*[newh]; - int j=0; - for (; j < h; j++) - newa[j] = els[j]; - for (; j < newh; j++) - newa[j] = new Real[maxw]; - delete[] els; - els=newa; - - h = maxh = newh; -} - -void -Full_storage::resize_rows(int neww) -{ - if (neww <= maxw) { - w=neww; - return; - } - for (int i=0; i < maxh ; i++) { - Real* newa = new Real[neww]; - for (int k=0; k < w; k++) - newa[k] = els[i][k]; - - delete[] els[i]; - els[i] = newa; - } - w = maxw = neww; -} - -Full_storage::~Full_storage() { - for (int i=0; i < maxh; i++) - delete [] els[i]; - delete[] els; -} - -void -Full_storage::resize(int rows, int cols) -{ - OK(); - resize_cols(rows); - resize_rows(cols); - -} - - -bool -Full_storage::mult_ok(int i, int j) const -{ - return valid(i,j); -} - -bool -Full_storage::trans_ok(int i, int j) const -{ - return valid(i,j); -} - - -void -Full_storage::trans_next(int &i, int &j) const -{ - assert(trans_ok(i,j)); - i++; - if (i >= h) { - i=0; - j ++; - } -} - -void -Full_storage::mult_next(int &i, int &j) const -{ - assert(mult_ok(i,j)); - j++; - if (j >= w) { - j=0; - i++; - } -} - -void -Full_storage::delete_column(int k) -{ - assert(0 <= k &&k k ; i--) - for (int j=0; j -Full_storage::row(int n) const -{ - Array r; - for (int j = 0; j < w; j++) - r.push(els[n][j]); - return r; -} - -Array -Full_storage::column(int n) const -{ - - Array r; - for (int i = 0; i=0 && i < h) - && (j < w && j >=0); - } - - - void resize_rows(int); - void resize_cols(int); - -public: - virtual int rows() const { - return h; - } - virtual int cols() const { - return w; - } - - - virtual void set_size(int i, int j) - { - resize(i,j); //this could be more efficient. - } - - virtual void set_size(int i) { - set_size(i,i); - } - virtual void resize(int i, int j); - virtual void resize(int i) { - resize(i,i); - } - - virtual Real& elem(int i,int j) { - assert(valid(i,j)); - return els[i][j]; - } - virtual const Real& elem(int i, int j) const { - assert(valid(i,j)); - return els[i][j]; - } - virtual Array row(int i) const; - virtual Array column(int j) const; - - Full_storage() { - init(); - } - Full_storage(int i, int j) { - init(); - set_size(i,j); - } - Full_storage(Full_storage&); - Full_storage(int i) { - init(); - set_size(i); - } - void OK() const; - void operator=(Full_storage const &); - - virtual void insert_row(int k); - virtual void delete_row(int k); - virtual void delete_column(int k); - - - ~Full_storage(); - virtual bool mult_ok(int i, int j)const; - virtual void mult_next(int &i, int &j) const ; - virtual bool trans_ok(int i, int j) const; - virtual void trans_next(int &i, int &j) const; - virtual virtual_smat * clone(); -}; - -#endif diff --git a/flower/string-convert.cc b/flower/string-convert.cc deleted file mode 100644 index 36c98dd490..0000000000 --- a/flower/string-convert.cc +++ /dev/null @@ -1,234 +0,0 @@ -/* - PROJECT: FlowerSoft C++ library - FILE : string-convert.cc - ---*/ - - -#include -#include "string.hh" -#include "string-convert.hh" - -/** - a safe length for stringconversion buffers - - worst case would be %f printing HUGE (or 1/HUGE), which is approx - 2e318, this number would have approx 318 zero's in its string. - - Should enlarge buff dynamically. - @see - man 3 snprintf - */ -static const int STRING_BUFFER_LEN=1024; - -String -String_convert::bin2hex_str( String bin_str ) -{ - String str; - Byte const* byte_c_l = bin_str.byte_c_l(); - for ( int i = 0; i < bin_str.length_i(); i++ ) { - str += (char)nibble2hex_byte( *byte_c_l >> 4 ); - str += (char)nibble2hex_byte( *byte_c_l++ ); - } - return str; -} - -int -String_convert::bin2_i( String bin_str ) -{ - assert( bin_str.length_i() <= 4 ); - - int result_i = 0; - for ( int i = 0; i < bin_str.length_i(); i++ ) { - result_i <<= 8; - result_i += (Byte)bin_str[ i ]; - } - return result_i; -} - -// breendet imp from String -int -String_convert::dec2_i( String dec_str ) -{ - if ( !dec_str.length_i() ) - return 0; - - long l = 0; - int conv = sscanf( dec_str.ch_c_l(), "%ld", &l ); - assert( conv ); - - return (int)l; -} - -String -String_convert::longlong_str(long long ll, char const* fmt) -{ - char buffer[STRING_BUFFER_LEN]; - snprintf(buffer, STRING_BUFFER_LEN, - (fmt ? fmt : "%Ld"), ll ); // assume radix 10 - return String(buffer); - -} -// breendet imp from String -double -String_convert::dec2_f( String dec_str ) -{ - if ( !dec_str.length_i() ) - return 0; - double d = 0; - int conv = sscanf( dec_str.ch_c_l(), "%lf", &d ); - assert( conv ); - return d; -} - -int -String_convert::hex2bin_i( String hex_str, String& bin_str_r ) -{ - if ( hex_str.length_i() % 2 ) - hex_str = "0" + hex_str; - - bin_str_r = ""; - Byte const* byte_c_l= hex_str.byte_c_l(); - int i = 0; - while ( i < hex_str.length_i() ) { - int high_i = hex2nibble_i( *byte_c_l++ ); - int low_i = hex2nibble_i( *byte_c_l++ ); - if ( high_i < 0 || low_i < 0 ) - return 1; // illegal char - bin_str_r += String( (char)( high_i << 4 | low_i ), 1 ); - i += 2; - } - return 0; -} - -String -String_convert::hex2bin_str( String hex_str ) -{ - String str; -// silly, asserts should alway be "on"! -// assert( !hex2bin_i( hex_str, str ) ); - int error_i = hex2bin_i( hex_str, str ); - assert( !error_i ); - return str; -} - -int -String_convert::hex2nibble_i( Byte byte ) -{ - if ( byte >= '0' && byte <= '9' ) - return byte - '0'; - if ( byte >= 'A' && byte <= 'F' ) - return byte - 'A' + 10; - if ( byte >= 'a' && byte <= 'f') - return byte - 'a' + 10; - return -1; -} - -// stupido. Should use int_str() -String -String_convert::i2dec_str( int i, int length_i, char ch ) -{ - char fill_ch = ch; - if ( fill_ch) - fill_ch = '0'; - - // ugh - String dec_str( i ); - - // ugh - return String( fill_ch, length_i - dec_str.length_i() ) + dec_str; -} - - -// stupido. Should use int_str() -String -String_convert::i2hex_str( int i, int length_i, char ch ) -{ - String str; - if ( !i ) - str = "0"; - while ( i ) { - str = ( i % 16 )["0123456789abcdef"] + str; - i /= 16; - } - if ( str.length_i() < length_i ) - str = String( ch, length_i - str.length_i() ) + str; - return str; -} - -Byte -String_convert::nibble2hex_byte( Byte byte ) -{ - if ( ( byte & 0x0f ) <= 9 ) - return ( byte & 0x0f ) + '0'; - else - return ( byte & 0x0f ) - 10 + 'a'; -} -/** - Convert an integer to a string - - @param - #fmt# is a printf style format, default assumes "%d" as format. - */ -String -String_convert::int_str(int i, char const* fmt) -{ - char buffer[STRING_BUFFER_LEN]; - snprintf(buffer, STRING_BUFFER_LEN, - (fmt ? fmt : "%d"), i ); // assume radix 10 - return String(buffer); -} - -/** - Convert a double to a string. - - @param #fmt# is a printf style format, default assumes "%lf" as format - */ -String -String_convert::double_str(double f, char const* fmt) -{ - char buf[STRING_BUFFER_LEN]; - - snprintf(buf, STRING_BUFFER_LEN, fmt ? fmt : "%f", f); - return buf; -} - -/** - Make a string from a single character. - - @param - #n# is a repetition count, default value is 1 - */ -String -String_convert::char_str(char c, int n) -{ - n = n >= 0 ? n : 0; - char* ch_p = new char[ n ]; - memset( ch_p, c, n ); - String s((Byte*)ch_p, n); - delete ch_p; - return s; -} - -String -String_convert::rational_str(Rational r) -{ - char * n = Itoa(r.numerator()); // LEAK???? - - String s = n; - if (r.denominator() != 1) { - char * d = Itoa(r.denominator()); - s += String( '/' ) + String(d); - //delete d; - } -/* delete n; - */ - return s; -} - -String -String_convert::pointer_str(const void *l) -{ - long long int ill = (long long int )l; - return String_convert::longlong_str(ill, "0x%0Lx"); -} diff --git a/flower/string-convert.hh b/flower/string-convert.hh deleted file mode 100644 index bcf461f8f3..0000000000 --- a/flower/string-convert.hh +++ /dev/null @@ -1,43 +0,0 @@ -/* - PROJECT: FlowerSoft C++ library - FILE : string-convert.hh - -*/ - -#ifndef STRING_CONVERT_HH -#define STRING_CONVERT_HH - -/* - ///a class which only has functions. -//#define functor class // cute. docxx fucks up -*/ - -/** - The functor String_convert handles all conversions to/from String (some - time, anyway). - The class is quite empty from data view. - */ -class String_convert { - static int hex2bin_i( String hex_str, String& bin_str_r ); - static int hex2nibble_i( Byte byte ); - static Byte nibble2hex_byte( Byte byte ); -public: - static String bin2dec_str( String bin_str ); - static String bin2hex_str( String bin_str ); - static String dec2bin_str( String str ); - static int bin2_i( String str ); - static String char_str(char c, int n); - static int dec2_i( String dec_str ); - static double dec2_f( String dec_str ); - static String double_str(double f, char const* fmt=0); - static int hex2int_i( String str ); - static String hex2bin_str( String str ); - static String int_str(int i, char const *fmt=0 ); - static String i2hex_str( int i, int length_i, char ch ); - static String i2dec_str( int i, int length_i, char ch ); - static String rational_str(Rational); - static String pointer_str(const void *); - static String longlong_str(long long , char const * fmt = 0); -}; - -#endif // __STRING_CONVERT_HH // diff --git a/flower/string-data.hh b/flower/string-data.hh deleted file mode 100644 index d4f4b6b5b9..0000000000 --- a/flower/string-data.hh +++ /dev/null @@ -1,95 +0,0 @@ -/* - string-data.hh -- declare String_data - - source file of the LilyPond music typesetter - - (c) 1997 Han-Wen Nienhuys -*/ - - -#ifndef STRINGDATA_HH -#define STRINGDATA_HH - - -/**Internal String struct. - the data itself. Handles simple tasks (resizing, resetting) - */ -class String_data { - // GNU malloc: storage overhead is 8 bytes anyway. - -friend class String_handle; - int maxlen; // maxlen is arraysize-1 - - int length_i_; - Byte* data_byte_p_; - int references; - - /// init to "" - String_data(); - - /// init from src. Conservative allocation. - String_data(String_data const &src); - - ~String_data(); - - /** POST: maxlen >= j. - @param j, maximum stringlength_i_. - contents thrown away. - */ - void setmax(int j); - - /** POST: maxlen >= j. - @param j, maximum stringlength_i_. - contents are kept if it grows. - */ - void remax(int j); - - /// check if writeable. - void OKW(); - - /// check state. - void OK(); - - /// reduce memory usage. - void tighten(); - - // assignment. - void set( Byte const* byte_c_l, int length_i ); - - void set( char const* ch_c_l ); - - /// concatenation. - void append( Byte const* byte_c_l, int length_i ); - - void operator += ( char const* ch_c_l ); - - char const* ch_c_l() const; - - char* ch_l(); - - Byte const* byte_c_l() const; - - // idem, non const - Byte* byte_l(); - - void trunc(int j); - - /** access element. not really safe. Can alter length_i_ without - #String_data# knowing it. */ - Byte &operator [](int j); - Byte operator [](int j) const; - bool null_terminated_b()const; -}; - - - -#ifdef STRING_UTILS_INLINED -#ifndef INLINE -#define INLINE inline -#endif -#include "string-data.inl" - -#endif - - -#endif // STRING_DATA_HH diff --git a/flower/string-data.inl b/flower/string-data.inl deleted file mode 100644 index f5bdc86c38..0000000000 --- a/flower/string-data.inl +++ /dev/null @@ -1,209 +0,0 @@ -/* -*-C++-*- - String_data.inl -- implement String_data - - source file of Flower lib - - (c) 1997 Han-Wen Nienhuys -*/ - -#ifndef STRINGDATA_INL -#define STRINGDATA_INL - -#include -#include - -#include "string-data.hh" -const int INITIALMAX=8; - -#include - -INLINE void -String_data::OKW() -{ - assert (references == 1); -} - -INLINE void -String_data::OK() -{ - assert(maxlen >= length_i_); - assert(bool(data_byte_p_)); - assert(references >= 1); -} - - -INLINE -String_data::String_data() -{ - references=0; - maxlen = INITIALMAX; - data_byte_p_ = new Byte[maxlen + 1]; - data_byte_p_[0] = 0; - length_i_ = 0; -} - -INLINE -String_data::String_data(String_data const &src) -{ - references=0; - maxlen = length_i_ = src.length_i_; - data_byte_p_ = new Byte[maxlen+1]; // should calc GNU 8byte overhead. - memcpy( data_byte_p_, src.data_byte_p_, length_i_ + 1 ); -} - -INLINE -String_data::~String_data() -{ - assert(references == 0); - delete[] data_byte_p_; -} - -INLINE void -String_data::setmax(int j) -{ - OKW(); - if (j > maxlen) { - delete data_byte_p_; - maxlen = j; - data_byte_p_ = new Byte[maxlen + 1]; - - data_byte_p_[0] = 0; - length_i_ = 0; - } -} - -/* this is all quite hairy: - update of length_i_ - update of maxlen - alloc of buffer - copying of buffer - needs blondification: - split tasks - define change authority -*/ -INLINE void -String_data::remax(int j) -{ - OKW(); - if (j > maxlen) { - Byte *p = new Byte[j + 1]; - memcpy( p, data_byte_p_, ( maxlen = 0 && j <= length_i_); - data_byte_p_[j] = 0; - length_i_ = j; -} - -INLINE bool -String_data::null_terminated_b()const -{ - return !memchr(data_byte_p_, length_i_, 0); -} - -INLINE Byte& -String_data::operator [](int j) -{ - assert(j >= 0 && j <= length_i_); - return data_byte_p_[j] ; -} - -INLINE Byte -String_data::operator [](int j) const -{ - assert(j >= 0 && j <= length_i_); - return data_byte_p_[j]; -} - - - - -#endif // __STRING_UTIL_CC // diff --git a/flower/string-handle.hh b/flower/string-handle.hh deleted file mode 100644 index fe109d8842..0000000000 --- a/flower/string-handle.hh +++ /dev/null @@ -1,70 +0,0 @@ -/* - string-handle.hh -- declare String_handle - - source file of the LilyPond music typesetter - - (c) 1997 Han-Wen Nienhuys -*/ - - -#ifndef STRINGHANDLE_HH -#define STRINGHANDLE_HH -#include "fproto.hh" - - -/** - Reference counting for strings. - - handles ref. counting, and provides a very thin interface using - Byte * - - */ -class String_handle { - String_data* data; - - /// decrease ref count. Named kind of like a Tanenbaum semafore - void down(); - - /// increase ref count - void up(String_data *d); - - /** make sure data has only one reference. - POST: data->references == 1 - */ - void copy(); - -public: - String_handle(); - ~String_handle(); - String_handle(String_handle const & src); - - Byte const* byte_c_l() const; - char const* ch_c_l() const; - Byte* byte_l(); - char* ch_l(); - bool null_terminated_b()const; - void operator =(String_handle const &src); - void operator += (char const *s); - Byte operator[](int j) const; - - /** Access elements. WARNING: NOT SAFE - don't use this for loops. Use byte_c_l() - */ - Byte &operator[](int j); - void append( Byte const* byte_c_l, int length_i ); - void set( Byte const* byte_c_l, int length_i ); - void operator = (char const *p); - void trunc(int j); - int length_i() const; -}; - -#ifdef STRING_UTILS_INLINED -#ifndef INLINE -#define INLINE inline -#endif -#include "string-handle.inl" -/* we should be resetting INLINE. oh well. */ -#endif - - -#endif // STRINGHANDLE_HH diff --git a/flower/string-handle.inl b/flower/string-handle.inl deleted file mode 100644 index 7286fd6d20..0000000000 --- a/flower/string-handle.inl +++ /dev/null @@ -1,156 +0,0 @@ -/* -*-c++-*- - - stringhandle.inl -- implement String_handle - - source file of Flower lib - - (c) 1997 Han-Wen Nienhuys -*/ - -#ifndef STRINGHANDLE_INL -#define STRINGHANDLE_INL - -#include -#include - -#include "string-data.hh" -#include "string-handle.hh" - -INLINE void -String_handle::down() -{ - if (!(--data->references)) delete data; data = 0; -} - -/// increase ref count -INLINE void -String_handle::up(String_data *d) -{ - data=d; data->references ++; -} - -INLINE void -String_handle::copy() -{ - if (data->references !=1){ - String_data *newdata = new String_data(*data); - down(); - up(newdata); - } -} - -INLINE -String_handle::String_handle() -{ - up(new String_data); -} - -INLINE -String_handle::~String_handle() -{ - down(); -} - -INLINE -String_handle::String_handle(String_handle const & src) -{ - up(src.data); -} - -INLINE Byte* -String_handle::byte_l() -{ - copy(); - return data->byte_l(); -} - -INLINE char* -String_handle::ch_l() -{ - copy(); - return (char*)data->byte_l(); -} - -INLINE Byte -const* String_handle::byte_c_l() const -{ - return data->byte_c_l(); -} - -INLINE char const* -String_handle::ch_c_l() const -{ - return (char const*)data->byte_c_l(); -} - -INLINE void -String_handle::operator =(String_handle const &src) -{ - if (this == &src) - return; - down(); - up(src.data); -} - -INLINE void -String_handle::operator += (char const *s) -{ - copy(); - *data += s; -} - - -INLINE Byte -String_handle::operator[](int j) const -{ - return (*data)[j]; -} - -// !NOT SAFE! -// don't use this for loops. Use byte_c_l() -INLINE Byte & -String_handle::operator[](int j) -{ - copy(); // hmm. Not efficient - return data->byte_l()[j]; -} - -INLINE void -String_handle::append( Byte const* byte_c_l, int length_i ) -{ - copy(); - data->append( byte_c_l, length_i ); -} - -INLINE void -String_handle::set( Byte const* byte_c_l, int length_i ) -{ - copy(); - data->set( byte_c_l, length_i ); -} - -INLINE void -String_handle::operator = (char const *p) -{ - copy(); - data->set( p ); -} - -INLINE void -String_handle::trunc(int j) -{ - copy(); data->trunc(j); -} - -INLINE int -String_handle::length_i() const -{ - return data->length_i_; -} - -INLINE bool -String_handle::null_terminated_b() const { - return data->null_terminated_b(); -} - -#endif diff --git a/flower/string.cc b/flower/string.cc deleted file mode 100644 index 60038f6a55..0000000000 --- a/flower/string.cc +++ /dev/null @@ -1,365 +0,0 @@ -/* - - string.cc - implement String - - (c) 1997 Han-Wen Nienhuys & Jan Nieuwenhuizen - - */ - -#include -#include - -#include -#include - -#include "string.hh" -#include "libc-extension.hh" -#include "string-convert.hh" - -#ifdef STRING_DEBUG -void* mymemmove( void* dest, void const* src, size_t n ); -#define memmove mymemmove -#endif - -// return array, alloced with new. -Byte* -String::copy_byte_p() const -{ - Byte const* src = strh_.byte_c_l(); - Byte* dest = new Byte[strh_.length_i() + 1]; - memcpy( dest, src, strh_.length_i() + 1 ); - return dest; -} -void -String::print_on(ostream& os) const -{ - if (strh_.null_terminated_b()) - os << ch_c_l(); - else - for ( int i = 0; i < length_i(); i++ ) - os << (Byte)(*this)[ i ]; -} - -/* - copying, constructing. - */ -String& -String::operator = (String const&source ) -{ - strh_ = source.strh_; - return *this; -} - - -String::String(Rational r) -{ - *this = String_convert::rational_str(r); -} - -String::String (double f, char const* fmt) -{ - *this= String_convert::double_str(f,fmt); -} - -String::String( char c, int n ) -{ - *this = String_convert::char_str (c,n); -} - -/** - @see - String_convert::int_str - */ -String::String(int i, const char * format ) -{ - *this = String_convert::int_str(i,format); -} - -String::String (bool b) -{ - *this = (char const* ) (b ? "true" : "false"); -} - -String::String( char const* source ) -{ - assert(source); - strh_ = source; -} - -String::String( Byte const* byte_l, int length_i ) -{ - strh_.set( byte_l, length_i ); -} - -void -String::append(String s) -{ - strh_.append( s.byte_c_l(), s.length_i() ); -} -void -String::operator +=(String s) -{ - append(s); -} - -void -String::prepend(String s) -{ - s += *this; - *this = s; -} - -int -String::length_i() const -{ - return strh_.length_i(); -} - -Byte const* -String::byte_c_l() const -{ - return strh_.byte_c_l(); -} - -char const* -String::ch_c_l() const -{ - return strh_.ch_c_l(); -} - -Byte* -String::byte_l() -{ - return strh_.byte_l(); -} - -char* -String::ch_l() -{ - return strh_.ch_l(); -} - -/** - Do a signed comparison, analogous to memcmp; - */ -int -String::compare_i(String const& s1, String const& s2 ) -{ - Byte const* p1 = s1.byte_c_l(); - Byte const* p2 = s2.byte_c_l(); - if ( p1 == p2 ) - return 0; - - int i1 = s1.length_i(); - int i2 = s2.length_i(); - - int result= memcmp( p1, p2, i1 = 0 ) { - index_i += next_i; - next_i = right_str( length_i() - index_i - length ).index_i( string ); - } - return index_i; -} - -/** find a character. - - @return - the index of the leftmost character #c# (0 <= return < length_i()), - or -1 if not found. - - ? should return length_i()?, as in string.left_str(index_i(delimiter)) -*/ -int -String::index_i(char c ) const -{ - char const* me = strh_.ch_c_l(); - char const* p = (char const *) memchr( me,c, length_i()); - if ( p ) - return p - me; - return -1; -} - -/** - find the substring. - - @return - index of leftmost occurrence of #searchfor# - */ -int -String::index_i( String searchfor ) const -{ - char const* me = strh_.ch_c_l(); - char const* p = (char const *) memmem( - me, length_i(), searchfor.ch_c_l(), searchfor.length_i()); - - if ( p ) - return p - me; - else - return -1; -} - -/** find chars of a set. - - @return - the index of the leftmost occurance of an element of #set# - */ -int -String::index_any_i( String set ) const -{ - int n = length_i(); - if ( !n ) - return -1; - - const void * me_l = (const void*) strh_.ch_c_l(); - for (int i=0; i < set.length_i(); i++) { - char * found=(char*) memchr(me_l, set[i], n ); - if (found) { - return found - me_l; - } - } - return -1; -} - -String -String::left_str( int n ) const -{ - if (n >= length_i()) - return *this; - - String retval; - if (n < 1) - return retval; - - retval = *this; - retval.strh_.trunc(n); - return retval; -} - -String -String::right_str( int n ) const -{ - if (n > length_i()) - return *this; - - if ( n < 1) - return ""; - - return String( strh_.byte_c_l() + length_i() - n, n ); -} - - -String -String::nomid_str( int index_i, int n ) const -{ - if ( index_i < 0 ) { - n += index_i; - index_i = 0; - } - if ( n <= 0) - return *this; - - return - left_str( index_i ) + - right_str( length_i() - index_i - n ) ; -} - -/* - proposal: change to "cut()" - */ -String -String::mid_str( int index_i, int n ) const -{ - if (index_i <0) { - n += index_i; - index_i=0; - } - - if ( !length_i() || ( index_i < 0 ) || ( index_i >= length_i() ) || ( n < 1 ) ) - return String(); - - if ( ( n > length_i() ) || ( index_i + n > length_i() ) ) - n = length_i() - index_i; - - return String( byte_c_l() + index_i, n ); -} - -String -String::upper_str() const -{ - String str = *this; - str.to_upper(); - return str; -} -void -String::to_upper() -{ - char *s = (char*)strh_.byte_l(); - strnupr( s ,length_i()); -} - -void -String::to_lower() -{ - char* s = strh_.ch_l(); - strnlwr(s,length_i()); -} - - -String -String::lower_str() const -{ - String str = *this; - str.to_lower(); - return str; -} -String -String::reversed_str() const -{ - String str = *this; - strrev( str.byte_l(), str.length_i() ); - return str; -} - -int -String::value_i() const -{ - return String_convert::dec2_i( *this ); -} - -double -String::value_f() const -{ - return String_convert::dec2_f( *this ); -} - - diff --git a/flower/string.hh b/flower/string.hh deleted file mode 100644 index 8cef141169..0000000000 --- a/flower/string.hh +++ /dev/null @@ -1,193 +0,0 @@ -/* - - FILE : string.hh -- declare String - - Rehacked by HWN 3/nov/95 - removed String & 's - introduced Class String_handle - */ - -#ifndef STRING_HH -#define STRING_HH - - -#include -#include -#include - -#include "string-handle.hh" - -/** - - Intuitive string class. provides -\begin{itemize} -\item - ref counting through #String_handle# -\item - conversion from bool, int, double, char* , char. -\item - to be moved to String_convert: - conversion to int, upcase, downcase - -\item - printable. - -\item - indexing (index_i, index_any_i, last_index_i) - -\item - cutting (left_str, right_str, mid_str) - -\item - concat (+=, +) - -\item - signed comparison (<, >, ==, etc) - -\item - No operator[] is provided, since this would be enormously slow. If needed, - convert to char const* . -\end{itemize} - -*/ -class String -{ -protected: - String_handle strh_; - - bool null_terminated(); - -public: - - /** init to empty string. This is needed because other - constructors are provided.*/ - String() { } - String(Rational); - - /// String s = "abc"; - String( char const* source ); - String( Byte const* byte_c_l, int length_i ); - - /// "ccccc" - String( char c, int n = 1 ); - - String( int i , char const *fmt=0); - String ( double f , char const* fmt =0); - /// 'true' or 'false' - String(bool ); - - /// return a "new"-ed copy of contents - Byte* copy_byte_p() const; // return a "new"-ed copy of contents - - char const* ch_c_l() const; - Byte const* byte_c_l() const; - char* ch_l(); - Byte* byte_l(); - - /// deprecated; use ch_c_l() - operator char const* () const { return ch_c_l(); } - - String &operator =( const String & source ); - - /// concatenate s - void operator += (char const* s) { strh_ += s; } - void operator += (String s); - - void append(String); - void prepend(String); - - char operator []( int n ) const { return strh_[n]; } - - /// return n leftmost chars - String left_str( int n ) const; - - /// return n rightmost chars - String right_str( int n ) const; - - /// return uppercase of *this - String upper_str() const; - - /// return lowercase of *this - String lower_str() const; - - /// return the "esrever" of *this - String reversed_str() const; - - - /// return a piece starting at index_i (first char = index_i 0), length n - String mid_str(int index_i, int n ) const; - - /// cut out a middle piece, return remainder - String nomid_str(int index_i, int n ) const; - - /// signed comparison, analogous to memcmp; - static int compare_i(const String& s1,const String& s2); - - /// index of rightmost c - int index_last_i( char c) const; - - /// index of rightmost element of string - int index_last_i( char const* string ) const; - - int index_i(char c ) const; - int index_i(String ) const; - int index_any_i(String ) const; - - void to_upper(); - void to_lower(); - /// provide Stream output - void print_on(ostream& os) const; - - /// the length of the string - int length_i() const; - - // ***** depreciated - int len() const { - return length_i(); - } - - /// convert to an integer - int value_i() const; - - /// convert to a double - double value_f() const; -}; - -#include "compare.hh" - -instantiate_compare(const String &, String::compare_i); - -// because char const* also has an operator ==, this is for safety: -inline bool operator==(String s1, char const* s2){ - return s1 == String(s2); -} -inline bool operator==(char const* s1, String s2) -{ - return String(s1)==s2; -} -inline bool operator!=(String s1, char const* s2 ) { - return s1!=String(s2); -} -inline bool operator!=(char const* s1,String s2) { - return String(s2) !=s1; -} - - -inline String -operator + (String s1, String s2) -{ - s1 += s2; - return s1; -} - -inline ostream & -operator << ( ostream& os, String d ) -{ - d.print_on(os); - return os; -} - - -// String quoteString(String message, String quote); - -#endif diff --git a/flower/stringtest.cc b/flower/stringtest.cc deleted file mode 100644 index 2f085a26d7..0000000000 --- a/flower/stringtest.cc +++ /dev/null @@ -1,114 +0,0 @@ -/* - stupid test program to verify stringlib - stringtest.cc - */ -#include -#include "string.hh" -#include "varray.hh" -#include "string-convert.hh" - -void -ctors() -{ - cout << "constructors"< a; - a.push("abcd"); - a.push("zxy"); - a.push("abc"); - a.push(""); - a.sort(String::compare_i); - cout << "compares: "< -*/ - -#ifdef STRING_DEBUG -#include -#include -void* -mymemmove( void* dest, void const* src, size_t n ) -{ - return memcpy( dest, src, n ); // wohltempererit: 69006 -} -#define memmove mymemmove -#endif - -#ifdef STRING_UTILS_INLINED -#undef STRING_UTILS_INLINED -#endif - -#ifdef INLINE -#undef INLINE -#endif - -#define INLINE - -#include "string-handle.hh" -#include "string-data.hh" -#include "string-data.inl" -#include "string-handle.inl" diff --git a/flower/text-db.cc b/flower/text-db.cc deleted file mode 100644 index ebfc992ff2..0000000000 --- a/flower/text-db.cc +++ /dev/null @@ -1,48 +0,0 @@ -#include "text-db.hh" -bool -Text_db::eof() -{ - Data_file::gobble_leading_white(); - return Data_file::eof(); -} - -void -Text_db::gobble_leading_white() -{ - while (1) { - Data_file::gobble_leading_white(); - if (eof()) - return ; - char c; - if ((c = data_get()) !='\n'){ - data_unget (c); - return ; - } - } -} - - -Text_record -Text_db::get_record() -{ - while (1) { - String s; - Array fields; - assert(!eof()); - - while ((s = get_word()) != "") - { - fields.push(s); - gobble_white(); - } - - - if (get_line() != "") - assert(false); - - assert (fields.size()); - return Text_record(fields, get_name(), line()); - } -} - - diff --git a/flower/text-db.hh b/flower/text-db.hh deleted file mode 100644 index 3535a84f8f..0000000000 --- a/flower/text-db.hh +++ /dev/null @@ -1,55 +0,0 @@ -#ifndef TEXTDB_HH -#define TEXTDB_HH - -#include "data-file.hh" - -/**a "const" Array. Contents can't be changed. do "#" comments, read quote enclosed fields */ - -class Text_record : Array -{ - int line_no; - String filename; - -public: - Text_record() { } // needed because of other ctor - - /// report an error in this line. - message(String s) { - cerr << '\n'<< filename << ": "<< line_no << s << "\n"; - } - String operator[](int j) { - return Array::operator[](j); - } - - Text_record(Array s, String fn, int j) : Array(s) { - filename = fn; line_no = j; - } - Array::size; -}; - -/** abstraction for a datafile. - add a subrec/fieldsep/record separator - */ - -class Text_db : private Data_file -{ - void gobble_leading_white(); -public: - /// get a line with records - Text_record get_record(); - - Text_db(String fn):Data_file(fn) { } - Data_file::error; - bool eof(); - - /// get next line. - Text_record operator++(int) { - return get_record(); - } - /// are we done yet? - operator bool() { - return !eof(); - } -}; - -#endif diff --git a/flower/text-stream.cc b/flower/text-stream.cc deleted file mode 100644 index a2d3e4b119..0000000000 --- a/flower/text-stream.cc +++ /dev/null @@ -1,31 +0,0 @@ -#include "text-stream.hh" - -Text_stream::Text_stream(String fn) -{ - ios::sync_with_stdio(); - if (fn == "") - { - name = ""; - f = stdin; - } - - else - { - name = fn; - f = fopen(fn, "r"); - } - - if (!f) { - cerr <<__FUNCTION__<< ": can't open `" << fn << "'\n"; - exit(1); - } - - line_no = 1; - } - -void -Text_stream::message(String s) -{ - cerr << "\n"< -#include -#include "string.hh" -#include "varray.hh" - -/** - line counting input stream. - a stream for textfiles. linecounting. Thin interface getchar and - ungetchar. (ungetc is unlimited) - - should protect get and unget against improper use -*/ - - -class Text_stream -{ - int line_no; - - // could just have used streams. - FILE *f; - Array pushback; - String name; - - public: - Text_stream(String fn); - String get_name() { return name; } - bool eof() { - return feof(f); - } - bool eol() { - return (peek() == '\n'); - } - char peek() { - char c = get(); - unget(c); - return c; - } - int line(){ - return line_no; - } - - char get() { - char c; - - if (pushback.empty()) - c = getc(f); - else - c = pushback.pop(); - - if (c =='\n') - line_no++; - return c; - } - void unget(char c) { - if (c =='\n') - line_no--; - pushback.push(c); - } - ~Text_stream (){ - if (!eof()) - cerr <<__FUNCTION__<< ": closing unended file"; - - fclose(f); - } - - /// GNU format message. - void message(String s); -}; - -#endif diff --git a/flower/unionfind.cc b/flower/unionfind.cc deleted file mode 100644 index e7b0831dd1..0000000000 --- a/flower/unionfind.cc +++ /dev/null @@ -1,35 +0,0 @@ -#include "unionfind.hh" -/* - see a book on data structures - */ - -Union_find::Union_find(int n) -{ - classes.set_size(n); - - for (int i=0; i < n; i++) { - classes[i] = i; - } -} - -int -Union_find::find(int i) -{ - int rep = i; - while (classes[rep] != rep) - rep = classes[rep]; - while (classes[i] != rep) { - int next =classes[i]; - classes[i] = rep; - i = next; - } - return rep; -} - -void -Union_find::connect(int i, int j) -{ - i = find(i); - j = find(j); - classes[i] = j; -} diff --git a/flower/unionfind.hh b/flower/unionfind.hh deleted file mode 100644 index fbaa51e731..0000000000 --- a/flower/unionfind.hh +++ /dev/null @@ -1,25 +0,0 @@ -#ifndef UNIONFIND_HH -#define UNIONFIND_HH -#include "varray.hh" - -/* - which points of a graph are connected?. - Union find, a standard algorithm: - - Union_find represents an undirected graph of N points. You can - connect two points using #connect()#. #find(i)# finds a uniquely - determined representant of the equivalence class of points - connected to #i#. - - */ -struct Union_find { - void connect(int i, int j); - int find(int i); - bool equiv(int i, int j) { return find(i) == find(j); } - Union_find(int sz); - -private: - Array classes; - -}; -#endif diff --git a/flower/varray.hh b/flower/varray.hh deleted file mode 100644 index febf3e7601..0000000000 --- a/flower/varray.hh +++ /dev/null @@ -1,186 +0,0 @@ -/* - (c) Han-Wen Nienhuys 1995,96 - - Distributed under GNU GPL -*/ - -#ifndef ARRAY_H -#define ARRAY_H -#include - -/// copy a bare (C-)array from #src# to #dest# sized #count# -template -inline void arrcpy(T*dest, T*src, int count) { - for (int i=0; i < count ; i++) - *dest++ = *src++; -} - - -/** - Scaleable array/stack template, for a type T with default constructor. - - - This template implements a scaleable vector. With (or without) range - checking. It may be flaky for objects with complicated con- and - destructors. The type T should have a default constructor. It is - best suited for simple types, such as int, double or String, it - provides a paranoidly safe replacement for the new T[int] construct. - - It uses stack terminology, (push, pop, top), and can be used as a stack. - - - */ -template -class Array { -protected: - /// maximum length of array. - int max; - - /// the data itself - T *thearray; - - /// stretch or shrink array. - void remax(int newmax) { - T* newarr = new T[newmax]; - size_ = (newmax < size_) ? newmax : size_; - arrcpy(newarr, thearray, size_); - - delete[] thearray; - thearray = newarr; - max = newmax; - } - int size_; - -public: - /// check invariants - void OK() const { - assert(max >= size_ && size_ >=0); - if (max) assert(thearray); - } - /** report the size_. - @see {setsize_} - */ - int size() const { return size_; } - - /// POST: size() == 0 - void clear() { size_ = 0; } - - Array() { thearray = 0; max =0; size_ =0; } - - - /** set the size_ to #s#. - POST: size() == s. - Warning: contents are unspecified */ - void set_size(int s) { - if (s >= max) remax(s); - size_ = s; - } - - ~Array() { delete[] thearray; } - - /// return a "new"ed copy of array - T* copy_array() const { - T* Tarray = new T[size_]; - arrcpy(Tarray, thearray, size_); - return Tarray; - } - // depracated - operator T* () const { - return copy_array(); - } - void operator=(Array const & src) { - set_size (src.size_); - arrcpy(thearray,src.thearray, size_); - } - Array(const Array & src) { - thearray = src.copy_array(); - max = size_ = src.size_; - } - - /// tighten array size_. - void precompute () { remax(size_); } - - /// this makes Array behave like an array - T &operator[] (const int i) const { - assert(i >=0&&i=0 && j<= size_); - set_size(size_+1); - for (int i=size_-1; i > j; i--) - thearray[i] = thearray[i-1]; - thearray[j] = k; - } - void del(int i) { - assert(i >=0&& i < size_); - arrcpy(thearray+i, thearray+i+1, size_-i-1); - size_--; - } - // quicksort. - void sort (int (*compare)( T const&,T const&), - int lower = -1, int upper = -1 ) { - if (lower < 0) { - lower = 0 ; - upper = size()-1; - } - if (lower >= upper) - return; - swap(lower, (lower+upper)/2); - int last = lower; - for (int i= lower +1; i <= upper; i++) - if (compare(thearray[i], thearray[lower]) < 0 ) - swap( ++last,i); - swap(lower, last); - sort(compare, lower, last-1); - sort(compare, last+1, upper); - } - void concat(Array const &src) { - int s = size_; - set_size(size_ + src.size_); - arrcpy(thearray+s,src.thearray, src.size_); - } - Array subvec(int lower, int upper) { - assert(lower >= 0 && lower <=upper&& upper <= size_); - Array r; - int s =upper-lower; - r.set_size(s); - arrcpy(r.thearray, thearray + lower, s); - return r; - } -}; - -#endif diff --git a/flower/vector.cc b/flower/vector.cc deleted file mode 100644 index 5cc76bfd7b..0000000000 --- a/flower/vector.cc +++ /dev/null @@ -1,25 +0,0 @@ -#include "vector.hh" -Vector::Vector(Array d) - : dat(d) -{ - -} -Vector::Vector(const Vector&n) - : dat(n.dat) -{ -} - -Vector -Vector::operator-() const -{ - Vector v(*this); - v*=-1; - return v; -} - -void -Vector::set_unit(int j) -{ - fill(0.0); - dat[j] = 1.0; -} diff --git a/flower/vector.hh b/flower/vector.hh deleted file mode 100644 index 4d91397cc6..0000000000 --- a/flower/vector.hh +++ /dev/null @@ -1,111 +0,0 @@ -#ifndef VECTOR_HH -#define VECTOR_HH - -#include -#include "real.hh" -#include "varray.hh" - -class Dstream; -class String; -void set_matrix_debug(Dstream&ds); - -/** a row of numbers. - a vector. Storage is handled in Array, Vector only does the mathematics. - */ -class Vector { - Array dat; -public: - void OK() const { dat.OK();} - int dim() const { return dat.size(); } - Vector() { } - Vector(Array d ); - Vector(const Vector&n); - Vector(int n) { - dat.set_size(n); - fill(0); - } - void insert(Real v, int i) { - dat.insert(v,i); - } - void del(int i) { dat.del(i); } - operator String() const; - void fill(Real r) { - for (int i=0; i < dim(); i++) - dat[i] =r; - } - - void operator +=(Vector v) { - assert(v.dim() == dim()); - for (int i=0; i < dim(); i++) - dat[i] += v.dat[i]; - } - - void operator /=(Real a) { - (*this) *= 1/a; - } - - void operator *=(Real a) { - for (int i=0; i < dim(); i++) - dat[i] *= a; - } - - void operator -=(Vector v) { - assert(v.dim() == dim()); - for (int i=0; i < dim(); i++) - dat[i] -= v(i); - } - - Real &operator()(int i) { return dat[i]; } - Real operator()(int i) const { return dat[i]; } - Real elem(int i) { return dat[i]; } - Real operator *(Vector v) const { - Real ip=0; - assert(v.dim() == dim()); - for (int i=0; i < dim(); i++) - ip += dat[i] *v(i); - return ip; - } - Vector operator-() const; - Real norm() { - return sqrt(norm_sq() ); - } - Real norm_sq() { - return ((*this) * (*this)); - } - operator Array () { return dat; } - void print() const; - /// set to j-th element of unit-base - void set_unit(int j) ; -}; - -inline Vector -operator+(Vector a, Vector const &b) { - a += b; - return a; -} - -inline Vector -operator-(Vector a, Vector const &b) { - a -= b; - return a; -} - -inline Vector -operator*(Vector v, Real a) { - v *= a; - return v; -} - -inline Vector -operator*( Real a,Vector v) { - v *= a; - return v; -} - -inline Vector -operator/(Vector v,Real a) { - v *= 1/a; - return v; -} - -#endif diff --git a/flower/vsmat.hh b/flower/vsmat.hh deleted file mode 100644 index 283b1e567b..0000000000 --- a/flower/vsmat.hh +++ /dev/null @@ -1,141 +0,0 @@ -#ifndef VSMAT_HH -#define VSMAT_HH -#include "varray.hh" -#include "real.hh" -/** base class for interface with matrix storageclasses. There are no - iterators for matrixclasses, since matrices are (like arrays) - explicitly int-indexed. - - Iteration is provided by *_next, *_ok, which update and check both - index variables simultaneously. - - TODO - determine type of product matrix. - -*/ -class virtual_smat { - - -public: - /// check invariants - virtual void OK() const=0; - - /// height of matrix - virtual int rows() const = 0; - - /// width of matrix - virtual int cols() const = 0; - - - /** set the size. contents lost. - PRE - i >=0, j>=0 - */ - virtual void set_size(int i, int j) = 0; - - /**set the size to square dimen. contents lost - PRE - i>=0 - */ - virtual void set_size(int i) = 0; - /**set the size to i. - - keep contents. If enlarged contents unspecified - - PRE - i>=0, j>=0 - - */ - virtual void resize(int i, int j) = 0; - - /** - set the size to square dimen. contents kept - Keep contents. If enlarged contents are unspecified - - PRE - i>=0 - */ - virtual void resize(int i) = 0; - - - /** - access an element. - - Generate an errormessage, if this happens - in the 0-part of a sparse matrix. - */ - - virtual Real& elem(int i,int j) = 0; - - /// access a element, no modify - virtual const Real& elem(int i, int j) const = 0; - -#if 1 - virtual Array row(int i) const = 0; - virtual Array column(int j) const = 0; -#endif - - - /** - add a row to the matrix before row k. Contents - of added row are unspecified - - 0 <= k <= rows() - */ - virtual void insert_row(int k)=0; - - - /** - delete a row from this matrix. - - PRE - 0 <= k < rows(); - */ - virtual void delete_row(int k)=0; - virtual void delete_column(int k)=0; - virtual ~virtual_smat() { } - virtual virtual_smat *clone()=0; - - - - /** - at end of matrix?. when doing loop - - for(i=0; i