From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: MON KEY Newsgroups: gmane.emacs.devel Subject: Re: locate-library, the NOSUFFIX arg and a [PATCH] Date: Thu, 21 Jan 2010 18:58:15 -0500 Message-ID: References: NNTP-Posting-Host: lo.gmane.org Mime-Version: 1.0 Content-Type: multipart/mixed; boundary=000e0cd358d2fb6eeb047db579e2 X-Trace: ger.gmane.org 1264118321 11792 80.91.229.12 (21 Jan 2010 23:58:41 GMT) X-Complaints-To: usenet@ger.gmane.org NNTP-Posting-Date: Thu, 21 Jan 2010 23:58:41 +0000 (UTC) Cc: emacs-devel@gnu.org To: Stefan Monnier Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Fri Jan 22 00:58:33 2010 Return-path: Envelope-to: ged-emacs-devel@m.gmane.org Original-Received: from lists.gnu.org ([199.232.76.165]) by lo.gmane.org with esmtp (Exim 4.50) id 1NY6v1-0003cQ-Ra for ged-emacs-devel@m.gmane.org; Fri, 22 Jan 2010 00:58:33 +0100 Original-Received: from localhost ([127.0.0.1]:38206 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1NY6v2-0007Nm-3F for ged-emacs-devel@m.gmane.org; Thu, 21 Jan 2010 18:58:32 -0500 Original-Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1NY6uv-0007Ln-Uq for emacs-devel@gnu.org; Thu, 21 Jan 2010 18:58:26 -0500 Original-Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1NY6uq-0007Bw-VD for emacs-devel@gnu.org; Thu, 21 Jan 2010 18:58:25 -0500 Original-Received: from [199.232.76.173] (port=42106 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1NY6uq-0007Bf-PF for emacs-devel@gnu.org; Thu, 21 Jan 2010 18:58:20 -0500 Original-Received: from mail-yx0-f191.google.com ([209.85.210.191]:50157) by monty-python.gnu.org with esmtp (Exim 4.60) (envelope-from ) id 1NY6uq-00059M-3z for emacs-devel@gnu.org; Thu, 21 Jan 2010 18:58:20 -0500 Original-Received: by yxe29 with SMTP id 29so1280650yxe.14 for ; Thu, 21 Jan 2010 15:58:16 -0800 (PST) Original-Received: by 10.151.29.2 with SMTP id g2mr3091077ybj.261.1264118295915; Thu, 21 Jan 2010 15:58:15 -0800 (PST) In-Reply-To: X-Google-Sender-Auth: aac7bb7c394b18a9 X-detected-operating-system: by monty-python.gnu.org: GNU/Linux 2.6 (newer, 2) X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "Emacs development discussions." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Original-Sender: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Errors-To: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Xref: news.gmane.org gmane.emacs.devel:120280 Archived-At: --000e0cd358d2fb6eeb047db579e2 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable Hi Stefan, On Thu, Jan 21, 2010 at 9:08 AM, Stefan Monnier wrote: >> ,---- >> | It can omit the suffix (a.k.a. file-name extension) if NOSUFFIX is >> | nil (which is the default, see below). >> `---- > > This is poorly worded but means that it will not only look for files > of the form DIR/FILE.SUFFIX but also for DIR/FILE (i.e. it will add the > empty string as a valid suffix). > A library is not a file. It is an abstraction of one. This is a subtle but important difference as you are no doubt well aware. The current docstring begins: ,---- | Show the precise file name of Emacs library library. `---- There can not be a precise file name for an abstraction... (get-load-suffixes) =3D> (".elc" ".elc.gz" ".el" ".el.gz") ;and sometimes "" Unless there is a most bona fide of the library suffixe. Or, some pigs are more equal than others. > This is poorly worded but means that it will not only look for files > of the form DIR/FILE.SUFFIX but also for DIR/FILE (i.e. it will add the > empty string as a valid suffix). A) It doesn't do that now. B) If the empty string is a valid suffix then all strings are potentially v= alid library suffixes. With regards A my patch and the newly modified version below address this. With regards B, is this your intention here?. If so, I don't believe this a= case of poor wording. It is a situation where the user visible ``spec'' (i.e. th= e docstring) says one thing but the function does something entirely differen= t (badly) b/c the empty string becomes the operative factor _not_ the value o= f `load-suffixes'. Regardless, you've ignored the second portion of the docs which negates _yo= ur_ interpretation above, and have neglected to explain or address my initial q= uery: "Aren't these two statements mutually exclusive?" ,---- | Optional second arg NOSUFFIX non-nil means don't add suffixes `load-suffi= xes' | to the specified name LIBRARY. `---- According to the docs we have: o If NOSUFFIX is nil - omit the suffix o If NOSUFIX is non-nil don't add suffixes `load-suffixes'. What other suffixes are there other than `load-suffixes'? The docs don't explicitly mention that the values of `load-file-rep-suffixe= s', and `get-load-suffixes' _also_ affect the return value. load-suffixes =3D> (".elc" ".el") (locate-library "subr") =3D> "{...}/emacs/lisp/subr.elc" (locate-library "subr" t) =3D> nil Again, according to the docs the `t' arg should elide ".elc" and ".el" suffixes. Still, this shouldn't cause locate-library to return nil, none th= e less this is the value returned in lieu of empty string element from `load-file-rep-suffixes'. >> I don't think the docstring even reflects the intent of locate-library's >> NOSUFFIX arg esp. as it doesn't appear to be _able_ to return a library = name >> sans extension when not called-interactively. > > Indeed, this arg only controls how the search is performed, not in which > form the result will be returned. > Come on Stefan! Are you implying that (locate-library "subr" t) should retu= rn non-nil regardless the second arg? It doesn't. If the search directs the outcome of the result then it also controls the form returned. Directing the search to, "not add suffixes `load-suffixes'" will not cause = it to search all but ".elc" and ".el", nor will it cause it to return the precise library file name. >> "When called from a program and NOSUFFIX is a boolean, string, or list o= f >> strings, return LIBRARY's file-truename as if by `file-name-sans-extensi= on'." > > That completely changes the meaning of this argument. Only to the extent that: a) The existing NOSUFFIX arg works as advertised. It doesn't, see item A ab= ove. b) There is fixity w/re the meaning of the NOSUFFIX argument... W/re to a and A above one can't break what is already broken. "He's only mostly dead." "She's only a 'lil bit pregnant" Apropos b, you've already acknowledged that the meaning is poorly specified= . I don't understand how my patch can change the meaning of a poorly specifie= d and malfunctioning argument. > Why don't you call file-name-sans-extension outside of locate-library ins= tead, > if you want that? > > Stefan Because a library is not a file. Indeed, if I wanted to strip the suffix I would use `locate-file'. Which be= gs the question, why can't one _add/filter_ the most appropriate extension to = the return value of locate-library if that is what is wanted? This is the intention of my proposed patch. I've attached a modified version of the original patch. The existing change to the NOSUFFIX arg from the previous patch remains. Th= is is IMO a non-breaking semantic change. In addition, I've added a new optional arg SHOW-COMPRESSED which allows revealing whether the located library has the ".el[c]?.gz" extension. This = arg is applicable both as an interactive prefix arg and when called programatic= ally. The _ONLY_ potentially breaking change to the existing procedure I can find= is that where one supplies a non-nil argument for NOSUFFIX instead of returnin= g nil, it will now filter the suffix from the return result or any matching library found. The benefit here being that it will now actually return _something_ if there is a library-ish looking thing in the path. This shou= ldn't be a big deal esp. as the existing procedure just bails out... albeit not before first lying to me: (locate-library "subr" t) =3D> nil Even though there _IS_ a "subr" library in the loadpath (maybe more than on= e). Following are some more example test evaluations to give you an idea of wha= t the revised patch attached below is intended to accomplish: ;;; =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D ;; These files were present in path when testing: (directory-files "/home/MON/fnd-sbr" nil "s.*") =3D> ("subr.el" "subr.el.gz" "subr.elc" "subr.elc.gz") ;; Return value from existing unpatched `locate-library': (locate-library "subr" nil '("/home/MON/fnd-sbr")) =3D> "/home/MON/fnd-sbr/subr.elc" (locate-library "subr" "" '("/home/MON/fnd-sbr")) =3D> nil ;You keep using that word. I do not think it means what you think it means. (locate-library "subr" t '("/home/MON/fnd-sbr/")) =3D> nil ;You make me feel so cheap and used. ;; Now with patched version and the new optional arg SHOW-COMPRESSED (locate-library "subr" nil '("/home/MON/fnd-sbr")) =3D> "/home/MON/fnd-sbr/subr.elc" ;Same as it ever was. (locate-library "subr" t '("/home/MON/fnd-sbr")) =3D> "/home/MON/fnd-sbr/subr" ;Hey, thats much better. (locate-library "i-dont-exist" t '("/home/MON/fnd-sbr")) =3D> nil ;At least you didn't lie to me. Maybe, we can still be friends? (locate-library "subr" ".bad-ext" '("/home/MON/fnd-sbr")) =3D> nil ;Are you sure you've turned a new leaf? (locate-library "subr" ".elc" '("/home/MON/fnd-sbr")) =3D> "/home/MON/fnd-sbr/subr" ;OK, but could you be less vague? (locate-library "subr" ".elc.gz" '("/home/MON/fnd-sbr")) =3D> "/home/MON/fnd-sbr/subr" ;Apparently not. (locate-library "subr" ".elc.gz" '("/home/MON/fnd-sbr") nil t) =3D> "/home/MON/fnd-sbr/subr.elc.gz" ;So... you do grok Lempel-Ziv. (locate-library "subr" '(".el.gz" ".elc.gz") '("/home/MON/fnd-sbr")) =3D> "/home/MON/fnd-sbr/subr" ;But now which one did we match? (locate-library "subr" '(".elc" ".elc.gz") '("/home/MON/fnd-sbr") nil t) =3D> "/home/MON/fnd-sbr/subr" ;Was it most specific first? (locate-library "subr" '(".elc.gz" ".elc") '("/home/MON/fnd-sbr")) =3D> "/home/MON/fnd-sbr/subr" ;Or, was it mostest specific firster morely? (locate-library "subr" '(".elc.gz" ".elc") '("/home/MON/fnd-sbr") nil t) =3D> "/home/MON/fnd-sbr/subr.elc.gz" ;Now we know she's a compressed lib. ;; Example of current unpatched behavior: (apply 'locate-library "subr" '(nil nil t)) =3D> "/usr/share/emacs/23.1.90/lisp/subr.elc" ;Same as it ever was. ;; Now with the newest patch. ;; In following two examples we supply the NOSUFIX arg as proof of concept = that ;; NOPREFIX arg could find and filter the library file with suffix for each= of ;; the file suffixes: .el, .elc, .el.gz, .elc.gz ;; Example of an interactive call; (apply 'locate-library "subr" '(".el" nil t)) =3D> "/usr/share/emacs/23.1.90/lisp/subr" (apply 'locate-library "subr" '(".el.gz" nil t)) =3D> "/usr/share/emacs/23.1.90/lisp/subr" (apply 'locate-library "subr" '(".elc" nil t)) =3D> "/usr/share/emacs/23.1.90/lisp/subr" (apply 'locate-library "subr" '(".elc.gz" nil t)) =3D> "/usr/share/emacs/23.1.90/lisp/subr" ;; Example of an interactive call with NOPREFIX as prefix arg (apply 'locate-library "subr" '(t nil t)) =3D> "/usr/share/emacs/23.1.90/lisp/subr" ;; Example of an interactive call with SHOW-COMPRESSED as prefix arg. (apply 'locate-library "subr" '(".el.gz" nil t 2)) =3D> "/usr/share/emacs/23.1.90/lisp/subr.el.gz" ;; Example2 of interactive call with SHOW-COMPRESSED as prefix arg. (apply 'locate-library "subr" '(".elc.gz" nil t 2)) =3D> "/usr/share/emacs/23.1.90/lisp/subr.elc.gz" ;<- (assuming it exists) ;; Example3 of interactive call with SHOW-COMPRESSED as prefix arg. (apply 'locate-library "subr" '(nil nil t 2)) =3D> "/usr/share/emacs/23.1.90/lisp/subr" ;; Example4 of interactive call with SHOW-COMPRESSED as prefix-arg. ;; This example shows that even where we force finding ".elc" we can't make= it ;; return the library's file with a suffix. (apply 'locate-library "subr" '(".elc" nil t 2)) =3D> "/usr/share/emacs/23.1.90/lisp/subr" (let ((sfxs '(".bubba" ".el" ".elc" "" ".el.gz" ".elc.gz")) (in-paths '("/home/MON/fnd-sbr")) gthr-rslts tmp-rslts) (progn (push `(:booleans ,(dolist (l sfxs (setq show-libs (nreverse tmp-rslts))) (push (if (locate-library "subr" l in-paths) t nil) tmp-rslts))) gthr-rslts) (setq tmp-rslts nil) (push `(:paths-nocompress ,(dolist (l sfxs (setq show-libs (nreverse tmp-rslts))) (push (locate-library "subr" l in-paths) tmp-rslts))) gthr-rslts) (setq tmp-rslts nil) (push `(:paths-w-compress ,(dolist (l sfxs (setq show-libs (nreverse tmp-rslts))) (push (locate-library "subr" l in-paths nil t) tmp-rsl= ts))) gthr-rslts) (setq gthr-rslts (nreverse gthr-rslts)))) ;: :NOTE When empty string is provided to NOSUFFIX returns nil. ;; Nothing new about that. =3D> ((:booleans (nil t t nil t t)) (:paths-nocompress (nil "/home/MON/fnd-sbr/subr" "/home/MON/fnd-sbr/subr" nil "/home/MON/fnd-sbr/subr" "/home/MON/fnd-sbr/subr")) (:paths-w-compress (nil "/home/MON/fnd-sbr/subr" "/home/MON/fnd-sbr/subr" nil "/home/MON/fnd-sbr/subr.el.gz" "/home/MON/fnd-sbr/subr.elc.gz"))) ;; This last example illustrates that as we know the argument(s) to NOSUFFI= X one ;; can now use `locate-library' to actually find a _precise_ library filename(s). ;;; =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D --- subr.el~99304~ 2010-01-19 15:34:00.000000000 -0500 +++ subr.el 2010-01-21 16:39:46.000000000 -0500 @@ -1564,7 +1564,7 @@ (setq files (cdr files))) file))) -(defun locate-library (library &optional nosuffix path interactive-call) +(defun locate-library (library &optional nosuffix path interactive-call show-compressed) "Show the precise file name of Emacs library LIBRARY. LIBRARY should be a relative file name of the library, a string. It can omit the suffix (a.k.a. file-name extension) if NOSUFFIX is @@ -1585,17 +1585,37 @@ 'locate-file-completion-table load-path (get-load-suffixes))) nil nil - t)) - (let ((file (locate-file library - (or path load-path) - (append (unless nosuffix (get-load-suffixes)) - load-file-rep-suffixes)))) + t (if current-prefix-arg t))) + (let* ((lfrs (remove "" load-file-rep-suffixes)) + (sfx (cond ((booleanp nosuffix) + (delete-dups (append lfrs (get-load-suffixes)))) + ((and nosuffix (stringp nosuffix)) + `(,nosuffix + ,@(mapcar #'(lambda (z) + (concat nosuffix z)) + lfrs))) + ((consp nosuffix) + (delete-dups (append nosuffix lfrs))) + (t (append lfrs(get-load-suffixes))))) + (file (locate-file library + (or path load-path) + sfx))) + (when (and file (or nosuffix (and show-compressed (not nosuffix)))) + (setq file (file-truename file)) + (let ((smp-gz (string-match-p ".*.gz" file))) + (setq file (concat (file-name-directory file) + (cond ((or (not show-compressed) + (and show-compressed (not smp-gz))) + (file-name-sans-extension + (file-name-nondirectory + (file-name-sans-extension file)))) + ((or (and show-compressed smp-gz) t) + (file-name-nondirectory file))))))) (if interactive-call - (if file - (message "Library is file %s" (abbreviate-file-name file)) - (message "No library %s in search path" library))) + (if file + (message "Library is file %s" (abbreviate-file-name file)) + (message "No library %s in search path" library))) file)) - =0C ;;;; Specifying things to do later. --000e0cd358d2fb6eeb047db579e2 Content-Type: application/octet-stream; name="subr.el.diff2" Content-Disposition: attachment; filename="subr.el.diff2" Content-Transfer-Encoding: base64 X-Attachment-Id: f_g4q77dyl0 LS0tIHN1YnIuZWx+OTkzMDR+CTIwMTAtMDEtMTkgMTU6MzQ6MDAuMDAwMDAwMDAwIC0wNTAwCisr KyBzdWJyLmVsCTIwMTAtMDEtMjEgMTY6Mzk6NDYuMDAwMDAwMDAwIC0wNTAwCkBAIC0xNTY0LDcg KzE1NjQsNyBAQAogCShzZXRxIGZpbGVzIChjZHIgZmlsZXMpKSkKICAgICAgIGZpbGUpKSkKIAot KGRlZnVuIGxvY2F0ZS1saWJyYXJ5IChsaWJyYXJ5ICZvcHRpb25hbCBub3N1ZmZpeCBwYXRoIGlu dGVyYWN0aXZlLWNhbGwpCisoZGVmdW4gbG9jYXRlLWxpYnJhcnkgKGxpYnJhcnkgJm9wdGlvbmFs IG5vc3VmZml4IHBhdGggaW50ZXJhY3RpdmUtY2FsbCBzaG93LWNvbXByZXNzZWQpCiAgICJTaG93 IHRoZSBwcmVjaXNlIGZpbGUgbmFtZSBvZiBFbWFjcyBsaWJyYXJ5IExJQlJBUlkuCiBMSUJSQVJZ IHNob3VsZCBiZSBhIHJlbGF0aXZlIGZpbGUgbmFtZSBvZiB0aGUgbGlicmFyeSwgYSBzdHJpbmcu CiBJdCBjYW4gb21pdCB0aGUgc3VmZml4IChhLmsuYS4gZmlsZS1uYW1lIGV4dGVuc2lvbikgaWYg Tk9TVUZGSVggaXMKQEAgLTE1ODUsMTcgKzE1ODUsMzcgQEAKICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICdsb2NhdGUtZmlsZS1jb21wbGV0aW9uLXRhYmxlCiAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsb2FkLXBhdGggKGdldC1sb2FkLXN1ZmZp eGVzKSkpCiAJCSAgICAgbmlsIG5pbAotCQkgICAgIHQpKQotICAobGV0ICgoZmlsZSAobG9jYXRl LWZpbGUgbGlicmFyeQotCQkJICAgKG9yIHBhdGggbG9hZC1wYXRoKQotCQkJICAgKGFwcGVuZCAo dW5sZXNzIG5vc3VmZml4IChnZXQtbG9hZC1zdWZmaXhlcykpCi0JCQkJICAgbG9hZC1maWxlLXJl cC1zdWZmaXhlcykpKSkKKwkJICAgICB0IChpZiBjdXJyZW50LXByZWZpeC1hcmcgdCkpKQorICAo bGV0KiAoKGxmcnMgKHJlbW92ZSAiIiBsb2FkLWZpbGUtcmVwLXN1ZmZpeGVzKSkKKyAgICAgICAg IChzZnggIChjb25kICgoYm9vbGVhbnAgbm9zdWZmaXgpCisgICAgICAgICAgICAgICAgICAgICAg KGRlbGV0ZS1kdXBzIChhcHBlbmQgbGZycyAoZ2V0LWxvYWQtc3VmZml4ZXMpKSkpCisgICAgICAg ICAgICAgICAgICAgICAoKGFuZCBub3N1ZmZpeCAoc3RyaW5ncCBub3N1ZmZpeCkpCisgICAgICAg ICAgICAgICAgICAgICAgYCgsbm9zdWZmaXggCisgICAgICAgICAgICAgICAgICAgICAgICAsQCht YXBjYXIgIycobGFtYmRhICh6KQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAoY29uY2F0IG5vc3VmZml4IHopKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg IGxmcnMpKSkKKyAgICAgICAgICAgICAgICAgICAgICgoY29uc3Agbm9zdWZmaXgpCisgICAgICAg ICAgICAgICAgICAgICAgKGRlbGV0ZS1kdXBzIChhcHBlbmQgbm9zdWZmaXggbGZycykpKQorICAg ICAgICAgICAgICAgICAgICAgKHQgKGFwcGVuZCAgbGZycyhnZXQtbG9hZC1zdWZmaXhlcykpKSkp CisgICAgICAgICAoZmlsZSAobG9jYXRlLWZpbGUgbGlicmFyeQorICAgICAgICAgICAgICAgICAg ICAgICAgICAgIChvciBwYXRoIGxvYWQtcGF0aCkKKyAgICAgICAgICAgICAgICAgICAgICAgICAg ICBzZngpKSkKKyAgICAod2hlbiAoYW5kIGZpbGUgKG9yIG5vc3VmZml4IChhbmQgc2hvdy1jb21w cmVzc2VkIChub3Qgbm9zdWZmaXgpKSkpCisgICAgICAoc2V0cSBmaWxlIChmaWxlLXRydWVuYW1l IGZpbGUpKQorICAgICAgKGxldCAoKHNtcC1neiAoc3RyaW5nLW1hdGNoLXAgIi4qLmd6IiBmaWxl KSkpCisgICAgICAgIChzZXRxIGZpbGUgKGNvbmNhdCAoZmlsZS1uYW1lLWRpcmVjdG9yeSBmaWxl KQorICAgICAgICAgICAgICAgICAgICAgICAgICAgKGNvbmQgKChvciAobm90IHNob3ctY29tcHJl c3NlZCkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGFuZCBzaG93LWNv bXByZXNzZWQgKG5vdCBzbXAtZ3opKSkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAoZmlsZS1uYW1lLXNhbnMtZXh0ZW5zaW9uCisgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgIChmaWxlLW5hbWUtbm9uZGlyZWN0b3J5IAorICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgKGZpbGUtbmFtZS1zYW5zLWV4dGVuc2lvbiBmaWxlKSkpKQorICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgKChvciAoYW5kIHNob3ctY29tcHJlc3NlZCBzbXAtZ3op IHQpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGZpbGUtbmFtZS1ub25kaXJl Y3RvcnkgZmlsZSkpKSkpKSkKICAgICAoaWYgaW50ZXJhY3RpdmUtY2FsbAotCShpZiBmaWxlCi0J ICAgIChtZXNzYWdlICJMaWJyYXJ5IGlzIGZpbGUgJXMiIChhYmJyZXZpYXRlLWZpbGUtbmFtZSBm aWxlKSkKLQkgIChtZXNzYWdlICJObyBsaWJyYXJ5ICVzIGluIHNlYXJjaCBwYXRoIiBsaWJyYXJ5 KSkpCisgICAgICAgIChpZiBmaWxlCisgICAgICAgICAgICAobWVzc2FnZSAiTGlicmFyeSBpcyBm aWxlICVzIiAoYWJicmV2aWF0ZS1maWxlLW5hbWUgZmlsZSkpCisgICAgICAgICAgICAobWVzc2Fn ZSAiTm8gbGlicmFyeSAlcyBpbiBzZWFyY2ggcGF0aCIgbGlicmFyeSkpKQogICAgIGZpbGUpKQot CiAMCiA7Ozs7IFNwZWNpZnlpbmcgdGhpbmdzIHRvIGRvIGxhdGVyLgogCg== --000e0cd358d2fb6eeb047db579e2--