From f303f11689162e645926d83fe40ba79772e01557 Mon Sep 17 00:00:00 2001 From: fred Date: Mon, 3 Mar 1997 13:57:50 +0000 Subject: [PATCH] flower-1.1.4 --- flower/NEWS | 5 +- flower/Sources.make | 23 +++--- flower/assoc-iter.hh | 39 ++++++++++ flower/assoc.hh | 9 ++- flower/choleski.cc | 2 +- flower/data-file.cc | 95 ++++++++++++++++++++++++ flower/data-file.hh | 59 +++++++++++++++ flower/fproto.hh | 24 +++--- flower/lgetopt.cc | 30 +++++--- flower/lgetopt.hh | 37 ++++++---- flower/matdebug.cc | 1 + flower/pcursor.hh | 4 +- flower/smat.cc | 12 +-- flower/string-data.hh | 95 ++++++++++++++++++++++++ flower/string-handle.hh | 70 ++++++++++++++++++ flower/string-handle.inl | 156 +++++++++++++++++++++++++++++++++++++++ flower/string.hh | 47 +++++------- flower/stringtest.cc | 105 +++++++++++++++++++++----- flower/stringutil.cc | 8 +- flower/text-db.cc | 48 ++++++++++++ flower/text-db.hh | 55 ++++++++++++++ flower/text-stream.cc | 31 ++++++++ flower/text-stream.hh | 74 +++++++++++++++++++ flower/varray.hh | 11 ++- 24 files changed, 922 insertions(+), 118 deletions(-) create mode 100644 flower/assoc-iter.hh create mode 100644 flower/data-file.cc create mode 100644 flower/data-file.hh create mode 100644 flower/string-data.hh create mode 100644 flower/string-handle.hh create mode 100644 flower/string-handle.inl create mode 100644 flower/text-db.cc create mode 100644 flower/text-db.hh create mode 100644 flower/text-stream.cc create mode 100644 flower/text-stream.hh diff --git a/flower/NEWS b/flower/NEWS index d6d6d86aed..36c03ddcd4 100644 --- a/flower/NEWS +++ b/flower/NEWS @@ -1,4 +1,7 @@ -pl 1.1.3-1 + +pl 1.1.4 + - great file-renaming. + - String cleanup (binary <-> null terminate), several bugfixes - great renaming of String and String_convert interfaces - more conversions moved (copied actually) to String_convert - String indexing now all base = 0, not found = -1 diff --git a/flower/Sources.make b/flower/Sources.make index 82454e3e3c..4e08bec735 100644 --- a/flower/Sources.make +++ b/flower/Sources.make @@ -1,18 +1,21 @@ -cc=choleski.cc datafile.cc dstream.cc lgetopt.cc matdebug.cc matrix.cc\ -path.cc scalar.cc smat.cc string.cc string-convert.cc stringutil.cc\ -textdb.cc textstream.cc unionfind.cc vector.cc +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 stringdata.inl stringhandle.inl +inl=link.inl list.inl cursor.inl plist.inl string-data.inl string-handle.inl -hh=assoc.hh associter.hh choleski.hh compare.hh cursor.hh dstream.hh\ -fproto.hh handle.hh interval.hh iterate.hh lgetopt.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 stringhandle.hh stringdata.hh\ -textdb.hh textstream.hh unionfind.hh pqueue.hh\ -varray.hh vector.hh vsmat.hh datafile.hh +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/assoc-iter.hh b/flower/assoc-iter.hh new file mode 100644 index 0000000000..34b88df22d --- /dev/null +++ b/flower/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/assoc.hh b/flower/assoc.hh index 07afb8a27c..99e20914b7 100644 --- a/flower/assoc.hh +++ b/flower/assoc.hh @@ -4,6 +4,9 @@ #include "varray.hh" #include +/** + A helper for Assoc + */ template struct Assoc_ent_ { bool free; @@ -12,7 +15,8 @@ struct Assoc_ent_ { }; -/** mindblowingly stupid Associative array implementation.Hungarian: map +/** mindblowingly stupid Associative array implementation. + Hungarian: map */ template struct Assoc { @@ -62,9 +66,6 @@ public: int i = find_creat(key); arr[i].val = val; } - /* - should create "set" template - */ V& operator[](K key) { return arr[find_creat(key)].val; } diff --git a/flower/choleski.cc b/flower/choleski.cc index 4202a9b1e5..1d64f949ac 100644 --- a/flower/choleski.cc +++ b/flower/choleski.cc @@ -59,7 +59,7 @@ Choleski_decomposition::Choleski_decomposition(Matrix P) assert((original()-P).norm() / P.norm() < EPS); #endif } - + Matrix Choleski_decomposition::original() const { diff --git a/flower/data-file.cc b/flower/data-file.cc new file mode 100644 index 0000000000..0dad79c91f --- /dev/null +++ b/flower/data-file.cc @@ -0,0 +1,95 @@ +#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 new file mode 100644 index 0000000000..dae9e56347 --- /dev/null +++ b/flower/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 IPointerList; template struct Cursor; template struct PCursor; template struct Link; -template struct Handle ; -templatestruct Interval_t ; +template struct Handle; +templatestruct Interval_t; #include "real.hh" typedef Interval_t Interval; -struct Choleski_decomposition ; +struct Choleski_decomposition; -struct long_option_init ; -struct Getopt_long ; -struct Matrix ; -struct String_data ; -struct String_handle ; +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 ; -class Text_stream; -class Data_file ; +struct virtual_smat; +struct Vector ; +struct Text_stream; +struct Data_file; struct Text_db; struct Scalar; typedef unsigned char Byte; diff --git a/flower/lgetopt.cc b/flower/lgetopt.cc index 523d54ee5f..a56c64c6db 100644 --- a/flower/lgetopt.cc +++ b/flower/lgetopt.cc @@ -1,7 +1,6 @@ /* process command line, GNU style. - this is (Copyleft) 1996, Han-Wen Nienhuys, */ #include @@ -10,15 +9,18 @@ #include "lgetopt.hh" long -Getopt_long::intarg() { +Getopt_long::intarg() +{ long l; if (sscanf(optarg, "%ld", &l) != 1) report(E_ILLEGALARG); return l; } -long_option_init * -Getopt_long::parselong() { + +Long_option_init * +Getopt_long::parselong() +{ const char *optnm = argv[optind] + 2 ; assert(*optnm); @@ -64,7 +66,7 @@ Getopt_long::parselong() { ostream & -long_option_init::printon(ostream &errorout) +Long_option_init::printon(ostream &errorout) { if (shortname) errorout <<"-" << shortname; @@ -91,7 +93,8 @@ Getopt_long::report(Errorcod c) *errorout << "requires an argument"<longname << "' does not allow an argument"<longname << "' does not allow an argument"<::ok; Cursor::del; Cursor::backspace; - T get() { + T get_p() { T p = ptr(); Cursor::del(); return p; } T get_prev() { (*this)--; - return get(); + return get_p(); } PointerList &list() { return (PointerList&)Cursor::list(); } diff --git a/flower/smat.cc b/flower/smat.cc index d89e3bc285..dcc61ce44e 100644 --- a/flower/smat.cc +++ b/flower/smat.cc @@ -19,16 +19,6 @@ Full_storage::OK() const assert(maxh >= h && maxw >= w); assert(h >= 0 && w >= 0); assert(els||!maxh); - if (maxh>0) { // access outer elts. - Real *r = els[maxh -1]; - #if 0 - if (maxw>0) { - assert(r); - Real s = r[maxw -1]; // accessing unitialised memory. - s = sin(s); - } - #endif - } #endif } void @@ -59,7 +49,7 @@ Full_storage::resize_rows(int neww) return; } for (int i=0; i < maxh ; i++) { - Real* newa=new Real[neww]; + Real* newa = new Real[neww]; for (int k=0; k < w; k++) newa[k] = els[i][k]; diff --git a/flower/string-data.hh b/flower/string-data.hh new file mode 100644 index 0000000000..d4f4b6b5b9 --- /dev/null +++ b/flower/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 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-handle.hh b/flower/string-handle.hh new file mode 100644 index 0000000000..fe109d8842 --- /dev/null +++ b/flower/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 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 new file mode 100644 index 0000000000..7286fd6d20 --- /dev/null +++ b/flower/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::null_terminated_b() const { + return data->null_terminated_b(); +} + +#endif diff --git a/flower/string.hh b/flower/string.hh index 7aa19047d1..8cef141169 100644 --- a/flower/string.hh +++ b/flower/string.hh @@ -15,7 +15,7 @@ #include #include -#include "stringhandle.hh" +#include "string-handle.hh" /** @@ -24,15 +24,12 @@ \item ref counting through #String_handle# \item - - conversion from bool, int, double, char* , char. + conversion from bool, int, double, char* , char. \item - to be moved to String_convert: conversion to int, upcase, downcase \item - printable. \item @@ -51,35 +48,34 @@ No operator[] is provided, since this would be enormously slow. If needed, convert to char const* . \end{itemize} + */ class String { protected: - String_handle strh_; // should derive String from String_handle? + String_handle strh_; + bool null_terminated(); + public: - /** init to "". needed because other constructors are provided.*/ + /** 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 s( 10 ); - String( int i ); - + String( int i , char const *fmt=0); + String ( double f , char const* fmt =0); /// 'true' or 'false' String(bool ); - /// String s( 3.14, 6, '#' ); - String ( double f , char const* fmt =0); - String( int i, int n, char c = ' ' ); - /// return a "new"-ed copy of contents Byte* copy_byte_p() const; // return a "new"-ed copy of contents @@ -91,12 +87,15 @@ public: /// deprecated; use ch_c_l() operator char const* () const { return ch_c_l(); } - String operator =( const String & source ) { strh_ = source.strh_; return *this; } + 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 @@ -130,17 +129,12 @@ public: /// index of rightmost element of string int index_last_i( char const* string ) const; - /** - index of leftmost c. - - @return - -1 if not found, else index - */ int index_i(char c ) const; - int index_i(char const* string ) const; - int index_any_i(char const* string ) 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; @@ -157,7 +151,6 @@ public: /// convert to a double double value_f() const; - // ***** }; #include "compare.hh" @@ -197,6 +190,4 @@ operator << ( ostream& os, String d ) // String quoteString(String message, String quote); -#include "string-convert.hh" - #endif diff --git a/flower/stringtest.cc b/flower/stringtest.cc index c0c50da5c6..2f085a26d7 100644 --- a/flower/stringtest.cc +++ b/flower/stringtest.cc @@ -1,42 +1,113 @@ -// stringtest.cc - +/* + 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: "< 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 new file mode 100644 index 0000000000..3535a84f8f --- /dev/null +++ b/flower/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/text-stream.cc b/flower/text-stream.cc new file mode 100644 index 0000000000..a2d3e4b119 --- /dev/null +++ b/flower/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"< +#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/varray.hh b/flower/varray.hh index d2c2f55321..febf3e7601 100644 --- a/flower/varray.hh +++ b/flower/varray.hh @@ -17,13 +17,18 @@ inline void arrcpy(T*dest, T*src, int count) { /** - scaleable array/stack template, for T with def ctor. + 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 + 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 { @@ -146,7 +151,7 @@ public: size_--; } // quicksort. - void sort (int (*compare)(T& , T& ), + void sort (int (*compare)( T const&,T const&), int lower = -1, int upper = -1 ) { if (lower < 0) { lower = 0 ; -- 2.39.5