plug memleak in case of failed files.
don't allocate part combine events statically. Plugs small leak.
ignore gcstat files.
don't delete .scale.pfa; the FF script may not have read themyet. Fixes brace OTF bug
more ignores.
Remove set-part-combine-listener. This plugs a memory leak.
clear lexer scopes after parsing file. Plugs pseudo memory leak
set-part-combine fix for autochange.
implement and use ASSERT_LIVE_IS_ALLOWED()
autochange thinko.
*.midi
\#*
lily-[0-9][0-9][0-9]*
+gcstat*.scm
+*.aux
+*.svg
+*.pyc
+*.log
+.htaccess
+*.tfm
+*.afm
+
+2006-11-02 Han-Wen Nienhuys <hanwen@lilypond.org>
+
+ * scm/autochange.scm:
+ autochange thinko.
+
+ * lily/context-def.cc:
+ * lily/include/parse-scm.hh:
+ * lily/include/smobs.hh:
+ * lily/parse-scm.cc:
+ * lily/prob.cc:
+ * lily/program-option.cc:
+ * scm/lily.scm:
+ implement and use ASSERT_LIVE_IS_ALLOWED()
+
+ * ly/music-functions-init.ly:
+ * scm/autochange.scm:
+ set-part-combine fix for autochange.
+
+ * lily/include/lily-lexer.hh:
+ * lily/include/lily-parser.hh:
+ * lily/lily-lexer.cc:
+ * lily/lily-parser-scheme.cc:
+ * lily/lily-parser.cc:
+ clear lexer scopes after parsing file. Plugs pseudo memory leak
+
+ * ly/declarations-init.ly:
+ * ly/music-functions-init.ly:
+ * scm/part-combiner.scm:
+ Remove set-part-combine-listener. This plugs a memory leak.
+
+ * .gitignore:
+ more ignores.
+
+ * mf/GNUmakefile:
+ don't delete .scale.pfa; the FF script may not have read themyet. Fixes brace OTF bug
+
+ * .gitignore:
+ ignore gcstat files.
+
+ * lily/part-combine-iterator.cc:
+ don't allocate part combine events statically. Plugs small leak.
+
+ * lily/lily-parser-scheme.cc:
+ plug memleak in case of failed files.
+
+ * lily/include/source.hh:
+ * lily/source.cc:
+ clean up Sources
+
+ * lily/lexer.ll:
+ hi-bit ascii is also counted as alpha chars. This allows unicodeidentifiers, and fixes premature stop at accented char. (#134)
+
+ * lily/include/program-option.hh:
+ * lily/program-option.cc:
+ get_program_option() function
+
+ * ly/titling-init.ly:
+ change naming: print-page-number becomescreate-page-number-stencil. This avoids nameclash withprint-page-number boolean, and fixes page number printing.
+
+ * lily/include/translator.hh:
+ * lily/include/translator.icc:
+ * lily/translator.cc:
+ minor cleanups
+
+ * lily/figured-bass-engraver.cc:
+ don't use ASSIGN_EVENT_ONCE for Figured_bass_engraver. Fixes #128.
+
+ * stepmake/stepmake/compile-vars.make:
+ don't do -fPIC for mingw. Suppresses warning about unnecessary -fPIC
+
2006-11-01 Han-Wen Nienhuys <hanwen@lilypond.org>
* python/midi.c:
SCM
Context_def::mark_smob (SCM smob)
{
+ ASSERT_LIVE_IS_ALLOWED();
+
Context_def *me = (Context_def *) SCM_CELL_WORD_1 (smob);
scm_gc_mark (me->description_);
void add_scope (SCM);
SCM set_current_scope ();
+ bool has_scope () const;
SCM remove_scope ();
void start_main_input ();
DECLARE_SCHEME_CALLBACK (layout_description, ());
+ void clear ();
void do_init_file ();
void do_yyparse ();
void parse_file (string init, string name, string out_name);
#include "lily-guile.hh"
extern bool parse_protect_global;
+extern bool parsed_objects_should_be_dead;
struct Parse_start
{
SCM ly_get_option (SCM);
SCM ly_set_option (SCM, SCM);
+bool get_program_option (const char *);
+
#endif /* SCM_OPTION_HH */
#include "lily-guile.hh"
#include "virtual-methods.hh"
+#include "warn.hh"
/*
Smobs are GUILEs mechanism of exporting C(++) objects to the Scheme
void protect_smob (SCM smob, SCM *prot_cons);
void unprotect_smob (SCM smob, SCM *prot_cons);
+extern bool parsed_objects_should_be_dead;
+
+#define ASSERT_LIVE_IS_ALLOWED() \
+ static bool passed_here_once;\
+ if (parsed_objects_should_be_dead && !passed_here_once) { \
+ programming_error (string ("Parsed object should be dead: ") + __PRETTY_FUNCTION__ ); \
+ passed_here_once = true;\
+ }
+
#endif /* SMOBS_HH */
/* A set of sourcefiles. */
class Sources
{
- Sources (Sources const &) {}
+ Sources (Sources const &);
vector<Source_file*> sourcefiles_;
- bool is_binary_;
public:
Sources ();
Source_file *get_sourcefile (char const *);
void add (Source_file *sourcefile);
void set_path (File_path *);
- void set_binary (bool);
const File_path *path_;
};
(*(YYLTYPE*)lexloc)
#define YY_USER_ACTION add_lexed_char (YYLeng ());
-/*
-
-LYRICS ({AA}|{TEX})[^0-9 \t\n\f]*
-
-*/
SCM scan_fraction (string);
%x sourcefilename
%x version
-A [a-zA-Z]
+A [a-zA-Z\200-\377]
AA {A}|_
N [0-9]
AN {AA}|{N}
ANY_CHAR (.|\n)
PUNCT [?!:'`]
ACCENT \\[`'"^]
-NATIONAL [\001-\006\021-\027\031\036\200-\377]
+NATIONAL [\001-\006\021-\027\031\036]
TEX {AA}|-|{PUNCT}|{ACCENT}|{NATIONAL}
WORD {A}{AN}*
DASHED_WORD {A}({AN}|-)*
DASHED_KEY_WORD \\{DASHED_WORD}
+
+
+
ALPHAWORD {A}+
DIGIT {N}
UNSIGNED {N}+
EXTENDER __
HYPHEN --
BOM_UTF8 \357\273\277
+
%%
int i;
sscanf (YYText (), "%d", &i);
-// this->set_debug (1);
yy_pop_state ();
this->here_input ().get_source_file ()->set_line (here_input ().start (), i);
}
set_current_scope ();
}
+bool
+Lily_lexer::has_scope () const
+{
+ return scm_is_pair (scopes_);
+}
SCM
Lily_lexer::remove_scope ()
SCM
Lily_lexer::mark_smob (SCM s)
{
+ ASSERT_LIVE_IS_ALLOWED();
+
Lily_lexer *lexer = (Lily_lexer *) SCM_CELL_WORD_1 (s);
scm_gc_mark (lexer->chordmodifier_tab_);
exit (2);
}
+
+ bool error = false;
if ((file_name != "-") && file_name.empty ())
{
warning (_f ("can't find file: `%s'", file));
- scm_throw (ly_symbol2scm ("ly-file-failed"),
- scm_list_1 (scm_makfrom0str (file_name.c_str ())));
+ error = true;
}
else
{
parser->parse_file (init, file_name, out_file);
- bool error = parser->error_level_;
+ error = parser->error_level_;
+ parser->clear ();
parser->unprotect ();
- if (error)
- /* TODO: pass renamed input file too. */
- scm_throw (ly_symbol2scm ("ly-file-failed"),
- scm_list_1 (scm_makfrom0str (file_name.c_str ())));
}
+
+ /*
+ outside the if-else to ensure cleanup fo Sources object,
+ */
+ if (error)
+ /* TODO: pass renamed input file too. */
+ scm_throw (ly_symbol2scm ("ly-file-failed"),
+ scm_list_1 (scm_makfrom0str (file_name.c_str ())));
+
return SCM_UNSPECIFIED;
}
}
error_level_ = error_level_ | lexer_->error_level_;
- lexer_ = 0;
+ clear ();
}
void
error_level_ = error_level_ | lexer_->error_level_;
}
+void
+Lily_parser::clear ()
+{
+ if (lexer_)
+ {
+ while (lexer_->has_scope ())
+ lexer_->remove_scope ();
+
+
+ }
+ lexer_ = 0;
+}
+
char const *
Lily_parser::here_str0 () const
{
}
bool parse_protect_global = true;
+bool parsed_objects_should_be_dead = false;
/* Try parsing. Upon failure return SCM_UNDEFINED.
FIXME: shouldn't we return SCM_UNSCPECIFIED -- jcn */
protected:
virtual void derived_substitute (Context *f, Context *t);
virtual void derived_mark () const;
- Part_combine_iterator (Part_combine_iterator const &);
virtual void construct_children ();
virtual Moment pending_moment () const;
SCM split_list_;
+ Stream_event *unisono_event_;
+ Stream_event *solo_one_event_;
+ Stream_event *solo_two_event_;
+ Stream_event *mmrest_event_;
+
enum Status
{
APART,
Part_combine_iterator::Part_combine_iterator ()
{
+ mmrest_event_ = 0;
+ unisono_event_ = 0;
+ solo_two_event_ = 0;
+ solo_one_event_= 0;
+
first_iter_ = 0;
second_iter_ = 0;
split_list_ = SCM_EOL;
scm_gc_mark (first_iter_->self_scm ());
if (second_iter_)
scm_gc_mark (second_iter_->self_scm ());
+
+ Stream_event *ptrs[] = {
+ unisono_event_,
+ mmrest_event_,
+ solo_two_event_,
+ solo_one_event_,
+ 0
+ };
+ for (int i = 0; ptrs[i]; i++)
+ if (ptrs[i])
+ scm_gc_mark (ptrs[i]->self_scm ());
}
void
void
Part_combine_iterator::kill_mmrest (int in)
{
- static Stream_event *mmrest;
- if (!mmrest)
+
+ if (!mmrest_event_)
{
- mmrest = new Stream_event (ly_symbol2scm ("multi-measure-rest-event"));
- mmrest->set_property ("duration", SCM_EOL);
+ mmrest_event_ = new Stream_event (ly_symbol2scm ("multi-measure-rest-event"));
+ mmrest_event_->set_property ("duration", SCM_EOL);
+ mmrest_event_->unprotect ();
}
- handles_[in].get_outlet ()->event_source ()->broadcast (mmrest);
+ handles_[in].get_outlet ()->event_source ()->broadcast (mmrest_event_);
}
void
if (playing_state_ != SOLO1)
{
- static Stream_event *event;
- if (!event)
- event = new Stream_event (ly_symbol2scm ("solo-one-event"));
+ if (!solo_one_event_)
+ {
+ solo_one_event_ = new Stream_event (ly_symbol2scm ("solo-one-event"));
+ solo_one_event_->unprotect ();
+ }
- first_iter_->get_outlet ()->event_source ()->broadcast (event);
+ first_iter_->get_outlet ()->event_source ()->broadcast (solo_one_event_);
}
playing_state_ = SOLO1;
}
if (playing_state_ != UNISONO
&& newstate == UNISONO)
{
- static Stream_event *event;
- if (!event)
- event = new Stream_event (ly_symbol2scm ("unisono-event"));
-
+ if (!unisono_event_)
+ {
+ unisono_event_ = new Stream_event (ly_symbol2scm ("unisono-event"));
+ unisono_event_->unprotect ();
+ }
+
Context *out = (last_playing_ == SOLO2 ? second_iter_ : first_iter_)
->get_outlet ();
- out->event_source ()->broadcast (event);
+ out->event_source ()->broadcast (unisono_event_);
playing_state_ = UNISONO;
}
state_ = newstate;
if (playing_state_ != SOLO2)
{
- static Stream_event *event;
- if (!event)
- event = new Stream_event (ly_symbol2scm ("solo-two-event"));
-
- second_iter_->get_outlet ()->event_source ()->broadcast (event);
+ if (!solo_two_event_)
+ {
+ solo_two_event_ = new Stream_event (ly_symbol2scm ("solo-two-event"));
+ solo_two_event_->unprotect ();
+ }
+
+ second_iter_->get_outlet ()->event_source ()->broadcast (solo_two_event_);
playing_state_ = SOLO2;
}
}
}
/*
-* Processes a moment in an iterator, and returns whether any new music was reported.
+ Processes a moment in an iterator, and returns whether any new music
+ was reported.
*/
bool
Part_combine_iterator::try_process (Music_iterator *i, Moment m)
SCM
Prob::mark_smob (SCM smob)
{
+ ASSERT_LIVE_IS_ALLOWED();
+
Prob *system = (Prob *) SCM_CELL_WORD_1 (smob);
scm_gc_mark (system->mutable_property_alist_);
system->derived_mark ();
bool do_internal_type_checking_global;
bool strict_infinity_checking = false;
-
static SCM option_hash;
void internal_set_option (SCM var, SCM val)
do_internal_type_checking_global = to_boolean (val);
val = scm_from_bool (to_boolean (val));
}
+ else if (var == ly_symbol2scm ("debug-gc-assert-parsed-dead"))
+ {
+ parsed_objects_should_be_dead = to_boolean (val);
+ val = scm_from_bool (parsed_objects_should_be_dead);
+ }
else if (var == ly_symbol2scm ("old-relative"))
{
lily_1_8_relative = to_boolean (val);
return scm_from_bool (be_verbose_global);
}
+
+
+
LY_DEFINE (ly_get_option, "ly:get-option", 1, 0, 0, (SCM var),
"Get a global option setting.")
{
SCM_ARG1, __FUNCTION__, "symbol");
return scm_hashq_ref (option_hash, var, SCM_BOOL_F);
}
+
+
+bool
+get_program_option (const char *s)
+{
+ SCM sym = ly_symbol2scm (s);
+
+ return to_boolean (ly_get_option (sym));
+}
Sources::Sources ()
{
path_ = 0;
- is_binary_ = false;
}
-void
-Sources::set_binary (bool bo)
+
+Sources::Sources (Sources const &)
{
- is_binary_ = bo;
+ assert (false);
}
+
void
Sources::set_path (File_path *f)
{
}
}
-Source_file *
-Sources::get_sourcefile (char const *str0)
-{
- for (vector<Source_file*>::iterator i = sourcefiles_.begin();
- i != sourcefiles_.end (); i++)
- {
- if ((*i)->contains (str0))
- return *i;
- }
-
- return 0;
-}
-
}
}
-#(set-part-combine-listener partCombineListener)
-
\include "dynamic-scripts-init.ly"
\include "spanners-init.ly"
\include "property-init.ly"
addquote =
#(define-music-function (parser location name music) (string? ly:music?)
"Add a piece of music to be quoted "
- (add-quotable name music)
+ (add-quotable parser name music)
(make-music 'SequentialMusic 'void #t))
autochange =
#(define-music-function (parser location music) (ly:music?)
- (make-autochange-music music))
+ (make-autochange-music parser music))
applyContext =
#(define-music-function (parser location proc) (procedure?)
))
partcombine =
#(define-music-function (parser location part1 part2) (ly:music? ly:music?)
- (make-part-combine-music (list part1 part2)))
+ (make-part-combine-music parser
+ (list part1 part2)))
pitchedTrill =
$(outdir)/aybabtu.otf $(outdir)/aybabtu.svg: $(outdir)/aybabtu.pe $(foreach s,$(BRACES),$(outdir)/feta-braces-$(s).pfa) $(outdir)/aybabtu.otf-table $(outdir)/aybabtu.otf-gtable
cd $(outdir) && $(FONTFORGE) -script aybabtu.pe
- -rm -f $(outdir)/*.scale.{pfa,afm}
$(outdir)/%.pfa: $(outdir)/%.log
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; autochange - fairly related to part combining.
-(define-public (make-autochange-music music)
+(define-public (make-autochange-music parser music)
(define (generate-split-list change-moment event-list acc)
(if (null? event-list)
acc
(let* ((m (make-music 'AutoChangeMusic))
(m1 (make-non-relative-music (context-spec-music music 'Voice "one")))
- (context-list (recording-group-emulate music part-combine-listener))
+ (context-list (recording-group-emulate music
+ (ly:parser-lookup parser 'partCombineListener)))
(evs (car context-list))
(rev (reverse! (cdar context-list)))
(split (reverse! (generate-split-list
(clip-systems #f "Generate cut-out snippets of a score")
(debug-gc #f
"dump memory debugging statistics")
+ (debug-gc-assert-parsed-dead #f
+ "for memory debugging: ensure that all refs to parsed objects are dead.")
+
(debug-midi #f "generate human readable MIDI")
- (debug-parser #f "debug the bison parser")
(debug-lexer #f "debug the flex lexer")
(debug-midi #f "generate human readable MIDI")
(delete-intermediate-files #f
(display "Live object statistics: GC'ing\n")
(gc)
(gc)
+ (ly:set-option 'debug-gc-assert-parsed-dead #t)
+ (gc)
(set! stats (gc-live-object-stats))
(display "Dumping live object statistics.\n")
(for-each
(lambda (x)
+ (ly:set-option 'debug-gc-assert-parsed-dead #f)
(lilypond-file handler x)
(ly:clear-anonymous-modules)
(if (ly:get-option 'debug-gc)
(lambda () (ly:parse-file file-name))
(lambda (x . args) (handler x file-name))))
-(use-modules (scm editor)
- )
+(use-modules (scm editor))
(define-public (gui-main files)
(if (null? files)
(ly:interpret-music-expression (make-non-relative-music music) global)
context-list))
-(define noticed '())
-;; todo: junk this, extract $defaultlayout from parser instead
-(define part-combine-listener '())
-
-; UGH - should pass noticed setter to part-combine-listener
-(define-safe-public (set-part-combine-listener x)
- (set! part-combine-listener x))
-
-(define-public (notice-the-events-for-pc context lst)
- "add CONTEXT-ID, EVENT list to NOTICED variable."
-
- (set! noticed (acons (ly:context-id context) lst noticed)))
-
-(define-public (make-part-combine-music music-list)
+(define-public (make-part-combine-music parser music-list)
(let* ((m (make-music 'PartCombineMusic))
(m1 (make-non-relative-music (context-spec-music (first music-list) 'Voice "one")))
(m2 (make-non-relative-music (context-spec-music (second music-list) 'Voice "two")))
- (evs2 (recording-group-emulate m2 part-combine-listener))
- (evs1 (recording-group-emulate m1 part-combine-listener)))
+ (listener (ly:parser-lookup parser 'partCombineListener))
+ (evs2 (recording-group-emulate m2 listener))
+ (evs1 (recording-group-emulate m1 listener)))
(set! (ly:music-property m 'elements) (list m1 m2))
(set! (ly:music-property m 'split-list)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-(define-public (add-quotable name mus)
- (set! noticed '())
+(define-public (add-quotable parser name mus)
(let* ((tab (eval 'musicQuotes (current-module)))
(context-list (recording-group-emulate (context-spec-music mus 'Voice)
- part-combine-listener)))
+ (ly:parser-lookup parser 'partCombineListener))))
(if (pair? context-list)
(hash-set! tab name
;; cdr : skip name string