From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: Klaus-Dieter Bauer Newsgroups: gmane.emacs.devel Subject: Re: Can the byte-compiler check whether functions passed by name are defined? Date: Sun, 4 Aug 2013 20:41:13 +0200 Message-ID: References: NNTP-Posting-Host: plane.gmane.org Mime-Version: 1.0 Content-Type: multipart/mixed; boundary=20cf3071ced413979204e3238b7d X-Trace: ger.gmane.org 1375641716 13432 80.91.229.3 (4 Aug 2013 18:41:56 GMT) X-Complaints-To: usenet@ger.gmane.org NNTP-Posting-Date: Sun, 4 Aug 2013 18:41:56 +0000 (UTC) Cc: Sebastian Wiesner , emacs-devel@gnu.org To: Stefan Monnier Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Sun Aug 04 20:41:58 2013 Return-path: Envelope-to: ged-emacs-devel@m.gmane.org Original-Received: from lists.gnu.org ([208.118.235.17]) by plane.gmane.org with esmtp (Exim 4.69) (envelope-from ) id 1V63Fc-0008PP-0d for ged-emacs-devel@m.gmane.org; Sun, 04 Aug 2013 20:41:56 +0200 Original-Received: from localhost ([::1]:52339 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1V63Fb-0006RD-9n for ged-emacs-devel@m.gmane.org; Sun, 04 Aug 2013 14:41:55 -0400 Original-Received: from eggs.gnu.org ([2001:4830:134:3::10]:50849) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1V63FT-0006PV-M5 for emacs-devel@gnu.org; Sun, 04 Aug 2013 14:41:51 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1V63FQ-0008TA-Iq for emacs-devel@gnu.org; Sun, 04 Aug 2013 14:41:47 -0400 Original-Received: from mail-vb0-x22e.google.com ([2607:f8b0:400c:c02::22e]:38893) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1V63FQ-0008T1-Bt for emacs-devel@gnu.org; Sun, 04 Aug 2013 14:41:44 -0400 Original-Received: by mail-vb0-f46.google.com with SMTP id p13so2155967vbe.33 for ; Sun, 04 Aug 2013 11:41:43 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:in-reply-to:references:from:date:message-id:subject:to :cc:content-type; bh=Z0nmoaxT5+NkMxd1RcXwBC2ZLApTnLUwqwve0EBVugY=; b=febhEyOuPckgvg7tTzpQ1rUiktKILVYFqszdP5QkBLGWcDbQafJBpspFEaU165La0X BW8rWl6y+Y5CXTkpmt7gj0E5GO06mnpZtFmY2ERQ7VsTZfie8V9DE3Y1lWz+54sDBqph C4x8OCGI8bBc8W7+K115v0Oyn66tID/lME6acmT6ueoTEvZ30CWE1wr8xCEmYi6c+Rx8 UGr5hEEwqJ8tv9S/YH0XEPd2YQtXt4/ikxBrmeVf5SZbHWayFOtLJqnkZcnT+R+hC4ke ouJL7gUocUxrEdkLvMqQsKWn+iIb0Z5LPHYf64hgX/2Ahx6S2p9JlhZFhoeMkPTrwqzF +2iQ== X-Received: by 10.52.75.4 with SMTP id y4mr3994982vdv.118.1375641703516; Sun, 04 Aug 2013 11:41:43 -0700 (PDT) Original-Received: by 10.220.38.194 with HTTP; Sun, 4 Aug 2013 11:41:13 -0700 (PDT) In-Reply-To: X-detected-operating-system: by eggs.gnu.org: Error: Malformed IPv6 address (bad octet value). X-Received-From: 2607:f8b0:400c:c02::22e X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: "Emacs development discussions." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Original-Sender: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Xref: news.gmane.org gmane.emacs.devel:162415 Archived-At: --20cf3071ced413979204e3238b7d Content-Type: multipart/alternative; boundary=20cf3071ced413978c04e3238b7b --20cf3071ced413978c04e3238b7b Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable 2013/8/1 Stefan Monnier > >>> 1. Has to be done, though maybe through a macro, for every higher-ord= er > >>> function. > >> Note that macroexp.el already has special handling for the main > >> higher-order functions (to warn about '(lambda ...)). So it could be > >> implemented there. > > I presume the list of =E2=80=9Cmain higher-order=E2=80=9D functions is = hard-coded > > then, isn't it? > > Currently, yes. It could be moved from macroexp.el's main loop to > a bunch of compiler-macros (the code predates the introduction of > compiler macros in core Elisp), if needed. > > > Is there a symbol property or "declare" form to mark specific > > arguments as function arguments, to have the same warnings for higher > > order functions from 3rd party libraries, too? Similar to how > > "docstring" arguments for macros are handled? > > No, and I think it would be overkill. But 3rd party can also use > a compiler-macro to turn the ' into a #'. > > The approach I use for '(lambda ...) is to emit warnings in the common > cases, so that coders will slowly learn, which then benefits all cases. > > For '(lambda ...) that works well, because removing the ' (or using #') > is often useful (making it possible to byte-compile the code, or using > lexically bound vars), but for single quoted symbols, the benefit is > a lot less clear ("turn 'foo into #'foo to get rid of the silly new > warning" only to then get another warning because the compiler doesn't > understand that `foo' will very much exist by the time we try to call it)= . > > > Stefan > I have written an implementation of the compile-time check, see the attached patch to "lisp/bytecomp.el". Since I also introduced as new declare form for `defun', I have also attached a patch to "doc/functions.texi". The code handles both the cases (function SYMBOL) and (quote SYMBOL). In the latter case it requires a symbol property "higher-order-arguments" to be set, which should preferably be done by a declare form, but for now is implemented by checking for a set of common functions (apply, funcall, all functions I found starting with "map" or "cl-map") for the property and setting it if it is not yet set. The value of the property should be a list of integers, which give the positions of the arguments that are expected to be functions, counting from 0. If the patch becomes part of the emacs sources, I can also provide a patch that adds the needed declare forms to the various definitions, though I don't know how to do it for functions defined in the C-code such as `mapcar'. Currently such a function (in this case requiring lexical binding) definition would read (defun my-combine (func1 func2) (declare (higher-order-arguments 0 1) (lambda (arg) (funcall func1 (funcall func2 arg)))) or (defun my-map (func list) (declare (higher-order 0)) (mapcar func list)) I was thinking of allowing to declare the number of arguments the function will be passed, but didn't have the time for that detail (yet?). One thing I am not sure about: I define the handler for the declare form in "bytecomp.el", hence the handler is not known before loading that file. When loading a file from source the declare form will therefore cause a warning. When compiling it doesn't seem to cause issues though. I couldn't define the handler in "byte-run.el" however, as when I added it to the declaration of `defun-declaration-alist', it would suddenly be missing again during compilation. - Klaus --20cf3071ced413978c04e3238b7b Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: quoted-printable
2013/8/1 Stefan Monnier <monnier@iro.umontreal.ca<= /a>>
>>> 1. Has to be done, though maybe through a ma= cro, for every higher-order
>>> function.
>> Note that macroexp.el already has special handling for the main >> higher-order functions (to warn about '(lambda ...)). =C2=A0So= it could be
>> implemented there.
> I presume the list of =E2=80=9Cmain higher-order=E2=80=9D functions is= hard-coded
> then, isn't it?

Currently, yes. =C2=A0It could be moved from macroexp.el's main l= oop to
a bunch of compiler-macros (the code predates the introduction of
compiler macros in core Elisp), if needed.

> Is there a symbol property or "declare" form to mark specifi= c
> arguments as function arguments, to have the same warnings for higher<= br> > order functions from 3rd party libraries, too? =C2=A0Similar to how > "docstring" arguments for macros are handled?

No, and I think it would be overkill. =C2=A0But 3rd party can also us= e
a compiler-macro to turn the ' into a #'.

The approach I use for '(lambda ...) is to emit warnings in the common<= br> cases, so that coders will slowly learn, which then benefits all cases.

For '(lambda ...) that works well, because removing the ' (or using= #')
is often useful (making it possible to byte-compile the code, or using
lexically bound vars), but for single quoted symbols, the benefit is
a lot less clear ("turn 'foo into #'foo to get rid of the sill= y new
warning" only to then get another warning because the compiler doesn&#= 39;t
understand that `foo' will very much exist by the time we try to call i= t).


=C2=A0 =C2=A0 =C2=A0 =C2=A0 Stefan

=C2=A0I have written an imple= mentation of the compile-time check, see the attached patch to "lisp/b= ytecomp.el". Since I also introduced as new declare form for `defun= 9;, I have also attached a patch to "doc/functions.texi".

The code handles both the cases (function SYMBOL) and (quote SYMBOL). In th= e latter case it requires a symbol property "higher-order-arguments&qu= ot; to be set, which should preferably be done by a declare form, but for n= ow is implemented by checking for a set of common functions (apply, funcall= , all functions I found starting with "map" or "cl-map"= ) for the property and setting it if it is not yet set. The value of the p= roperty should be a list of integers, which give the positions of the argum= ents that are expected to be functions, counting from 0.

If the patch becomes part of the emacs sources, I can also provide a patch = that adds the needed declare forms to the various definitions, though I don= 't know how to do it for functions defined in the C-code such as `mapca= r'.

Currently such a function (in this case requiring lexical binding) definiti= on would read

(defun my-combine (func1 func2)
(declare (higher-order-arguments 0 1)
(lambda (arg)
(funcall func1 (funcall func2 arg))))

or

(defun my-map (func list)
(declare (higher-order 0))
(mapcar func list))

I was thinking of allowing to declare the number of arguments the function = will be passed, but didn't have the time for that detail (yet?).

One thing I am not sure about: I define the handler for the declare form in= "bytecomp.el", hence the handler is not known before loading tha= t file. When loading a file from source the declare form will therefore cau= se a warning. When compiling it doesn't seem to cause issues though.

I couldn't define the handler in "byte-run.el" however, as wh= en I added it to the declaration of `defun-declaration-alist', it would= suddenly be missing again during compilation.

- Klaus

--20cf3071ced413978c04e3238b7b-- --20cf3071ced413979204e3238b7d Content-Type: application/octet-stream; name="functions.texi.patch" Content-Disposition: attachment; filename="functions.texi.patch" Content-Transfer-Encoding: base64 X-Attachment-Id: f_hjyisze81 LS0tIGZ1bmN0aW9ucy50ZXhpLm9yaWcJMjAxMy0wNy0wMSAxMDoyMTowOC40MDQzOTcwMDAgKzAy MDAKKysrIGZ1bmN0aW9ucy50ZXhpCTIwMTMtMDgtMDQgMTQ6MDU6NDEuNTE2NTUzNDAwICswMjAw CkBAIC0xMzA3LDYgKzEzMDcsMTMgQEAKIHdoaWNoIGNhc2UgdGhlIHdhcm5pbmcgbWVzc2FnZSBn aXZlcyBubyBleHRyYSBkZXRhaWxzKS4gIEB2YXJ7d2hlbn0KIHNob3VsZCBiZSBhIHN0cmluZyBp bmRpY2F0aW5nIHdoZW4gdGhlIGZ1bmN0aW9uIG9yIG1hY3JvIHdhcyBmaXJzdAogbWFkZSBvYnNv bGV0ZS4KKworQGl0ZW0gKGhpZ2hlci1vcmRlci1hcmd1bWVudHMgW0B2YXJ7cG9zfSAuLl0pCitU ZWxsIHRoZSBieXRlIGNvbXBpbGVyIHRoYXQgdGhlIGFyZ3VtZW50IGF0IHBvc2l0aW9uIEB2YXJ7 cG9zfSBpcworZXhwZWN0ZWQgdG8gYmUgYSBmdW5jdGlvbi4gQHZhcntwb3N9IHN0YXJ0cyBmcm9t IDAuIFdoZW4gdGhlIGFjdHVhbAorcGFyYW1ldGVyIGlzIGEgcXVvdGVkIHN5bWJvbCwgdGhlIGJ5 dGUgY29tcGlsZXIgd2lsbCB3YXJuIGFib3V0IGFuCit1bmtub3duIGZ1bmN0aW9uLCBpZiB0aGUg c3ltYm9sIGlzIG5vdCBrbm93biB0byBiZSBib3VuZCB0byBhIGZ1bmN0aW9uCithdCBjb21waWxl IHRpbWUuIFplcm8gb3IgbW9yZSBAdmFye3Bvc30gY2FuIGJlIHNwZWNpZmllZC4KIEBlbmQgdGFi bGUKIEBlbmQgZGVmbWFjCiAK --20cf3071ced413979204e3238b7d Content-Type: application/octet-stream; name="bytecomp.el.patch" Content-Disposition: attachment; filename="bytecomp.el.patch" Content-Transfer-Encoding: base64 X-Attachment-Id: f_hjylhem62 LS0tIGJ5dGVjb21wLmVsLm9yaWcJMjAxMy0wNy0wMiAyMjoyODozNC45MzY3MzE2MDAgKzAyMDAN CisrKyBieXRlY29tcC5lbAkyMDEzLTA4LTA0IDIwOjM4OjM4LjUzNDY1MTkwMCArMDIwMA0KQEAg LTE0OTYsNiArMTQ5Niw3IEBADQogICAgICAgICAgKGJ5dGUtY29tcGlsZS1jb25zdC12YXJpYWJs ZXMgbmlsKQ0KICAgICAgICAgIChieXRlLWNvbXBpbGUtZnJlZS1yZWZlcmVuY2VzIG5pbCkNCiAg ICAgICAgICAoYnl0ZS1jb21waWxlLWZyZWUtYXNzaWdubWVudHMgbmlsKQ0KKwkgKGJ5dGUtY29t cGlsZS0taGlnaGVyLW9yZGVyLS11bnJlc29sdmVkLWZ1bmN0aW9ucyBuaWwpDQogICAgICAgICAg OzsNCiAgICAgICAgICA7OyBDbG9zZSBvdmVyIHRoZXNlIHZhcmlhYmxlcyBzbyB0aGF0IGBieXRl LWNvbXBpbGVyLW9wdGlvbnMnDQogICAgICAgICAgOzsgY2FuIGNoYW5nZSB0aGVtIG9uIGEgcGVy LWZpbGUgYmFzaXMuDQpAQCAtMTkzOSw2ICsxOTQwLDcgQEANCiAJOzsgTWFrZSB3YXJuaW5ncyBh Ym91dCB1bnJlc29sdmVkIGZ1bmN0aW9ucw0KIAk7OyBnaXZlIHRoZSBlbmQgb2YgdGhlIGZpbGUg YXMgdGhlaXIgcG9zaXRpb24uDQogCShzZXRxIGJ5dGUtY29tcGlsZS1sYXN0LXBvc2l0aW9uIChw b2ludC1tYXgpKQ0KKwkoYnl0ZS1jb21waWxlLS1oaWdoZXItb3JkZXItLXdhcm4tYWJvdXQtdW5y ZXNvbHZlZC1mdW5jdGlvbi1uYW1lcykNCiAJKGJ5dGUtY29tcGlsZS13YXJuLWFib3V0LXVucmVz b2x2ZWQtZnVuY3Rpb25zKSkNCiAgICAgICA7OyBGaXggdXAgdGhlIGhlYWRlciBhdCB0aGUgZnJv bnQgb2YgdGhlIG91dHB1dA0KICAgICAgIDs7IGlmIHRoZSBidWZmZXIgY29udGFpbnMgbXVsdGli eXRlIGNoYXJhY3RlcnMuDQpAQCAtMjk2MCw2ICsyOTYyLDcgQEANCiAoZGVmdW4gYnl0ZS1jb21w aWxlLW5vcm1hbC1jYWxsIChmb3JtKQ0KICAgKHdoZW4gKGFuZCAoYnl0ZS1jb21waWxlLXdhcm5p bmctZW5hYmxlZC1wICdjYWxsYXJncykNCiAgICAgICAgICAgICAgKHN5bWJvbHAgKGNhciBmb3Jt KSkpDQorICAgIChieXRlLWNvbXBpbGUtLWhpZ2hlci1vcmRlci0tY2hlY2stYXJndW1lbnRzIGZv cm0pDQogICAgIChpZiAobWVtcSAoY2FyIGZvcm0pDQogICAgICAgICAgICAgICAnKGN1c3RvbS1k ZWNsYXJlLWdyb3VwIGN1c3RvbS1kZWNsYXJlLXZhcmlhYmxlDQogICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgIGN1c3RvbS1kZWNsYXJlLWZhY2UpKQ0KQEAgLTQ2NTksNiArNDY2 MiwxNzAgQEANCiAJICAgICAgKGluZGVudC10byA0MCkNCiAJICAgICAgKGluc2VydCAoaW50LXRv LXN0cmluZyBuKSAiXG4iKSkpDQogCShzZXRxIGkgKDErIGkpKSkpKSkNCisNCis7Ozs7IChERUNM QVJFIChISUdIRVItT1JERVItQVJHVU1FTlRTKSkgQU5EIENIRUNLIFtCRUdJTk5JTkddIDs7Ozs7 Ozs7DQorDQorKGRlZnZhciBieXRlLWNvbXBpbGUtLWhpZ2hlci1vcmRlci0tdW5yZXNvbHZlZC1m dW5jdGlvbnMgbmlsDQorICAiQSBsaXN0IG9mIGZ1bmN0aW9ucyB0aGF0IHdlcmUgcGFzc2VkIGJ5 IG5hbWUgdG8gaGlnaGVyIG9yZGVyIGZ1bmN0aW9ucyBidXQgd2hlcmUgbm90IGtub3duIHRvIGJl IGRlZmluZWQuDQorDQorVXNlZCBkdXJpbmcgY29tcGlsYXRpb24gdG8gcmVwb3J0IGZ1bmN0aW9u cyByZWZlcnJlZCB0byBieSAocXVvdGUNCitTWU1CT0wpIG9yIChmdW5jdGlvbiBTWU1CT0wpIHRo YXQgYXJlIG5vdCBrbm93biB0byBiZSBkZWZpbmVkLg0KKw0KKyBTZWUgYWxzbw0KK2BieXRlLWNv bXBpbGUtLWhpZ2hlci1vcmRlci0td2Fybi1hYm91dC11bnJlc29sdmVkLWZ1bmN0aW9uLW5hbWVz JywNCitgYnl0ZS1jb21waWxlLS1oaWdoZXItb3JkZXItLWNoZWNrLWFyZ3VtZW50cycuIikNCisN CisoZGVmdW4gYnl0ZS1jb21waWxlLS1oaWdoZXItb3JkZXItLXdhcm4tYWJvdXQtdW5yZXNvbHZl ZC1mdW5jdGlvbi1uYW1lcyAoKQ0KKyAgIkVtaXQgY29tcGlsZXIgd2FybmluZ3Mgd2hlbiB0aGVy ZSBhcmUgdW5yZXNvbHZlZCBmdW5jdGlvbiBhIHN5bWJvbHMgcGFzc2VkIHRvIGhpZ2hlciBvcmRl ciBmdW5jdGlvbnMuDQorU2VlIGFsc28gYGJ5dGUtY29tcGlsZS0taGlnaGVyLW9yZGVyLS11bnJl c29sdmVkLWZ1bmN0aW9ucycuIg0KKyAgOzsgVGhlIGxvZ2ljIGlzIHNpbWlsaWFyIHRvIGBieXRl LWNvbXBpbGUtd2Fybi1hYm91dC11bnJlc29sdmVkLWZ1bmN0aW9ucycuDQorICAod2hlbiAoYnl0 ZS1jb21waWxlLXdhcm5pbmctZW5hYmxlZC1wICd1bnJlc29sdmVkKQ0KKyAgICAobGV0ICgoYnl0 ZS1jb21waWxlLWN1cnJlbnQtZm9ybSA6ZW5kKQ0KKwkgIG5vdC1kZWZpbmVkLWF0LXJ1bnRpbWUt bWF5YmUtc3ltYm9sLWxpc3QNCisJICByZXNvbHZlZC10by1mdW5jdGlvbi1saXN0DQorCSAgcmVz b2x2ZWQtdG8tbWFjcm8tbGlzdA0KKwkgIHVucmVzb2x2ZWQtc3ltYm9sLWxpc3QpDQorICAgIChk b2xpc3QgKGZ1bmN0aW9uLW5hbWUgYnl0ZS1jb21waWxlLS1oaWdoZXItb3JkZXItLXVucmVzb2x2 ZWQtZnVuY3Rpb25zKQ0KKyAgICAgIChjb25kICgoYXNzcSBmdW5jdGlvbi1uYW1lIGJ5dGUtY29t cGlsZS1mdW5jdGlvbi1lbnZpcm9ubWVudCkNCisJICAgICAocHVzaCBmdW5jdGlvbi1uYW1lIHJl c29sdmVkLXRvLWZ1bmN0aW9uLWxpc3QpKQ0KKwkgICAgKChhc3NxIGZ1bmN0aW9uLW5hbWUgYnl0 ZS1jb21waWxlLW1hY3JvLWVudmlyb25tZW50KQ0KKwkgICAgIChwdXNoIGZ1bmN0aW9uLW5hbWUg cmVzb2x2ZWQtdG8tbWFjcm8tbGlzdCkpDQorCSAgICAoKGZib3VuZHAgZnVuY3Rpb24tbmFtZSkN CisJICAgICAocHVzaCBmdW5jdGlvbi1uYW1lIG5vdC1kZWZpbmVkLWF0LXJ1bnRpbWUtbWF5YmUt c3ltYm9sLWxpc3QpKQ0KKwkgICAgKHQgKHB1c2ggZnVuY3Rpb24tbmFtZSB1bnJlc29sdmVkLXN5 bWJvbC1saXN0KSkpKQ0KKyAgICAoZG9saXN0IChyZXNvbHZlZC1uYW1lIHJlc29sdmVkLXRvLWZ1 bmN0aW9uLWxpc3QpDQorICAgICAgKHNldHEgYnl0ZS1jb21waWxlLS1oaWdoZXItb3JkZXItLXVu cmVzb2x2ZWQtZnVuY3Rpb25zDQorCSAgICAoZGVscSByZXNvbHZlZC1uYW1lDQorCQkgIGJ5dGUt Y29tcGlsZS0taGlnaGVyLW9yZGVyLS11bnJlc29sdmVkLWZ1bmN0aW9ucykpKQ0KKyAgICAoYnl0 ZS1jb21waWxlLXByaW50LXN5bXMgDQorICAgICAiVGhlIHN5bWJvbCBgJVMnIHdhcyBwYXNzZWQg dG8gYSBmdW5jdGlvbiBhcyBpZiB0aGUgbmFtZSBvZiBhIGZ1bmN0aW9uLCBidXQgaXMgYm91bmQg dG8gYSBtYWNybyBpbnN0ZWFkLiINCisgICAgICJUaGUgZm9sbG93aW5nIHN5bWJvbHMgd2VyZSBw YXNzZWQgdG8gYSBmdW5jdGlvbiBhcyBpZiB0aGUgbmFtZXMgZnVuY3Rpb25zIGJ1dCBhcmUgYm91 bmQgdG8gbWFjcm9zIGluc3RlYWQ6Ig0KKyAgICAgcmVzb2x2ZWQtdG8tbWFjcm8tbGlzdCkNCisg ICAgKGJ5dGUtY29tcGlsZS1wcmludC1zeW1zDQorICAgICAiVGhlIHN5bWJvbCBgJVMnIHdhcyB1 c2VkIGFzIGZ1bmN0aW9uIG5hbWUgYnV0IHRoZSBmdW5jdGlvbiBpcyBub3Qga25vd24gdG8gYmUg ZGVmaW5lZC4iDQorICAgICAiVGhlIGZvbGxvd2luZyBzeW1ib2xzIHdlcmUgdXNlZCBhcyBmdW5j dGlvbiBuYW1lcyBidXQgdGhlIGZ1bmN0aW9ucyBhcmUgbm90IGtub3duIHRvIGJlIGRlZmluZWQ6 Ig0KKyAgICAgdW5yZXNvbHZlZC1zeW1ib2wtbGlzdCkNCisgICAgKGJ5dGUtY29tcGlsZS1wcmlu dC1zeW1zDQorICAgICAiVGhlIGZ1bmN0aW9uIGAlUycgd2FzIHVzZWQgYXMgZnVuY3Rpb24gbmFt ZSBidXQgdGhlIGZ1bmN0aW9uIG1pZ2h0IG5vdCBiZSBkZWZpbmVkIGF0IHJ1bnRpbWUuIg0KKyAg ICAgIlRoZSBmb2xsb3dpbmcgc3ltYm9scyB3ZXJlIHVzZWQgYXMgZnVuY3Rpb24gbmFtZXMgYnV0 IHRoZSBmdW5jdGlvbnMgbWlnaHQgbm90IGJlIGRlZmluZWQgYXQgcnVudGltZToiDQorICAgICBu b3QtZGVmaW5lZC1hdC1ydW50aW1lLW1heWJlLXN5bWJvbC1saXN0KSkpKQ0KKw0KKyhkZWZ1biBi eXRlLWNvbXBpbGUtLWhpZ2hlci1vcmRlci0tY2hlY2stYXJndW1lbnRzIChmb3JtKQ0KKyAgIk9u IEZPUk0sIHdoaWNoIGlzIGEgZnVuY3Rpb24gY2FsbCwgY2hlY2sgd2hldGhlciBmdW5jdGlvbnMg cGFzc2VkIGJ5IG5hbWUgYXJlIGtub3duIHRvIGJlIGRlZmluZWQuDQorDQorSWYgYSBwYXJhbWV0 ZXIgaGFzIHRoZSBmb3JtIChmdW5jdGlvbiBTWU1CT0wpIG9yIGl0IGlzIGtub3duIHRvDQorYmUg ZXhwZWN0ZWQgdG8gYmUgYSBmdW5jdGlvbiB0aHJvdWdoIHRoZSBgaGlnaGVyLW9yZGVyLWFyZ3Vt ZW50cycNCitwcm9wZXJ0eSBvZiB0aGUgc3ltYm9sIChjYXIgRk9STSkgYW5kIGhhcyB0aGUgZm9y bSAocXVvdGUgU1lNQk9MKQ0KK3dlIGVpdGhlciB3YXJuIHJpZ2h0IGF3YXksIGlmIFNZTUJPTCBp cyBrbm93biB0byBiZSBib3VuZCB0bw0KK3NvbWV0aGluZyB0aGF0IGNhbm5vdCBiZSBwYXNzZWQg dG8gaGlnaGVyIG9yZGVyIGZ1bmN0aW9ucyBzdWNoIGFzDQorc3BlY2lhbCBmb3JtcyBhbmQgbWFj cm9zLiBJZiBTWU1CT0wncyBmdW5jdGlvbiBjZWxsIGlzIGVtcHR5LCB3ZQ0KK3F1ZXVlIHRoZSBz eW1ib2wgaW50bw0KK2BieXRlLWNvbXBpbGUtLWhpZ2hlci1vcmRlci0tdW5yZXNvbHZlZC1mdW5j dGlvbnMnIGZvciBjaGVja2luZw0KK2F0IHRoZSBlbmQgb2YgdGhlIGZpbGUsIHNlZQ0KK2BieXRl LWNvbXBpbGUtLWhpZ2hlci1vcmRlci0td2Fybi1hYm91dC11bnJlc29sdmVkLWZ1bmN0aW9uLW5h bWVzJy4iDQorICAobGV0ICgoaGlnaGVyLW9yZGVyLWFyZ3VtZW50cw0KKwkgKGFuZCAoc3ltYm9s cCAoY2FyIGZvcm0pKQ0KKwkgICAgICAoZ2V0IChjYXIgZm9ybSkgJ2hpZ2hlci1vcmRlci1hcmd1 bWVudHMpKSkNCisJKHBvcyAtMSkpDQorICAgIChkb2xpc3QgKHN1YmZvcm0gKGNkciBmb3JtKSkN CisgICAgICAoc2V0cSBwb3MgKDErIHBvcykpDQorICAgICAgOzsgQ2hlY2sgd2hlbiBzdWJmb3Jt IGhhcyBmb3JtIChmdW5jdGlvbiBTWU1CT0wpIG9yIChxdW90ZSBTWU1CT0wpDQorICAgICAgOzsg YW5kIHBvc2l0aW9uIG1hdGNoZXMgb25lIG1lbnRpb25lZCBpbiBoaWdoZXItb3JkZXItYXJndW1l bnRzLg0KKyAgICAgICh3aGVuIChvciAoYW5kIChsaXN0cCBzdWJmb3JtKSA7OyBjYXNlOiAoZnVu Y3Rpb24gU1lNQk9MKQ0KKwkJICAgICAoZXEgKGNhciBzdWJmb3JtKSAnZnVuY3Rpb24pDQorCQkg ICAgIChzeW1ib2xwIChjYXIgKGNkciBzdWJmb3JtKSkpDQorCQkgICAgIChudWxsIChjZHIgKGNk ciBzdWJmb3JtKSkpKQ0KKwkJKGFuZCAobGlzdHAgc3ViZm9ybSkgOzsgY2FzZTogKHF1b3RlIFNZ TUJPTCkNCisJCSAgICAgKGVxIChjYXIgc3ViZm9ybSkgJ3F1b3RlKQ0KKwkJICAgICAoc3ltYm9s cCAoY2FyIChjZHIgc3ViZm9ybSkpKQ0KKwkJICAgICAobnVsbCAoY2RyIChjZHIgc3ViZm9ybSkp KQ0KKwkJICAgICAobWVtYmVyIHBvcyBoaWdoZXItb3JkZXItYXJndW1lbnRzKSkpDQorCShsZXQg KChmdW5jdGlvbi1uYW1lIChjYXIgKGNkciBzdWJmb3JtKSkpKQ0KKwkgIDs7IElzIHRoZSBmdW5j dGlvbiBhbHJlYWR5IGRlZmluZWQgb3IgYWxyZWFkeSBrbm93biB0byBiZQ0KKwkgIDs7IGRlZmlu ZWQgaW4gdGhpcyBmaWxlPyBOb3RlIHRoYXQgbWFjcm9zIGFyZSBub3QgYWxsb3dlZCENCisJICAo Y29uZCAoKGFzc3EgZnVuY3Rpb24tbmFtZSBieXRlLWNvbXBpbGUtZnVuY3Rpb24tZW52aXJvbm1l bnQpKSA7OyBEbyBub3RoaW5nLg0KKwkJKChhc3NxIGZ1bmN0aW9uLW5hbWUgYnl0ZS1jb21waWxl LW1hY3JvLWVudmlyb25tZW50KQ0KKwkJIChieXRlLWNvbXBpbGUtd2FybiAiSW52YWxpZCBhcmd1 bWVudCBgJVMnIHRvIGZ1bmN0aW9uIGAlUyc6IE5vdCBhIGZ1bmN0aW9uLiINCisJCQkJICAgIGZ1 bmN0aW9uLW5hbWUgKGNhciBmb3JtKSkpDQorCQkoKGZ1bmN0aW9ucCBmdW5jdGlvbi1uYW1lKSkg OzsgTm8gbm90aGluZywgaXMgb2suDQorCQkoKGZib3VuZHAgZnVuY3Rpb24tbmFtZSkNCisJCSAo Ynl0ZS1jb21waWxlLXdhcm4gIkludmFsaWQgYXJndW1lbnQgYCVTJyB0byBmdW5jdGlvbiBgJVMn OiBOb3QgYSBmdW5jdGlvbi4iDQorCQkJCSAgICBmdW5jdGlvbi1uYW1lIChjYXIgZm9ybSkpKQ0K KwkJKHQgOzsgVW5rbm93biBzeW1ib2wNCisJCSAoYWRkLXRvLWxpc3QgJ2J5dGUtY29tcGlsZS0t aGlnaGVyLW9yZGVyLS11bnJlc29sdmVkLWZ1bmN0aW9ucw0KKwkJCSAgICAgIGZ1bmN0aW9uLW5h bWUpKSkpKSkpKQ0KKw0KKzs7IFBsYWNpbmcgdGhlIGVudHJ5IGluc2lkZSB0aGUgZGVmaW5pdGlv biBvZg0KKzs7IGBkZWZ1bi1kZWNsYXJhdGlvbi1hbGlzdCcgZGlyZWN0bHkgZm9yIHNvbWUgcmVh c29uIGRvZXNuJ3Qgd29yay4NCisoYWRkLXRvLWxpc3QgJ2RlZnVuLWRlY2xhcmF0aW9ucy1hbGlz dA0KKwkgICAgICcoaGlnaGVyLW9yZGVyLWFyZ3VtZW50cyANCisJICAgICAgIGJ5dGUtY29tcGls ZS0taGlnaGVyLW9yZGVyLS1kZWNsYXJlLWZvcm0taGFuZGxlcikpDQorDQorKGRlZnVuIGJ5dGUt Y29tcGlsZS0taGlnaGVyLW9yZGVyLS1kZWNsYXJlLWZvcm0taGFuZGxlciAoZiBfYXJncyAmcmVz dCB2YWwpDQorICAiSGFuZGxlciBmb3IgdGhlIChkZWNsYXJlIChoaWdoZXItb3JkZXItYXJndW1l bnRzIFtOVU0gLi4uXSkpIGZvcm0sIHNlZSBgZGVmdW4tZGVjbGFyYXRpb25zLWFsaXN0Jy4NCisN CitGIGlzIHRoZSBuYW1lIG9mIHRoZSBmdW5jdGlvbiwgX0FSR1MgdGhlIGZvcm1hbCBwYXJhbWV0 ZXIgbGlzdCwNCitWQUwgc2hvdWxkIGJlIChOVU0gLi4pLg0KKw0KK0xJTUlUQVRJT046IFdoZW4g dGhlIGZ1bmN0aW9uIGhhcyBiZWVuIHVzZWQgYmVmb3JlIGl0IHdhcw0KK2RlZmluZWQsIGEgY29t cGlsZXIgd2FybmluZyBpcyBlbWl0dGVkIHBvaW50aW5nIG91dCB0aGF0IHByaW9yDQordXNlIG1p Z2h0IG5vdCBoYXZlIGJlZW4gY2hlY2tlZC4iDQorICA7OyBDaGVjayB0aGF0IFZBTCBpcyBsaXN0 IG9mIGludGVnZXJzLg0KKyAgKGlmIChvciAobm90IChsaXN0cCB2YWwpKQ0KKwkgIChkZWxldGUg bmlsDQorCSAgICAobWFwY2FyIChsYW1iZGEgKGUpIChub3QgKGludGVnZXJwIGUpKSkNCisJICAg ICAgdmFsKSkpDQorICAgICAgOzsgV2FybiBhYm91dCBpbnZhbGlkIGBkZWNsYXJlJyBmb3JtDQor ICAgICAgKGxldCAoKHdhcm4tdGV4dCANCisJICAgICAoY29uY2F0ICIoZGVjbGFyZSAuLikgZm9y bSAoaGlnaGVyLW9yZGVyLWFyZ3VtZW50cyBbTlVNIC4uXSkgd2l0aCBpbnZhbGlkIGFyZ3VtZW50 cyAiDQorCQkgICAgIChtYXBjb25jYXQgKGxhbWJkYSAoZSkgKGZvcm1hdCAiJVMiIGUpKSB2YWwg IiAiKSkpKQ0KKwkoaWYgYnl0ZS1jb21waWxlLWN1cnJlbnQtZmlsZSANCisJICAgIChieXRlLWNv bXBpbGUtd2FybiAiJXMiIHdhcm4tdGV4dCkNCisJICAod2FybiAiJXMiIHdhcm4tdGV4dCkpDQor CW5pbCkNCisgICAgOzsgUmV0dXJuIGEgYHB1dCcgZm9ybSwgYnV0IGFsc28gcGVyZm9ybSBpdCBh dCBjb21waWxlIHRpbWUuDQorICAgIDs7IExpbWl0YXRpb246IEFmZmFjdHMgb25seSBoaWdoZXIg b3JkZXIgZnVuY3Rpb25zIGRlZmluZWQgYmVmb3JlDQorICAgIDs7IHRoZWlyIGZpcnN0IHVzZS4N CisgICAgKHdoZW4gKGFzc3EgZiBieXRlLWNvbXBpbGUtdW5yZXNvbHZlZC1mdW5jdGlvbnMpDQor ICAgICAgKGJ5dGUtY29tcGlsZS13YXJuIA0KKyAgICAgICAiJXMiDQorICAgICAgIChjb25jYXQg IkhpZ2hlciBvcmRlciBmdW5jdGlvbiAiIChzeW1ib2wtbmFtZSBmKSAiIHdhcyB1c2VkIGJlZm9y ZSBpdCB3YXMgZGVmaW5lZC4gIg0KKwkgICAgICAgIkFjdHVhbCBwYXJhbWV0ZXJzIHdlcmUgbm90 IGNoZWNrZWQgZm9yIHZhbGlkaXR5LiIpKSkNCisgICAgKGxpc3QgJ2V2YWwtYW5kLWNvbXBpbGUg DQorCSAgKGxpc3QgJ3B1dCAobGlzdCAncXVvdGUgZikgJydoaWdoZXItb3JkZXItYXJndW1lbnRz DQorCQkobGlzdCAncXVvdGUgdmFsKSkpKSkNCisNCis7OyBTZXR0aW5nIHRoZSBwcm9wZXJ0eSBm b3IgY2VydGFpbiBrbm93biBmdW5jdGlvbnMuDQorDQorKGRlZm1hY3JvIGJ5dGUtY29tcGlsZS0t aGlnaGVyLW9yZGVyLS1yZWdpc3Rlci1rbm93bi1mdW5jdGlvbnMgKHBvcyAmcmVzdCBzeW1ib2wt bGlzdCkNCisgICJGb3IgZWxlbWVudHMgb2YgU1lNQk9MLUxJU1Qgc2V0IHRoZSBoaWdoZXItb3Jk ZXItYXJndW1lbnRzIHByb3BlcnR5IHRvIChQT1MpIHdoZW4gaXQgaXMgbm90IHlldCBzZXQuDQor DQorT25seSBmb3IgYmFja3dhcmQgY29tcGF0aWJpbGl0eSB1c2UgaW4gYnl0ZWNvbXAuZWwuIElm IHlvdSB3YW50DQordG8gc2V0IHRoZSBwcm9wZXJ0eSBmb3IgeW91ciBvd24gZnVuY3Rpb25zIHVz ZQ0KK3RoZSAoZGVjbGFyZSAoaGlnaGVyLW9yZGVyIFtOVU0gLi5dKSkgZm9ybS4iDQorICAoZGVj bGFyZSAoaW5kZW50IDEpKQ0KKyAgKGxldCAoZm9ybXMpDQorICAgIChkb2xpc3QgKGZ1bmN0aW9u LW5hbWUgc3ltYm9sLWxpc3QpDQorICAgICAgKHB1c2ggKGxpc3QgJ2lmIChsaXN0ICdub3QgKGxp c3QgJ2dldCAobGlzdCAncXVvdGUgZnVuY3Rpb24tbmFtZSkgJydoaWdoZXItb3JkZXItYXJndW1l bnRzKSkNCisJCSAgKGxpc3QgJ3B1dCAobGlzdCAncXVvdGUgZnVuY3Rpb24tbmFtZSkgJydoaWdo ZXItb3JkZXItYXJndW1lbnRzIA0KKwkJCShsaXN0ICdxdW90ZSAobGlzdCBwb3MpKSkpDQorCSAg ICBmb3JtcykpDQorICAgIChjb25zICdwcm9nbiAocmV2ZXJzZSBmb3JtcykpKSkNCisNCisoYnl0 ZS1jb21waWxlLS1oaWdoZXItb3JkZXItLXJlZ2lzdGVyLWtub3duLWZ1bmN0aW9ucyAwDQorICA7 OyBGdW5jdGlvbnMgZGVmaW5lZCBpbiBDLXNvdXJjZS4NCisgIGFwcGx5IGZ1bmNhbGwgbWFwLWNo YXItdGFibGUgbWFwLWNoYXJzZXQtY2hhcnMgbWFwLWtleW1hcA0KKyAgbWFwLWtleW1hcC1pbnRl cm5hbCBtYXBhdG9tcyBtYXBjIG1hcGNhciBtYXBjb25jYXQgbWFwaGFzaA0KKyAgOzsgRnVuY3Rp b25zIGRlZmluZWQgaW4gc3RhbmRhcmQgZWxpc3AgZmlsZXMNCisgIG1hcC1rZXltYXAtc29ydGVk IG1hcC1xdWVyeS1yZXBsYWNlLXJlZ2V4cCBtYXAteS1vci1uLXANCisgIDs7IEZyb20gdGhlIGRl cHJlY2F0ZWQgYGNsJw0KKyAgbWFwIG1hcGNhbiBtYXBjYXIqIG1hcGNvbiBtYXBsIG1hcGxpc3QN CisgIDs7IE5vbi1vYnNvbGV0ZSBub24taW50ZXJuYWwgZnVuY3Rpb25zIGZyb20gYGNsLWxpYicN CisgIGNsLW1hcCBjbC1tYXBjIGNsLW1hcGNhbiBjbC1tYXBjYXIgY2wtbWFwY29uIGNsLW1hcGhh c2ggY2wtbWFwbA0KKyAgY2wtbWFwbGlzdCkNCisNCis7Ozs7IChERUNMQVJFIChISUdIRVItT1JE RVItQVJHVU1FTlRTKSkgQU5EIENIRUNLIFtFTkRdIDs7Ozs7Ozs7Ozs7Ozs7DQorDQogDA0KIDs7 IFRvIGF2b2lkICJsaXNwIG5lc3RpbmcgZXhjZWVkcyBtYXgtbGlzcC1ldmFsLWRlcHRoIiB3aGVu IGJ5dGVjb21wIGNvbXBpbGVzDQogOzsgaXRzZWxmLCBjb21waWxlIHNvbWUgb2YgaXRzIG1vc3Qg dXNlZCByZWN1cnNpdmUgZnVuY3Rpb25zIChhdCBsb2FkIHRpbWUpLg0K --20cf3071ced413979204e3238b7d--