lilypond-user
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Regtest for issue 5181


From: David Kastrup
Subject: Re: Regtest for issue 5181
Date: Sun, 24 Sep 2017 01:02:02 +0200
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/26.0.50 (gnu/linux)

Thomas Morley <address@hidden> writes:

> 2017-09-23 18:17 GMT+02:00 David Kastrup <address@hidden>:
>> David Kastrup <address@hidden> writes:
>>
>>> Thomas Morley <address@hidden> writes:
>
>>>> Up to now I've only a vage impression what
>>>> 'parse-lily-and-compute-lily-string' and #(read-hash-extend ...) does.
>>>> I'll currently not dive deeper into it until forced. ;)
>>>
>>>  -- Scheme Procedure: read-hash-extend chr proc
>>>  -- C Function: scm_read_hash_extend (chr, proc)
>>>      Install the procedure PROC for reading expressions starting with
>>>      the character sequence ‘#’ and CHR.  PROC will be called with two
>>>      arguments: the character CHR and the port to read further data
>>>      from.  The object returned will be the return value of ‘read’.
>>>      Passing ‘#f’ for PROC will remove a previous setting.
>>>
>>> Basically what is done with those does a similar job as
>>> scm/parser-ly-from-scheme.scm does for #{ ... #} in Scheme, just for #[
>>> ... #].  Also it doesn't bother to cater for closures or sensible
>>> error/expression file locations.
>
> So far I figured already.
> I meant more some details.
> What exactly does the loop?

Fetches characters and creates a read value from them.

> Why a quasiquote (let ...)?

Because this becomes part of the Scheme reader: stuff is not evaluated
when read, but later.  Sort-of like macros, except that macro arguments
have already been read when the macro is called.  The hash extender
needs to do its own reading.

If #( was not already defined, you could write

(read-hash-extend #\( (lambda (ch port) (unread-char ch port)
                        (apply vector (read port))))

in order to read a parenthesized list and create a vector from it (this
makes use of the fact that a vector evaluates to itself: otherwise it
would need more quoting to work).

> Those questions came to my mind. Though, I didn't think it was worth
> to research them.
>
>>
>> Also it's stupid here: the whole idea for display-lily-test was to
>> compare input string and output expression, and the input string is
>> not really of interest for _this_ check, so the whole complicated
>> deal does not pay off.  I'll try to see whether I can make do without
>> it.
>
> Meanwhile I convinced myself that a regtest with no pdf-output is the
> right one here.
> We have others. Ofcourse for midi, but also display-lily-tests.ly (as
> mentioned already) and general-scheme-bindings.ly, probably more, I
> didn't look through all regression-tests.
>
> I tried to simplify your suggestion:
>
> pitch = c'
> note = c'4
> chord = <c' g'>
> lyr = \lyricmode { foo }
>
> #(define lst
> ;; create a list with lily-code, variable-call, possible post-event
> and expected equality
> ;; first three need to be strings, last is a boolean
> '(
>   ("c'4" "\\note" "--" #f)
>   ("c-\\single \\slurUp (" "c \\single \\slurUp (" "-1" #f)
>   ("<c' g'>" "\\chord" "-1" #f)
>   ("{c'4-1}" "{ \\note -1 }" "" #t)
>   ("{ \\lyricmode { foo -- } }" "\\lyricmode { \\lyr -- }" "" #t)
>   ))
>
> foo =
> #(define-void-function (ls)(list?)
> (let* ((cases
>          (map
>            (lambda (arg)
>              (string-trim-both
>                 (with-output-to-string
>                   (lambda ()
>                    (ly:parse-string-expression
>                      (ly:parser-clone)
>                      (format #f "\\displayLilyMusic ~a ~a"
>                        arg (third ls))
>                      )))))
>            (take ls 2)))
>         (same? (string=? (car cases) (cadr cases))))
>   (cond ;; all working
>         ((and same? (last ls))
>          (ly:message "expressions are equal"))
>
>         ;; expressions are equal, but equality is unexpected
>         ((and same? (not (last ls)))
>          (ly:input-warning (*location*)
>            "Unexpected equality for ~a and ~a"
>              (car cases) (cadr cases)))
>
>         ;; expressions are not equal, but equality was expected
>         ;; possible bug
>         ((and (not same?) (last ls))
>          (ly:warning
>            "BUG for ~a and ~a possible"
>              (car cases) (cadr cases)))
>
>         (else
>          (ly:message "expressions are not equal as expected")))))
>
> $(for-each foo lst)
>
> Manually creating 'lst' is *aargh*, though.
> Maybe I've a better idea tomorrow, but I thought I should post the idea.

Ugh.  I'm by now arrived at something else.  Depends on one patch pushed
to staging (and not yet merged to master) though.

Defining ly:music-error may look like overkill for this application but,
uh, it is actually already being used, so defining it seems appropriate.

diff --git a/input/regression/added-post-event-test.ly 
b/input/regression/added-post-event-test.ly
new file mode 100644
index 0000000000..06cfe03552
--- /dev/null
+++ b/input/regression/added-post-event-test.ly
@@ -0,0 +1,64 @@
+\version "2.21.0"
+
+\header {
+
+  texidoc = "This is a test of combining post-events with various
+constructs.  Problems are reported on the stderr of this run; there
+are no images produced."
+
+}
+
+%%%
+%%% Testing utilities
+%%%
+#(use-modules (scm display-lily))
+
+testIt =
+#(define-void-function (harmless music) ((boolean?) ly:music?)
+   ;; We check whether there is sequential music with a single
+   ;; expression that has the location of its single element basically
+   ;; at the end of the expression:
+   ;;
+   ;; That's when the expression has been combined immediately at
+   ;; parse time and not in a second sweep
+   (define (contained? m p)
+     (let ((m-loc (ly:input-both-locations (ly:music-property m 'origin)))
+           (p-loc (ly:input-both-locations (ly:music-property p 'origin))))
+       (and (string= (first m-loc) (first p-loc))
+            (= (fourth m-loc) (fourth p-loc))
+            (>= (fifth m-loc) (fifth p-loc)))))
+   (let* ((musl (and (music-is-of-type? music 'sequential-music)
+                     (ly:music-property music 'elements)))
+          (muse (and (pair? musl) (not (pair? (cdr musl))) (car musl)))
+          (badpost (and muse
+                        (find (lambda (m) (not (contained? muse m)))
+                              (extract-typed-music muse 'post-event)))))
+     (cond ((not muse)
+            (ly:music-error music (_ "expected single-element sequential 
expression")))
+           (badpost
+            (if harmless
+                (ly:music-message badpost (_ "late post-event, expected"))
+                (ly:music-warning badpost (_ "late post-event, unexpected"))))
+           (else
+            (if harmless
+                (ly:music-warning muse (_ "no late post-event, 
unexpected")))))))
+
+pitch = c'
+note = c'4
+chord = <c' g'>
+lyr = \lyricmode { two words }
+
+\testIt ##t { \note -1 }
+\testIt ##t { $note -1 }
+\testIt ##t { \chord -1 }
+\testIt { { \note -1 } }
+\testIt ##t { { \note -1 } -2 }
+\testIt { < \note -1 g' > -2 }
+\testIt { { \chord -1 } }
+\testIt { $pitch -1 }
+\testIt { c-\single \slurUp ( -1 }
+\testIt ##t { c \single \slurUp ( -1 }
+\testIt ##t \lyricmode { \lyr __ }
+\testIt ##t \lyricmode { \lyr -- }
+
+%% end test.
diff --git a/scm/music-functions.scm b/scm/music-functions.scm
index 5bbd07ea8f..ff62c17c01 100644
--- a/scm/music-functions.scm
+++ b/scm/music-functions.scm
@@ -1087,6 +1087,10 @@ actually fully cloned."
         (apply ly:input-warning ip msg rest)
         (apply ly:warning msg rest))))
 
+(define-public (ly:music-error music msg . rest)
+  (ly:parser-error (apply format #f msg rest)
+                   (ly:music-property music 'origin)))
+
 (define-public (ly:event-warning event msg . rest)
   (let ((ip (ly:event-property event 'origin)))
     (if (ly:input-location? ip)

-- 
David Kastrup

reply via email to

[Prev in Thread] Current Thread [Next in Thread]