From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 17146 invoked by alias); 9 Jan 2012 00:25:39 -0000 Mailing-List: contact zsh-workers-help@zsh.org; run by ezmlm Precedence: bulk X-No-Archive: yes List-Id: Zsh Workers List List-Post: List-Help: X-Seq: 30103 Received: (qmail 25866 invoked from network); 9 Jan 2012 00:25:35 -0000 X-Spam-Checker-Version: SpamAssassin 3.3.2 (2011-06-06) on f.primenet.com.au X-Spam-Level: X-Spam-Status: No, score=-1.6 required=5.0 tests=BAYES_00,DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED,FREEMAIL_FROM,NML_ADSP_CUSTOM_MED,RCVD_IN_DNSWL_LOW, T_DKIM_INVALID,T_TO_NO_BRKTS_FREEMAIL autolearn=no version=3.3.2 Received-SPF: pass (ns1.primenet.com.au: SPF record at _spf.google.com designates 209.85.213.171 as permitted sender) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=mime-version:in-reply-to:references:date:message-id:subject:from:to :content-type; bh=JNgcH3mMod0IZNRNYJtKsD+xVc5RT3jcxNN+wqA9XKg=; b=dXfSv7dUVRTkGpLfI3RkWh3i0NXbSfdGE+gmJxlvJe+2r2MZPqcNBc1oCuJ/ycMZbf xLqrnzB6wMmKXePBwpEFO0P5I2Cv3pPq7l+WEJJ+0YjbYD7HPg0au5I0cYDeODV0vl1X 9MWhzrNW+nRMR/Wb23pYlHS3H/fBQhmlVv/Ks= MIME-Version: 1.0 In-Reply-To: <20120104173844.34681459@pws-pc.ntlworld.com> References: <20111221113947.75942dd8@pwslap01u.europe.root.pri> <20120104173844.34681459@pws-pc.ntlworld.com> Date: Sun, 8 Jan 2012 16:20:20 -0800 Message-ID: Subject: Re: Adding tests for zle? The missing X series tests From: Felix Rosencrantz To: zsh-workers@zsh.org Content-Type: multipart/mixed; boundary=20cf303b3b972d920e04b60d5d66 --20cf303b3b972d920e04b60d5d66 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable I've attached draft versions of the incremental search tests, based on the suggestions of Bart and Peter. I just added on Peter's latest change, previously I was using a hard coded escape sequence. The zletest file is based on comptest, and includes debugging code. The test is flaky, so there might be some buffering issues, or I'm not properly reseting the state between tests. (Or just confused on what to expect...) If you are interested in seeing what it does, you can add these under the Test directory and run: make TESTNUM=3DX check I would be interest in any feedback. These are still draft condition, but might be of interest to anyone following this thread. -FR On Wed, Jan 4, 2012 at 9:38 AM, Peter Stephenson wrote: > On Wed, 21 Dec 2011 11:39:47 +0000 > Peter Stephenson wrote: >> Probably easier is to intercept the terminal output at a low-level >> inside the shell by having an option that directly outputs values from >> an associative array with termcap codes as keys (this doesn't need to be >> particularly user-friendly, and as zsh internally still uses termcap >> codes this looks like the easiest way to test it) instead of using the >> termcap output functions. =A0That shouldn't be too much work --- termcap >> is vastly simpler than e.g. curses --- and makes the job no harder (!) >> than testing completion. =A0There are also potential uses for this in >> debugging --- it should provide a simpler method of finding out what has >> caused the cursor to end up where it did. > > A function both makes this flexible and allows you to handle all termcap > entries uniformly. > > I've done this by adding a generic command for zle transformations, but > I don't know that we'll ever use this for anything else. > > Try > > tcfunc() { > =A0if [[ -n $2 ]]; then > =A0 =A0REPLY=3D"" > =A0else > =A0 =A0REPLY=3D"" > fi > } > zle -T tc tcfunc > > and > > zle -Tr tc > > to turn it off (your typing had better be accurate). > > There's a completely irrelevant zsfree(argzero) snuck in because I was > too lazy to separate it. =A0This stops a valgrind warning in some cases > (it's a very minor leak since it only happens once at the start). > > Index: Doc/Zsh/zle.yo > =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=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=3D=3D=3D=3D=3D=3D=3D > RCS file: /cvsroot/zsh/zsh/Doc/Zsh/zle.yo,v > retrieving revision 1.95 > diff -p -u -r1.95 zle.yo > --- Doc/Zsh/zle.yo =A0 =A0 =A04 Nov 2011 14:14:27 -0000 =A0 =A0 =A0 1.95 > +++ Doc/Zsh/zle.yo =A0 =A0 =A04 Jan 2012 17:32:13 -0000 > @@ -370,6 +370,7 @@ xitem(tt(zle) tt(-U) var(string)) > =A0xitem(tt(zle) tt(-K) var(keymap)) > =A0xitem(tt(zle) tt(-F) [ tt(-L) ] [ var(fd) [ var(handler) ] ]) > =A0xitem(tt(zle) tt(-I)) > +xitem(tt(zle) tt(-T) [ tt(tc) var(function) | tt(-r) tt(tc) | tt(-L) ] ) > =A0item(tt(zle) var(widget) tt([ -n) var(num) tt(]) tt([ -Nw ] [ -K) var(= keymap) tt(]) var(args) ...)( > =A0The tt(zle) builtin performs a number of different actions concerning > =A0ZLE. > @@ -572,6 +573,33 @@ this may have been by a previous call to > =A0notification. =A0To test if a zle widget may be called at this point, = execute > =A0tt(zle) with no arguments and examine the return status. > =A0) > +item(tt(-T))( > +This is used to add, list or remove internal transformations on the > +processing performed by the line editor. =A0It is typically used only fo= r > +debugging or testing and is therefore of little interest to the general > +user. > + > +`tt(zle -T) var(transformation) var(func)' specifies that the > +given var(transformation) (see below) is effected by shell function > +var(func). > + > +`tt(zle -Tr) var(transformation)' removes the given var(transformation) > +if it was present (it is not an error if none was). > + > +`tt(zle -TL)' can be used to list all transformations currently in > +operation. > + > +Currently the only transformation is tt(tc). =A0This is used instead > +of outputting termcap codes to the terminal. =A0When the transformation = is > +in operation the shell function is passed the termcap code that would be > +output as its first argument; if the operation required a numeric > +argument, that is passed as a second argument. =A0The function should se= t > +the shell variable tt(REPLY) to the transformed termcap code. =A0Typical= ly > +this is used to produce some simply formatted version of the code and > +optional argument for debugging or testing. =A0Note that this > +transformation is not applied to other non-printing characters such as > +carriage returns and newlines. > +) > =A0item(var(widget) tt([ -n) var(num) tt(]) tt([ -Nw ] [ -K) var(keymap) = tt(]) var(args) ...)( > =A0Invoke the specified widget. =A0This can only be done when ZLE is > =A0active; normally this will be within a user-defined widget. > Index: Src/init.c > =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=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=3D=3D=3D=3D=3D=3D=3D > RCS file: /cvsroot/zsh/zsh/Src/init.c,v > retrieving revision 1.120 > diff -p -u -r1.120 init.c > --- Src/init.c =A09 May 2011 09:49:09 -0000 =A0 =A0 =A0 1.120 > +++ Src/init.c =A04 Jan 2012 17:32:14 -0000 > @@ -558,6 +558,19 @@ static char *tccapnams[TC_COUNT] =3D { > =A0 =A0 "ku", "kd", "kl", "kr", "sc", "rc", "bc", "AF", "AB" > =A0}; > > +/**/ > +mod_export char * > +tccap_get_name(int cap) > +{ > + =A0 =A0if (cap >=3D TC_COUNT) { > +#ifdef DEBUG > + =A0 =A0 =A0 dputs("name of invalid capability %d requested", cap); > +#endif > + =A0 =A0 =A0 return ""; > + =A0 =A0} > + =A0 =A0return tccapnams[cap]; > +} > + > =A0/* Initialise termcap */ > > =A0/**/ > @@ -978,6 +991,7 @@ setupshin(char *runscript) > =A0 =A0 =A0 =A0 =A0 =A0exit(127); > =A0 =A0 =A0 =A0} > =A0 =A0 =A0 =A0scriptfilename =3D sfname; > + =A0 =A0 =A0 zsfree(argzero); /* ztrdup'd in parseargs */ > =A0 =A0 =A0 =A0argzero =3D runscript; > =A0 =A0 } > =A0 =A0 /* > Index: Src/Zle/zle_main.c > =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=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=3D=3D=3D=3D=3D=3D=3D > RCS file: /cvsroot/zsh/zsh/Src/Zle/zle_main.c,v > retrieving revision 1.131 > diff -p -u -r1.131 zle_main.c > --- Src/Zle/zle_main.c =A02 Jan 2012 19:31:16 -0000 =A0 =A0 =A0 1.131 > +++ Src/Zle/zle_main.c =A04 Jan 2012 17:32:14 -0000 > @@ -1927,7 +1927,7 @@ zle_main_entry(int cmd, va_list ap) > =A0static struct builtin bintab[] =3D { > =A0 =A0 BUILTIN("bindkey", 0, bin_bindkey, 0, -1, 0, "evaM:ldDANmrsLRp", = NULL), > =A0 =A0 BUILTIN("vared", =A0 0, bin_vared, =A0 1, =A01, 0, "aAcehM:m:p:r:= t:", NULL), > - =A0 =A0BUILTIN("zle", =A0 =A0 0, bin_zle, =A0 =A0 0, -1, 0, "aAcCDFgGIK= lLmMNRU", NULL), > + =A0 =A0BUILTIN("zle", =A0 =A0 0, bin_zle, =A0 =A0 0, -1, 0, "aAcCDFgGIK= lLmMNrRTU", NULL), > =A0}; > > =A0/* The order of the entries in this table has to match the *HOOK > Index: Src/Zle/zle_refresh.c > =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=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=3D=3D=3D=3D=3D=3D=3D > RCS file: /cvsroot/zsh/zsh/Src/Zle/zle_refresh.c,v > retrieving revision 1.88 > diff -p -u -r1.88 zle_refresh.c > --- Src/Zle/zle_refresh.c =A0 =A0 =A0 17 Aug 2011 10:15:50 -0000 =A0 =A0 = =A01.88 > +++ Src/Zle/zle_refresh.c =A0 =A0 =A0 4 Jan 2012 17:32:14 -0000 > @@ -233,6 +233,12 @@ int n_region_highlights; > =A0/**/ > =A0int region_active; > > +/* > + * Name of function to use to output termcap values, if defined. > + */ > +/**/ > +char *tcout_func_name; > + > =A0#ifdef HAVE_SELECT > =A0/* cost of last update */ > =A0/**/ > @@ -2271,11 +2277,78 @@ tc_downcurs(int ct) > =A0 =A0 return ret; > =A0} > > +/* > + * Output a termcap value using a function defined by "zle -T tc". > + * Loosely inspired by subst_string_by_func(). > + * > + * cap is the internal index for the capability; it will be looked up > + * in the table and the string passed to the function. > + * > + * arg is eithr an argument to the capability or -1 if there is none; > + * if it is not -1 it will be passed as an additional argument to the > + * function. > + * > + * outc is the output function; currently this is always putshout > + * but in principle it may be used to output to a string. > + */ > + > +/**/ > +static void > +tcout_via_func(int cap, int arg, int (*outc)(int)) > +{ > + =A0 =A0Shfunc tcout_func; > + =A0 =A0int osc, osm, old_incompfunc; > + > + =A0 =A0osc =3D sfcontext; > + =A0 =A0osm =3D stopmsg; > + =A0 =A0old_incompfunc =3D incompfunc; > + > + =A0 =A0sfcontext =3D SFC_SUBST; > + =A0 =A0incompfunc =3D 0; > + > + =A0 =A0if ((tcout_func =3D getshfunc(tcout_func_name))) { > + =A0 =A0 =A0 LinkList l =3D newlinklist(); > + =A0 =A0 =A0 char buf[DIGBUFSIZE], *str; > + > + =A0 =A0 =A0 addlinknode(l, tcout_func_name); > + =A0 =A0 =A0 addlinknode(l, tccap_get_name(cap)); > + > + =A0 =A0 =A0 if (arg !=3D -1) { > + =A0 =A0 =A0 =A0 =A0 sprintf(buf, "%d", arg); > + =A0 =A0 =A0 =A0 =A0 addlinknode(l, buf); > + =A0 =A0 =A0 } > + > + =A0 =A0 =A0 (void)doshfunc(tcout_func, l, 1); > + > + =A0 =A0 =A0 str =3D getsparam("REPLY"); > + =A0 =A0 =A0 if (str) { > + =A0 =A0 =A0 =A0 =A0 while (*str) { > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 int chr; > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 if (*str =3D=3D Meta) { > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 chr =3D str[1] ^ 32; > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 str +=3D 2; > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 } else { > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 chr =3D *str++; > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 } > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 (void)outc(chr); > + =A0 =A0 =A0 =A0 =A0 } > + =A0 =A0 =A0 } > + =A0 =A0} > + > + =A0 =A0sfcontext =3D osc; > + =A0 =A0stopmsg =3D osm; > + =A0 =A0incompfunc =3D old_incompfunc; > +} > + > =A0/**/ > =A0mod_export void > =A0tcout(int cap) > =A0{ > - =A0 =A0tputs(tcstr[cap], 1, putshout); > + =A0 =A0if (tcout_func_name) { > + =A0 =A0 =A0 tcout_via_func(cap, -1, putshout); > + =A0 =A0} else { > + =A0 =A0 =A0 tputs(tcstr[cap], 1, putshout); > + =A0 =A0} > =A0 =A0 SELECT_ADD_COST(tclen[cap]); > =A0} > > @@ -2286,7 +2359,11 @@ tcoutarg(int cap, int arg) > =A0 =A0 char *result; > > =A0 =A0 result =3D tgoto(tcstr[cap], arg, arg); > - =A0 =A0tputs(result, 1, putshout); > + =A0 =A0if (tcout_func_name) { > + =A0 =A0 =A0 tcout_via_func(cap, arg, putshout); > + =A0 =A0} else { > + =A0 =A0 =A0 tputs(result, 1, putshout); > + =A0 =A0} > =A0 =A0 SELECT_ADD_COST(strlen(result)); > =A0} > > Index: Src/Zle/zle_thingy.c > =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=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=3D=3D=3D=3D=3D=3D=3D > RCS file: /cvsroot/zsh/zsh/Src/Zle/zle_thingy.c,v > retrieving revision 1.35 > diff -p -u -r1.35 zle_thingy.c > --- Src/Zle/zle_thingy.c =A0 =A0 =A0 =A04 Nov 2011 14:14:27 -0000 =A0 =A0= =A0 1.35 > +++ Src/Zle/zle_thingy.c =A0 =A0 =A0 =A04 Jan 2012 17:32:14 -0000 > @@ -353,6 +353,7 @@ bin_zle(char *name, char **args, Options > =A0 =A0 =A0 =A0{ 'K', bin_zle_keymap, 1, 1 }, > =A0 =A0 =A0 =A0{ 'I', bin_zle_invalidate, 0, 0 }, > =A0 =A0 =A0 =A0{ 'F', bin_zle_fd, 0, 2 }, > + =A0 =A0 =A0 { 'T', bin_zle_transform, 0, 2}, > =A0 =A0 =A0 =A0{ 0, =A0 bin_zle_call, 0, -1 }, > =A0 =A0 }; > =A0 =A0 struct opn const *op, *opp; > @@ -856,6 +857,69 @@ bin_zle_fd(char *name, char **args, Opti > =A0 =A0 return 0; > =A0} > > +/**/ > +static int > +bin_zle_transform(char *name, char **args, Options ops, UNUSED(char func= )) > +{ > + =A0 =A0/* > + =A0 =A0 * -1: too few arguments > + =A0 =A0 * 0: just right > + =A0 =A0 * 1: too many arguments > + =A0 =A0 * 2: first argument not recognised > + =A0 =A0 */ > + =A0 =A0int badargs =3D 0; > + > + =A0 =A0if (OPT_ISSET(ops,'L')) { > + =A0 =A0 =A0 if (args[0]) { > + =A0 =A0 =A0 =A0 =A0 if (args[1]) { > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 badargs =3D 1; > + =A0 =A0 =A0 =A0 =A0 } else if (strcmp(args[0], "tc")) { > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 badargs =3D 2; > + =A0 =A0 =A0 =A0 =A0 } > + =A0 =A0 =A0 } > + =A0 =A0 =A0 if (!badargs && tcout_func_name) { > + =A0 =A0 =A0 =A0 =A0 fputs("zle -T tc ", stdout); > + =A0 =A0 =A0 =A0 =A0 quotedzputs(tcout_func_name, stdout); > + =A0 =A0 =A0 =A0 =A0 putchar('\n'); > + =A0 =A0 =A0 } > + =A0 =A0} else if (OPT_ISSET(ops,'r')) { > + =A0 =A0 =A0 if (!args[0]) { > + =A0 =A0 =A0 =A0 =A0 badargs =3D -1; > + =A0 =A0 =A0 } else if (args[1]) { > + =A0 =A0 =A0 =A0 =A0 badargs =3D 1; > + =A0 =A0 =A0 } else if (tcout_func_name) { > + =A0 =A0 =A0 =A0 =A0 zsfree(tcout_func_name); > + =A0 =A0 =A0 =A0 =A0 tcout_func_name =3D NULL; > + =A0 =A0 =A0 } > + =A0 =A0} else { > + =A0 =A0 =A0 if (!args[0] || !args[1]) { > + =A0 =A0 =A0 =A0 =A0 badargs =3D -1; > + =A0 =A0 =A0 =A0 =A0 /* we've already checked args <=3D 2 */ > + =A0 =A0 =A0 } else { > + =A0 =A0 =A0 =A0 =A0 if (!strcmp(args[0], "tc")) { > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 if (tcout_func_name) { > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 zsfree(tcout_func_name); > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 } > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 tcout_func_name =3D ztrdup(args[1]); > + =A0 =A0 =A0 =A0 =A0 } else { > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 badargs =3D 2; > + =A0 =A0 =A0 =A0 =A0 } > + =A0 =A0 =A0 } > + =A0 =A0} > + > + =A0 =A0if (badargs) { > + =A0 =A0 =A0 if (badargs =3D=3D 2) { > + =A0 =A0 =A0 =A0 =A0 zwarnnam(name, "-T: no such transformation '%s'", a= rgs[0]); > + =A0 =A0 =A0 } else { > + =A0 =A0 =A0 =A0 =A0 char *way =3D (badargs > 0) ? "many" : "few"; > + =A0 =A0 =A0 =A0 =A0 zwarnnam(name, "too %s arguments for option -T", wa= y); > + =A0 =A0 =A0 } > + =A0 =A0 =A0 return 1; > + =A0 =A0} > + > + =A0 =A0return 0; > +} > + > =A0/*******************/ > =A0/* initialiasation */ > =A0/*******************/ --20cf303b3b972d920e04b60d5d66 Content-Type: application/octet-stream; name="X01isearch.ztst" Content-Disposition: attachment; filename="X01isearch.ztst" Content-Transfer-Encoding: base64 X-Attachment-Id: f_gx6qt2rc0 JXByZXAKICBpZiAoIHptb2Rsb2FkIC1pIHpzaC96cHR5ICkgPi9kZXYvbnVsbCAyPiYxOyB0aGVu CiAgICAuICRaVFNUX3NyY2Rpci96bGV0ZXN0CiAgICBta2RpciB6bGUudG1wCiAgICBjZCB6bGUu dG1wCiAgICB6bGV0ZXN0aW5pdCAteiAkWlRTVF90ZXN0ZGlyLy4uL1NyYy96c2gKICBlbHNlCiAg ICBaVFNUX3VuaW1wbGVtZW50ZWQ9InRoZSB6c2gvenB0eSBtb2R1bGUgaXMgbm90IGF2YWlsYWJs ZSIKICBmaQoKJXRlc3QKIyBUZXN0cyB0byBhZGQ6CiMgIGNhc2UtaW5zZXNpdGl2aXR5CiMgIGln bm9yaW5nIGR1cGxpY2F0ZSBsaW5lcwojICBzcGVjaWFsIGtleXMKCiMgRG9lc24ndCB3b3JrLCBm aW5hbCBwcm9tcHQgaXMgZW1wdHksIHNpbmNlIGNvbW1hbmQgcmFuOgojIHpsZXRlc3RldmFsICdm YyAtUiBoaXN0b3J5WDAxJwojIHpsZXRlc3QgJCdmYyAtbCAtM1xuJwojMHE6VmVyaWZ5IGluY3Jl bWVudGFsIHNlYXJjaAoKIHpsZXRlc3RldmFsICdmYyAtUiBoaXN0b3J5WDAxJwogemxldGVzdCAk J1xDLVJhYmMnCjBxOlZlcmlmeSBpbmNyZW1lbnRhbCBzZWFyY2ggZmlyc3QgbWF0Y2gKPmVjaG8g PEZHIDI+PEJHIDE+YWJjPEZHIDk+PEJHIDk+Cj5iY2staS1zZWFyY2g6IGFiY18KCiB6bGV0ZXN0 ZXZhbCAnZmMgLVIgaGlzdG9yeVgwMScKIHpsZXRlc3QgJCdcQy1SYWJjZFxDLUgnCjBxOlZlcmlm eSBpbmNyZW1lbnRhbCBzZWFyY2ggZmlyc3QgbWF0Y2ggdmlhIGJhY2tzcGFjZQo+ZWNobyA8Rkcg Mj48QkcgMT5hYmM8RkcgOT48QkcgOT4KPmJjay1pLXNlYXJjaDogYWJjXwoKIHpsZXRlc3RldmFs ICdmYyAtUiBoaXN0b3J5WDAxJwogemxldGVzdCAkJ1xuXEMtUmFiY1xDLVInCjBxOlZlcmlmeSBp bmNyZW1lbnRhbCBzZWFyY2ggc2Vjb25kIG1hdGNoCj5lY2hvIGFiYyA8RkcgMj48QkcgMT5hYmM8 RkcgOT48QkcgOT5kZWYKPmJjay1pLXNlYXJjaDogYWJjXwoKIHpsZXRlc3RldmFsICdmYyAtUiBo aXN0b3J5WDAxJwogemxldGVzdCAkJ1xDLVJhYmNcQy1SXEMtUicKMHE6VmVyaWZ5IGluY3JlbWVu dGFsIHNlYXJjaCB0aGlyZCBtYXRjaAo+ZWNobyA8RkcgMj48QkcgMT5hYmM8RkcgOT48QkcgOT4g YWJjZGVmCj5iY2staS1zZWFyY2g6IGFiY18KCiB6bGV0ZXN0ZXZhbCAnZmMgLVIgaGlzdG9yeVgw MScKIHpsZXRlc3QgJCdcQy1SYWJjXEMtUlxDLVJcQy1SJwowcTpWZXJpZnkgaW5jcmVtZW50YWwg c2VhcmNoIGZvdXJ0aCBtYXRjaAo+ZWNobyAxMjMgPEZHIDI+PEJHIDE+YWJjPEZHIDk+PEJHIDk+ Cj5iY2staS1zZWFyY2g6IGFiY18KCiB6bGV0ZXN0ZXZhbCAnZmMgLVIgaGlzdG9yeVgwMScKIHps ZXRlc3QgJCdcQy1SYWJjXEMtUlxDLVJcQy1SXEMtUicKMHE6VmVyaWZ5IGluY3JlbWVudGFsIHNl YXJjaCBmYWlsZWQgZmlmdGggbWF0Y2gKPmVjaG8gMTIzIGFiYwo+ZmFpbGluZyBiY2staS1zZWFy Y2g6IGFiY18KCiB6bGV0ZXN0ZXZhbCAnZmMgLVIgaGlzdG9yeVgwMScKIHpsZXRlc3QgJCdcQy1S YWJjXEMtUlxDLVJcQy1SZCcKMHE6VmVyaWZ5IGluY3JlbWVudGFsIHNlYXJjaCBwYXNzIHNvbWV0 aGluZyAKPmVjaG8gMTIzIGFiYwo+ZmFpbGluZyBiY2staS1zZWFyY2g6IGFiY2RfCgogemxldGVz dGV2YWwgJ2ZjIC1SIGhpc3RvcnlYMDEnCiB6bGV0ZXN0ICQnXEMtUmFiY1xDLVJcQy1SXEMtUmRc Qy1IXEMtSFxDLUhkJwowcTpWZXJpZnkgaW5jcmVtZW50YWwgc2VhcmNoIHBhc3MsIGJhY2t1cCwg YW5kIGZpbmQgYWdhaW4uCj5lY2hvIGFiYyA8RkcgMj48QkcgMT5hYmNkPEZHIDk+PEJHIDk+ZWYK PmJjay1pLXNlYXJjaDogYWJjZF8KCiB6bGV0ZXN0ZXZhbCAnZmMgLVIgaGlzdG9yeVgwMScKIHps ZXRlc3QgJCdcQy1SYWJjZFxDLVQnCjBxOlZlcmlmeSBpbmNyZW1lbnRhbCBzZWFyY2ggcGFzcywg dGhlbiB1c2Ugc2VhcmNoIGZvcndhcmQgdG8gZmluZC4KPmVjaG8gYWJjIDxGRyAyPjxCRyAxPmFi Y2Q8RkcgOT48QkcgOT5lZgo+ZndkLWktc2VhcmNoOiBhYmNkXwoKIHpsZXRlc3RldmFsICdmYyAt UiBoaXN0b3J5WDAxJwogemxldGVzdCAkJ1xDLVJeZGF0ZScKMHE6VmVyaWZ5IGluY3JlbWVudGFs IHNlYXJjaCBib2wgcGF0dGVybgo+PEZHIDI+PEJHIDE+ZGF0ZTxGRyA5PjxCRyA5Pgo+YmNrLWkt c2VhcmNoOiBeZGF0ZV8KCiB6bGV0ZXN0ZXZhbCAnZmMgLVIgaGlzdG9yeVgwMScKIHpsZXRlc3Qg JCdcQy1SXFwnCjBxOlZlcmlmeSBpbmNyZW1lbnRhbCBzZWFyY2ggYmFja3NsYXNoCj5lY2hvICc8 RkcgMj48QkcgMT5cPEZHIDk+PEJHIDk+bicKPmJjay1pLXNlYXJjaDogXF8KCiB6bGV0ZXN0ZXZh bCAnZmMgLVIgaGlzdG9yeVgwMScKIHpsZXRlc3QgJCdcQy1YUlxcKicKMHE6VmVyaWZ5IGluY3Jl bWVudGFsIHNlYXJjaCBiYWNrc2xhc2ggc3Rhcgo+ZWNobyAiKldIQVQ/PEZHIDI+PEJHIDE+KjxG RyA5PjxCRyA5PiIKPmJjay1pLXNlYXJjaDogXCpfCgojIyMjIyMjIyMjIyMjIGluY3JlbWVudGFs IHBhdHRlcm4gc2VhcmNoCgogemxldGVzdGV2YWwgJ2ZjIC1SIGhpc3RvcnlYMDEnCiB6bGV0ZXN0 ICQnXEMtWFJhYmMnCjBxOlZlcmlmeSBpbmNyZW1lbnRhbCBwYXR0ZXJuIHNlYXJjaCBmaXJzdCBt YXRjaAo+ZWNobyA8RkcgMj48QkcgMT5hYmM8RkcgOT48QkcgOT4KPmJjay1pLXNlYXJjaDogYWJj XwoKIHpsZXRlc3RldmFsICdmYyAtUiBoaXN0b3J5WDAxJwogemxldGVzdCAkJ1xDLVhSYWJjZFxD LUgnCjBxOlZlcmlmeSBpbmNyZW1lbnRhbCBwYXR0ZXJuIHNlYXJjaCBmaXJzdCBtYXRjaCB2aWEg YmFja3NwYWNlCj5lY2hvIDxGRyAyPjxCRyAxPmFiYzxGRyA5PjxCRyA5Pgo+YmNrLWktc2VhcmNo OiBhYmNfCgogemxldGVzdGV2YWwgJ2ZjIC1SIGhpc3RvcnlYMDEnCiB6bGV0ZXN0ICQnXG5cQy1Y UmFiY1xDLVhSJwowcTpWZXJpZnkgaW5jcmVtZW50YWwgcGF0dGVybiBzZWFyY2ggc2Vjb25kIG1h dGNoCj5lY2hvIGFiYyA8RkcgMj48QkcgMT5hYmM8RkcgOT48QkcgOT5kZWYKPmJjay1pLXNlYXJj aDogYWJjXwoKIHpsZXRlc3RldmFsICdmYyAtUiBoaXN0b3J5WDAxJwogemxldGVzdCAkJ1xDLVhS YWJjXEMtWFJcQy1YUicKMHE6VmVyaWZ5IGluY3JlbWVudGFsIHBhdHRlcm4gc2VhcmNoIHRoaXJk IG1hdGNoCj5lY2hvIDxGRyAyPjxCRyAxPmFiYzxGRyA5PjxCRyA5PiBhYmNkZWYKPmJjay1pLXNl YXJjaDogYWJjXwoKIHpsZXRlc3RldmFsICdmYyAtUiBoaXN0b3J5WDAxJwogemxldGVzdCAkJ1xD LVhSYWJjXEMtWFJcQy1YUlxDLVhSJwowcTpWZXJpZnkgaW5jcmVtZW50YWwgcGF0dGVybiBzZWFy Y2ggZm91cnRoIG1hdGNoCj5lY2hvIDEyMyA8RkcgMj48QkcgMT5hYmM8RkcgOT48QkcgOT4KPmJj ay1pLXNlYXJjaDogYWJjXwoKIHpsZXRlc3RldmFsICdmYyAtUiBoaXN0b3J5WDAxJwogemxldGVz dCAkJ1xDLVhSYWJjXEMtWFJcQy1YUlxDLVhSXEMtWFInCjBxOlZlcmlmeSBpbmNyZW1lbnRhbCBw YXR0ZXJuIHNlYXJjaCBmYWlsZWQgZmlmdGggbWF0Y2gKPmVjaG8gMTIzIGFiYwo+ZmFpbGluZyBi Y2staS1zZWFyY2g6IGFiY18KCiB6bGV0ZXN0ZXZhbCAnZmMgLVIgaGlzdG9yeVgwMScKIHpsZXRl c3QgJCdcQy1YUmFiY1xDLVhSXEMtWFJcQy1YUmQnCjBxOlZlcmlmeSBpbmNyZW1lbnRhbCBwYXR0 ZXJuIHNlYXJjaCBwYXNzIHNvbWV0aGluZyAKPmVjaG8gMTIzIGFiYwo+ZmFpbGluZyBiY2staS1z ZWFyY2g6IGFiY2RfCgogemxldGVzdGV2YWwgJ2ZjIC1SIGhpc3RvcnlYMDEnCiB6bGV0ZXN0ICQn XEMtWFJhYmNcQy1YUlxDLVhSXEMtWFJkXEMtSFxDLUhcQy1IZCcKMHE6VmVyaWZ5IGluY3JlbWVu dGFsIHBhdHRlcm4gc2VhcmNoIHBhc3MsIGJhY2t1cCwgYW5kIGZpbmQgYWdhaW4uCj5lY2hvIGFi YyA8RkcgMj48QkcgMT5hYmNkPEZHIDk+PEJHIDk+ZWYKPmJjay1pLXNlYXJjaDogYWJjZF8KCiB6 bGV0ZXN0ZXZhbCAnZmMgLVIgaGlzdG9yeVgwMScKIHpsZXRlc3QgJCdcQy1YUmFiY2RcQy1YVCcK MHE6VmVyaWZ5IGluY3JlbWVudGFsIHBhdHRlcm4gc2VhcmNoIHBhc3MsIHRoZW4gdXNlIHNlYXJj aCBmb3J3YXJkIHRvIGZpbmQuCj5lY2hvIGFiYyA8RkcgMj48QkcgMT5hYmNkPEZHIDk+PEJHIDk+ ZWYKPmZ3ZC1pLXNlYXJjaDogYWJjZF8KCiB6bGV0ZXN0ZXZhbCAnZmMgLVIgaGlzdG9yeVgwMScK IHpsZXRlc3QgJCdcQy1YUl5kYXRlJwowcTpWZXJpZnkgaW5jcmVtZW50YWwgcGF0dGVybiBzZWFy Y2ggYm9sIHBhdHRlcm4KIyMjPjxGRyAyPjxCRyAxPmRhdGU8RkcgOT48QkcgOT4KIyMjPmJjay1p LXNlYXJjaDogXmRhdGVfCgogemxldGVzdGV2YWwgJ2ZjIC1SIGhpc3RvcnlYMDEnCiB6bGV0ZXN0 ICQnXEMtWFJcXCcKMHE6VmVyaWZ5IGluY3JlbWVudGFsIHBhdHRlcm4gc2VhcmNoIGJhY2tzbGFz aAo+ZWNobyAnPEZHIDI+PEJHIDE+XDxGRyA5PjxCRyA5Pm4nCj5iY2staS1zZWFyY2g6IFxfCgog emxldGVzdGV2YWwgJ2ZjIC1SIGhpc3RvcnlYMDEnCiB6bGV0ZXN0ICQnXEMtWFJcXConCjBxOlZl cmlmeSBpbmNyZW1lbnRhbCBwYXR0ZXJuIHNlYXJjaCBiYWNrc2xhc2ggc3Rhcgo+ZWNobyAiKldI QVQ/PEZHIDI+PEJHIDE+KjxGRyA5PjxCRyA5PiIKPmJjay1pLXNlYXJjaDogXCpfCgolY2xlYW4K IyBUaGlzIG9wdGlvbmFsIHNlY3Rpb24gY2xlYW5zIHVwIGFmdGVyIHRoZSB0ZXN0LCBpZiBuZWNl c3NhcnksCiMgZS5nLiBraWxsaW5nIHByb2Nlc3NlcyBldGMuICBUaGlzIGlzIGluIGFkZGl0aW9u IHRvIHRoZSByZW1vdmFsIG9mICoudG1wCiMgc3ViZGlyZWN0b3JpZXMuICBUaGlzIGlzIGVzc2Vu dGlhbGx5IGxpa2UgJXByZXAsIGV4Y2VwdCB0aGF0IHN0YXR1cwojIHJldHVybiB2YWx1ZXMgYXJl IGlnbm9yZWQuCnptb2Rsb2FkIC11aSB6c2gvenB0eQo= --20cf303b3b972d920e04b60d5d66 Content-Type: application/octet-stream; name=zletest Content-Disposition: attachment; filename=zletest Content-Transfer-Encoding: base64 X-Attachment-Id: f_gx6qtt1z1 emxldGVzdGluaXQgKCkgewogIHNldG9wdCBleHRlbmRlZGdsb2IKICBbWyAtZCAkWlRTVF90ZXN0 ZGlyL01vZHVsZXMvenNoIF1dICYmIG1vZHVsZV9wYXRoPSggJFpUU1RfdGVzdGRpci9Nb2R1bGVz ICkKICBmcGF0aD0oICRaVFNUX3NyY2Rpci8uLi9GdW5jdGlvbnMvKn4qL0NWUygvKQogICAgICAg ICAgJFpUU1Rfc3JjZGlyLy4uL0NvbXBsZXRpb24KICAgICAgICAgICRaVFNUX3NyY2Rpci8uLi9D b21wbGV0aW9uLyovKn4qL0NWUygvKSApCgogIHptb2Rsb2FkIC1pIHpzaC96cHR5IHx8IHJldHVy biAkPwoKICB6bGV0ZXN0X3pzaD0ke1pTSDotenNofQoKICB3aGlsZSBnZXRvcHRzIHo6IG9wdDsg ZG8KICAgIGNhc2UgJG9wdCBpbgogICAgICB6KSB6bGV0ZXN0X3pzaD0iJE9QVEFSRyI7OwogICAg ZXNhYwogIGRvbmUKICAoKCBPUFRJTkQgPiAxICkpICYmIHNoaWZ0ICQoKCBPUFRJTkQgLSAxICkp CgogIGV4cG9ydCBQUzE9IjxQUk9NUFQ+IiBQUzI9IiIgUlBTMT0iIiBSUFMyPSIiCiAgenB0eSB6 c2ggIiR6bGV0ZXN0X3pzaCAtZiArWiIKCiAgenB0eSAtciB6c2ggbG9nMSAiKjxQUk9NUFQ+KiIg fHwgeyAKICAgIHByaW50ICJmaXJzdCBwcm9tcHQgaGFzbid0IGFwcGVhcmVkLiIKICAgIHJldHVy biAxCiAgfQoKICBjYXQgPiBoaXN0b3J5WDAxIDw8RU9GCmRhdGUKZWNobyB4eXogdGhyZWUKZWNo byB4eXogdHdvCmVjaG8gMTIzIGFiYwplY2hvIGFiYyBhYmNkZWYKZWNobyBhYmMKZWNobyB4eXoK ZWNobyBkYXRlCmVjaG8gJypPSCBOTyonICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAplY2hvICdcbicKZWNobyAi KldIQVQ/KiIKRU9GCgogIHpsZXRlc3RldmFsIFwKImV4cG9ydCBMQ19BTEw9QyIgXAoiZW11bGF0 ZSAtUiB6c2giIFwKImV4cG9ydCBaRE9URElSPSRaVFNUX3Rlc3RkaXIiIFwKIm1vZHVsZV9wYXRo PSggJG1vZHVsZV9wYXRoICkiIFwKImZwYXRoPSggJGZwYXRoICkiIFwKInpsZV9oaWdobGlnaHQ9 KGJnX3N0YXJ0X2NvZGU6J1w8QkcgJyBiZ19lbmRfY29kZTonXD4nIGZnX3N0YXJ0X2NvZGU6J1w8 RkcgJyBmZ19lbmRfY29kZTonXD4nIGlzZWFyY2g6Ymc9MSxmZz0yKSIgXAonTElTVE1BWD0xMDAw MDAwMApURVJNPXZ0MTAwCnN0dHkgY29sdW1ucyAyNTYgcm93cyAyNDAKc2V0b3B0IHpsZQpiaW5k a2V5IC1lCnRjZnVuYygpIHsKIGlmIFtbIC1uICQyIF1dOyB0aGVuCiAgIFJFUExZPSI8dGM9JDEs YXJnPSQyPiIKIGVsc2UKICAgUkVQTFk9Ijx0Yz0kMT4iCmZpCn0KemxlIC1UIHRjIHRjZnVuYwpm aW5pc2ggKCkgewogIHpsZSBraWxsLXdob2xlLWxpbmUKICB6bGUga2lsbC13aG9sZS1saW5lCiAg emxlIGNsZWFyLXNjcmVlbgogIHByaW50ICI8ZmluaXNoPiIKICB6bGUgLVIKfQp6bGUgLU4gZmlu aXNoCmJpbmRrZXkgIl5aIiBmaW5pc2gKYmluZGtleSAiXlQiIGhpc3RvcnktaW5jcmVtZW50YWwt c2VhcmNoLWZvcndhcmQKYmluZGtleSAiXlhSIiBoaXN0b3J5LWluY3JlbWVudGFsLXBhdHRlcm4t c2VhcmNoLWJhY2t3YXJkCmJpbmRrZXkgIl5YVCIgaGlzdG9yeS1pbmNyZW1lbnRhbC1wYXR0ZXJu LXNlYXJjaC1mb3J3YXJkCicKfQoKemxldGVzdGV2YWwgKCkgewogIGxvY2FsIHRtcD0vdG1wL3ps ZXRlc3QuJCQKCiAgcHJpbnQgLWxyIC0gIiRAIiA+ICR0bXAKICB6cHR5IC13IHpzaCAiLiAkdG1w IgogIHpwdHkgLXIgLW0genNoIGxvZ19ldmFsICIqPFBST01QVD4qIiB8fCB7CiAgICBwcmludCAi cHJvbXB0IGhhc24ndCBhcHBlYXJlZC4iCiAgICByZXR1cm4gMQogIH0KICBybSAkdG1wCn0KCnps ZXRlc3QgKCkgewogIGlucHV0PSIkKiIKICAjIHpwdHkgZmxhZ3M6IAogICMgIC13IHNlbmQgaW5w dXQgdG8gcHR5CiAgIyAgLW4gZG9uJ3QgYWRkIG5ld2xpbmUKICAjICAtbSByZWFkIGlucHV0IHVu dGlsIHBhdHRlcm4KICB6cHR5IC1uIC13IHpzaCAiJGlucHV0IgogICMgY2xlYXIgc2NyZWVuLCB0 byBjbGVhciBvdXQgY29udHJvbCBzZXF1ZW5jZXMKICB6cHR5IC1uIC13IHpzaCAkJ1xDLUwnCiAg IyBzZW5kIHRyYWlsaW5nIG91dHB1dCB0byBzY3JhcGUgb2ZmLgogIHpwdHkgLW4gLXcgenNoICQn XEMtWlxDLVUnCiAgenB0eSAtciAtbSB6c2ggbG9nICIqPGZpbmlzaD4qPFBST01QVD4iIHx8IHsK ICAgIHByaW50ICJmYWlsZWQgdG8gaW52b2tlIGZpbmlzaCB3aWRnZXQuIgogICAgcmV0dXJuIDEK ICB9CiAgKGVjaG8gbG9nOiAkbG9nIDsgZWNobyBET05FKSA+ISAvdG1wL3gwMS1sYXN0Lm91dCAg ICMgREVCVUcKICAjIHRoZXJlIG1pZ2h0IGJlIG11bHRpcGxlIDxQUk9NUFQ+J3MgaW4gbG9nLCBn cmFiIHRoZSBsYXN0IG9uZQogICMgZ2VuZXJhdGVkIGFmdGVyIHRoZSBjbGVhciBzY3JlZW4uCiAg bG9nPSR7bG9nJSU8ZmluaXNoPip9CiAgbG9ncz0oJHsoczo8UFJPTVBUPjopbG9nfSkKICBsb2cy PSRsb2dzWy0xXQogICMgU3BsaXQgb3V0cHV0IGludG8gbGluZXMsIHN0cmlwIHRyYWlsaW5nIF5b W0sgdG8gZW9sCiAgbGluZXM9KCR7KGYpbG9nMn0pCiAgZm9yIGxpbmUgaW4gIiRsaW5lc1tAXSIg OyBkbyAKICAgICNsaW5lPSR7bGluZSUlJCdcZVtLJyp9CiAgICBsaW5lPSR7bGluZSUlPHRjPWM/ Pip9CiAgICBlY2hvICRsaW5lCiAgZG9uZQp9Cg== --20cf303b3b972d920e04b60d5d66--