For now, don't show a g_warning() for empty tag strings and NULL
tags with non-git versions; we should wait for the fixes in our
plugin modules to make it into a release before we enable this
unconditionally.
Don't forbid the empty string "" in generic structures, only in taglists.
Properly allow the NULL string by adding special cases for serialising
and deserialising it. prop1=(string)NULL is the NULL string,
prop1=(string)"NULL" is the actual string with the value "NULL"
Add a bunch of vararg getter convenience functions to complement
the vararg setter functions, and a basic unit test. Fixes#534208.
API: gst_structure_get()
API: gst_structure_id_get()
API: gst_structure_get_valist()
API: gst_structure_id_get_valist()
Fix some memory leaks shown by the new serialisation/deserialisation unit
test. Split the gst_string_wrap function in gstvalue.c into components and
use them to make gst_string_take_and_wrap, which takes ownership of the
string, avoiding a strdup.
Add some G_LIKELY/UNLIKELY, and clean up some leaks in error paths.
Use string_warp/unwrap to escape delimiters, otherwise deserialisation fails.
Also move GST_ASCII_IS_STRING to private header to avoid keeping it in sync.
Also use '\0' when terminating a string for better readability.
Fixes minor memory leak in unit tests caused by the recent changes.
Since we're expected to take ownership of the GValue in the structure
field struct here, we need to unset it if we don't use it.
Also warn if an element or application tries to add a field with an
empty string to a structure (NULL strings are still needed and
allowed though) and do all those checks in the right function.
Fixes#559643.
Original commit message from CVS:
* gst/gstcaps.c: (gst_caps_copy), (_gst_caps_free),
(gst_caps_merge_structure), (gst_caps_get_structure),
(gst_caps_copy_nth), (gst_caps_set_simple),
(gst_caps_set_simple_valist), (gst_caps_is_fixed),
(gst_caps_is_equal_fixed), (gst_caps_intersect),
(gst_caps_subtract), (gst_caps_normalize), (gst_caps_do_simplify),
(gst_caps_to_string):
Callgrind micro optimisations.
Avoid array bounds checks and force inline of trivial function.
* gst/gstobject.c: (gst_object_set_name_default):
-1 is equivalent to letting glib to the strlen but then there is more
room for optimisations and it's not our fault.
* gst/gststructure.c: (gst_structure_id_empty_new_with_size):
no need to clear the array, we're cool.
* gst/gstvalue.c: (gst_type_is_fixed), (gst_value_is_fixed):
The most common _is_fixed() check is done on fundamental glib base
types so we check this first instead of doing a huge amount of
useless GST_TYPE_ARRAY calls.
Original commit message from CVS:
* gst/gststructure.c: (gst_structure_id_empty_new_with_size):
No need to memset, we can clear the value ourselves.
* gst/gstvalue.c: (gst_type_is_fixed),
(gst_value_get_compare_func):
Some optimisations from a few callgrind sessions:
When checking if a type is fixed, check for trivial fundamental types
first before checking types for which we need to get the type followed
by the heavy duty type checks, this reduces the amount of
g_type_fundamental() calls a lot.
When getting the compare function, first check for our registered types.
If that fails, do the heavy duty g_type_is_a() checks, reduces the
amount of g_type_is_a() considerably.
Original commit message from CVS:
Patch by: Olivier Crete <tester at tester dot ca>
* gst/gststructure.c:
(gst_structure_fixate_field_nearest_fraction):
Avoid overflows in fixation code when dealing with MAXINT values, which
v4l2src seems to do.
Fixes#546328.
* tests/check/gst/gststructure.c: (GST_START_TEST):
Make a unit test to check the fix.
Original commit message from CVS:
2008-03-03 Andy Wingo <wingo@pobox.com>
* tests/check/gst/gststructure.c (GST_START_TEST): Add a check for
the new warning.
* gst/gststructure.c (gst_structure_from_string): Warn if
structure_from_string didn't consume the whole string, but the
caller did not provide an end pointer.
Original commit message from CVS:
* gst/gst_private.h: (STRUCTURE_ESTIMATED_STRING_LEN):
* gst/gstcaps.c: (gst_caps_to_string):
* gst/gststructure.c: (GST_ASCII_IS_STRING),
(priv_gst_structure_append_to_gstring), (gst_structure_to_string):
Yet another gratuitous GString micro-optimisation: add a (private)
function that serialises a structure appending to an existing
GString, so that when we serialise caps we don't need to alloc+free
a throwaway GString for each structure (each of which also entailing
multiple reallocs on the way); also use g_string_sized_new() in
various places with an approximate string length to avoid reallocs
within GString. See #500143.
Original commit message from CVS:
* gst/gststructure.c: (gst_structure_id_set_value):
Always check UTF-8 conformance of structure strings and not only
if the debugging system is enabled; reasoning: the behaviour of
the actual code shouldn't really change depending on whether the
debugging system is enabled or not (#508291).
Original commit message from CVS:
* gst/gststructure.c: (gst_structure_validate_name),
(gst_structure_new_valist), (gst_structure_parse_value),
(gst_structure_from_string):
Don't crash in _from_string() if the structure name is not valid
(fixes#501560). Allow structure names to start with a number
again (this apparently broke the ubuntu codec installer).
* tests/check/gst/gststructure.c: (GST_START_TEST), (GST_START_TEST),
(GST_START_TEST):
Add unit test for the crash; update unit tests for new behaviour.
Original commit message from CVS:
* gst/gstcaps.c: (gst_caps_to_string),
(gst_caps_from_string_inplace):
* gst/gststructure.c: (gst_structure_get_abbrs),
(gst_structure_to_string), (gst_structure_from_string):
* gst/gstvalue.c: (gst_value_set_structure),
(gst_value_get_structure), (gst_value_serialize_structure),
(gst_value_deserialize_structure), (_gst_value_initialize):
* gst/gstvalue.h:
* tests/check/gst/gststructure.c: (GST_START_TEST),
(gst_structure_suite):
* tests/check/gst/gstvalue.c: (GST_START_TEST):
Added GstStructure to gst_value_table and its related functions.
Changed gst_structure_to_string to print ';' in the end.
Changed gst_caps_to_string to not print ';' beteween its
fields (structures) anymore and remove the lastes ';' from latest
structure. Now it is possible to have nested structures.
In addition, backward compatibilty is assured by accepting '\0' as
end delimiter. Fixes: #487969.
API: add gst_value_set_structure()
API: add gst_value_get_structure()
Original commit message from CVS:
* gst/gststructure.c:
* tests/check/gst/gststructure.c:
Revert serialisation change and constrain structure-names after
consensus on irc. Update api documentation to reflect the change.
Original commit message from CVS:
* gst/gststructure.c:
Improve serialization and fix tests.
* tests/check/gst/gststructure.c:
Add another test that covers why I actually did the previous structure
change.
Original commit message from CVS:
* gst/gststructure.c:
* gst/gstvalue.c:
Add some more comments and debug output. Quote structure name to fix
deserialisation of some strings.
Original commit message from CVS:
* gst/gststructure.c:
(gst_structure_fixate_field_nearest_fraction):
Fix fraction list fixation code. Take the fraction with the smallest
difference with the target instead of the first one in the list.
* tests/check/gst/gststructure.c: (GST_START_TEST),
(gst_structure_suite):
Added test to verify correct fraction list fixation behaviour.
Original commit message from CVS:
* docs/gst/gstreamer-sections.txt:
* gst/gststructure.c: (gst_structure_get_uint):
* gst/gststructure.h:
Add function to get uint from a structure.
API: gst_structure_get_uint()
Original commit message from CVS:
* gst/gststructure.c: (gst_structure_parse_value):
When deserialising foo=bar without a type cast, check if it's a
boolean before falling back to a string type, otherwise things like
audiotestsrc ! audio/x-raw-int,signed=true ! fakesink won't work,
because the filtercaps end up having a signed=(string)true field,
which causes problems later when intersection caps.
* tests/check/gst/gststructure.c: (GST_START_TEST):
Add a unit test for this.
Original commit message from CVS:
* docs/design/part-states.txt:
two tiny additional comments
* gst/gststructure.c:
doc fixing
* tests/check/Makefile.am:
* tests/check/elements/queue.c: (queue_overrun), (queue_underrun),
(GST_START_TEST):
disable test for now, unless it gets fixed
Original commit message from CVS:
* gst/gststructure.c: (gst_structure_id_set_value):
If someone tries to set a non-UTF8 string field on a structure,
don't just print a warning, but also ignore the request and do
not change/add that field to the structure.
* tests/check/gst/gsttag.c: (GST_START_TEST), (gst_tag_suite):
Test for the above.
Original commit message from CVS:
* gst/gststructure.c:
Fix typo in docs and re-wrap docs blurb to not exceed 80 chars/line.
* gst/gstvalue.h:
Expand on the difference between arrays and lists as we use them.
Original commit message from CVS:
* gst/gstcaps.c: (gst_static_caps_get), (gst_caps_get_structure):
Fix useless assert, a uint is always positive.
* gst/gststructure.c: (gst_structure_nth_field_name),
(gst_structure_foreach), (gst_structure_map_in_place):
Check input arguments for public functions to avoid obvious crashes.
* plugins/elements/gstfakesink.c: (gst_fake_sink_render):
* plugins/elements/gstfakesink.h:
Do less useless typechecking.
Original commit message from CVS:
* gst/gststructure.c: (gst_structure_id_set),
(gst_structure_id_set_valist):
* gst/gststructure.h:
Add API for setting values into structures without performing
a quark lookup, if the appropriate quark is already known.
API: gst_structure_id_set
API: gst_structure_id_set_valist
* gst/parse/grammar.y:
* gst/parse/parse.l:
Remove some dead code shown by the coverage information.
Don't throw a critical g_warning when encountering a syntax error,
just warn and let the normal error path handle it.
* plugins/elements/gstelements.c:
Bump the rank of filesink up to PRIMARY so that it is preferred over
gnomevfssink for file:// sink uri's
* tests/check/pipelines/parse-launch.c: (expected_fail_pipe),
(GST_START_TEST), (run_delayed_test),
(gst_parse_test_element_base_init),
(gst_parse_test_element_class_init), (gst_parse_test_element_init),
(gst_parse_test_element_change_state),
(gst_register_parse_element), (parse_suite):
Beef up the tests for parse syntax to check that more error cases
fail as they are supposed to. Increases the test coverage a bit.
Original commit message from CVS:
* gst/gststructure.c: (gst_structure_gtype_from_abbr),
(gst_structure_parse_value):
add some comments
rename a method so that it actually says what it does better
Original commit message from CVS:
* gst/gststructure.c: (gst_structure_id_set_value):
Make sure that string fields in structures/taglists
contain valid UTF-8 - we don't want to pass rubbish to
applications because of a buggy plugin (cp. #334167).
Original commit message from CVS:
* gst/gstbin.c: (gst_bin_get_type), (gst_bin_handle_message_func):
Help the compiler a bit with type registration.
Use existing forward cod path instead of duplicating it when
handling a message.
* gst/gstbus.c: (gst_bus_get_type):
* gst/gstcaps.c: (gst_caps_get_type), (gst_static_caps_get_type):
* gst/gstchildproxy.c: (gst_child_proxy_get_type):
* gst/gstclock.c: (gst_clock_get_type):
* gst/gstelement.c: (gst_element_get_type),
* gst/gstelementfactory.c: (gst_element_factory_get_type):
* gst/gstindexfactory.c: (gst_index_factory_get_type):
* gst/gstminiobject.c: (gst_mini_object_get_type):
* gst/gstpad.c: (gst_pad_get_type):
* gst/gstsegment.c: (gst_segment_get_type):
* gst/gststructure.c: (gst_structure_get_type):
* gst/gstsystemclock.c: (gst_system_clock_get_type):
* gst/gsttask.c: (gst_task_get_type), (gst_task_join):
* gst/gstvalue.c:
Help compiler with type registration.
* plugins/elements/gstqueue.c: (gst_queue_handle_sink_event):
Small doc update.
Original commit message from CVS:
* gst/gststructure.c: (gst_structure_get_fraction),
(gst_structure_parse_value),
(gst_structure_fixate_field_nearest_fraction):
* gst/gststructure.h:
* gst/gstutils.c: (gst_util_uint64_scale_int):
* gst/gstutils.h:
* scripts/update-funcnames:
API Changes.
Rename gst_util_clock_time_scale to gst_util_uint64_scale_int
Make gst_structure_fixate_field_nearest_fraction take a numerator
and denominator argument instead of a GValue
add gst_structure_get_fraction helper function.
Original commit message from CVS:
* check/gst/gststructure.c: (GST_START_TEST):
* gst/gststructure.c: (gst_structure_parse_value):
Oops, broke automatic string type parsing.
Add a test to catch it in future.
Original commit message from CVS:
* check/gst/capslist.h:
Comment test cases
* check/gst/gststructure.c: (GST_START_TEST),
(gst_structure_suite):
Test automatic value type detection in gst_structure_from_string.
* gst/gststructure.c: (gst_structure_parse_value):
Add fraction as a type we try and guess automatically in
caps/structure strings.
Original commit message from CVS:
* check/gst/gstcaps.c: (GST_START_TEST):
Extend caps string tests to check that a caps to string
conversion is reversible and produces the same caps.
* gst/gststructure.c: (gst_structure_value_get_generic_type):
Output "fraction" as the generic type fraction range, so caps
serialisation and deserialisation works.
* check/gst/capslist.h:
* gst/gstvalue.c: (gst_value_deserialize_fraction):
Support 'MIN' and 'MAX' for deserialising fractions.
Original commit message from CVS:
* check/gst/capslist.h:
* check/gst/gstcaps.c: (GST_START_TEST):
* check/gst/gstvalue.c: (GST_START_TEST), (gst_value_suite):
* gst/gststructure.c: (gst_structure_parse_range),
(gst_structure_fixate_field_nearest_fraction):
* gst/gststructure.h:
* gst/gstvalue.c: (gst_value_init_fraction_range),
(gst_value_free_fraction_range), (gst_value_copy_fraction_range),
(gst_value_collect_fraction_range),
(gst_value_lcopy_fraction_range), (gst_value_set_fraction_range),
(gst_value_set_fraction_range_full),
(gst_value_get_fraction_range_min),
(gst_value_get_fraction_range_max),
(gst_value_serialize_fraction_range),
(gst_value_transform_fraction_range_string),
(gst_value_compare_fraction_range),
(gst_value_deserialize_fraction_range),
(gst_value_intersect_fraction_fraction_range),
(gst_value_intersect_fraction_range_fraction_range),
(gst_value_subtract_fraction_fraction_range),
(gst_value_subtract_fraction_range_fraction),
(gst_value_subtract_fraction_range_fraction_range),
(gst_value_collect_fraction), (gst_value_fraction_multiply),
(gst_value_fraction_subtract), (gst_value_deserialize_fraction),
(gst_value_transform_string_fraction), (_gst_value_initialize):
* gst/gstvalue.h:
Implement fraction ranges and extend GstFraction to support
arithmetic subtraction, as well as deserialization from integer
strings such as "100"
Add a testsuite as for int and double range set operations
Original commit message from CVS:
patch by: Tim-Philipp Müller <tim at centricular dot net>
* gst/gststructure.c: (gst_structure_parse_field),
(gst_structure_from_string):
Forward-port a 0.8 patch to handle escaped spaces in structure string, so that gst_parse_launch() can deal with spaces in filtered link
caps (fixes#164479)
* check/gst/capslist.h:
* check/gst/gststructure.c: (GST_START_TEST):
add unit tests for this change
Original commit message from CVS:
2005-10-13 Thomas Vander Stichele <thomas at apestaart dot org>
* gst/gststructure.c: (gst_structure_to_string):
guard against NULL printf - happens when for example
a message structure with GstClock gets serialized
Original commit message from CVS:
* common/gtk-doc.mak:
don't fail on building XML, FC4 slave shows a bunch of doc
missing bits that I don't get
* gst/gstpad.c:
* gst/gstpipeline.c:
* gst/gststructure.c:
some doc updates
Original commit message from CVS:
* docs/gst/gstreamer-sections.txt:
* gst/gststructure.c: (gst_structure_get_clock_time):
* gst/gststructure.h:
add a method to get a GstClockTime out of a structure
Original commit message from CVS:
* docs/gst/gstreamer-sections.txt:
* gst/gststructure.c: (gst_structure_set_valist),
(gst_structure_get_date):
* gst/gststructure.h:
* gst/gstvalue.c: (gst_value_set_date), (gst_value_get_date),
(gst_date_copy), (gst_value_compare_date),
(gst_value_serialize_date), (gst_value_deserialize_date),
(gst_value_transform_date_string),
(gst_value_transform_string_date), (_gst_value_initialize):
* gst/gstvalue.h:
Add GST_TYPE_DATE, a boxed type that wraps GDate, and the usual
bunch of utility functions along with a hack that checks that
developers don't accidentally use G_TYPE_DATE where GST_TYPE_DATE
is required. Part of the grand scheme in #170777.
Original commit message from CVS:
* gst/gstbuffer.c: (gst_buffer_new_and_alloc):
some debugging
* gst/gstcaps.h:
whitespace fixes
* gst/gstpad.c: (gst_pad_activate_push), (gst_pad_alloc_buffer):
more debugging
* gst/gststructure.c: (gst_caps_structure_fixate_field_boolean):
* gst/gststructure.h:
add a fixate function for booleans; add a FIXME that these func
names should probably be gst_structure_fixate_*
Original commit message from CVS:
* check/Makefile.am:
* check/gst/capslist.h:
copy over from 0.8, and add two with bitmasks specified with
(int) 0xFF...
* check/gst/gstcaps.c: (START_TEST), (gst_caps_suite):
add test to parse everything from capslist.h
* check/gst/gststructure.c: (START_TEST), (gst_value_suite),
(main):
add test for structure deserialization
* check/gst/gstvalue.c: (START_TEST), (gst_value_suite):
add tests for deserialization of strings to int types
* gst/gststructure.c: (gst_structure_nth_field_name):
* gst/gststructure.h:
add a way to get the name of a field referenced by index
* gst/gstvalue.c: (gst_value_deserialize_int_helper):
instead of checking if the resulting long long lies between
min and max, we check if the long long would fit into
a number of bytes for the final type.
This fixes cases where a string represents 2^32 - 1, which
when cast to int would be the (valid) -1, but is bigger than
G_MAXINT
Original commit message from CVS:
2005-05-09 Andy Wingo <wingo@pobox.com>
* gst/gstiterator.h: Add some includes.
* gst/gstqueryutils.h: Include more headers.
* gst/gstpad.h:
* gst/gstpad.c (gst_pad_query_position): New routine, replaces
some uses of gst_pad_query.
* gst/gstqueryutils.c: Build fixes. Make parse functions ignore
NULL out parameters.
(gst_query_new_position): New proc, allocates a new position
query.
* gst/Makefile.am (libgstreamer_@GST_MAJORMINOR@_la_SOURCES): Add
gstqueryutils.c to the build.
* gst/gststructure.c (gst_structure_set_valist): Implement with
the generic G_VALUE_COLLECT.
Original commit message from CVS:
Next big merge.
Added GstBus for mainloop integration.
Added GstMessage for sending notifications on the bus.
Added GstTask as an abstraction for pipeline entry points.
Removed GstThread.
Removed Schedulers.
Simplified GstQueue for multithreaded core.
Made _link threadsafe, removed old capsnego.
Added STREAM_LOCK and PREROLL_LOCK in GstPad.
Added pad blocking functions.
Reworked scheduling functions in GstPad to prepare for
scheduling updates soon.
Moved events out of data stream.
Simplified GstEvent types.
Added return values to push/pull.
Removed clocking from GstElement.
Added prototypes for state change function for next merge.
Removed iterate from bins and state change management.
Fixed some elements, disabled others for now.
Fixed -inspect and -launch.
Added check for GstBus.
Original commit message from CVS:
First THREADED backport attempt, focusing on adding locks and
making sure the API is threadsafe. Needs more work. More docs
follow this week.
Original commit message from CVS:
* gst/gststructure.c: (gst_structure_get_abbrs),
(gst_structure_from_abbr), (gst_structure_to_abbr):
Remove that ugly if-then thing in the code that converts
between strings and types.
Original commit message from CVS:
* gst/gststructure.c: (gst_structure_id_empty_new_with_size),
(gst_structure_id_empty_new), (gst_structure_empty_new),
(gst_structure_copy):
add gst_structure_id_empty_new_with_size to allow preallocating
value array sizes. Use this in gst_structure_copy to get rid of
reallocs.
don't do quark=>string=>quark when copying structures
Original commit message from CVS:
* gst/gststructure.c: (gst_structure_id_empty_new),
(gst_structure_empty_new): Set type field correctly.
* gst/gststructure.h: Check type field correctly.
* testsuite/caps/Makefile.am:
* testsuite/caps/structure.c: (test1), (main): Add a very small
test for structures.
Original commit message from CVS:
* docs/gst/tmpl/gstcaps.sgml:
* docs/gst/tmpl/gstfilesrc.sgml:
* docs/gst/tmpl/gststructure.sgml:
* docs/gst/tmpl/gstvalue.sgml:
update for recent API changes
* gst/gstcaps.c: (gst_caps_do_simplify):
fix to stop trying with a freed structure
* gst/gstpad.c: (gst_pad_link_fixate):
simplify caps
* gst/gstpad.c: (gst_pad_template_get_caps_by_name):
remove C++ comment
* gst/gstpad.h:
deprecate gst_pad_template_get_caps_by_name, it doesn't work anyway
* gst/gststructure.c: (gst_structure_value_get_generic_type),
(gst_structure_to_string):
keep the correct type when using lists of ranges
* gst/gstvalue.c: (gst_value_list_prepend_value),
(gst_value_list_append_value):
copy the value before adding to the list (d'oh)
* gst/gstvalue.c: (gst_value_subtract_int_range_int),
(gst_value_subtract_int_range_int_range):
handle overflows correctly
* gst/gstvalue.c: (gst_value_subtract_from_list):
fix memleak
* testsuite/caps/caps.h:
add a caps that caused segfaults
Original commit message from CVS:
* gst/gstbuffer.c: (_gst_buffer_initialize), (gst_buffer_get_type),
(gst_buffer_free_chunk): Added gst_buffer_get_type() and changed
to using it.
* gst/gstbuffer.h: Changed GST_BUFFER_TYPE to gst_buffer_get_type()
* gst/gstcaps.c: (gst_caps_is_fixed_foreach): Buffer is a fixed type
* gst/gstpad.c: (_gst_pad_default_fixate_foreach): same
* gst/gststructure.c: (gst_structure_set_valist),
(gst_structure_from_abbr), (gst_structure_to_abbr): Add vararg
support for buffers.
* gst/gsttag.c: (gst_tag_register): Constify a prototype that was
intended to be const.
* gst/gsttag.h: same
* gst/gstvalue.c: (gst_value_serialize_buffer),
(gst_value_deserialize_buffer), (_gst_value_initialize): Add code
to (de)serialize buffers.
* testsuite/caps/Makefile.am: Add a bit of buffer testing
* testsuite/caps/string-conversions.c: (main):
* testsuite/caps/value_serialize.c: add new test
Original commit message from CVS:
reviewed by Benjamin Otte <otte@gnome.org>
* gst/gststructure.c: (gst_structure_free):
memleak fix: free fields array (partial fix for #134839)
Original commit message from CVS:
* gst/elements/gstmultifilesrc.c: (gst_multifilesrc_class_init):
Use G_TYPE_STRING in signal prototype instead of G_TYPE_POINTER.
* gst/elements/gsttypefind.c: (gst_type_find_element_class_init):
Use GST_TYPE_CAPS in signal prototype.
* gst/gstcaps.c: (_gst_caps_initialize), (gst_caps_copy_conditional):
Convert GST_TYPE_CAPS to boxed.
* gst/gstelement.c: (gst_element_class_init):
Use GST_TYPE_TAG_LIST in signal prototype.
* gst/gstindex.c: (gst_index_class_init):
* gst/gstindex.h:
Add GST_TYPE_INDEX_ENTRY type.
* gst/gstmarshal.list:
Add necessary marshal types.
* gst/gstpad.c: (gst_real_pad_class_init),
(_gst_real_pad_fixate_accumulator), (gst_pad_link_fixate),
(gst_pad_recover_caps_error):
Use GST_TYPE_CAPS in signal prototypes. Fix some debugging strings.
* gst/gststructure.c: (_gst_structure_initialize),
(gst_structure_copy), (_gst_structure_copy_conditional):
* gst/gststructure.h:
Convert GST_TYPE_STRUCTURE to boxed.
* gst/gsttag.c: (gst_tag_list_get_type):
* gst/gsttag.h:
Add GST_TYPE_TAG_LIST type.
Original commit message from CVS:
Trying to fix the mess that I made with the two previous commits.
First commit, doing something wrong (fixing comparisons of signed and unsigned).
Second commit, trying to revert the previous, but changing other things and
reverting unrelated work of other people.
And this third, hopefully fixes it.