]> git.donarmstrong.com Git - lilypond.git/blobdiff - Documentation/contributor/programming-work.itexi
Merge branch 'master' into translation
[lilypond.git] / Documentation / contributor / programming-work.itexi
index a02910b768f1af603cc4508b46c9e92efb379327..66a792066c532f991c30342ab4bcf169acd13bc7 100644 (file)
@@ -771,8 +771,8 @@ The error functions come in three different flavors: fatal error messages,
 programming error messages and normal error messages.  Errors written
 by the @code{error ()} function will cause LilyPond to exit immediately,
 errors by @code{Input::error ()} will continue the compilation, but
-return a non-zero return value of the lilypond call (i.e. indicate an 
-unsuccessful program execution).  All other errors will be printed on the 
+return a non-zero return value of the LilyPond call (i.e. indicate an
+unsuccessful program execution).  All other errors will be printed on the
 console, but not exit LilyPond or indicate an unsuccessful return code.
 Their only differences to a warnings are the displayed text and that
 they will be shown with loglevel @code{ERROR}.
@@ -882,7 +882,7 @@ treated as if @code{Input::error} was called.
 
 The most commonly used tool for debugging LilyPond is the GNU
 debugger gdb.  The gdb tool is used for investigating and debugging
-core Lilypond code written in C++.  Another tool is available for
+core LilyPond code written in C++.  Another tool is available for
 debugging Scheme code using the Guile debugger.  This section
 describes how to use both gdb and the Guile Debugger.
 
@@ -913,17 +913,21 @@ The GNU debugger, gdb, is the principal tool for debugging C++ code.
 @subheading Compiling LilyPond for use with gdb
 
 In order to use gdb with LilyPond, it is necessary to compile
-LilyPond with debugging information.  This is accomplished by running
-the following commands in the main LilyPond source directory.
+LilyPond with debugging information.  This is the current default
+mode of compilation.  Often debugging becomes more complicated
+when the compiler has optimised variables and function calls away.
+In that case it may be helpful to run the following command in the
+main LilyPond source directory:
 
 @example
-./configure  --disable-optimising
+./configure --disable-optimising
 make
 @end example
 
-This will create a version of LilyPond containing debugging
-information that will allow the debugger to tie the source code
-to the compiled code.
+This will create a version of LilyPond with minimal optimization
+which will allow the debugger to access all variables and step
+through the source code in-order.  It may not accurately reproduce
+bugs encountered with the optimized version, however.
 
 You should not do @var{make install} if you want to use a debugger
 with LilyPond.  The @var{make install} command will strip debugging
@@ -931,7 +935,7 @@ information from the LilyPond binary.
 
 @subheading Typical gdb usage
 
-Once you have compiled the Lilypond image with the necessary
+Once you have compiled the LilyPond image with the necessary
 debugging information it will have been written to a location in a
 subfolder of your current working directory:
 
@@ -1105,7 +1109,7 @@ commands.  For a listing of these commands, type:
 debug> help
 @end example
 
-Alternatively you may code the breakpoints in your Lilypond source
+Alternatively you may code the breakpoints in your LilyPond source
 file using a command such as:
 
 @example
@@ -1130,18 +1134,17 @@ in has been declared.  For example, if you are working on routines
 called by @var{print-book-with} in @file{lily-library.scm}:
 
 @example
-(define (print-book-with parser book process-procedure)
-  (let* ((paper (ly:parser-lookup parser '$defaultpaper))
-        (layout (ly:parser-lookup parser '$defaultlayout))
-        (outfile-name (get-outfile-name parser)))
+(define (print-book-with book process-procedure)
+  (let* ((paper (ly:parser-lookup '$defaultpaper))
+         (layout (ly:parser-lookup '$defaultlayout))
+         (outfile-name (get-outfile-name book)))
     (process-procedure book paper layout outfile-name)))
 
-(define-public (print-book-with-defaults parser book)
-  (print-book-with parser book ly:book-process))
-
-(define-public (print-book-with-defaults-as-systems parser book)
-  (print-book-with parser book ly:book-process-to-systems))
+(define-public (print-book-with-defaults book)
+  (print-book-with book ly:book-process))
 
+(define-public (print-book-with-defaults-as-systems book)
+  (print-book-with book ly:book-process-to-systems))
 @end example
 
 At this point in the code you could add this to set a breakpoint at
@@ -1204,8 +1207,15 @@ number of different platforms:
 
 In order for the Graphviz tool to work, config.make must be modified.
 It is probably a good idea to first save a copy of config.make under
-a different name.  Then, edit config.make by removing every occurrence
-of @option{-DNDEBUG}.
+a different name.
+
+In order to have the required functionality available, LilyPond
+needs to be compiled with the option @option{-DDEBUG}.  You can
+achieve this by configuring with
+
+@example
+./configure --enable-checking
+@end example
 
 @item Rebuilding LilyPond
 
@@ -1222,9 +1232,9 @@ In order to use the graphviz utility, the @file{.ly} file must include
 grobs and symbols that should be tracked.  An example of this
 is found in @file{input/regression/graphviz.ly}.
 
-@item Run lilypond with output sent to a log file
+@item Run LilyPond with output sent to a log file
 
-The Graphviz data is sent to stderr by lilypond, so it is
+The Graphviz data is sent to stderr by LilyPond, so it is
 necessary to redirect stderr to a logfile:
 
 @example
@@ -1233,11 +1243,11 @@ lilypond graphviz.ly 2> graphviz.log
 
 @item Edit the logfile
 
-The logfile has standard lilypond output, as well as the Graphviz
+The logfile has standard LilyPond output, as well as the Graphviz
 output data.  Delete everything from the beginning of the file
 up to but not including the first occurrence of @code{digraph}.
 
-Also, delete the final lilypond message about success from the end
+Also, delete the final LilyPond message about success from the end
 of the file.
 
 @item Process the logfile with @code{dot}
@@ -1253,10 +1263,10 @@ dot -Tpdf graphviz.log > graphviz.pdf
 
 The pdf file can then be viewed with any pdf viewer.
 
-When compiled without @option{-DNDEBUG}, lilypond may run slower
-than normal.  The original configuration can be restored by either
-renaming the saved copy of @code{config.make} or rerunning
-@code{configure}.  Then rebuild lilypond with
+When compiled with @option{-DDEBUG}, LilyPond may run slower
+than normal.  The original configuration can be restored by rerunning
+@code{./configure} with @option{--disable-checking}.  Then
+rebuild LilyPond with
 
 @example
 make -C lily clean && make -C lily
@@ -1365,7 +1375,7 @@ scripts/auxiliar/update-with-convert-ly.sh
 If you did an out-of-tree build, pass in the relative path:
 
 @example
-BUILD_DIR=../build-lilypond/ scripts/auxiliar/update-with-convert-ly.sh
+LILYPOND_BUILD_DIR=../build-lilypond/ scripts/auxiliar/update-with-convert-ly.sh
 @end example
 
 
@@ -1373,7 +1383,7 @@ BUILD_DIR=../build-lilypond/ scripts/auxiliar/update-with-convert-ly.sh
 @subsection Manually update documentation
 
 Where the convert-ly rule is not able to automatically update the inline
-lilypond code in the documentation (i.e. if a NOT_SMART rule is used), the
+LilyPond code in the documentation (i.e. if a NOT_SMART rule is used), the
 documentation must be manually updated.  The inline snippets that require
 changing must be changed in the English version of the docs and all
 translated versions.  If the inline code is not changed in the
@@ -1808,7 +1818,8 @@ time and to prevent you some major headaches.
 
 @node Purity in LilyPond
 @subsection Purity in LilyPond
-Pure properties in LilyPond that do not have any @q{side effects}.
+Pure properties in LilyPond are properties that do not have any
+@q{side effects}.
 That is, looking up a pure property should never result in calls to the
 following functions:
 @itemize
@@ -1889,7 +1900,7 @@ of a spanner broken at given starting and ending columns.
 @node How purity is defined and stored
 @subsection How purity is defined and stored
 Purity is defined in LilyPond with the creation of an unpure-pure container
-(unpure is not a word, but hey, neither was Lilypond until the 90s).  For example:
+(unpure is not a word, but hey, neither was LilyPond until the 90s).  For example:
 
 @example
 #(define (foo grob)
@@ -2012,7 +2023,7 @@ instead of pure height.
 @node LilyPond scoping
 @section LilyPond scoping
 
-The Lilypond language has a concept of scoping, i.e. you can do:
+The LilyPond language has a concept of scoping, i.e. you can do:
 
 @example
 foo = 1
@@ -2028,7 +2039,7 @@ is translated in to a scheme variable definition.
 This implemented using modules, with each scope being an anonymous
 module that imports its enclosing scope's module.
 
-Lilypond's core, loaded from @file{.scm} files, is usually placed in the
+LilyPond's core, loaded from @file{.scm} files, is usually placed in the
 @code{lily} module, outside the @file{.ly} level.  In the case of
 
 @example
@@ -2131,7 +2142,7 @@ but not @code{scm_is_equal}.
 Return @code{true} if @var{b} is @code{SCM_BOOL_T}, else return @code{false}.
 
 This should be used instead of @code{scm_is_true} and
-@code{scm_is_false} for properties since in Lilypond, unset properties
+@code{scm_is_false} for properties since in LilyPond, unset properties
 are read as an empty list, and by convention unset Boolean properties
 default to false.  Since both @code{scm_is_true} and
 @code{scm_is_false} only compare with @code{##f} in line with what
@@ -2146,10 +2157,10 @@ Behave the same as scm_is_[something] would do if it existed.
 
 Test whether the type of @var{s} is [type].
 [type] is a LilyPond-only set of values (direction, axis...).  More
-often than not, the code checks Lilypond specific C++-implemented
+often than not, the code checks LilyPond specific C++-implemented
 types using
 
-@subsubheading [Type *] Type::unsmob (SCM s)
+@subsubheading [Type *] unsmob<Type> (SCM s)
 
 This tries converting a Scheme object to a pointer of the desired
 kind.  If the Scheme object is of the wrong type, a pointer value
@@ -2547,22 +2558,24 @@ this will display OBJ through GUILE.
 @subsection Music functions and GUILE debugging
 
 Ian Hulin was trying to do some debugging in music functions, and
-came up with the following question
+came up with the following question (edited and adapted to current
+versions):
 
 HI all,
 I'm working on the Guile Debugger Stuff, and would like to try
 debugging a music function definition such as:
 
 @example
-conditionalMark = #(define-music-function (parser location) ()
-    #@{ \tag #'instrumental-part @{\mark \default@}  #@} )
+conditionalMark =
+#(define-music-function () ()
+  #@{ \tag instrumental-part @{\mark \default@} #@} )
 @end example
 
-It appears conditionalMark does not get set up as an
+It appears @code{conditionalMark} does not get set up as an
 equivalent of a Scheme
 
 @example
-(define conditionalMark = define-music-function(parser location () ...
+(define conditionalMark = define-music-function () () ...
 @end example
 
 @noindent
@@ -2576,25 +2589,54 @@ although something gets defined because Scheme apparently recognizes
 later on in the file without signalling any Guile errors.
 
 However the breakpoint trap is never encountered as
-define-music-function passed things on to ly:make-music-function,
-which is really C++ code ly_make_music_function, so Guile never
-finds out about the breakpoint.
+@code{define-music-function} passed things on to
+@code{ly:make-music-function}, which is really C++ code
+@code{ly_make_music_function}, so Guile never finds out about the
+breakpoint.
+
+
+The answer in the mailing list archive at that time was less than
+helpful.  The question already misidentifies the purpose of
+@code{ly:make-music-function} which is only called once at the
+time of @emph{defining} @code{conditionalMark} but is not involved
+in its later @emph{execution}.
 
-Han-Wen answered as follows:
+Here is the real deal:
 
-You can see the definition by doing
+A music function is not the same as a GUILE function.  It boxes
+both a proper Scheme function (with argument list and body from
+the @code{define-music-function} definition) along with a call
+signature representing the @emph{types} of both function and
+arguments.
+
+Those components can be reextracted using
+@code{ly:music-function-extract} and
+@code{ly:music-function-signature}, respectively.
+
+When LilyPond's parser encounters a music function call in its
+input, it reads, interprets, and verifies the arguments
+individually according to the call signature and @emph{then} calls
+the proper Scheme function.
+
+While it is actually possible these days to call a music function
+@emph{as if} it were a Scheme function itself, this pseudo-call
+uses its own wrapping code matching the argument list @emph{as a
+whole} to the call signature, substituting omitted optional
+arguments with defaults and verifying the result type.
+
+So putting a breakpoint on the music function itself will still
+not help with debugging uses of the function using LilyPond
+syntax.
+
+However, either calling mechanism ultimately calls the proper
+Scheme function stored as part of the music function, and that is
+where the breakpoint belongs:
 
 @example
-#(display conditionalMark)
+#(set-break! (ly:music-function-extract conditionalMark))
 @end example
 
-noindent
-inside the @file{.ly} file.
-
-The breakpoint failing may have to do with the call sequence.  See
-@file{parser.yy}, run_music_function().  The function is called directly from
-C++, without going through the GUILE evaluator, so I think that is why
-there is no debugger trap.
+will work for either calling mechanism.
 
 @node Articulations on EventChord
 @subsection Articulations on EventChord