lilypond-devel
[Top][All Lists]
Advanced

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

Re: [PATCH] Scheme function ly:string->duration


From: Joe Neeman
Subject: Re: [PATCH] Scheme function ly:string->duration
Date: Sat, 17 May 2008 08:16:32 +1000

On Sat, May 17, 2008 at 4:59 AM, Neil Puttock <address@hidden> wrote:
Hello,

In the thread about creating custom metronome markups
(http://lists.gnu.org/archive/html/lilypond-user/2008-04/msg00629.html)
and the subsequent discussion at The LilyPond Report, Valentin
expressed the wish for a convenient way to convert duration strings to
durations.  Since I agreed, I thought I'd have a go at implementing an
exported scheme function in duration-scheme.cc which can be used
within lilypond files.

Attached is a patch with "My First C++ Code", which provides this
functionality. :)
 
Hi Neil,
This looks pretty good overall; my main complaint is that it is a bit too permissive in its parsing. Comments below:
 
+
+LY_DEFINE (ly_string_2_duration, "ly:string->duration",
+       1, 0, 0, (SCM str),
+       "Convert @var{str} to a duration.")
+{
+  LY_ASSERT_TYPE (scm_is_string, str, 1);
+  string s = ly_scm2string (str);
+  stringstream stream (s);
+  int len = 0;
+  int dots = 0;
+  size_t pos = 0;
+
+  while (pos !=NPOS)

Space after !=

+    {
+      pos = s.find (".", pos);

This will allow strings like "2.asdf..". Why not just search for the first '.' and then check all subsequent characters?

+      if (pos != NPOS)
+    {
+      dots++;
+      pos++;
+    }
+    }
+  s = s.substr (0, (s.length () - dots));
+
+  stream >> len;

You need to check that all of the characters were used up in the conversion or else "2asdf." will pass. I'd suggest
if (sscanf (s.c_str (), "%d") != s.size ()) ...
since I find the C stdlib functions less unwieldy than C++ streams, particularly in simple situations.

+  if (!stream.fail () && (len && len == 1 << intlog2 (len)))
+      len = intlog2 (len);
+  else
+    {
+      if (s == "breve")
+      len = -1;
+      else if (s == "longa")
+      len = -2;
+      else if (s == "maxima")
+      len = -3;
+      else
+        {
+      len = 0;
+      dots = 0;
+      warning (_ ("invalid duration string, setting to whole note"));

Perhaps print the invalid duration string as part of the message (using _f ()).

Joe


reply via email to

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