Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

PATCH: wrapper functions in modules



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@xxxxxxxxxxxxxxxxxxxxxxx



Messages sorted by: Reverse Date, Date, Thread, Author