From 6d10791f358dc637ee7d8858fb61f959f1262b3c Mon Sep 17 00:00:00 2001 From: Han-Wen Nienhuys Date: Sun, 14 Nov 2004 14:16:09 +0000 Subject: [PATCH] * lily/include/object-key-undumper.hh (Module): new file. * lily/object-key-undumper.cc (Module): New file. Deserialize keys. SCM bindings * lily/object-key-dumper.cc (Object_key_dumper): idem. Provide SCM bindings. * lily/include/object-key-dumper.hh (class Object_key_dumper): new file. Serialize object keys. * lily/object-key.cc (dump): new function. (as_scheme): new virtual function (undump): new function (undumpers): new table. * lily/include/global-context.hh (Context): take \score key upon init. * lily/object-key-dumper.cc (serialize_key): new file. * lily/include/object-key-dumper.hh (class Object_key_dumper): new file. * lily/lily-lexer.cc: remove \quote. * lily/lookup.cc (triangle): rewrite, obviating symmetric_x_triangle(). * lily/context.cc (Context): take key argument in ctor. (create_context): new function * lily/lilypond-key.cc (do_compare): new file. * lily/object-key.cc (Object_key): new file. * lily/include/object-key.hh (class Object_key): new file. * lily/include/lilypond-key.hh (class Lilypond_context_key): new file. --- ChangeLog | 25 +++++ VERSION | 2 +- lily/book.cc | 33 +++++-- lily/global-context.cc | 4 +- lily/include/book.hh | 10 +- lily/include/global-context.hh | 2 +- lily/include/lilypond-key.hh | 20 ++++ lily/include/moment.hh | 2 +- lily/include/object-key-dumper.hh | 42 ++++++++ lily/include/object-key-undumper.hh | 29 ++++++ lily/include/object-key.hh | 20 +++- lily/include/output-def.hh | 1 + lily/include/score.hh | 9 +- lily/lily-lexer.cc | 2 +- lily/lily-parser.cc | 13 ++- lily/lilypond-key.cc | 116 +++++++++++++++++++++- lily/lookup.cc | 2 +- lily/moment.cc | 10 ++ lily/object-key-dumper.cc | 148 ++++++++++++++++++++++++++++ lily/object-key-undumper.cc | 128 ++++++++++++++++++++++++ lily/object-key.cc | 65 +++++++++++- lily/parser.yy | 16 ++- lily/score.cc | 54 +++++++--- ly/init.ly | 2 +- scm/lily.scm | 3 +- 25 files changed, 707 insertions(+), 51 deletions(-) create mode 100644 lily/include/object-key-dumper.hh create mode 100644 lily/include/object-key-undumper.hh create mode 100644 lily/object-key-dumper.cc create mode 100644 lily/object-key-undumper.cc diff --git a/ChangeLog b/ChangeLog index 023d20da13..b79a8d1df0 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,30 @@ 2004-11-14 Han-Wen Nienhuys + * lily/include/object-key-undumper.hh (Module): new file. + + * lily/object-key-undumper.cc (Module): New file. Deserialize + keys. SCM bindings + + * lily/object-key-dumper.cc (Object_key_dumper): idem. + Provide SCM bindings. + + * lily/include/object-key-dumper.hh (class Object_key_dumper): + new file. Serialize object keys. + + + * lily/object-key.cc (dump): new function. + (as_scheme): new virtual function + (undump): new function + (undumpers): new table. + + * lily/include/global-context.hh (Context): take \score key upon init. + + * lily/object-key-dumper.cc (serialize_key): new file. + + * lily/include/object-key-dumper.hh (class Object_key_dumper): new file. + + * lily/lily-lexer.cc: remove \quote. + * lily/lookup.cc (triangle): rewrite, obviating symmetric_x_triangle(). * lily/context.cc (Context): take key argument in ctor. diff --git a/VERSION b/VERSION index 7395742c6f..7a3bd85580 100644 --- a/VERSION +++ b/VERSION @@ -2,5 +2,5 @@ PACKAGE_NAME=LilyPond MAJOR_VERSION=2 MINOR_VERSION=5 PATCH_LEVEL=0 -MY_PATCH_LEVEL= +MY_PATCH_LEVEL=hwn1 diff --git a/lily/book.cc b/lily/book.cc index e9f7eee375..640600f6d3 100644 --- a/lily/book.cc +++ b/lily/book.cc @@ -8,6 +8,7 @@ #include +#include "lilypond-key.hh" #include "book.hh" #include "global-context.hh" #include "ly-module.hh" @@ -47,6 +48,10 @@ Book::mark_smob (SCM s) for (int i = 0; i < score_count; i++) scm_gc_mark (book->scores_[i]->self_scm ()); +#if 0 + if (book->key_) + scm_gc_mark (book->key_->self_scm()); +#endif if (book->paper_) scm_gc_mark (book->paper_->self_scm ()); return book->header_; @@ -70,26 +75,33 @@ Book::process (String outname, Output_def *default_def) if (error) return 0; - + Paper_book *paper_book = new Paper_book (); Real scale = scm_to_double (paper_->c_variable ("outputscale")); - Output_def * scaled_bookdef = scale_output_def (paper_, scale); + + Object_key * key = new Lilypond_general_key (0, user_key_, 0); + SCM scm_key = key->self_scm(); + scm_gc_unprotect_object (scm_key); + paper_book->paper_ = scaled_bookdef; scm_gc_unprotect_object (scaled_bookdef->self_scm()); paper_book->header_ = header_; - int score_count = scores_.size (); for (int i = 0; i < score_count; i++) { SCM systems = scores_[i]->book_rendering (outname, paper_book->paper_, - default_def); + default_def, + key + ); - /* If the score is empty, generate no output. Should we - do titling? */ + /* + If the score is empty, generate no output. Should we + do titling? + */ if (SCM_NFALSEP(scm_vector_p (systems))) { Score_systems sc; @@ -99,6 +111,8 @@ Book::process (String outname, Output_def *default_def) } } + + scm_remember_upto_here_1 (scm_key); return paper_book; } @@ -129,3 +143,10 @@ LY_DEFINE(ly_make_book, "ly:make-book", return x; } + +void +Book::add_score (Score *s) +{ + scores_.push (s); + scm_gc_unprotect_object (s->self_scm ()); +} diff --git a/lily/global-context.cc b/lily/global-context.cc index 869e93622f..44065e9cb4 100644 --- a/lily/global-context.cc +++ b/lily/global-context.cc @@ -18,8 +18,8 @@ #include "output-def.hh" #include "lilypond-key.hh" -Global_context::Global_context (Output_def *o, Moment final) - : Context (new Lilypond_context_key(0, +Global_context::Global_context (Output_def *o, Moment final, Object_key *key) + : Context (new Lilypond_context_key(key, Moment(0), "Global", "", 0)) { diff --git a/lily/include/book.hh b/lily/include/book.hh index 7f3eca8607..062658420a 100644 --- a/lily/include/book.hh +++ b/lily/include/book.hh @@ -13,18 +13,22 @@ #include "lily-proto.hh" #include "parray.hh" #include "smobs.hh" +#include "object-key.hh" +#include "string.hh" class Book : public Input { DECLARE_SMOBS (Book, foo); - public: + String user_key_; + SCM header_; Output_def *paper_; - + + void add_score (Score*); Link_array scores_; Book (); - + void set_keys (); Paper_book* process (String, Output_def*); }; DECLARE_UNSMOB (Book, book); diff --git a/lily/include/global-context.hh b/lily/include/global-context.hh index 353b8cf044..1a779a7eac 100644 --- a/lily/include/global-context.hh +++ b/lily/include/global-context.hh @@ -20,7 +20,7 @@ class Global_context : public virtual Context friend class Output_def; public: - Global_context (Output_def*, Moment final); + Global_context (Output_def*, Moment final, Object_key *key); int get_moments_left () const; Moment sneaky_insert_extra_moment (Moment); void add_moment_to_process (Moment); diff --git a/lily/include/lilypond-key.hh b/lily/include/lilypond-key.hh index afdb72f6da..0dba228d08 100644 --- a/lily/include/lilypond-key.hh +++ b/lily/include/lilypond-key.hh @@ -27,10 +27,12 @@ public: Moment start, String name, int); + static Object_key *from_scheme (SCM); protected: virtual int get_type () const; virtual void derived_mark () const; virtual int do_compare (Object_key const* a) const; + virtual SCM as_scheme () const; }; class Lilypond_context_key : public Object_key @@ -48,12 +50,30 @@ public: String id, int count); + static Object_key *from_scheme (SCM); protected: virtual int get_type () const; virtual int do_compare (Object_key const* a) const; virtual void derived_mark () const; + virtual SCM as_scheme () const; }; +class Lilypond_general_key : public Object_key +{ + Object_key const *parent_; + String name_; + int disambiguation_count_; +public: + Lilypond_general_key (Object_key const *parent, String name, + int count); + + static Object_key *from_scheme (SCM); +protected: + virtual int get_type () const; + virtual int do_compare (Object_key const* a) const; + virtual void derived_mark () const; + virtual SCM as_scheme () const; +}; #endif /* LILYPOND_KEY_HH */ diff --git a/lily/include/moment.hh b/lily/include/moment.hh index 7d4f7977bc..7bd38e7a43 100644 --- a/lily/include/moment.hh +++ b/lily/include/moment.hh @@ -48,7 +48,7 @@ public: */ String to_string () const; static int compare (Moment const&, Moment const&); - + SCM as_scheme () const; }; IMPLEMENT_ARITHMETIC_OPERATOR (Moment, + ); IMPLEMENT_ARITHMETIC_OPERATOR (Moment, - ); diff --git a/lily/include/object-key-dumper.hh b/lily/include/object-key-dumper.hh new file mode 100644 index 0000000000..1dd1e6c113 --- /dev/null +++ b/lily/include/object-key-dumper.hh @@ -0,0 +1,42 @@ +/* + object-key-dumper.hh -- declare Object_key_dumper + + source file of the GNU LilyPond music typesetter + + (c) 2004 Han-Wen Nienhuys + +*/ + +#ifndef OBJECT_KEY_DUMPER_HH +#define OBJECT_KEY_DUMPER_HH + +#include + +#include "lily-guile.hh" +#include "object-key.hh" +#include "smobs.hh" + +typedef std::map Key_to_key_map; +typedef std::map Pointer_to_int_map; +typedef std::map Int_to_key_map; + +class Object_key_dumper +{ + SCM file_contents_; + Key_to_key_map serialized_keys_; + Pointer_to_int_map key_serial_numbers_; + int next_available_; + + SCM key_serial (int); + SCM serialize_key (Object_key const *); + DECLARE_SMOBS (Object_key_dumper,); +public: + Object_key_dumper (); + SCM get_file_contents () const; + SCM dump_key (Object_key const *); +}; + +DECLARE_UNSMOB(Object_key_dumper, key_dumper); + +#endif /* OBJECT_KEY_DUMPER_HH */ + diff --git a/lily/include/object-key-undumper.hh b/lily/include/object-key-undumper.hh new file mode 100644 index 0000000000..8c516cad76 --- /dev/null +++ b/lily/include/object-key-undumper.hh @@ -0,0 +1,29 @@ +/* + object-key-undumper.hh -- declare Object_key_undumper + + source file of the GNU LilyPond music typesetter + + (c) 2004 Han-Wen Nienhuys + +*/ + +#ifndef OBJECT_KEY_UNDUMPER_HH +#define OBJECT_KEY_UNDUMPER_HH + +#include +#include "object-key.hh" + +typedef std::map Int_to_key_map; + +struct Object_key_undumper +{ + DECLARE_SMOBS(Object_key_undumper,); + Int_to_key_map keys_; + void parse_contents (SCM); +public: + Object_key_undumper (SCM s); + Object_key const *get_key (int k); +}; +DECLARE_UNSMOB(Object_key_undumper, key_undumper); + +#endif diff --git a/lily/include/object-key.hh b/lily/include/object-key.hh index 400ee4c12a..f4919a4cba 100644 --- a/lily/include/object-key.hh +++ b/lily/include/object-key.hh @@ -28,16 +28,21 @@ protected: virtual void derived_mark () const; virtual int get_type () const; virtual int do_compare (Object_key const * other) const; - + virtual SCM as_scheme () const; public: + static Object_key *from_scheme (SCM); + static Object_key *undump (SCM); int compare (Object_key const *other) const; + SCM dump () const; }; enum Object_key_type { + BASE_KEY, + COPIED_KEY, GENERAL_KEY, GROB_KEY, CONTEXT_KEY, - COPIED_KEY, + KEY_COUNT, }; class Copied_key : public Object_key @@ -51,11 +56,20 @@ protected: virtual void derived_mark () const; virtual int get_type () const; virtual int do_compare (Object_key const * other) const; - + virtual SCM as_scheme () const; public: + static Object_key *from_scheme (SCM); Copied_key (Object_key const*, int); }; DECLARE_UNSMOB(Object_key, key); +struct Object_key_less { + bool operator () (Object_key const *const &t1, Object_key const *const &t2) const + { + return t1->compare (t2); + } +}; + + #endif /* OBJECT_KEY_HH */ diff --git a/lily/include/output-def.hh b/lily/include/output-def.hh index 1a7df747d7..05e7259e94 100644 --- a/lily/include/output-def.hh +++ b/lily/include/output-def.hh @@ -46,6 +46,7 @@ public: SCM scope_; Output_def * parent_; Input input_origin_; + String user_key_; Output_def (Output_def const&); Output_def (); diff --git a/lily/include/score.hh b/lily/include/score.hh index 3705d16be5..42872b3388 100644 --- a/lily/include/score.hh +++ b/lily/include/score.hh @@ -15,6 +15,7 @@ #include "parray.hh" #include "smobs.hh" #include "virtual-methods.hh" +#include "string.hh" class Score : public Input { @@ -22,6 +23,7 @@ class Score : public Input SCM music_; public: + String user_key_; Link_array defs_; SCM header_; bool error_found_; @@ -30,13 +32,14 @@ public: void set_music (SCM music, SCM parser); Score (); Score (Score const&); - SCM book_rendering (String, Output_def*, Output_def*); + + SCM book_rendering (String, Output_def*, Output_def*, Object_key*); }; DECLARE_UNSMOB (Score, score); -SCM ly_run_translator (SCM, SCM); +SCM ly_run_translator (SCM, SCM, SCM); SCM ly_render_output (SCM, SCM); -void default_rendering (SCM, SCM, SCM, SCM, SCM); +void default_rendering (SCM, SCM, SCM, SCM, SCM, SCM); #endif /* SCORE_HH */ diff --git a/lily/lily-lexer.cc b/lily/lily-lexer.cc index aa3376dbe5..82fa29b217 100644 --- a/lily/lily-lexer.cc +++ b/lily/lily-lexer.cc @@ -57,13 +57,13 @@ static Keyword_ent the_key_tab[] = { {"midi", MIDI}, {"name", NAME}, {"new", NEWCONTEXT}, + {"objectid", OBJECTID}, {"notemode", NOTEMODE}, {"octave", OCTAVE}, {"once", ONCE}, {"override", OVERRIDE}, {"paper", PAPER}, {"partial", PARTIAL}, - {"quote", QUOTE}, {"relative", RELATIVE}, {"remove", REMOVE}, {"repeat", REPEAT}, diff --git a/lily/lily-parser.cc b/lily/lily-parser.cc index 379a1b286e..d83528ccc5 100644 --- a/lily/lily-parser.cc +++ b/lily/lily-parser.cc @@ -7,7 +7,9 @@ Jan Nieuwenhuizen */ + #include "book.hh" +#include "lilypond-key.hh" #include "context-selector.hh" #include "grob-selector.hh" #include "file-name.hh" @@ -433,6 +435,8 @@ LY_DEFINE (ly_parser_print_score, "ly:parser-print-score", Lily_parser *parser = unsmob_my_lily_parser (parser_smob); Score *score = unsmob_score (score_smob); + Object_key * key = new Lilypond_general_key (0, score->user_key_, 0); + if (score->error_found_) return SCM_UNSPECIFIED; @@ -453,16 +457,19 @@ LY_DEFINE (ly_parser_print_score, "ly:parser-print-score", for (int i = 0; i < score->defs_.size (); i++) default_rendering (score->get_music (), score->defs_[i]->self_scm (), paper, - header, os); + header, os, + key->self_scm ()); if (score->defs_.is_empty ()) { Output_def *layout = get_layout (parser); default_rendering (score->get_music(), layout->self_scm (), get_paper (parser)->self_scm (), - header, os); + header, os, key->self_scm ()); scm_gc_unprotect_object (layout->self_scm ()); } + + scm_gc_unprotect_object (key->self_scm ()); return SCM_UNSPECIFIED; } @@ -506,8 +513,8 @@ LY_DEFINE (ly_parser_print_book, "ly:parser-print-book", (*c)++; Output_def *layout = get_layout (parser); - Paper_book* pb = book->process (outname.to_string (), layout); + if (pb) { pb->output (outname.to_string ()); diff --git a/lily/lilypond-key.cc b/lily/lilypond-key.cc index df8d027caf..ecb339e090 100644 --- a/lily/lilypond-key.cc +++ b/lily/lilypond-key.cc @@ -60,8 +60,28 @@ Lilypond_grob_key::get_type () const return GROB_KEY; } -/****************************************************************/ +SCM +Lilypond_grob_key::as_scheme () const +{ + return scm_list_4 (context_ ? context_->self_scm() : SCM_BOOL_F, + creation_moment_.smobbed_copy(), + scm_makfrom0str (grob_name_.to_str0()), + scm_from_int (disambiguation_count_)); +} + + +Object_key * +Lilypond_grob_key::from_scheme (SCM a) +{ + return new Lilypond_grob_key (unsmob_key (scm_car (a)), + *unsmob_moment (scm_cadr (a)), + ly_scm2string (scm_caddr (a)), + scm_to_int (scm_cadddr (a))); +} + + +/****************************************************************/ void Lilypond_context_key::derived_mark () const @@ -91,12 +111,17 @@ Lilypond_context_key::do_compare (Object_key const *key) const = dynamic_cast (key); int c; - if (parent_context_) + if (parent_context_ && other->parent_context_) { c = parent_context_->compare (other->parent_context_); if (c) return c; } + else if (parent_context_) + return -1 ; + else if (other->parent_context_) + return 1; + c = Moment::compare (start_moment_, other->start_moment_); if (c) @@ -122,3 +147,90 @@ Lilypond_context_key::get_type () const { return CONTEXT_KEY; } + + +SCM +Lilypond_context_key::as_scheme () const +{ + return scm_list_5 (parent_context_ ? parent_context_->self_scm() : SCM_BOOL_F, + start_moment_.smobbed_copy(), + scm_makfrom0str (context_name_.to_str0()), + scm_makfrom0str (id_.to_str0()), + scm_from_int (disambiguation_count_)); +} + +Object_key * +Lilypond_context_key::from_scheme (SCM a) +{ + return new Lilypond_grob_key (unsmob_key (scm_car (a)), + *unsmob_moment (scm_cadr (a)), + ly_scm2string (scm_list_ref (a, scm_from_int (2))), + scm_to_int (scm_list_ref (a, scm_from_int (3)))); +} + + +/****************************************************************/ + +int +Lilypond_general_key::get_type () const +{ + return GENERAL_KEY; +} + +void +Lilypond_general_key::derived_mark () const +{ + if (parent_) + scm_gc_mark (parent_->self_scm ()); +} + +Lilypond_general_key::Lilypond_general_key (Object_key const*parent, + String name, + int count) +{ + parent_ = parent; + name_ = name; + disambiguation_count_ = count; +} + + +int +Lilypond_general_key::do_compare (Object_key const* key)const +{ + Lilypond_general_key const* other + = dynamic_cast (key); + + if (parent_ && other->parent_) + parent_->compare (other->parent_); + else if (parent_) + return -1 ; + else if (other->parent_) + return 1; + + int c = String::compare (name_, other->name_); + if (c) + return c; + + + c = sign (disambiguation_count_ - other->disambiguation_count_); + if (c) + return c; + + return 0; +} + +SCM +Lilypond_general_key::as_scheme () const +{ + return scm_list_3 (parent_ ? parent_->self_scm() : SCM_BOOL_F, + scm_makfrom0str (name_.to_str0()), + scm_from_int (disambiguation_count_)); +} + +Object_key * +Lilypond_general_key::from_scheme (SCM a) +{ + return new Lilypond_general_key (unsmob_key (scm_car (a)), + ly_scm2string (scm_list_ref (a, scm_from_int (1))), + scm_to_int (scm_list_ref (a, scm_from_int (2)))); +} diff --git a/lily/lookup.cc b/lily/lookup.cc index 8cab963897..801ead5801 100644 --- a/lily/lookup.cc +++ b/lily/lookup.cc @@ -693,7 +693,7 @@ Lookup::triangle (Interval iv, Real thick, Real protude) Offset z1(iv[LEFT], 0); Offset z2(iv[RIGHT], 0); - Offset z3(z2[X_AXIS]/2, protude); + Offset z3((z1 + z2)[X_AXIS]/2, protude); /* TODO: move Triangle to Line_interface ? diff --git a/lily/moment.cc b/lily/moment.cc index f4caf2823e..a257daec74 100644 --- a/lily/moment.cc +++ b/lily/moment.cc @@ -56,6 +56,16 @@ Moment::print_smob (SCM s, SCM port, scm_print_state *) return 1; } +SCM +Moment::as_scheme () const +{ + return scm_list_5 (ly_symbol2scm ("ly:make-moment"), + scm_from_int (main_part_.num()), + scm_from_int (main_part_.den()), + scm_from_int (grace_part_.num()), + scm_from_int (grace_part_.den())); +} + /* TODO: add optional factor argument. */ LY_DEFINE (ly_make_moment, "ly:make-moment", 2, 2, 0, (SCM n, SCM d, SCM gn, SCM gd), diff --git a/lily/object-key-dumper.cc b/lily/object-key-dumper.cc new file mode 100644 index 0000000000..6fc4c78261 --- /dev/null +++ b/lily/object-key-dumper.cc @@ -0,0 +1,148 @@ +/* + object-key-dumper.cc -- implement Object_key_dumper + + source file of the GNU LilyPond music typesetter + + (c) 2004 Han-Wen Nienhuys + +*/ + + +#include + +#include "ly-smobs.icc" + +#include "moment.hh" +#include "object-key-dumper.hh" +#include "object-key.hh" + + +SCM +Object_key_dumper::mark_smob (SCM smob ) +{ + Object_key_dumper * dumper = (Object_key_dumper*) SCM_CELL_WORD_1 (smob); + + for (Key_to_key_map::const_iterator i (dumper->serialized_keys_.begin ()); + i != dumper->serialized_keys_.end(); + i++) + { + scm_gc_mark ((*i).first->self_scm()); + } + return SCM_EOL; +} + +int +Object_key_dumper::print_smob (SCM, SCM port, scm_print_state*) +{ + scm_puts ("#", port); + return 1; +} + +IMPLEMENT_DEFAULT_EQUAL_P(Object_key_dumper); +IMPLEMENT_SMOBS(Object_key_dumper); + +Object_key_dumper::Object_key_dumper () +{ + file_contents_ = SCM_EOL; + next_available_ = 0; + smobify_self (); +} + +SCM +Object_key_dumper::key_serial (int k) +{ + return scm_cons (ly_symbol2scm ("key"), + scm_from_int (k)); +} + +SCM +Object_key_dumper::serialize_key (Object_key const *key) +{ + SCM skey = key->dump(); + for (SCM s = skey ; scm_is_pair (s) ; s = scm_cdr (s)) + { + if (Object_key const * sub_key = unsmob_key (scm_car (s))) + { + scm_set_car_x (s, dump_key (sub_key)); + } + else if (Moment *mom = unsmob_moment (scm_car (s))) + { + scm_set_car_x (s, + scm_list_2 (ly_symbol2scm ("unquote"), + mom->as_scheme())); + } + } + + file_contents_ = scm_cons (scm_list_3 (ly_symbol2scm("define-key"), + scm_from_int (next_available_), + skey), + file_contents_); + + serialized_keys_[key] = key; + key_serial_numbers_[key] = next_available_; + SCM retval = key_serial (next_available_); + next_available_ ++; + + return retval; +} + +SCM +Object_key_dumper::dump_key (Object_key const *key) +{ + if (key_serial_numbers_.find (key) != key_serial_numbers_.end ()) + { + return key_serial (key_serial_numbers_[key]); + } + else if (Object_key const *serialized = serialized_keys_[key]) + { + return key_serial (key_serial_numbers_[ serialized_keys_ [serialized] ]); + } + + return serialize_key (key); +} + +SCM +Object_key_dumper::get_file_contents () const +{ + return scm_reverse (file_contents_); +} + +LY_DEFINE(ly_make_dumper, "ly:make-dumper", + 1,0,0, + (), + "Create a key dumper. " + ) +{ + Object_key_dumper *u = new Object_key_dumper (); + SCM x = u->self_scm(); + scm_gc_unprotect_object (x); + return x; +} + +LY_DEFINE(ly_dumper_definitions, "ly:dumper-definitions", + 1,0,0, + (SCM dumper), + "Return list of key definitions. " + ) +{ + Object_key_dumper *u = unsmob_key_dumper (dumper); + SCM_ASSERT_TYPE(u, dumper, SCM_ARG1, __FUNCTION__, "dumper"); + return u->get_file_contents(); +} + +LY_DEFINE(ly_dumper_key_serial, "ly:dumper-key-serial", + 2,0,0, + (SCM dumper, SCM key), + "Return the key serial number @var{key}. " + ) +{ + Object_key_dumper* u = unsmob_key_dumper (dumper); + Object_key *k = unsmob_key (key); + SCM_ASSERT_TYPE(u, dumper, SCM_ARG1, __FUNCTION__, "dumper"); + SCM_ASSERT_TYPE(k, key, SCM_ARG2, __FUNCTION__, "key"); + return u->dump_key (k); +} + +Object_key_dumper::~Object_key_dumper() +{ +} diff --git a/lily/object-key-undumper.cc b/lily/object-key-undumper.cc new file mode 100644 index 0000000000..01ac9b4e89 --- /dev/null +++ b/lily/object-key-undumper.cc @@ -0,0 +1,128 @@ +/* + object-key-undumper.cc -- implement Object_key_undumper + + source file of the GNU LilyPond music typesetter + + (c) 2004 Han-Wen Nienhuys + +*/ + +#include + + +#include "smobs.hh" +#include "object-key.hh" +#include "object-key-undumper.hh" + +#include "ly-smobs.icc" + +IMPLEMENT_SMOBS(Object_key_undumper); +IMPLEMENT_DEFAULT_EQUAL_P(Object_key_undumper); + +SCM +Object_key_undumper::mark_smob (SCM smob) +{ + Object_key_undumper * undumper = (Object_key_undumper*) SCM_CELL_WORD_1(smob); + for (Int_to_key_map::const_iterator i (undumper->keys_.begin()); + i != undumper->keys_.end(); i++) + { + scm_gc_mark ((*i).second->self_scm ()); + } + + return SCM_BOOL_F; +} + +int +Object_key_undumper::print_smob (SCM s, SCM port, scm_print_state*) +{ + scm_puts ("#", port); + return 1; +} + + +Object_key_undumper::Object_key_undumper (SCM s) +{ + smobify_self(); + parse_contents (s); +} + + +LY_DEFINE(ly_make_undumper, "ly:make-undumper", + 1,0,0, + (SCM contents), + "Create a key undumper for @var{contents}. " + ) +{ + Object_key_undumper *u = new Object_key_undumper (contents); + SCM x = u->self_scm(); + scm_gc_unprotect_object (x); + return x; +} + + +LY_DEFINE(ly_undumper_lookup, "ly:undumper-lookup", + 2,0,0, + (SCM undumper, SCM serial), + "Return the object key for number @var{serial}. " + ) + +{ + Object_key_undumper* u = unsmob_key_undumper (undumper); + + SCM_ASSERT_TYPE(u, undumper, SCM_ARG1, __FUNCTION__, "undumper"); + SCM_ASSERT_TYPE(scm_is_integer(serial), serial, SCM_ARG2, __FUNCTION__, "integer"); + return u->get_key (scm_to_int (serial))->self_scm(); +} + + +void +Object_key_undumper::parse_contents (SCM contents) +{ + for (SCM s = contents; scm_is_pair (s); s = scm_cdr (s)) + { + SCM entry = scm_car (s); + if (scm_car (entry) != ly_symbol2scm ("define-key")) + continue; + + + int number = scm_to_int (scm_cadr (entry)); + SCM skey = scm_caddr (entry); + + SCM new_key = SCM_EOL; + SCM *tail = &new_key; + for (SCM t = skey; scm_is_pair (t); t = scm_cdr (t)) + { + SCM entry = scm_car (t); + if (scm_is_pair (entry) + && scm_car (entry) == ly_symbol2scm ("key")) + { + int index = scm_to_int (scm_cadr (entry)); + Object_key const *key = get_key (index); + *tail = scm_cons (key->self_scm(), SCM_EOL); + } + else + { + *tail = scm_cons (entry, SCM_EOL); + } + tail = SCM_CDRLOC(*tail); + } + + Object_key *k = Object_key::undump (new_key); + keys_[number] = k; + scm_gc_unprotect_object (k->self_scm()); + } + +} + +Object_key const* +Object_key_undumper::get_key (int idx) +{ + Int_to_key_map::const_iterator i (keys_.find (idx)); + assert (i != keys_.end()); + + return (*i).second; +} + +Object_key_undumper::~Object_key_undumper() +{ +} diff --git a/lily/object-key.cc b/lily/object-key.cc index 2f95bec8be..9a7ae7107b 100644 --- a/lily/object-key.cc +++ b/lily/object-key.cc @@ -7,8 +7,7 @@ */ - -#include "object-key.hh" +#include "lilypond-key.hh" #include "ly-smobs.icc" SCM @@ -38,6 +37,10 @@ Object_key::get_type () const int Object_key::print_smob (SCM smob, SCM port, scm_print_state*) { + Object_key* k = (Object_key*) SCM_CELL_WORD_1 (smob); + scm_puts ("#get_type()), port); + scm_puts (">", port); return 1; } @@ -71,11 +74,53 @@ Object_key::equal_p (SCM a , SCM b) } int -Object_key::do_compare (Object_key const *other) const +Object_key::do_compare (Object_key const *) const { return 0; } + +SCM +Object_key::dump () const +{ + return scm_cons (scm_from_int (get_type()), + as_scheme()); +} + + + +SCM +Object_key::as_scheme () const +{ + return SCM_EOL; +} + +Object_key* +Object_key::from_scheme (SCM) +{ + return new Object_key(); +} + +struct { + Object_key_type type_; + Object_key* (*ctor_)(SCM); +} undumpers[] = { + {BASE_KEY, Object_key::from_scheme}, + {COPIED_KEY, Copied_key::from_scheme}, + {GROB_KEY, Lilypond_grob_key::from_scheme}, + {CONTEXT_KEY, Lilypond_context_key::from_scheme}, + {GENERAL_KEY, Lilypond_general_key::from_scheme}, + {KEY_COUNT,0}, +}; + +Object_key * +Object_key::undump (SCM scm_key) +{ + int t = scm_to_int (scm_car (scm_key)); + assert (t == undumpers[t].type_); + return (undumpers[t].ctor_)(scm_cdr (scm_key)); +} + /****************************************************************/ Copied_key::Copied_key (Object_key const* key, int count) @@ -107,3 +152,17 @@ Copied_key::derived_mark () const { scm_gc_mark (original_->self_scm ()); } + +SCM +Copied_key::as_scheme () const +{ + return scm_list_2 (original_ ? original_->self_scm() : SCM_BOOL_F, scm_from_int (copy_count_)); +} + + +Object_key * +Copied_key::from_scheme (SCM a) +{ + return new Copied_key (unsmob_key (scm_car (a)), + scm_to_int (scm_list_ref (a, scm_from_int (1)))); +} diff --git a/lily/parser.yy b/lily/parser.yy index 3b2b4ec8ea..9439c6f3bc 100644 --- a/lily/parser.yy +++ b/lily/parser.yy @@ -299,6 +299,7 @@ or %token NAME %token NEWCONTEXT %token NOTEMODE +%token OBJECTID %token OCTAVE %token ONCE %token OVERRIDE SET REVERT @@ -445,6 +446,7 @@ or %type markup markup_line markup_list markup_list_body full_markup %type mode_changing_head %type mode_changing_head_with_context +%type object_id_setting %type score_block score_body @@ -471,6 +473,11 @@ lilypond: /* empty */ } ; + +object_id_setting: + OBJECTID STRING { $$ = $2; } + ; + toplevel_expression: lilypond_header { THIS->lexer_->set_identifier (ly_symbol2scm ("$globalheader"), $1); @@ -672,8 +679,7 @@ book_body: } | book_body score_block { Score *score = $2; - $$->scores_.push (score); - scm_gc_unprotect_object (score->self_scm ()); + $$->add_score (score); } | book_body lilypond_header { $$->header_ = $2; @@ -682,6 +688,9 @@ book_body: $$->paper_ = 0; $$->scores_.clear(); } + | book_body object_id_setting { + $$->user_key_ = ly_scm2string ($2); + } ; score_block: @@ -704,6 +713,9 @@ score_body: $$ = new Score ( *unsmob_score ($1)); $$->set_spot (THIS->here_input ()); } + | score_body object_id_setting { + $$->user_key_ = ly_scm2string ($2); + } | score_body Music { SCM m = $2->self_scm (); scm_gc_unprotect_object (m); diff --git a/lily/score.cc b/lily/score.cc index 4c09db3021..22852d79b8 100644 --- a/lily/score.cc +++ b/lily/score.cc @@ -8,6 +8,7 @@ #include +#include "lilypond-key.hh" #include "lily-parser.hh" #include "book.hh" #include "cpu-timer.hh" @@ -47,6 +48,12 @@ SCM Score::mark_smob (SCM s) { Score *sc = (Score*) SCM_CELL_WORD_1 (s); + +#if 0 + if (sc->key_) + scm_gc_mark (sc->key_->self_scm()); +#endif + if (sc->header_) scm_gc_mark (sc->header_); for (int i = sc->defs_.size (); i--;) @@ -87,11 +94,14 @@ Score::Score (Score const &s) LY_DEFINE (ly_run_translator, "ly:run-translator", - 2, 0, 0, (SCM mus, SCM output_def), - "Process @var{mus} according to @var{output_def}. " - "An interpretation context is set up, " - "and @var{mus} is interpreted with it. " - "The context is returned in its final state.") + 2, 1, 0, (SCM mus, SCM output_def, SCM key), + "Process @var{mus} according to @var{output_def}. \n" + "An interpretation context is set up,\n" + "and @var{mus} is interpreted with it. \n" + "The context is returned in its final state.\n" + + "\n\nOptionally, this routine takes an Object-key to\n" + "to uniquely identify the Score block containing it.\n") { Output_def *odef = unsmob_output_def (output_def); Music *music = unsmob_music (mus); @@ -103,12 +113,14 @@ LY_DEFINE (ly_run_translator, "ly:run-translator", return SCM_BOOL_F; } - SCM_ASSERT_TYPE (music, mus, SCM_ARG1, __FUNCTION__, "Music"); - SCM_ASSERT_TYPE (odef, output_def, SCM_ARG2, __FUNCTION__, "Output definition"); + SCM_ASSERT_TYPE (music, mus, SCM_ARG1, + __FUNCTION__, "Music"); + SCM_ASSERT_TYPE (odef, output_def, SCM_ARG2, __FUNCTION__, + "Output definition"); Cpu_timer timer; - Global_context *trans = new Global_context (odef, music->get_length ()); + Global_context *trans = new Global_context (odef, music->get_length (), unsmob_key (key) ); if (!trans) { programming_error ("no toplevel translator"); @@ -159,7 +171,8 @@ LY_DEFINE (ly_format_output, "ly:format-output", void default_rendering (SCM music, SCM outdef, SCM book_outputdef, - SCM header, SCM outname) + SCM header, SCM outname, + SCM key) { SCM scaled_def = outdef; SCM scaled_bookdef = book_outputdef; @@ -182,7 +195,7 @@ default_rendering (SCM music, SCM outdef, scm_gc_unprotect_object (scaled_def); } - SCM context = ly_run_translator (music, scaled_def); + SCM context = ly_run_translator (music, scaled_def, key); if (Global_context *g = dynamic_cast (unsmob_context (context))) { @@ -221,7 +234,8 @@ LAYOUTBOOK should be scaled already. SCM Score::book_rendering (String outname, Output_def *layoutbook, - Output_def *default_def) + Output_def *default_def, + Object_key *book_key) { if (error_found_) return SCM_EOL; @@ -235,6 +249,10 @@ Score::book_rendering (String outname, SCM out = scm_makfrom0str (outname.to_str0 ()); SCM systems = SCM_EOL; int outdef_count = defs_.size (); + + Object_key * key = new Lilypond_general_key (book_key, user_key_, 0); + SCM scm_key = key->self_scm(); + for (int i = 0; !i || i < outdef_count; i++) { Output_def *def = outdef_count ? defs_[i] : default_def; @@ -248,7 +266,7 @@ Score::book_rendering (String outname, } /* TODO: fix or junk --no-layout. */ - SCM context = ly_run_translator (music_, def->self_scm ()); + SCM context = ly_run_translator (music_, def->self_scm (), scm_key); if (dynamic_cast (unsmob_context (context))) { SCM s = ly_format_output (context, out); @@ -258,7 +276,8 @@ Score::book_rendering (String outname, scm_remember_upto_here_1 (scaled); } - + + scm_remember_upto_here_1 (scm_key); scm_remember_upto_here_1 (scaled_bookdef); return systems; } @@ -267,10 +286,12 @@ Score::book_rendering (String outname, LY_DEFINE (ly_score_embedded_format, "ly:score-embedded-format", - 2, 0, 0, (SCM score, SCM layout), + 2, 1, 0, (SCM score, SCM layout, SCM key), "Run @var{score} through @var{layout}, an output definition, " "scaled to correct outputscale already, " - "return a list of layout-lines.") + "return a list of layout-lines. " + "\nTake optional Object_key argument." + ) { Score * sc = unsmob_score (score); Output_def *od = unsmob_output_def (layout); @@ -302,7 +323,8 @@ LY_DEFINE (ly_score_embedded_format, "ly:score-embedded-format", itself. */ score_def->parent_ = od; - SCM context = ly_run_translator (sc->get_music (), score_def->self_scm ()); + SCM context = ly_run_translator (sc->get_music (), score_def->self_scm (), + key); SCM lines = ly_format_output (context, scm_makfrom0str ("")); scm_remember_upto_here_1 (prot); diff --git a/ly/init.ly b/ly/init.ly index 3c0229c6e8..8e94170d0d 100644 --- a/ly/init.ly +++ b/ly/init.ly @@ -11,7 +11,7 @@ #(ly:set-option 'new-relative) #(ly:set-point-and-click #f) -#(define toplevel-scores '()) +#(define toplevel-scores '()) #(define $globalheader #f) \maininput diff --git a/scm/lily.scm b/scm/lily.scm index d9c9a01492..c18f1bf3f0 100644 --- a/scm/lily.scm +++ b/scm/lily.scm @@ -118,8 +118,7 @@ predicates. Print a message at LOCATION if any predicate failed." ;; stencil expressions should have docstrings. (define-public (ly:all-stencil-expressions) "Return list of stencil expressions." - '( - beam + '(beam bezier-sandwich blank bracket -- 2.39.2