From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 11327 invoked by alias); 27 Sep 2015 01:22:07 -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: 36651 Received: (qmail 27349 invoked from network); 27 Sep 2015 01:22:04 -0000 X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on f.primenet.com.au X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00,T_DKIM_INVALID autolearn=ham autolearn_force=no version=3.4.0 DKIM-Signature: v=1; a=rsa-sha1; c=relaxed/relaxed; d= daniel.shahaf.name; h=content-transfer-encoding:content-type :date:from:message-id:mime-version:subject:to:x-sasl-enc :x-sasl-enc; s=mesmtp; bh=7AWRMaah8mFMRMw393pkDFqrT4w=; b=cJDEW2 hxPe5HSSSaQ7jB5NsUIv87tmf/3VAP0XBbQ42ozvtoNZgxG+K2oAd/lG4467ST1u 2D1LAI9tjp7UPWjvcWTHw3zZKVl9lrXh6KGGXPXyNlOVLY6fcZnHk6aX+z5//ZIU BLiLQX0yrhrkTaLwseakEXDaMcfJ9in9bfL8Y= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed/relaxed; d= messagingengine.com; h=content-transfer-encoding:content-type :date:from:message-id:mime-version:subject:to:x-sasl-enc :x-sasl-enc; s=smtpout; bh=7AWRMaah8mFMRMw393pkDFqrT4w=; b=HubwQ Ej+MmuFMs28n8mWqHr/0XI+1+w3i8/xijVJa7BhiQoHjnbYUrc8om8bIwm5lCKam be/2aljuusezITOdefJMBnSM7sQUqJN9Om9xeWGuZQFLz/tcpj+S3QbnUfW9zyM/ n7SP/i3tKumPwyiuLPoR3+rKsYL9Zrm7JGjb0Q= X-Sasl-enc: Ys0KICYy3F51KyvfBmhzYxSlyd+wBX6zslrFBJdsG/56 1443316917 Date: Sun, 27 Sep 2015 01:21:55 +0000 From: Daniel Shahaf To: zsh-workers@zsh.org Subject: [PATCH] WARN_CREATE_GLOBAL += math expressions Message-ID: <20150927012155.GC1989@tarsus.local2> MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Disposition: inline Content-Transfer-Encoding: 8bit User-Agent: Mutt/1.5.21 (2010-09-15) Without this, '() { (( x=42 )) }' and '() { for (( i=0; … )) }' wouldn't warn about $x and $i, respectively, being created global. --- Doc/Zsh/options.yo | 4 ++-- Src/exec.c | 3 ++- Src/math.c | 25 +++++++++++++++++++++++++ Test/E01options.ztst | 4 ++++ 4 files changed, 33 insertions(+), 3 deletions(-) diff --git a/Doc/Zsh/options.yo b/Doc/Zsh/options.yo index abd0f87..7cb7b6f 100644 --- a/Doc/Zsh/options.yo +++ b/Doc/Zsh/options.yo @@ -746,9 +746,9 @@ pindex(NOWARNCREATEGLOBAL) cindex(parameters, warning when created globally) item(tt(WARN_CREATE_GLOBAL))( Print a warning message when a global parameter is created in a function -by an assignment. This often indicates that a parameter has not been +by an assignment or in math context. This often indicates that a parameter has not been declared local when it should have been. Parameters explicitly declared -global from within a function using tt(typeset -g) do not cause a warning. +within a function using the tt(typeset) family of commands do not cause a warning. Note that there is no warning when a local parameter is assigned to in a nested function, which may also indicate an error. ) diff --git a/Src/exec.c b/Src/exec.c index 109a04a..da808d6 100644 --- a/Src/exec.c +++ b/Src/exec.c @@ -176,7 +176,8 @@ mod_export int sfcontext; /**/ struct execstack *exstack; -/* Stack with names of functions currently active. */ +/* Stack with names of function calls, 'source' calls, and 'eval' calls + * currently active. */ /**/ mod_export Funcstack funcstack; diff --git a/Src/math.c b/Src/math.c index 977e923..56565a6 100644 --- a/Src/math.c +++ b/Src/math.c @@ -894,6 +894,24 @@ getcvar(char *s) } +/* If script execution is inside a function call that hasn't returned, + * return the name of that function. Else return NULL. + */ + +/**/ +static const char * +in_function_call(void) +{ + Funcstack i; + for (i = funcstack; i; i = i->prev) + if (i->tp == FS_FUNC) { + DPUTS(!i->name, "funcstack entry with no name"); + return i->name; + } + + return NULL; +} + /**/ static mnumber setmathvar(struct mathvalue *mvp, mnumber v) @@ -929,6 +947,13 @@ setmathvar(struct mathvalue *mvp, mnumber v) if (noeval) return v; untokenize(mvp->lval); + if (isset(WARNCREATEGLOBAL)) { + const char *function_name; + if (!paramtab->getnode(paramtab, mvp->lval) && + (function_name = in_function_call())) + zwarn("math parameter %s created globally in function %s", + mvp->lval, function_name); + } pm = setnparam(mvp->lval, v); if (pm) { /* diff --git a/Test/E01options.ztst b/Test/E01options.ztst index 2b91b21..1caee8d 100644 --- a/Test/E01options.ztst +++ b/Test/E01options.ztst @@ -1110,11 +1110,15 @@ foo3=bar6 } foo4=bar7 =true + (( foo5=8 )) + integer foo6=9 + (( foo6=10 )) } fn 0:WARN_CREATE_GLOBAL option ?fn:3: scalar parameter foo1 created globally in function ?fn:5: scalar parameter foo1 created globally in function +?fn:15: math parameter foo5 created globally in function fn # This really just tests if XTRACE is egregiously broken. # To test it properly would need a full set of its own. -- 2.1.4