zsh-workers
 help / color / mirror / code / Atom feed
From: Sven Wischnowsky <wischnow@informatik.hu-berlin.de>
To: zsh-workers@math.gatech.edu
Subject: PATCH: wrapper functions in modules
Date: Wed, 9 Dec 1998 15:44:36 +0100 (MET)	[thread overview]
Message-ID: <199812091444.PAA02328@beta.informatik.hu-berlin.de> (raw)


Hello

This is the next bit prepared for the new completion stuff that might
be interesting to have elsewhere.

The patch below allows modules to register functions that are to be
executed before and after a function is called. This is completely
hidden from the user so there is no documentation for it.

Again, I have enhanced the example module. After you have loaded it it 
turns on GLOB_DOTS in every function whose name starts with `example'.

Several of the hunks are used to change calls to doshfunc(), since
this now gets the name of the function called as its first argument.


Bye
 Sven

diff -c os/builtin.c Src/builtin.c
*** os/builtin.c	Wed Dec  9 15:36:12 1998
--- Src/builtin.c	Wed Dec  9 14:40:24 1998
***************
*** 994,1000 ****
      if ((l = getshfunc("chpwd")) != &dummy_list) {
  	fflush(stdout);
  	fflush(stderr);
! 	doshfunc(l, NULL, 0, 1);
      }
  
      dirstacksize = getiparam("DIRSTACKSIZE");
--- 994,1000 ----
      if ((l = getshfunc("chpwd")) != &dummy_list) {
  	fflush(stdout);
  	fflush(stderr);
! 	doshfunc("chpwd", l, NULL, 0, 1);
      }
  
      dirstacksize = getiparam("DIRSTACKSIZE");
diff -c os/exec.c Src/exec.c
*** os/exec.c	Tue Dec  8 16:31:15 1998
--- Src/exec.c	Wed Dec  9 15:17:00 1998
***************
*** 2602,2608 ****
  	deletejob(jobtab + thisjob);
      }
  
!     doshfunc(shf->funcdef, cmd->args, shf->flags, 0);
  
      if (!list_pipe)
  	deletefilelist(last_file_list);
--- 2602,2608 ----
  	deletejob(jobtab + thisjob);
      }
  
!     doshfunc(shf->nam, shf->funcdef, cmd->args, shf->flags, 0);
  
      if (!list_pipe)
  	deletefilelist(last_file_list);
***************
*** 2650,2656 ****
  
  /**/
  void
! doshfunc(List list, LinkList doshargs, int flags, int noreturnval)
  /* If noreturnval is nonzero, then reset the current return *
   * value (lastval) to its value before the shell function   *
   * was executed.                                            */
--- 2650,2656 ----
  
  /**/
  void
! doshfunc(char *name, List list, LinkList doshargs, int flags, int noreturnval)
  /* If noreturnval is nonzero, then reset the current return *
   * value (lastval) to its value before the shell function   *
   * was executed.                                            */
***************
*** 2661,2666 ****
--- 2661,2667 ----
      void *xexitfn, *newexitfn;
      char saveopts[OPT_SIZE];
      int obreaks = breaks;
+     FuncWrap wrap;
  
      HEAPALLOC {
  	pushheap();
***************
*** 2705,2710 ****
--- 2706,2715 ----
  		argzero = ztrdup(argzero);
  	    }
  	}
+ 	for (wrap = wrappers; wrap; wrap = wrap->next) {
+ 	    if (wrap->before)
+ 		wrap->before(wrap, name);
+ 	}
  	startparamscope();
  	ou = underscore;
  	underscore = ztrdup(underscore);
***************
*** 2712,2718 ****
  	zsfree(underscore);
  	underscore = ou;
  	endparamscope();
! 
  	if (retflag) {
  	    retflag = 0;
  	    breaks = obreaks;
--- 2717,2726 ----
  	zsfree(underscore);
  	underscore = ou;
  	endparamscope();
! 	for (wrap = wrappers; wrap; wrap = wrap->next) {
! 	    if (wrap->after)
! 		wrap->after(wrap, name, lastval);
! 	}
  	if (retflag) {
  	    retflag = 0;
  	    breaks = obreaks;
diff -c os/init.c Src/init.c
*** os/init.c	Wed Dec  9 15:36:12 1998
--- Src/init.c	Wed Dec  9 14:57:49 1998
***************
*** 117,123 ****
  		    if (he && he->text)
  			addlinknode(args, he->text);
  		} LASTALLOC;
! 		doshfunc(prelist, args, 0, 1);
  		freelinklist(args, (FreeFunc) NULL);
  		errflag = 0;
  	    }
--- 117,123 ----
  		    if (he && he->text)
  			addlinknode(args, he->text);
  		} LASTALLOC;
! 		doshfunc("preexec", prelist, args, 0, 1);
  		freelinklist(args, (FreeFunc) NULL);
  		errflag = 0;
  	    }
***************
*** 593,598 ****
--- 593,599 ----
      createparamtable();     /* create paramater hash table             */
  
      condtab = NULL;
+     wrappers = NULL;
  
  #ifdef TIOCGWINSZ
      adjustwinsize();
diff -c os/module.c Src/module.c
*** os/module.c	Wed Dec  9 15:36:13 1998
--- Src/module.c	Wed Dec  9 15:17:41 1998
***************
*** 316,321 ****
--- 316,366 ----
      return hadf ? hads : 1;
  }
  
+ /* The list of function wrappers defined. */
+ 
+ /**/
+ FuncWrap wrappers;
+ 
+ /* This adds a definition for a wrapper. Return value is one in case of *
+  * error and zero if all went fine. */
+ 
+ /**/
+ int
+ addwrapper(FuncWrap w)
+ {
+     if (w->flags & WRAPF_ADDED)
+ 	return 1;
+     w->next = wrappers;
+     wrappers = w;
+     w->flags |= WRAPF_ADDED;
+ 
+     return 0;
+ }
+ 
+ /* This removes the given wrapper definition from the list. Returned is *
+  * one in case of error and zero otherwise. */
+ 
+ /**/
+ int
+ deletewrapper(FuncWrap w)
+ {
+     FuncWrap p, q;
+ 
+     if (w->flags & WRAPF_ADDED) {
+ 	for (p = wrappers, q = NULL; p && p != w; q = p, p = p->next);
+ 
+ 	if (p) {
+ 	    if (q)
+ 		q->next = p->next;
+ 	    else
+ 		wrappers = p->next;
+ 	    p->flags &= ~WRAPF_ADDED;
+ 
+ 	    return 0;
+ 	}
+     }
+     return 1;
+ }
  
  #ifdef HAVE_DLFCN_H
  # include <dlfcn.h>
diff -c os/signals.c Src/signals.c
*** os/signals.c	Tue Dec  8 16:31:19 1998
--- Src/signals.c	Wed Dec  9 14:39:54 1998
***************
*** 712,718 ****
  	    addlinknode(args, num);
  	} LASTALLOC;
  	trapreturn = -1;
! 	doshfunc(sigfn, args, 0, 1);
  	freelinklist(args, (FreeFunc) NULL);
  	zsfree(name);
      } else HEAPALLOC {
--- 712,718 ----
  	    addlinknode(args, num);
  	} LASTALLOC;
  	trapreturn = -1;
! 	doshfunc(name, sigfn, args, 0, 1);
  	freelinklist(args, (FreeFunc) NULL);
  	zsfree(name);
      } else HEAPALLOC {
diff -c os/utils.c Src/utils.c
*** os/utils.c	Wed Dec  9 15:36:14 1998
--- Src/utils.c	Wed Dec  9 14:39:41 1998
***************
*** 636,642 ****
      /* If a shell function named "precmd" exists, *
       * then execute it.                           */
      if ((list = getshfunc("precmd")) != &dummy_list)
! 	doshfunc(list, NULL, 0, 1);
      if (errflag)
  	return;
  
--- 636,642 ----
      /* If a shell function named "precmd" exists, *
       * then execute it.                           */
      if ((list = getshfunc("precmd")) != &dummy_list)
! 	doshfunc("precmd", list, NULL, 0, 1);
      if (errflag)
  	return;
  
***************
*** 645,651 ****
       * executed "periodic", then execute it now.                    */
      if (period && (time(NULL) > lastperiodic + period) &&
  	(list = getshfunc("periodic")) != &dummy_list) {
! 	doshfunc(list, NULL, 0, 1);
  	lastperiodic = time(NULL);
      }
      if (errflag)
--- 645,651 ----
       * executed "periodic", then execute it now.                    */
      if (period && (time(NULL) > lastperiodic + period) &&
  	(list = getshfunc("periodic")) != &dummy_list) {
! 	doshfunc("periodic", list, NULL, 0, 1);
  	lastperiodic = time(NULL);
      }
      if (errflag)
diff -c os/zsh.h Src/zsh.h
*** os/zsh.h	Wed Dec  9 15:36:14 1998
--- Src/zsh.h	Wed Dec  9 15:25:52 1998
***************
*** 233,238 ****
--- 233,239 ----
  typedef struct param     *Param;
  typedef struct cmdnam    *Cmdnam;
  typedef struct shfunc    *Shfunc;
+ typedef struct funcwrap  *FuncWrap;
  typedef struct builtin   *Builtin;
  typedef struct nameddir  *Nameddir;
  typedef struct module    *Module;
***************
*** 770,775 ****
--- 771,792 ----
      int flags;			/* various flags          */
      List funcdef;		/* function definition    */
  };
+ 
+ /* node in list of function call wrappers */
+ 
+ typedef void (*WrapBefore) _((FuncWrap, char *));
+ typedef void (*WrapAfter) _((FuncWrap, char *, int));
+ 
+ struct funcwrap {
+     FuncWrap next;
+     int flags;
+     WrapBefore before;
+     WrapAfter after;
+ };
+ 
+ #define WRAPF_ADDED 1
+ 
+ #define WRAPDEF(before, after) { NULL, 0, before, after }
  
  /* node in builtin command hash table (builtintab) */
  
diff -c os/Modules/example.c Src/Modules/example.c
*** os/Modules/example.c	Wed Dec  9 15:36:14 1998
--- Src/Modules/example.c	Wed Dec  9 15:13:58 1998
***************
*** 79,84 ****
--- 79,115 ----
      return !strcmp("example", dyncat(s1, s2));
  }
  
+ struct ogd {
+     struct ogd *next;
+     int val;
+ };
+ 
+ static struct ogd *ogds;
+ 
+ /**/
+ static void
+ wrap_before(FuncWrap w, char *name)
+ {
+     if (!strncmp(name, "example", 7)) {
+ 	struct ogd *n = (struct ogd *) halloc(sizeof(*n));
+ 
+ 	n->next = ogds;
+ 	ogds = n;
+ 	n->val = opts[GLOBDOTS];
+ 	opts[GLOBDOTS] = 1;
+     }
+ }
+ 
+ /**/
+ static void
+ wrap_after(FuncWrap w, char *name, int ret)
+ {
+     if (!strncmp(name, "example", 7)) {
+ 	opts[GLOBDOTS] = ogds->val;
+ 	ogds = ogds->next;
+     }
+ }
+ 
  /*
   * boot_example is executed when the module is loaded.
   */
***************
*** 92,103 ****
      CONDDEF("ex", CONDF_INFIX, 0, 0, cond_i_ex),
  };
  
  /**/
  int
  boot_example(Module m)
  {
      return !(addbuiltins(m->nam, bintab, sizeof(bintab)/sizeof(*bintab)) |
! 	     addconddefs(m->nam, cotab, sizeof(cotab)/sizeof(*cotab)));
  }
  
  #ifdef MODULE
--- 123,140 ----
      CONDDEF("ex", CONDF_INFIX, 0, 0, cond_i_ex),
  };
  
+ static struct funcwrap wrapper[] = {
+     WRAPDEF(wrap_before, wrap_after),
+ };
+ 
  /**/
  int
  boot_example(Module m)
  {
+     ogds = NULL;
      return !(addbuiltins(m->nam, bintab, sizeof(bintab)/sizeof(*bintab)) |
! 	     addconddefs(m->nam, cotab, sizeof(cotab)/sizeof(*cotab)) |
! 	     !addwrapper(wrapper));
  }
  
  #ifdef MODULE
***************
*** 108,113 ****
--- 145,151 ----
  {
      deletebuiltins(m->nam, bintab, sizeof(bintab)/sizeof(*bintab));
      deleteconddefs(m->nam, cotab, sizeof(cotab)/sizeof(*cotab));
+     deletewrapper(wrapper);
      return 0;
  }
  #endif
diff -c os/Zle/zle_main.c Src/Zle/zle_main.c
*** os/Zle/zle_main.c	Tue Dec  8 16:31:51 1998
--- Src/Zle/zle_main.c	Wed Dec  9 14:41:29 1998
***************
*** 593,599 ****
  	} else {
  	  startparamscope();
  	  makezleparams();
! 	  doshfunc(l, NULL, 0, 1);
  	  endparamscope();
  	  lastcmd = 0;
  	}
--- 593,599 ----
  	} else {
  	  startparamscope();
  	  makezleparams();
! 	  doshfunc(w->u.fnnam, l, NULL, 0, 1);
  	  endparamscope();
  	  lastcmd = 0;
  	}
diff -c os/Zle/zle_tricky.c Src/Zle/zle_tricky.c
*** os/Zle/zle_tricky.c	Tue Dec  8 16:31:52 1998
--- Src/Zle/zle_tricky.c	Wed Dec  9 14:41:11 1998
***************
*** 4086,4092 ****
  	    /* This flag allows us to use read -l and -c. */
  	    incompctlfunc = 1;
  	    /* Call the function. */
! 	    doshfunc(list, args, 0, 1);
  	    incompctlfunc = 0;
  	    /* And get the result from the reply parameter. */
  	    if ((r = get_user_var("reply")))
--- 4086,4092 ----
  	    /* This flag allows us to use read -l and -c. */
  	    incompctlfunc = 1;
  	    /* Call the function. */
! 	    doshfunc(cc->func, list, args, 0, 1);
  	    incompctlfunc = 0;
  	    /* And get the result from the reply parameter. */
  	    if ((r = get_user_var("reply")))
***************
*** 4249,4255 ****
  
  	    /* No harm in allowing read -l and -c here, too */
  	    incompctlfunc = 1;
! 	    doshfunc(list, args, 0, 1);
  	    incompctlfunc = 0;
  	    uv = "reply";
  	}
--- 4249,4255 ----
  
  	    /* No harm in allowing read -l and -c here, too */
  	    incompctlfunc = 1;
! 	    doshfunc(cc->ylist, list, args, 0, 1);
  	    incompctlfunc = 0;
  	    uv = "reply";
  	}


--
Sven Wischnowsky                         wischnow@informatik.hu-berlin.de


             reply	other threads:[~1998-12-09 14:52 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
1998-12-09 14:44 Sven Wischnowsky [this message]
1998-12-11 13:18 ` Bart Schaefer
1998-12-10  9:22 PATCH: " Sven Wischnowsky
1998-12-10  9:22 ` Peter Stephenson
1998-12-11  6:59   ` Phil Pennock
1998-12-11  8:46     ` Peter Stephenson
1998-12-10 10:28 Sven Wischnowsky

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=199812091444.PAA02328@beta.informatik.hu-berlin.de \
    --to=wischnow@informatik.hu-berlin.de \
    --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).