From 16bd71e1dd946f873ba6f20f6ad97b7a043567bb Mon Sep 17 00:00:00 2001 From: Han-Wen Nienhuys & Jan Nieuwenhuizen Date: Thu, 6 Mar 1997 19:16:55 +0100 Subject: [PATCH] partial: 0.0.39-1.hanjan --- flower/lib/include/pcursor.hh | 68 ++++ flower/lib/include/plist.hh | 72 ++++ flower/lib/include/plist.inl | 21 + flower/lib/string.cc | 365 ++++++++++++++++++ {src => lib}/input-file.cc | 0 .../include/lyric-walker.hh | 0 {hdr => lily/include}/midi-walker.hh | 0 lily/midi-output.cc | 116 ++++++ {src => lily}/midi-walker.cc | 0 9 files changed, 642 insertions(+) create mode 100644 flower/lib/include/pcursor.hh create mode 100644 flower/lib/include/plist.hh create mode 100644 flower/lib/include/plist.inl create mode 100644 flower/lib/string.cc rename {src => lib}/input-file.cc (100%) rename hdr/lyricwalker.hh => lily/include/lyric-walker.hh (100%) rename {hdr => lily/include}/midi-walker.hh (100%) create mode 100644 lily/midi-output.cc rename {src => lily}/midi-walker.cc (100%) 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/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/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/src/input-file.cc b/lib/input-file.cc similarity index 100% rename from src/input-file.cc rename to lib/input-file.cc diff --git a/hdr/lyricwalker.hh b/lily/include/lyric-walker.hh similarity index 100% rename from hdr/lyricwalker.hh rename to lily/include/lyric-walker.hh diff --git a/hdr/midi-walker.hh b/lily/include/midi-walker.hh similarity index 100% rename from hdr/midi-walker.hh rename to lily/include/midi-walker.hh diff --git a/lily/midi-output.cc b/lily/midi-output.cc new file mode 100644 index 0000000000..7714a99fa8 --- /dev/null +++ b/lily/midi-output.cc @@ -0,0 +1,116 @@ +/* + midioutput.cc -- implement Midi_output + + source file of the LilyPond music typesetter + + (c) 1997 Han-Wen Nienhuys , Jan Nieuwenhuizen +*/ + +// "" huh? +#include "time.h" + +#include "proto.hh" +#include "plist.hh" +#include "string.hh" +#include "string-convert.hh" +#include "debug.hh" +#include "score.hh" +#include "staff.hh" +#include "main.hh" +#include "midi-stream.hh" +#include "midi-def.hh" +#include "midi-output.hh" +#include "midi-walker.hh" +#include "midi-item.hh" +#include "staff-column.hh" +#include "musicalrequest.hh" + + +Midi_output::Midi_output(Score* score_l, Midi_def* midi_l ) +{ + midi_l_ = midi_l; + score_l_ = score_l; + + Midi_stream midi_stream(midi_l->outfile_str_, score_l_->staffs_.size(), 384 ); + midi_stream_l_ = &midi_stream; + + header(); + staffs(); +} + +void +Midi_output::do_staff(Staff*st_l,int track_i) +{ + Midi_track midi_track( track_i ); + + // set track name + Midi_text track_name( Midi_text::TRACK_NAME, "Track " + String_convert::i2dec_str( track_i, 2, 0 ) ); + midi_track.add( Moment( 0.0 ), &track_name ); + + // set instrument :-) + Midi_text instrument_name( Midi_text::INSTRUMENT_NAME, "piano" ); + midi_track.add( Moment( 0.0 ), &instrument_name ); + + // set key, help, where to get key, where to get major/minor? + int accidentals_i = 0; + int minor_i = 0; + + // sorry, wanna test this... + // menuetto in F + if ( ( infile_str_g.index_i( "scsii-menuetto" ) >= 0 ) + || ( infile_str_g.index_i( "standchen" ) >= 0 ) ) + accidentals_i = -1; + // standchen in d + if ( ( infile_str_g.index_i( "standchen" ) >= 0 ) ) + minor_i = 1; + + Midi_key midi_key( accidentals_i, minor_i ); + midi_track.add( Moment( 0.0 ), &midi_key ); + + Midi_tempo midi_tempo( midi_l_->get_tempo_i( Moment( 1, 4 ) ) ); + midi_track.add( Moment( 0.0 ), &midi_tempo ); + + for (Midi_walker w (st_l, &midi_track); w.ok(); w++) + w.process_requests(); + + *midi_stream_l_ << midi_track; +} + +void +Midi_output::header() +{ + Midi_track midi_track( 0 ); + + time_t t = time( 0 ); + + // perhaps multiple text events? + String str = String( "Creator: " ) + get_version() + "\n"; + str += "Generated, at "; + str += ctime( &t ); + str += ", from musical definition: " + infile_str_g; + str += "\n"; + + Midi_text creator( Midi_text::TEXT, str ); + midi_track.add( Moment( 0.0 ), &creator ); + + struct tm* tm_l = gmtime( &t ); + String year_str = String_convert::i2dec_str( 1900 + tm_l->tm_year, 4, '0' ); + + // your copyleft here + str = " Copyleft (o) " + year_str; + str += " Han-Wen Nienhuys , " + " Jan Nieuwenhuizen \n"; + + Midi_text copyleft( Midi_text::COPYRIGHT, str ); + midi_track.add( Moment( 0.0 ), ©left ); + *midi_stream_l_ << midi_track; +} + +void +Midi_output::staffs() +{ + int track_i = 1; + for (iter_top(score_l_->staffs_,i); i.ok(); i++) + do_staff(i, track_i++); +} + diff --git a/src/midi-walker.cc b/lily/midi-walker.cc similarity index 100% rename from src/midi-walker.cc rename to lily/midi-walker.cc -- 2.39.5