From 887000f61099efaf85d6d5b580f20fcf84c0fc6f Mon Sep 17 00:00:00 2001 From: David Kastrup Date: Wed, 27 Feb 2013 16:06:29 +0100 Subject: [PATCH] Issue 3211: Let ly_deep_copy and ly_music_deep_copy iterate rather than recurse for lists Also improves DOC string of ly:music-deep-copy. --- lily/lily-guile.cc | 19 +++++++++++++++++-- lily/music-scheme.cc | 28 ++++++++++++++++++++-------- 2 files changed, 37 insertions(+), 10 deletions(-) diff --git a/lily/lily-guile.cc b/lily/lily-guile.cc index eb78d8bbfd..27909a6bc2 100644 --- a/lily/lily-guile.cc +++ b/lily/lily-guile.cc @@ -355,8 +355,23 @@ SCM ly_deep_copy (SCM src) { if (scm_is_pair (src)) - return scm_cons (ly_deep_copy (scm_car (src)), ly_deep_copy (scm_cdr (src))); - else if (scm_is_vector (src)) + { + SCM res = SCM_EOL; + do + { + res = scm_cons (ly_deep_copy (scm_car (src)), res); + src = scm_cdr (src); + } + while (scm_is_pair (src)); + // Oh, come on, GUILE. Why do you require the second argument + // of scm_reverse_x to be a proper list? That makes no sense. + // return scm_reverse_x (res, ly_deep_copy (src)); + SCM last_cons = res; + res = scm_reverse_x (res, SCM_EOL); + scm_set_cdr_x (last_cons, ly_deep_copy (src)); + return res; + } + if (scm_is_vector (src)) { int len = scm_c_vector_length (src); SCM nv = scm_c_make_vector (len, SCM_UNDEFINED); diff --git a/lily/music-scheme.cc b/lily/music-scheme.cc index ffa903b4eb..3412e73b56 100644 --- a/lily/music-scheme.cc +++ b/lily/music-scheme.cc @@ -114,18 +114,30 @@ LY_DEFINE (ly_music_list_p, "ly:music-list?", LY_DEFINE (ly_music_deep_copy, "ly:music-deep-copy", 1, 0, 0, (SCM m), - "Copy @var{m} and all sub expressions of@tie{}@var{m}.") + "Copy @var{m} and all sub expressions of@tie{}@var{m}." + " @var{m} may be an arbitrary type; cons cells and music" + " are copied recursively.") { - SCM copy = m; if (unsmob_music (m)) + return unsmob_music (m)->clone ()->unprotect (); + if (scm_is_pair (m)) { - Music *mcopy = unsmob_music (m)->clone (); - copy = mcopy->unprotect (); + SCM copy = SCM_EOL; + do + { + copy = scm_cons (ly_music_deep_copy (scm_car (m)), copy); + m = scm_cdr (m); + } + while (scm_is_pair (m)); + // Oh, come on, GUILE. Why do you require the second argument + // of scm_reverse_x to be a proper list? That makes no sense. + // return scm_reverse_x (copy, ly_music_deep_copy (m)); + SCM last_cons = copy; + copy = scm_reverse_x (copy, SCM_EOL); + scm_set_cdr_x (last_cons, ly_music_deep_copy (m)); + return copy; } - else if (scm_is_pair (m)) - copy = scm_cons (ly_music_deep_copy (scm_car (m)), - ly_music_deep_copy (scm_cdr (m))); - return copy; + return m; } LY_DEFINE (ly_music_transpose, "ly:music-transpose", -- 2.39.2