zsh-workers
 help / color / mirror / code / Atom feed
From: Zefram <zefram@dcs.warwick.ac.uk>
To: zsh-workers@math.gatech.edu
Subject: ksh autoloading
Date: Wed, 26 Mar 1997 17:46:21 GMT	[thread overview]
Message-ID: <11717.199703261746@stone.dcs.warwick.ac.uk> (raw)

-----BEGIN PGP SIGNED MESSAGE-----

This patch changes the way ksh autoloading is handled.  Currently it is
a kludge in execshfunc(), that if a function that was just autoloaded
redefines itself on first execution, it is executed again.  This breaks
on functions that really want to redefine themselves, which some do,
and in any case isn't applied to functions autoloaded for other purposes,
such as chpwd or widget functions.

The new scheme is that when a list has been read from the file and parsed,
it is examined to see if it is *in its entirety* a definition of the
function being loaded.  If it is, then the contents of that definition
is used, rather than the complete list.  This has much better defined
semantics than the old method.

 -zefram

      *** Src/exec.c	1997/03/22 07:00:53	1.53
      --- Src/exec.c	1997/03/26 02:57:18
      ***************
      *** 2482,2505 ****
        	if (!(funcdef = getfpfunc(nam))) {
        	    zerr("function not found: %s", nam, 0);
        	    lastval = 1;
      ! 	} else {
      ! 	    PERMALLOC {
      ! 		shf->flags &= ~PM_UNDEFINED;
      ! 		funcdef = shf->funcdef = (List) dupstruct(funcdef);
      ! 	    } LASTALLOC;
      ! 
      ! 	    /* Execute the function definition, we just retrived */
      ! 	    doshfunc(shf->funcdef, cmd->args, shf->flags, 0);
      ! 
      ! 	    /* See if this file defined the autoloaded function *
      ! 	     * by name.  If so, we execute it again.            */
      ! 	    if ((shf = (Shfunc) shfunctab->getnode(shfunctab, nam))
      ! 		&& shf->funcdef && shf->funcdef != funcdef)
      ! 		doshfunc(shf->funcdef, cmd->args, shf->flags, 0);
      ! 	}
      !     } else
      ! 	/* Normal shell function execution */
      ! 	doshfunc(shf->funcdef, cmd->args, shf->flags, 0);
            if (!list_pipe)
        	deletefilelist(last_file_list);
        }
      --- 2482,2497 ----
        	if (!(funcdef = getfpfunc(nam))) {
        	    zerr("function not found: %s", nam, 0);
        	    lastval = 1;
      ! 	    goto end;
      ! 	}
      ! 	shf->flags &= ~PM_UNDEFINED;
      ! 	PERMALLOC {
      ! 	    shf->funcdef = (List) dupstruct(funcdef);
      ! 	} LASTALLOC;
      !     }
      !     doshfunc(shf->funcdef, cmd->args, shf->flags, 0);
      ! 
      !     end:
            if (!list_pipe)
        	deletefilelist(last_file_list);
        }
      ***************
      *** 2658,2664 ****
        			r = parse_string(d);
        		    } LASTALLOC;
        		    zfree(d, len + 1);
      ! 		    return r;
        		} else {
        		    zfree(d, len + 1);
        		    close(fd);
      --- 2650,2656 ----
        			r = parse_string(d);
        		    } LASTALLOC;
        		    zfree(d, len + 1);
      ! 		    return stripkshdef(r, s);
        		} else {
        		    zfree(d, len + 1);
        		    close(fd);
      ***************
      *** 2669,2674 ****
      --- 2661,2697 ----
        	}
            }
            return NULL;
      + }
      + 
      + /* Handle ksh-style autoloading.  Given the list read from an autoload file, *
      +  * and the name of the function being defined, check to see if the file      *
      +  * consists entirely of a single definition for that function.  If so,       *
      +  * use the contents of that definition.  Otherwise, use the entire file.     */
      + 
      + /**/
      + List
      + stripkshdef(List l, char *name)
      + {
      +     Sublist s;
      +     Pline p;
      +     Cmd c;
      +     if(!l)
      + 	return NULL;
      +     if(l->type != Z_SYNC || l->right)
      + 	return l;
      +     s = l->left;
      +     if(s->flags || s->right)
      + 	return l;
      +     p = s->left;
      +     if(p->right)
      + 	return l;
      +     c = p->left;
      +     if(c->type != FUNCDEF || c->flags ||
      + 	nonempty(c->redir) || nonempty(c->vars) ||
      + 	empty(c->args) || lastnode(c->args) != firstnode(c->args) ||
      + 	strcmp(name, peekfirst(c->args)))
      + 	return l;
      +     return c->u.list;
        }
        
        /* check to see if AUTOCD applies here */

-----BEGIN PGP SIGNATURE-----
Version: 2.6.3ia
Charset: ascii

iQCVAwUBMziTIXD/+HJTpU/hAQHmbQP7B++6X39X6L344dwuvXKO23W22kvhWW/T
P0Vc60AOgL/09xfzQO68nOlwawQFFLedtznwwMExpPbAn5lARw81JjTDG1jONyJN
sEtoK31eQHcbBYtbOk17MWF5TeFlsPm7aap2/seKXE/djuS9yUZP6tTjCwN/6A0J
FDwUrNL2yek=
=MxJ5
-----END PGP SIGNATURE-----


             reply	other threads:[~1997-03-26 17:53 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
1997-03-26 17:46 Zefram [this message]
1997-03-27 18:15 ` Roderick Schertler
1997-03-27 18:36   ` Zefram
1997-03-27 18:57     ` Roderick Schertler
1997-03-27 19:11       ` Zefram
1997-04-01  0:08 Zefram

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=11717.199703261746@stone.dcs.warwick.ac.uk \
    --to=zefram@dcs.warwick.ac.uk \
    --cc=zsh-workers@math.gatech.edu \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://git.vuxu.org/mirror/zsh/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).