+void
+Translator::derived_mark () const
+{
+}
+
+int
+Translator::print_smob (SCM s, SCM port, scm_print_state *)
+{
+ Translator *me = (Translator *) SCM_CELL_WORD_1 (s);
+ scm_puts ("#<Translator ", port);
+ scm_puts (me->class_name (), port);
+ scm_puts (" >", port);
+ return 1;
+}
+
+void
+add_acknowledger (Engraver_void_function_engraver_grob_info ptr,
+ char const *func_name,
+ vector<Acknowledge_information> *ack_array)
+{
+ Acknowledge_information inf;
+ inf.function_ = ptr;
+
+ string interface_name (func_name);
+
+ interface_name = replace_all (&interface_name, '_', '-');
+ interface_name += "-interface";
+
+ /*
+ this is only called during program init, so safe to use scm_gc_protect_object ()
+ */
+ inf.symbol_ = scm_gc_protect_object (ly_symbol2scm (interface_name.c_str ()));
+ ack_array->push_back (inf);
+}
+
+Engraver_void_function_engraver_grob_info
+generic_get_acknowledger (SCM sym, vector<Acknowledge_information> const *ack_array)
+{
+ for (vsize i = 0; i < ack_array->size (); i++)
+ {
+ if (ack_array->at (i).symbol_ == sym)
+ return ack_array->at (i).function_;
+ }
+ return 0;
+}
+
+
+Moment
+get_event_length (Stream_event *e)
+{
+ Moment *m = unsmob_moment (e->get_property ("length"));
+ if (m)
+ return *m;
+ else
+ return Moment (0);
+}
+
+Moment
+get_event_length (Stream_event *e, Moment now)
+{
+ Moment len = get_event_length (e);
+
+ if (now.grace_part_)
+ {
+ len.grace_part_ = len.main_part_;
+ len.main_part_ = Rational (0);
+ }
+ return len;
+}
+
+/*
+ Helper, used through ASSIGN_EVENT_ONCE to throw warnings for
+ simultaneous events. The helper is only useful in listen_* methods
+ of translators.
+*/
+bool
+internal_event_assignment (Stream_event **old_ev, Stream_event *new_ev, const char *function)
+{
+ if (*old_ev &&
+ !to_boolean (scm_equal_p ((*old_ev)->self_scm (),
+ new_ev->self_scm ())))
+ {
+ /* extract event class from function name */
+ string ev_class = function;
+
+ /* This assertion fails if EVENT_ASSIGNMENT was called outside a
+ translator listener. Don't do that. */
+ const char *prefix = "listen_";
+ assert (0 == ev_class.find (prefix));
+
+ /* "listen_foo_bar" -> "foo-bar" */
+ ev_class.erase (0, strlen (prefix));
+ replace_all (&ev_class, '_', '-');
+
+ new_ev->origin ()->warning (_f ("Two simultaneous %s events, junking this one", ev_class.c_str ()));
+ (*old_ev)->origin ()->warning (_f ("Previous %s event here", ev_class.c_str ()));
+ return false;
+ }
+ else
+ {
+ *old_ev = new_ev;
+ return true;
+ }
+}
+
+ADD_TRANSLATOR (Translator,
+ /* doc */
+ "Base class. Not instantiated.",
+
+ /* create */
+ "",
+
+ /* read */
+ "",
+
+ /* write */
+ ""
+ );