]> git.donarmstrong.com Git - lilypond.git/blob - lily/prob.cc
Issue 5167/3: Split off `markup-lambda' from `define-markup-command'
[lilypond.git] / lily / prob.cc
1 /*
2   This file is part of LilyPond, the GNU music typesetter.
3
4   Copyright (C) 2004--2015 Jan Nieuwenhuizen <janneke@gnu.org>
5
6   LilyPond is free software: you can redistribute it and/or modify
7   it under the terms of the GNU General Public License as published by
8   the Free Software Foundation, either version 3 of the License, or
9   (at your option) any later version.
10
11   LilyPond is distributed in the hope that it will be useful,
12   but WITHOUT ANY WARRANTY; without even the implied warranty of
13   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14   GNU General Public License for more details.
15
16   You should have received a copy of the GNU General Public License
17   along with LilyPond.  If not, see <http://www.gnu.org/licenses/>.
18 */
19
20 #include "prob.hh"
21 #include "main.hh"
22 #include "item.hh"
23 #include "input.hh"
24 #include "profile.hh"
25
26
27 const char * const Prob::type_p_name_ = "ly:prob?";
28
29 SCM
30 Prob::equal_p (SCM sa, SCM sb)
31 {
32   /* This comparison function is only designed to make the copy
33      constructor preserve equality.
34
35      Perhaps it would be better to use a more strict definition of
36      equality; e.g., that two probs are equal iff they can be
37      distinguished by calls to ly:prob-property.
38   */
39   Prob *probs[2] = {unsmob<Prob> (sa), unsmob<Prob> (sb)};
40   SCM props[2][2];
41   int i;
42
43   for (i = 0; i < 2; i++)
44     {
45       props[i][0] = probs[i]->immutable_property_alist_;
46       props[i][1] = probs[i]->mutable_property_alist_;
47     }
48
49   if (strcmp (probs[0]->class_name (), probs[1]->class_name ()))
50     return SCM_BOOL_F;
51
52   /* Compare mutable and immutable lists, element by element. */
53   for (i = 0; i < 2; i++)
54     {
55       SCM aprop = props[0][i];
56       SCM bprop = props[1][i];
57
58       for (;
59            scm_is_pair (aprop) && scm_is_pair (bprop);
60            aprop = scm_cdr (aprop), bprop = scm_cdr (bprop))
61         {
62           SCM aval = scm_cdar (aprop);
63           SCM bval = scm_cdar (bprop);
64           if (!scm_is_eq (scm_caar (aprop), scm_caar (bprop))
65               || (!(unsmob<Input> (aval) && unsmob<Input> (bval))
66                   && !ly_is_equal (aval, bval)))
67             return SCM_BOOL_F;
68         }
69
70       /* is one list shorter? */
71       if (!scm_is_null (aprop) || !scm_is_null (bprop))
72         return SCM_BOOL_F;
73     }
74
75   return SCM_BOOL_T;
76 }
77
78 Prob::Prob (SCM type, SCM immutable_init) : Smob<Prob> ()
79 {
80   mutable_property_alist_ = SCM_EOL;
81   immutable_property_alist_ = immutable_init;
82   type_ = type;
83   smobify_self ();
84 }
85
86 Prob::~Prob ()
87 {
88 }
89
90 Prob::Prob (Prob const &src)
91   : Smob<Prob> ()
92 {
93   immutable_property_alist_ = src.immutable_property_alist_;
94   mutable_property_alist_ = SCM_EOL;
95   type_ = src.type_;
96
97   /* First we smobify_self, then we copy over the stuff.  If we don't,
98      stack vars that hold the copy might be optimized away, meaning
99      that they won't be protected from GC. */
100   smobify_self ();
101   mutable_property_alist_ = src.copy_mutable_properties ();
102 }
103
104 SCM
105 Prob::copy_mutable_properties () const
106 {
107   return ly_deep_copy (mutable_property_alist_);
108 }
109
110 void
111 Prob::derived_mark () const
112 {
113 }
114
115 SCM
116 Prob::mark_smob () const
117 {
118   ASSERT_LIVE_IS_ALLOWED (self_scm ());
119
120   scm_gc_mark (mutable_property_alist_);
121   derived_mark ();
122
123   return immutable_property_alist_;
124 }
125
126 int
127 Prob::print_smob (SCM port, scm_print_state *) const
128 {
129   scm_puts ("#<", port);
130   scm_puts ("Prob: ", port);
131   scm_display (type_, port);
132   scm_puts (" C++: ", port);
133   scm_puts (class_name (), port);
134   scm_display (mutable_property_alist_, port);
135   scm_display (immutable_property_alist_, port);
136
137   scm_puts (" >\n", port);
138   return 1;
139 }
140
141 SCM
142 Prob::internal_get_property (SCM sym) const
143 {
144 #ifdef DEBUG
145   if (profile_property_accesses)
146     note_property_access (&prob_property_lookup_table, sym);
147 #endif
148
149   /*
150     TODO: type checking
151    */
152   SCM s = scm_sloppy_assq (sym, mutable_property_alist_);
153   if (scm_is_true (s))
154     return scm_cdr (s);
155
156   s = scm_sloppy_assq (sym, immutable_property_alist_);
157   return scm_is_false (s) ? SCM_EOL : scm_cdr (s);
158 }
159
160 /* We don't (yet) instrument probs */
161 void
162 Prob::instrumented_set_property (SCM sym, SCM val, const char *, int, const char *)
163 {
164   internal_set_property (sym, val);
165 }
166
167 void
168 Prob::internal_set_property (SCM sym, SCM val)
169 {
170   if (do_internal_type_checking_global)
171     type_check_assignment (sym, val);
172
173   mutable_property_alist_ = scm_assq_set_x (mutable_property_alist_, sym, val);
174 }
175
176 void
177 Prob::type_check_assignment (SCM, SCM) const
178 {
179   /* empty */
180 }
181
182 SCM
183 Prob::get_property_alist (bool m) const
184 {
185   return (m) ? mutable_property_alist_ : immutable_property_alist_;
186 }
187
188 string
189 Prob::name () const
190 {
191   SCM nm = get_property ("name");
192   if (scm_is_symbol (nm))
193     return ly_symbol2string (nm);
194   else
195     return class_name ();
196 }