[ << Programming work ] | [Top][Contents] | [ Release work >> ] |
[ < Scheme->C interface ] | [ Up : Scheme->C interface ] | [ Conversion > ] |
10.15.1 Comparison
This is the trickiest part of the interface.
Mixing Scheme values with C comparison operators won’t produce any crash or warning when compiling but must be avoided:
scm_string_p (scm_value) == SCM_BOOL_T
As we can read in the reference, scm_string_p
returns a Scheme
value: either #t
or #f
which are written SCM_BOOL_T
and SCM_BOOL_F
in C. This will work, but it is not following
to the API guidelines. For further information, read this discussion:
https://lists.gnu.org/archive/html/lilypond-devel/2011-08/msg00646.html |
There are functions in the Guile reference that returns C values
instead of Scheme values. In our example, a function called
scm_is_string
(described after string?
and scm_string_p
)
returns the C value 0 or 1.
So the best solution was simply:
scm_is_string (scm_value)
There a simple solution for almost every common comparison. Another example: we want to know if a Scheme value is a non-empty list. Instead of:
(scm_is_true (scm_list_p (scm_value)) && scm_value != SCM_EOL)
one can usually use:
scm_is_pair (scm_value)
since a list of at least one member is a pair. This test is
cheap; scm_list_p
is actually quite more complex since it makes
sure that its argument is neither a ‘dotted list’ where the last pair
has a non-null cdr
, nor a circular list. There are few
situations where the complexity of those tests make sense.
Unfortunately, there is not a scm_is_[something]
function for
everything. That’s one of the reasons why LilyPond has its own Scheme
interface. As a rule of thumb, tests that are cheap enough to be
worth inlining tend to have such a C interface. So there is
scm_is_pair
but not scm_is_list
, and scm_is_eq
but not scm_is_equal
.
General definitions
bool to_boolean (SCM b)
Return true
if b is SCM_BOOL_T
, else return false
.
This should be used instead of scm_is_true
and
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 scm_is_true
and
scm_is_false
only compare with ##f
in line with what
Scheme’s conditionals do, they are not really useful for checking the
state of a Boolean property.
bool ly_is_[something] (args)
Behave the same as scm_is_[something] would do if it existed.
bool is_[type] (SCM s)
Test whether the type of s is [type]. [type] is a LilyPond-only set of values (direction, axis...). More often than not, the code checks LilyPond specific C++-implemented types using
[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
of 0
is returned, making this suitable for a Boolean test.
[ << Programming work ] | [Top][Contents] | [ Release work >> ] |
[ < Scheme->C interface ] | [ Up : Scheme->C interface ] | [ Conversion > ] |