Re: Troubleshooting sip assignHelper != NULL assertion

Scott Talbert <[email protected]> Sun, 31 May 2020 12:48:46 -0400 (EDT)
Newsgroups gmane.comp.python.pyqt-pykde
Message-ID <[email protected]>
  This message is in MIME format.  The first part should be readable text,
  while the remaining parts are likely unreadable without MIME-aware tools.

---2033333575-1591116323-1590943726=:18055
Content-Type: text/plain; charset=UTF-8; format=flowed
Content-Transfer-Encoding: 8BIT

On Sun, 31 May 2020, Phil Thompson wrote:

> On 31/05/2020 16:29, Scott Talbert wrote:
>> On Sun, 31 May 2020, Phil Thompson wrote:
>> 
>>> On 31/05/2020 01:23, Scott Talbert wrote:
>>>> On Sat, 30 May 2020, Phil Thompson wrote:
>>>> 
>>>>> On 28/05/2020 16:52, Scott Talbert wrote:
>>>>>> On Thu, 28 May 2020, Phil Thompson wrote:
>>>>>> 
>>>>>>> On 28/05/2020 16:30, Scott Talbert wrote:
>>>>>>>> On Thu, 28 May 2020, Phil Thompson wrote:
>>>>>>>> 
>>>>>>>>>>>> Hi,
>>>>>>>>>>>> 
>>>>>>>>>>>> I'm running into the following assertion in wxPython that I 
>>>>>>>>>>>> don't
>>>>>>>>>>>> quite understand:
>>>>>>>>>>>> 
>>>>>>>>>>>> python3: ../../../../sip/siplib/siplib.c:3444: parseResult: 
>>>>>>>>>>>> Assertion
>>>>>>>>>>>> `assign_helper != NULL' failed.
>>>>>>>>>>>> 
>>>>>>>>>>>> This is the relevant C++ class:
>>>>>>>>>>>> 
>>>>>>>>>>>> class wxPGWindowList
>>>>>>>>>>>> {
>>>>>>>>>>>> public:
>>>>>>>>>>>>     wxPGWindowList(wxWindow* primary, wxWindow* secondary = 
>>>>>>>>>>>> NULL)
>>>>>>>>>>>>         : m_primary(primary)
>>>>>>>>>>>>         , m_secondary(secondary)
>>>>>>>>>>>>     {
>>>>>>>>>>>>     }
>>>>>>>>>>>>
>>>>>>>>>>>>     void SetSecondary(wxWindow* secondary) { m_secondary = 
>>>>>>>>>>>> secondary; }
>>>>>>>>>>>>
>>>>>>>>>>>>     wxWindow* GetPrimary() const { return m_primary; }
>>>>>>>>>>>>     wxWindow* GetSecondary() const { return m_secondary; }
>>>>>>>>>>>>
>>>>>>>>>>>>     wxWindow*   m_primary;
>>>>>>>>>>>>     wxWindow*   m_secondary;
>>>>>>>>>>>> };
>>>>>>>>>>> 
>>>>>>>>>>> It doesn't matter what the C++ class looks like, it's the 
>>>>>>>>>>> corresponding .sip that would be of interest.
>>>>>>>>>> 
>>>>>>>>>> My bad, here it is:
>>>>>>>>>> class wxPGWindowList
>>>>>>>>>> {
>>>>>>>>>>     %Docstring
>>>>>>>>>>         PGWindowList(primary, secondary=None)
>>>>>>>>>>
>>>>>>>>>>         Contains a list of editor windows returned by 
>>>>>>>>>> CreateControls.
>>>>>>>>>>     %End
>>>>>>>>>>     %TypeHeaderCode
>>>>>>>>>>         #include <wx/propgrid/editors.h>
>>>>>>>>>>     %End
>>>>>>>>>> 
>>>>>>>>>> public:
>>>>>>>>>>     wxPGWindowList(
>>>>>>>>>>         wxWindow * primary,
>>>>>>>>>>         wxWindow * secondary = NULL
>>>>>>>>>>     );
>>>>>>>>>>
>>>>>>>>>>     void SetSecondary(
>>>>>>>>>>         wxWindow * secondary
>>>>>>>>>>     );
>>>>>>>>>>     %Docstring
>>>>>>>>>>         SetSecondary(secondary)
>>>>>>>>>>     %End
>>>>>>>>>>
>>>>>>>>>>     wxWindow * GetPrimary() const;
>>>>>>>>>>     %Docstring
>>>>>>>>>>         GetPrimary() -> wx.Window
>>>>>>>>>>
>>>>>>>>>>         Gets window of primary editor.
>>>>>>>>>>     %End
>>>>>>>>>>
>>>>>>>>>>     wxWindow * GetSecondary() const;
>>>>>>>>>>     %Docstring
>>>>>>>>>>         GetSecondary() -> wx.Window
>>>>>>>>>>
>>>>>>>>>>         Gets window of secondary editor.
>>>>>>>>>>     %End
>>>>>>>>>>
>>>>>>>>>>     public:
>>>>>>>>>> 
>>>>>>>>>>
>>>>>>>>>>     %Property(name=Primary, get=GetPrimary)
>>>>>>>>>>     %Property(name=Secondary, get=GetSecondary, set=SetSecondary)
>>>>>>>>>> };  // end of class wxPGWindowList
>>>>>>>>>> 
>>>>>>>>>> 
>>>>>>>>>>>> The assertion occurs when trying to return an instance of
>>>>>>>>>>>> wxPGWindowList in a Python method, e.g.:
>>>>>>>>>>>> 
>>>>>>>>>>>> def foo():
>>>>>>>>>>>>     return wxpg.PGWindowList(a, b)
>>>>>>>>>>>> 
>>>>>>>>>>>> From what I can tell, there is no assignment helper assigned by 
>>>>>>>>>>>> sip
>>>>>>>>>>>> because there is no default constructor?  I may be missing 
>>>>>>>>>>>> something,
>>>>>>>>>>>> but I can't see why a default constructor would be needed.
>>>>>>>>>>> 
>>>>>>>>>>> You don't say what version of the sip module you are using but 
>>>>>>>>>>> I'm guessing that that assertion is when it's parsing the Python 
>>>>>>>>>>> object returned by a re-implementation of a C++ virtual. That 
>>>>>>>>>>> doesn't seem to be happening in the above which suggests things 
>>>>>>>>>>> aren't happening where you think they are.
>>>>>>>>>> 
>>>>>>>>>> sip module version is 4.19.19.  You are correct, I oversimplified 
>>>>>>>>>> what
>>>>>>>>>> is actually happening.  This is really what is happening:
>>>>>>>>>> 
>>>>>>>>>> class LargeImageEditor(wxpg.PGEditor):
>>>>>>>>>>     def CreateControls(self, propgrid, property, pos, sz):
>>>>>>>>>>         ...
>>>>>>>>>>         return wxpg.PGWindowList(self.tc, btn)
>>>>>>>>>> 
>>>>>>>>>> Where CreateControls is a C++ virtual, relevant .sip snippet:
>>>>>>>>>>
>>>>>>>>>>     virtual
>>>>>>>>>>     wxPGWindowList CreateControls(
>>>>>>>>>>         wxPropertyGrid * propgrid,
>>>>>>>>>>         wxPGProperty * property,
>>>>>>>>>>         const wxPoint & pos,
>>>>>>>>>>         const wxSize & size
>>>>>>>>>>     ) const = 0;
>>>>>>>>>>     %Docstring
>>>>>>>>>>         CreateControls(propgrid, property, pos, size) -> 
>>>>>>>>>> PGWindowList
>>>>>>>>>>
>>>>>>>>>>         Instantiates editor controls.
>>>>>>>>>>     %End
>>>>>>>>> 
>>>>>>>>> So SIP need to copy the wxPGWindowList from the stack to the heap. 
>>>>>>>>> Shouldn't CreateControls return a pointer to the wxPGWindowList?
>>>>>>>>> 
>>>>>>>>> Of course SIP should detect this when generating the code rather 
>>>>>>>>> than rely on a runtime assertion.
>>>>>>>> 
>>>>>>>> That is probably how I would have designed the API, but alas it 
>>>>>>>> wasn't
>>>>>>>> done that way.  :)
>>>>>>>> 
>>>>>>>> Shouldn't a (default) copy constructor be sufficient to copy the
>>>>>>>> wxPGWindowList in this case?
>>>>>>> 
>>>>>>> SIP may be being too conservative when determining if there is an 
>>>>>>> implied copy ctor. Try adding an explicit copy ctor to the 
>>>>>>> wxPGWindowList .sip file.
>>>>>> 
>>>>>> I don't think that will be enough, though.  SIP seems to only set the
>>>>>> assignment helper if there are *both* a public default constructor and
>>>>>> a public copy constructor, see:
>>>>>> 
>>>>>> https://www.riverbankcomputing.com/hg/sip/file/d85e9957e726/sipgen/transform.c#l596
>>>>>> 
>>>>>> Scott
>>>>> 
>>>>> Should be fixed in the current repo. SIP v4.19.23 will be released next 
>>>>> week.
>>>>> 
>>>>> Be aware that the fix may expose missing private ctors in other .sip 
>>>>> files - PyQt had two cases.
>>>> 
>>>> Thanks for the quick fix.
>>>> 
>>>> However, I think I found a situation with the new code where an assign
>>>> function is getting created where it probably shouldn't be.
>>>> 
>>>> struct wxSplitterRenderParams
>>>> {
>>>>     %Docstring
>>>>         SplitterRenderParams(widthSash_, border_, isSens_)
>>>>
>>>>         This is just a simple struct used as a return value of
>>>>         wxRendererNative::GetSplitterParams().
>>>>     %End
>>>>     %TypeHeaderCode
>>>>         #include <wx/renderer.h>
>>>>     %End
>>>>
>>>>     wxSplitterRenderParams(
>>>>         wxCoord widthSash_,
>>>>         wxCoord border_,
>>>>         bool isSens_
>>>>     );
>>>>
>>>>     const wxCoord border;
>>>>
>>>>     const bool isHotSensitive;
>>>>
>>>>     const wxCoord widthSash;
>>>> 
>>>> };  // end of class wxSplitterRenderParams
>>>> 
>>>> This results in:
>>>> 
>>>> ../../../../sip/cpp/sip_corewxSplitterRenderParams.cpp: In function
>>>> ‘void assign_wxSplitterRenderParams(void*, Py_ssize_t, void*)’:
>>>> ../../../../sip/cpp/sip_corewxSplitterRenderParams.cpp:31:125: error:
>>>> use of deleted function ‘wxSplitterRenderParams&
>>>> wxSplitterRenderParams::operator=(const wxSplitterRenderParams&)’
>>>>    31 |     reinterpret_cast< ::wxSplitterRenderParams
>>>> *>(sipDst)[sipDstIdx] = *reinterpret_cast< ::wxSplitterRenderParams
>>>> *>(sipSrc);
>>>>       | ^
>>>> In file included from 
>>>> ../../../../sip/cpp/sip_corewxSplitterRenderParams.cpp:12:
>>>> ../../../../../Phoenix/ext/wxWidgets/include/wx/renderer.h:97:25:
>>>> note: ‘wxSplitterRenderParams& wxSplitterRenderParams::operator=(const
>>>> wxSplitterRenderParams&)’ is implicitly deleted because the default
>>>> definition would be ill-formed:
>>>>    97 | struct WXDLLIMPEXP_CORE wxSplitterRenderParams
>>>>       |                         ^~~~~~~~~~~~~~~~~~~~~~
>>>> ../../../../../Phoenix/ext/wxWidgets/include/wx/renderer.h:97:25:
>>>> error: non-static const member ‘const wxCoord
>>>> wxSplitterRenderParams::widthSash’, cannot use default assignment
>>>> operator
>>>> ../../../../../Phoenix/ext/wxWidgets/include/wx/renderer.h:97:25:
>>>> error: non-static const member ‘const wxCoord
>>>> wxSplitterRenderParams::border’, cannot use default assignment
>>>> operator
>>>> ../../../../../Phoenix/ext/wxWidgets/include/wx/renderer.h:97:25:
>>>> error: non-static const member ‘const bool
>>>> wxSplitterRenderParams::isHotSensitive’, cannot use default assignment
>>>> operator
>>> 
>>> Yes, that's what I meant by missing private copy ctors. SIP cannot 
>>> accurately determine whether a copy ctor is available unless it knows 
>>> everything about the C++ class (including private members and their 
>>> types), but SIP is not a full C++ parser (and never will be). Therefore 
>>> you need to declare a private copy ctor in the .sip file to correct the 
>>> assumption that there is a public copy ctor available. In the future I 
>>> may add a class annotation to achieve the same thing.
>> 
>> Thanks, I understand that now.  :)  After declaring a private copy
>> ctor in the above .sip file, I'm now getting this:
>> 
>> ../../../../sip/cpp/sip_corewxDelegateRendererNative.cpp: In function
>> ‘PyObject* meth_wxDelegateRendererNative_GetSplitterParams(PyObject*,
>> PyObject*, PyObject*)’:
>> ../../../../sip/cpp/sip_corewxDelegateRendererNative.cpp:1360:38:
>> error: taking address of rvalue [-fpermissive]
>>  1360 |             sipRes = &(sipSelfWasArg ? sipCpp->
>> ::wxDelegateRendererNative::GetSplitterParams(win) :
>> sipCpp->GetSplitterParams(win));
>>       |
>> ~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>> 
>> So, since SIP can't copy the wxSplitterRenderParams, it is trying to
>> return a reference to the original one, but it seems that doesn't
>> work?
>
> So what does the .sip file for wxDelegateRenderNative look like?

It's a bit long, so attached.

Thanks,
Scott
---2033333575-1591116323-1590943726=:18055
Content-Type: text/plain; charset=US-ASCII; name=wxDelegateRendererNative.sip
Content-Transfer-Encoding: BASE64
Content-ID: <[email protected]>
Content-Description: 
Content-Disposition: attachment; filename=wxDelegateRendererNative.sip

Y2xhc3Mgd3hEZWxlZ2F0ZVJlbmRlcmVyTmF0aXZlIDogd3hSZW5kZXJlck5h
dGl2ZQ0Kew0KICAgICVEb2NzdHJpbmcNCiAgICAgICAgRGVsZWdhdGVSZW5k
ZXJlck5hdGl2ZSgpDQogICAgICAgIERlbGVnYXRlUmVuZGVyZXJOYXRpdmUo
cmVuZGVyZXJOYXRpdmUpDQogICAgICAgIA0KICAgICAgICB3eERlbGVnYXRl
UmVuZGVyZXJOYXRpdmUgYWxsb3dzIHJldXNlIG9mIHJlbmRlcmVycyBjb2Rl
IGJ5IGZvcndhcmRpbmcNCiAgICAgICAgYWxsIHRoZSB3eFJlbmRlcmVyTmF0
aXZlIG1ldGhvZHMgdG8gdGhlIGdpdmVuIG9iamVjdCBhbmQgdGh1cyBhbGxv
d2luZw0KICAgICAgICB5b3UgdG8gb25seSBtb2RpZnkgc29tZSBvZiBpdHMg
bWV0aG9kcyAgd2l0aG91dCBoYXZpbmcgdG8gcmVpbXBsZW1lbnQNCiAgICAg
ICAgYWxsIG9mIHRoZW0uDQogICAgJUVuZA0KICAgICVUeXBlSGVhZGVyQ29k
ZQ0KICAgICAgICAjaW5jbHVkZSA8d3gvcmVuZGVyZXIuaD4NCiAgICAlRW5k
DQoNCnB1YmxpYzoNCiAgICB3eERlbGVnYXRlUmVuZGVyZXJOYXRpdmUoKTsN
CiAgICAlUHJlTWV0aG9kQ29kZQ0KICAgICAgICBpZiAoIXd4UHlDaGVja0Zv
ckFwcCgpKSByZXR1cm4gTlVMTDsNCiAgICAlRW5kDQoNCiAgICB3eERlbGVn
YXRlUmVuZGVyZXJOYXRpdmUoDQogICAgICAgIHd4UmVuZGVyZXJOYXRpdmUg
JiByZW5kZXJlck5hdGl2ZQ0KICAgICk7DQogICAgJVByZU1ldGhvZENvZGUN
CiAgICAgICAgaWYgKCF3eFB5Q2hlY2tGb3JBcHAoKSkgcmV0dXJuIE5VTEw7
DQogICAgJUVuZA0KDQogICAgdmlydHVhbA0KICAgIGludCBEcmF3SGVhZGVy
QnV0dG9uKA0KICAgICAgICB3eFdpbmRvdyAqIHdpbiwNCiAgICAgICAgd3hE
QyAmIGRjLA0KICAgICAgICBjb25zdCB3eFJlY3QgJiByZWN0LA0KICAgICAg
ICBpbnQgZmxhZ3MgPSAwLA0KICAgICAgICB3eEhlYWRlclNvcnRJY29uVHlw
ZSBzb3J0QXJyb3cgPSB3eEhEUl9TT1JUX0lDT05fTk9ORSwNCiAgICAgICAg
d3hIZWFkZXJCdXR0b25QYXJhbXMgKiBwYXJhbXMgPSBOVUxMDQogICAgKTsN
CiAgICAlRG9jc3RyaW5nDQogICAgICAgIERyYXdIZWFkZXJCdXR0b24od2lu
LCBkYywgcmVjdCwgZmxhZ3M9MCwgc29ydEFycm93PUhEUl9TT1JUX0lDT05f
Tk9ORSwgcGFyYW1zPU5vbmUpIC0+IGludA0KICAgICAgICANCiAgICAgICAg
RHJhdyB0aGUgaGVhZGVyIGNvbnRyb2wgYnV0dG9uICh1c2VkLCBmb3IgZXhh
bXBsZSwgYnkgd3hMaXN0Q3RybCkuDQogICAgJUVuZA0KDQogICAgdmlydHVh
bA0KICAgIGludCBEcmF3SGVhZGVyQnV0dG9uQ29udGVudHMoDQogICAgICAg
IHd4V2luZG93ICogd2luLA0KICAgICAgICB3eERDICYgZGMsDQogICAgICAg
IGNvbnN0IHd4UmVjdCAmIHJlY3QsDQogICAgICAgIGludCBmbGFncyA9IDAs
DQogICAgICAgIHd4SGVhZGVyU29ydEljb25UeXBlIHNvcnRBcnJvdyA9IHd4
SERSX1NPUlRfSUNPTl9OT05FLA0KICAgICAgICB3eEhlYWRlckJ1dHRvblBh
cmFtcyAqIHBhcmFtcyA9IE5VTEwNCiAgICApOw0KICAgICVEb2NzdHJpbmcN
CiAgICAgICAgRHJhd0hlYWRlckJ1dHRvbkNvbnRlbnRzKHdpbiwgZGMsIHJl
Y3QsIGZsYWdzPTAsIHNvcnRBcnJvdz1IRFJfU09SVF9JQ09OX05PTkUsIHBh
cmFtcz1Ob25lKSAtPiBpbnQNCiAgICAgICAgDQogICAgICAgIERyYXcgdGhl
IGNvbnRlbnRzIG9mIGEgaGVhZGVyIGNvbnRyb2wgYnV0dG9uIChsYWJlbCwg
c29ydCBhcnJvd3MsDQogICAgICAgIGV0Yy4pLg0KICAgICVFbmQNCg0KICAg
IHZpcnR1YWwNCiAgICBpbnQgR2V0SGVhZGVyQnV0dG9uSGVpZ2h0KA0KICAg
ICAgICB3eFdpbmRvdyAqIHdpbg0KICAgICk7DQogICAgJURvY3N0cmluZw0K
ICAgICAgICBHZXRIZWFkZXJCdXR0b25IZWlnaHQod2luKSAtPiBpbnQNCiAg
ICAgICAgDQogICAgICAgIFJldHVybnMgdGhlIGhlaWdodCBvZiBhIGhlYWRl
ciBidXR0b24sIGVpdGhlciBhIGZpeGVkIHBsYXRmb3JtIGhlaWdodA0KICAg
ICAgICBpZiBhdmFpbGFibGUsIG9yIGEgZ2VuZXJpYyBoZWlnaHQgYmFzZWQg
b24gdGhlIHdpbiB3aW5kb3cncyBmb250Lg0KICAgICVFbmQNCg0KICAgIHZp
cnR1YWwNCiAgICBpbnQgR2V0SGVhZGVyQnV0dG9uTWFyZ2luKA0KICAgICAg
ICB3eFdpbmRvdyAqIHdpbg0KICAgICk7DQogICAgJURvY3N0cmluZw0KICAg
ICAgICBHZXRIZWFkZXJCdXR0b25NYXJnaW4od2luKSAtPiBpbnQNCiAgICAg
ICAgDQogICAgICAgIFJldHVybnMgdGhlIGhvcml6b250YWwgbWFyZ2luIG9u
IHRoZSBsZWZ0IGFuZCByaWdodCBzaWRlcyBvZiBoZWFkZXINCiAgICAgICAg
YnV0dG9uJ3MgbGFiZWwuDQogICAgJUVuZA0KDQogICAgdmlydHVhbA0KICAg
IHZvaWQgRHJhd1RyZWVJdGVtQnV0dG9uKA0KICAgICAgICB3eFdpbmRvdyAq
IHdpbiwNCiAgICAgICAgd3hEQyAmIGRjLA0KICAgICAgICBjb25zdCB3eFJl
Y3QgJiByZWN0LA0KICAgICAgICBpbnQgZmxhZ3MgPSAwDQogICAgKTsNCiAg
ICAlRG9jc3RyaW5nDQogICAgICAgIERyYXdUcmVlSXRlbUJ1dHRvbih3aW4s
IGRjLCByZWN0LCBmbGFncz0wKQ0KICAgICAgICANCiAgICAgICAgRHJhdyB0
aGUgZXhwYW5kZWQvY29sbGFwc2VkIGljb24gZm9yIGEgdHJlZSBjb250cm9s
IGl0ZW0uDQogICAgJUVuZA0KDQogICAgdmlydHVhbA0KICAgIHZvaWQgRHJh
d1NwbGl0dGVyQm9yZGVyKA0KICAgICAgICB3eFdpbmRvdyAqIHdpbiwNCiAg
ICAgICAgd3hEQyAmIGRjLA0KICAgICAgICBjb25zdCB3eFJlY3QgJiByZWN0
LA0KICAgICAgICBpbnQgZmxhZ3MgPSAwDQogICAgKTsNCiAgICAlRG9jc3Ry
aW5nDQogICAgICAgIERyYXdTcGxpdHRlckJvcmRlcih3aW4sIGRjLCByZWN0
LCBmbGFncz0wKQ0KICAgICAgICANCiAgICAgICAgRHJhdyB0aGUgYm9yZGVy
IGZvciBzYXNoIHdpbmRvdzogdGhpcyBib3JkZXIgbXVzdCBiZSBzdWNoIHRo
YXQgdGhlDQogICAgICAgIHNhc2ggZHJhd24gYnkgRHJhd1NwbGl0dGVyU2Fz
aCgpIGJsZW5kcyBpbnRvIGl0IHdlbGwuDQogICAgJUVuZA0KDQogICAgdmly
dHVhbA0KICAgIHZvaWQgRHJhd1NwbGl0dGVyU2FzaCgNCiAgICAgICAgd3hX
aW5kb3cgKiB3aW4sDQogICAgICAgIHd4REMgJiBkYywNCiAgICAgICAgY29u
c3Qgd3hTaXplICYgc2l6ZSwNCiAgICAgICAgd3hDb29yZCBwb3NpdGlvbiwN
CiAgICAgICAgd3hPcmllbnRhdGlvbiBvcmllbnQsDQogICAgICAgIGludCBm
bGFncyA9IDANCiAgICApOw0KICAgICVEb2NzdHJpbmcNCiAgICAgICAgRHJh
d1NwbGl0dGVyU2FzaCh3aW4sIGRjLCBzaXplLCBwb3NpdGlvbiwgb3JpZW50
LCBmbGFncz0wKQ0KICAgICAgICANCiAgICAgICAgRHJhdyBhIHNhc2guDQog
ICAgJUVuZA0KDQogICAgdmlydHVhbA0KICAgIHZvaWQgRHJhd0NvbWJvQm94
RHJvcEJ1dHRvbigNCiAgICAgICAgd3hXaW5kb3cgKiB3aW4sDQogICAgICAg
IHd4REMgJiBkYywNCiAgICAgICAgY29uc3Qgd3hSZWN0ICYgcmVjdCwNCiAg
ICAgICAgaW50IGZsYWdzID0gMA0KICAgICk7DQogICAgJURvY3N0cmluZw0K
ICAgICAgICBEcmF3Q29tYm9Cb3hEcm9wQnV0dG9uKHdpbiwgZGMsIHJlY3Qs
IGZsYWdzPTApDQogICAgICAgIA0KICAgICAgICBEcmF3IGEgYnV0dG9uIGxp
a2UgdGhlIG9uZSB1c2VkIGJ5IHd4Q29tYm9Cb3ggdG8gc2hvdyBhIGRyb3Ag
ZG93bg0KICAgICAgICB3aW5kb3cuDQogICAgJUVuZA0KDQogICAgdmlydHVh
bA0KICAgIHZvaWQgRHJhd0Ryb3BBcnJvdygNCiAgICAgICAgd3hXaW5kb3cg
KiB3aW4sDQogICAgICAgIHd4REMgJiBkYywNCiAgICAgICAgY29uc3Qgd3hS
ZWN0ICYgcmVjdCwNCiAgICAgICAgaW50IGZsYWdzID0gMA0KICAgICk7DQog
ICAgJURvY3N0cmluZw0KICAgICAgICBEcmF3RHJvcEFycm93KHdpbiwgZGMs
IHJlY3QsIGZsYWdzPTApDQogICAgICAgIA0KICAgICAgICBEcmF3IGEgZHJv
cCBkb3duIGFycm93IHRoYXQgaXMgc3VpdGFibGUgZm9yIHVzZSBvdXRzaWRl
IGEgY29tYm8gYm94Lg0KICAgICVFbmQNCg0KICAgIHZpcnR1YWwNCiAgICB2
b2lkIERyYXdDaGVja0JveCgNCiAgICAgICAgd3hXaW5kb3cgKiB3aW4sDQog
ICAgICAgIHd4REMgJiBkYywNCiAgICAgICAgY29uc3Qgd3hSZWN0ICYgcmVj
dCwNCiAgICAgICAgaW50IGZsYWdzID0gMA0KICAgICk7DQogICAgJURvY3N0
cmluZw0KICAgICAgICBEcmF3Q2hlY2tCb3god2luLCBkYywgcmVjdCwgZmxh
Z3M9MCkNCiAgICAgICAgDQogICAgICAgIERyYXcgYSBjaGVjayBib3guDQog
ICAgJUVuZA0KDQogICAgdmlydHVhbA0KICAgIHZvaWQgRHJhd0NoZWNrTWFy
aygNCiAgICAgICAgd3hXaW5kb3cgKiB3aW4sDQogICAgICAgIHd4REMgJiBk
YywNCiAgICAgICAgY29uc3Qgd3hSZWN0ICYgcmVjdCwNCiAgICAgICAgaW50
IGZsYWdzID0gMA0KICAgICk7DQogICAgJURvY3N0cmluZw0KICAgICAgICBE
cmF3Q2hlY2tNYXJrKHdpbiwgZGMsIHJlY3QsIGZsYWdzPTApDQogICAgICAg
IA0KICAgICAgICBEcmF3IGEgY2hlY2sgbWFyay4NCiAgICAlRW5kDQoNCiAg
ICB2aXJ0dWFsDQogICAgd3hTaXplIEdldENoZWNrQm94U2l6ZSgNCiAgICAg
ICAgd3hXaW5kb3cgKiB3aW4sDQogICAgICAgIGludCBmbGFncyA9IDANCiAg
ICApOw0KICAgICVEb2NzdHJpbmcNCiAgICAgICAgR2V0Q2hlY2tCb3hTaXpl
KHdpbiwgZmxhZ3M9MCkgLT4gU2l6ZQ0KICAgICAgICANCiAgICAgICAgUmV0
dXJucyB0aGUgc2l6ZSBvZiBhIGNoZWNrIGJveC4NCiAgICAlRW5kDQoNCiAg
ICB2aXJ0dWFsDQogICAgd3hTaXplIEdldENoZWNrTWFya1NpemUoDQogICAg
ICAgIHd4V2luZG93ICogd2luDQogICAgKTsNCiAgICAlRG9jc3RyaW5nDQog
ICAgICAgIEdldENoZWNrTWFya1NpemUod2luKSAtPiBTaXplDQogICAgICAg
IA0KICAgICAgICBSZXR1cm5zIHRoZSBzaXplIG9mIGEgY2hlY2sgbWFyay4N
CiAgICAlRW5kDQoNCiAgICB2aXJ0dWFsDQogICAgd3hTaXplIEdldEV4cGFu
ZGVyU2l6ZSgNCiAgICAgICAgd3hXaW5kb3cgKiB3aW4NCiAgICApOw0KICAg
ICVEb2NzdHJpbmcNCiAgICAgICAgR2V0RXhwYW5kZXJTaXplKHdpbikgLT4g
U2l6ZQ0KICAgICAgICANCiAgICAgICAgUmV0dXJucyB0aGUgc2l6ZSBvZiB0
aGUgZXhwYW5kZXIgdXNlZCBpbiB0cmVlLWxpa2UgY29udHJvbHMuDQogICAg
JUVuZA0KDQogICAgdmlydHVhbA0KICAgIHZvaWQgRHJhd1B1c2hCdXR0b24o
DQogICAgICAgIHd4V2luZG93ICogd2luLA0KICAgICAgICB3eERDICYgZGMs
DQogICAgICAgIGNvbnN0IHd4UmVjdCAmIHJlY3QsDQogICAgICAgIGludCBm
bGFncyA9IDANCiAgICApOw0KICAgICVEb2NzdHJpbmcNCiAgICAgICAgRHJh
d1B1c2hCdXR0b24od2luLCBkYywgcmVjdCwgZmxhZ3M9MCkNCiAgICAgICAg
DQogICAgICAgIERyYXcgYSBibGFuayBwdXNoIGJ1dHRvbiB0aGF0IGxvb2tz
IHZlcnkgc2ltaWxhciB0byB3eEJ1dHRvbi4NCiAgICAlRW5kDQoNCiAgICB2
aXJ0dWFsDQogICAgdm9pZCBEcmF3SXRlbVNlbGVjdGlvblJlY3QoDQogICAg
ICAgIHd4V2luZG93ICogd2luLA0KICAgICAgICB3eERDICYgZGMsDQogICAg
ICAgIGNvbnN0IHd4UmVjdCAmIHJlY3QsDQogICAgICAgIGludCBmbGFncyA9
IDANCiAgICApOw0KICAgICVEb2NzdHJpbmcNCiAgICAgICAgRHJhd0l0ZW1T
ZWxlY3Rpb25SZWN0KHdpbiwgZGMsIHJlY3QsIGZsYWdzPTApDQogICAgICAg
IA0KICAgICAgICBEcmF3IGEgc2VsZWN0aW9uIHJlY3RhbmdsZSB1bmRlcm5l
YXRoIHRoZSB0ZXh0IGFzIHVzZWQgZS5nLg0KICAgICVFbmQNCg0KICAgIHZp
cnR1YWwNCiAgICB2b2lkIERyYXdGb2N1c1JlY3QoDQogICAgICAgIHd4V2lu
ZG93ICogd2luLA0KICAgICAgICB3eERDICYgZGMsDQogICAgICAgIGNvbnN0
IHd4UmVjdCAmIHJlY3QsDQogICAgICAgIGludCBmbGFncyA9IDANCiAgICAp
Ow0KICAgICVEb2NzdHJpbmcNCiAgICAgICAgRHJhd0ZvY3VzUmVjdCh3aW4s
IGRjLCByZWN0LCBmbGFncz0wKQ0KICAgICAgICANCiAgICAgICAgRHJhdyBh
IGZvY3VzIHJlY3RhbmdsZSB1c2luZyB0aGUgc3BlY2lmaWVkIHJlY3Rhbmds
ZS4NCiAgICAlRW5kDQoNCiAgICB2aXJ0dWFsDQogICAgd3hTcGxpdHRlclJl
bmRlclBhcmFtcyBHZXRTcGxpdHRlclBhcmFtcygNCiAgICAgICAgY29uc3Qg
d3hXaW5kb3cgKiB3aW4NCiAgICApOw0KICAgICVEb2NzdHJpbmcNCiAgICAg
ICAgR2V0U3BsaXR0ZXJQYXJhbXMod2luKSAtPiBTcGxpdHRlclJlbmRlclBh
cmFtcw0KICAgICAgICANCiAgICAgICAgR2V0IHRoZSBzcGxpdHRlciBwYXJh
bWV0ZXJzLCBzZWUgd3hTcGxpdHRlclJlbmRlclBhcmFtcy4NCiAgICAlRW5k
DQoNCiAgICB2aXJ0dWFsDQogICAgd3hSZW5kZXJlclZlcnNpb24gR2V0VmVy
c2lvbigpIGNvbnN0Ow0KICAgICVEb2NzdHJpbmcNCiAgICAgICAgR2V0VmVy
c2lvbigpIC0+IFJlbmRlcmVyVmVyc2lvbg0KICAgICAgICANCiAgICAgICAg
VGhpcyBmdW5jdGlvbiBpcyB1c2VkIGZvciB2ZXJzaW9uIGNoZWNraW5nOiBM
b2FkKCkgcmVmdXNlcyB0byBsb2FkIGFueQ0KICAgICAgICBzaGFyZWQgbGli
cmFyaWVzIGltcGxlbWVudGluZyBhbiBvbGRlciBvciBpbmNvbXBhdGlibGUg
dmVyc2lvbi4NCiAgICAlRW5kDQoNCiAgICBwcml2YXRlOg0KICAgICAgICB3
eERlbGVnYXRlUmVuZGVyZXJOYXRpdmUoY29uc3Qgd3hEZWxlZ2F0ZVJlbmRl
cmVyTmF0aXZlJik7DQoNCg0KICAgIHZpcnR1YWwgdm9pZCBEcmF3VGl0bGVC
YXJCaXRtYXAod3hXaW5kb3cqIHdpbiwgIHd4REMmIGRjLCAgY29uc3Qgd3hS
ZWN0JiByZWN0LCAgd3hUaXRsZUJhckJ1dHRvbiBidXR0b24sICBpbnQgZmxh
Z3MgPSAwKTsNCiAgICAlRG9jc3RyaW5nDQogICAgICAgIERyYXdUaXRsZUJh
ckJpdG1hcCh3aW4sIGRjLCByZWN0LCBidXR0b24sIGZsYWdzPTApDQogICAg
ICAgIA0KICAgICAgICBEcmF3IGEgdGl0bGUgYmFyIGJ1dHRvbiBpbiB0aGUg
Z2l2ZW4gc3RhdGUuDQogICAgJUVuZA0KICAgICVNZXRob2RDb2RlDQogICAg
ICAgIFB5RXJyX0NsZWFyKCk7DQogICAgICAgIFB5X0JFR0lOX0FMTE9XX1RI
UkVBRFMNCiAgICAgICAgX3d4RGVsZWdhdGVSZW5kZXJlck5hdGl2ZV9EcmF3
VGl0bGVCYXJCaXRtYXAoc2lwQ3BwLCB3aW4sIGRjLCByZWN0LCBidXR0b24s
IGZsYWdzKTsNCiAgICAgICAgUHlfRU5EX0FMTE9XX1RIUkVBRFMNCiAgICAg
ICAgaWYgKFB5RXJyX09jY3VycmVkKCkpIHNpcElzRXJyID0gMTsNCiAgICAl
RW5kDQogICAgJVR5cGVDb2RlDQogICAgdm9pZCBfd3hEZWxlZ2F0ZVJlbmRl
cmVyTmF0aXZlX0RyYXdUaXRsZUJhckJpdG1hcCh3eERlbGVnYXRlUmVuZGVy
ZXJOYXRpdmUqIHNlbGYsIHd4V2luZG93KiB3aW4sIHd4REMqIGRjLCBjb25z
dCB3eFJlY3QqIHJlY3QsIHd4VGl0bGVCYXJCdXR0b24gYnV0dG9uLCBpbnQg
ZmxhZ3MpDQogICAgew0KICAgICAgICAjaWZkZWYgd3hIQVNfRFJBV19USVRM
RV9CQVJfQklUTUFQDQogICAgICAgICAgICBzZWxmLT5EcmF3VGl0bGVCYXJC
aXRtYXAod2luLCAqZGMsICpyZWN0LCBidXR0b24sIGZsYWdzKTsNCiAgICAg
ICAgI2Vsc2UNCiAgICAgICAgICAgIHd4UHlSYWlzZU5vdEltcGxlbWVudGVk
KCk7DQogICAgICAgICNlbmRpZg0KICAgIH0NCiAgICAlRW5kDQoNCiAgICBw
dWJsaWM6DQoNCg0KICAgICVQcm9wZXJ0eShuYW1lPVZlcnNpb24sIGdldD1H
ZXRWZXJzaW9uKQ0KfTsgIC8vIGVuZCBvZiBjbGFzcyB3eERlbGVnYXRlUmVu
ZGVyZXJOYXRpdmUNCg0K

---2033333575-1591116323-1590943726=:18055--