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

PATCH: module cleanup



Hi

Here is the promised cleanup patch.

- The setup- and finish-function are now mandatory.
- The setup-funtions are always called for linked-in modules.
- That required to remove the uses of AIXDYNAMIC in the modules.
- I also changed the order of the four function in the modules to the
  order in which they are invoked.
- In the modules comp1, compctl, and zle setup and finish are used for 
  all non-user-interface-isms.
- I added a global variable `sfcontext' and some constants in
  zsh.h (SFC_*). This can be used to test in which context the shell
  function is called. Currently only the following are distinguished:
    SFC_DIRECT   - called directly by the user
    SFC_SIGNAL   - called as a signal handler
    SFC_HOOK     - automatically called from the shell (like chpwd)
    SFC_WIDGET   - called as a user-defined widget
    SFC_COMPLETE - called from the completion code
- For this I added save/set/restore sequences in various places.
- The documentation now describes the setup/boot/cleanup/finish things 
  more correctly. I also added a bit about the mdd files, mainly taken 
  from mkmakemd.sh.

With all that the patch has become rather biggish...

And I have a question: the cleanup/finish functions are currently
*not* called for linked-in modules and for loaded builtins if the
shell is exited without first unloading the modules. Now, if someone
writes a module that really needs to cleanup things (e.g. it has some
kind of write-cache without write-through) this will fail utterly.
Shouldn't we ensure that these functions are always called? Or was
there some reason not to do it?

Bye
 Sven

diff -cr os/Builtins/rlimits.c Src/Builtins/rlimits.c
*** os/Builtins/rlimits.c	Thu Dec 17 10:19:31 1998
--- Src/Builtins/rlimits.c	Thu Dec 17 10:24:01 1998
***************
*** 576,581 ****
--- 576,588 ----
  
  /**/
  int
+ setup_rlimits(Module m)
+ {
+     return 0;
+ }
+ 
+ /**/
+ int
  boot_rlimits(Module m)
  {
      return !addbuiltins(m->nam, bintab, sizeof(bintab)/sizeof(*bintab));
***************
*** 591,610 ****
      return 0;
  }
  
- #ifdef AIXDYNAMIC
- /**/
- int
- setup_rlimits(Module m)
- {
-     return 0;
- }
- 
  /**/
  int
  finish_rlimits(Module m)
  {
      return 0;
  }
- #endif
  
  #endif
--- 598,608 ----
diff -cr os/Builtins/sched.c Src/Builtins/sched.c
*** os/Builtins/sched.c	Thu Dec 17 10:19:31 1998
--- Src/Builtins/sched.c	Thu Dec 17 10:24:16 1998
***************
*** 185,190 ****
--- 185,197 ----
  
  /**/
  int
+ setup_sched(Module m)
+ {
+     return 0;
+ }
+ 
+ /**/
+ int
  boot_sched(Module m)
  {
      if(!addbuiltins(m->nam, bintab, sizeof(bintab)/sizeof(*bintab)))
***************
*** 211,230 ****
      return 0;
  }
  
- #ifdef AIXDYNAMIC
- /**/
- int
- setup_sched(Module m)
- {
-     return 0;
- }
- 
  /**/
  int
  finish_sched(Module m)
  {
      return 0;
  }
- #endif
  
  #endif
--- 218,228 ----
diff -cr os/Modules/cap.c Src/Modules/cap.c
*** os/Modules/cap.c	Thu Dec 17 10:19:11 1998
--- Src/Modules/cap.c	Thu Dec 17 10:21:35 1998
***************
*** 124,129 ****
--- 124,136 ----
  
  /**/
  int
+ setup_cap(Module m)
+ {
+     return 0;
+ }
+ 
+ /**/
+ int
  boot_cap(Module m)
  {
      return !addbuiltins(m->nam, bintab, sizeof(bintab)/sizeof(*bintab));
***************
*** 139,158 ****
      return 0;
  }
  
- #ifdef AIXDYNAMIC
- /**/
- int
- setup_cap(Module m)
- {
-     return 0;
- }
- 
  /**/
  int
  finish_cap(Module m)
  {
      return 0;
  }
- #endif
  
  #endif
--- 146,156 ----
diff -cr os/Modules/clone.c Src/Modules/clone.c
*** os/Modules/clone.c	Thu Dec 17 10:19:11 1998
--- Src/Modules/clone.c	Thu Dec 17 10:21:55 1998
***************
*** 98,103 ****
--- 98,110 ----
  
  /**/
  int
+ setup_clone(Module m)
+ {
+     return 0;
+ }
+ 
+ /**/
+ int
  boot_clone(Module m)
  {
      return !addbuiltins(m->nam, bintab, sizeof(bintab)/sizeof(*bintab));
***************
*** 113,132 ****
      return 0;
  }
  
- #ifdef AIXDYNAMIC
- /**/
- int
- setup_clone(Module m)
- {
-     return 0;
- }
- 
  /**/
  int
  finish_clone(Module m)
  {
      return 0;
  }
- #endif
  
  #endif
--- 120,130 ----
diff -cr os/Modules/example.c Src/Modules/example.c
*** os/Modules/example.c	Thu Dec 17 10:19:11 1998
--- Src/Modules/example.c	Thu Dec 17 10:22:14 1998
***************
*** 109,114 ****
--- 109,123 ----
  
  /**/
  int
+ setup_example(Module m)
+ {
+     printf("The example module has now been set up.\n");
+     fflush(stdout);
+     return 0;
+ }
+ 
+ /**/
+ int
  boot_example(Module m)
  {
      return !(addbuiltins(m->nam, bintab, sizeof(bintab)/sizeof(*bintab)) |
***************
*** 125,139 ****
      deletebuiltins(m->nam, bintab, sizeof(bintab)/sizeof(*bintab));
      deleteconddefs(m->nam, cotab, sizeof(cotab)/sizeof(*cotab));
      deletewrapper(m, wrapper);
-     return 0;
- }
- 
- /**/
- int
- setup_example(Module m)
- {
-     printf("The example module has now been set up.\n");
-     fflush(stdout);
      return 0;
  }
  
--- 134,139 ----
diff -cr os/Modules/files.c Src/Modules/files.c
*** os/Modules/files.c	Thu Dec 17 10:19:12 1998
--- Src/Modules/files.c	Thu Dec 17 10:22:38 1998
***************
*** 511,516 ****
--- 511,523 ----
  
  /**/
  int
+ setup_files(Module m)
+ {
+     return 0;
+ }
+ 
+ /**/
+ int
  boot_files(Module m)
  {
      return !addbuiltins(m->nam, bintab, sizeof(bintab)/sizeof(*bintab));
***************
*** 526,545 ****
      return 0;
  }
  
- #ifdef AIXDYNAMIC
- /**/
- int
- setup_files(Module m)
- {
-     return 0;
- }
- 
  /**/
  int
  finish_files(Module m)
  {
      return 0;
  }
- #endif
  
  #endif
--- 533,543 ----
diff -cr os/Modules/stat.c Src/Modules/stat.c
*** os/Modules/stat.c	Thu Dec 17 10:19:12 1998
--- Src/Modules/stat.c	Thu Dec 17 10:23:05 1998
***************
*** 571,576 ****
--- 571,583 ----
  
  /**/
  int
+ setup_stat(Module m)
+ {
+     return 0;
+ }
+ 
+ /**/
+ int
  boot_stat(Module m)
  {
      return !addbuiltins(m->nam, bintab, sizeof(bintab)/sizeof(*bintab));
***************
*** 586,605 ****
      return 0;
  }
  
- #ifdef AIXDYNAMIC
- /**/
- int
- setup_stat(Module m)
- {
-     return 0;
- }
- 
  /**/
  int
  finish_stat(Module m)
  {
      return 0;
  }
- #endif
  
  #endif
--- 593,603 ----
diff -cr os/Modules/zftp.c Src/Modules/zftp.c
*** os/Modules/zftp.c	Thu Dec 17 10:19:12 1998
--- Src/Modules/zftp.c	Thu Dec 17 11:02:50 1998
***************
*** 1354,1360 ****
--- 1354,1364 ----
  	 * We do this here in case we needed to wait for a RETR
  	 * command to tell us how many bytes are coming.
  	 */
+ 	int osc = sfcontext;
+ 
+ 	sfcontext = SFC_HOOK;
  	doshfunc("zftp_progress", l, NULL, 0, 1);
+ 	sfcontext = osc;
  	/* Now add in the bit of the file we've got/sent already */
  	sofar = last_sofar = startat;
      }
***************
*** 1482,1489 ****
--- 1486,1497 ----
  	    break;
  	if (!ret && sofar != last_sofar && progress &&
  	    (l = getshfunc("zftp_progress")) != &dummy_list) {
+ 	    int osc = sfcontext;
+ 
  	    zfsetparam("ZFTP_COUNT", &sofar, ZFPM_READONLY|ZFPM_INTEGER);
+ 	    sfcontext = SFC_HOOK;
  	    doshfunc("zftp_progress", l, NULL, 0, 1);
+ 	    sfcontext = osc;
  	    last_sofar = sofar;
  	}
      }
***************
*** 2102,2110 ****
       * front end.  By putting it here, and in close when ZFTP_PWD is unset,
       * we at least cover the bases.
       */
!     if ((l = getshfunc("zftp_chpwd")) != &dummy_list)
! 	doshfunc("zftp_chpwd", l, NULL, 0, 1);
  
      return 0;
  }
  
--- 2110,2122 ----
       * front end.  By putting it here, and in close when ZFTP_PWD is unset,
       * we at least cover the bases.
       */
!     if ((l = getshfunc("zftp_chpwd")) != &dummy_list) {
! 	int osc = sfcontext;
  
+ 	sfcontext = SFC_HOOK;
+ 	doshfunc("zftp_chpwd", l, NULL, 0, 1);
+ 	sfcontext = osc;
+     }
      return 0;
  }
  
***************
*** 2303,2311 ****
--- 2315,2327 ----
  	zsfree(ln);
  	if (progress && (l = getshfunc("zftp_progress")) != &dummy_list) {
  	    /* progress to finish: ZFTP_TRANSFER set to GF or PF */
+ 	    int osc = sfcontext;
+ 
  	    zfsetparam("ZFTP_TRANSFER", ztrdup(recv ? "GF" : "PF"),
  		       ZFPM_READONLY);
+ 	    sfcontext = SFC_HOOK;
  	    doshfunc("zftp_progress", l, NULL, 0, 1);
+ 	    sfcontext = osc;
  	}
  	if (rest) {
  	    zsfree(rest);
***************
*** 2428,2436 ****
  	zfunsetparam(*aptr);
  
      /* Now ZFTP_PWD is unset.  It's up to zftp_chpwd to notice. */
!     if ((l = getshfunc("zftp_chpwd")) != &dummy_list)
! 	doshfunc("zftp_chpwd", l, NULL, 0, 1);
  
      /* tidy up status variables, because mess is bad */
      zfclosing = zfdrrrring = 0;
  
--- 2444,2456 ----
  	zfunsetparam(*aptr);
  
      /* Now ZFTP_PWD is unset.  It's up to zftp_chpwd to notice. */
!     if ((l = getshfunc("zftp_chpwd")) != &dummy_list) {
! 	int osc = sfcontext;
  
+ 	sfcontext = SFC_HOOK;
+ 	doshfunc("zftp_chpwd", l, NULL, 0, 1);
+ 	sfcontext = osc;
+     }
      /* tidy up status variables, because mess is bad */
      zfclosing = zfdrrrring = 0;
  
***************
*** 2558,2563 ****
--- 2578,2590 ----
  
  /**/
  int
+ setup_zftp(Module m)
+ {
+     return 0;
+ }
+ 
+ /**/
+ int
  boot_zftp(Module m)
  {
      int ret;
***************
*** 2593,2612 ****
      return 0;
  }
  
- #ifdef AIXDYNAMIC
- /**/
- int
- setup_zftp(Module m)
- {
-     return 0;
- }
- 
  /**/
  int
  finish_zftp(Module m)
  {
      return 0;
  }
- #endif
  
  #endif
--- 2620,2630 ----
diff -cr os/Zle/comp1.c Src/Zle/comp1.c
*** os/Zle/comp1.c	Thu Dec 17 10:19:44 1998
--- Src/Zle/comp1.c	Thu Dec 17 10:26:08 1998
***************
*** 430,436 ****
  
  /**/
  int
! boot_comp1(Module m)
  {
      compctlreadptr = compctlread;
      clwords = (char **) zcalloc((clwsize = 16) * sizeof(char *));
--- 430,436 ----
  
  /**/
  int
! setup_comp1(Module m)
  {
      compctlreadptr = compctlread;
      clwords = (char **) zcalloc((clwsize = 16) * sizeof(char *));
***************
*** 446,467 ****
      return 0;
  }
  
- #ifdef MODULE
- 
  /**/
  int
! cleanup_comp1(Module m)
  {
-     deletehashtable(compctltab);
-     zfree(clwords, clwsize * sizeof(char *));
-     compctlreadptr = fallback_compctlread;
      return 0;
  }
  
! #ifdef AIXDYNAMIC
  /**/
  int
! setup_comp1(Module m)
  {
      return 0;
  }
--- 446,463 ----
      return 0;
  }
  
  /**/
  int
! boot_comp1(Module m)
  {
      return 0;
  }
  
! #ifdef MODULE
! 
  /**/
  int
! cleanup_comp1(Module m)
  {
      return 0;
  }
***************
*** 470,477 ****
  int
  finish_comp1(Module m)
  {
      return 0;
  }
- #endif
  
  #endif /* MODULE */
--- 466,475 ----
  int
  finish_comp1(Module m)
  {
+     deletehashtable(compctltab);
+     zfree(clwords, clwsize * sizeof(char *));
+     compctlreadptr = fallback_compctlread;
      return 0;
  }
  
  #endif /* MODULE */
diff -cr os/Zle/compctl.c Src/Zle/compctl.c
*** os/Zle/compctl.c	Thu Dec 17 10:19:44 1998
--- Src/Zle/compctl.c	Thu Dec 17 10:27:06 1998
***************
*** 1638,1671 ****
  
  /**/
  int
! boot_compctl(Module m)
  {
-     if(!addbuiltins(m->nam, bintab, sizeof(bintab)/sizeof(*bintab)))
- 	return 1;
      compctltab->printnode = printcompctlp;
      printcompctlptr = printcompctl;
      compctl_widgetptr = compctl_widget;
      return 0;
  }
  
- #ifdef MODULE
- 
  /**/
  int
! cleanup_compctl(Module m)
  {
!     compctltab->printnode = NULL;
!     deletebuiltins(m->nam, bintab, sizeof(bintab)/sizeof(*bintab));
!     printcompctlptr = NULL;
!     compctl_widgetptr = NULL;
      return 0;
  }
  
! #ifdef AIXDYNAMIC
  /**/
  int
! setup_compctl(Module m)
  {
      return 0;
  }
  
--- 1638,1667 ----
  
  /**/
  int
! setup_compctl(Module m)
  {
      compctltab->printnode = printcompctlp;
      printcompctlptr = printcompctl;
      compctl_widgetptr = compctl_widget;
      return 0;
  }
  
  /**/
  int
! boot_compctl(Module m)
  {
!     if(!addbuiltins(m->nam, bintab, sizeof(bintab)/sizeof(*bintab)))
! 	return 1;
      return 0;
  }
  
! #ifdef MODULE
! 
  /**/
  int
! cleanup_compctl(Module m)
  {
+     deletebuiltins(m->nam, bintab, sizeof(bintab)/sizeof(*bintab));
      return 0;
  }
  
***************
*** 1673,1680 ****
  int
  finish_compctl(Module m)
  {
      return 0;
  }
- #endif
  
  #endif
--- 1669,1678 ----
  int
  finish_compctl(Module m)
  {
+     compctltab->printnode = NULL;
+     printcompctlptr = NULL;
+     compctl_widgetptr = NULL;
      return 0;
  }
  
  #endif
diff -cr os/Zle/deltochar.c Src/Zle/deltochar.c
*** os/Zle/deltochar.c	Thu Dec 17 10:19:44 1998
--- Src/Zle/deltochar.c	Thu Dec 17 10:27:51 1998
***************
*** 73,78 ****
--- 73,85 ----
  
  /**/
  int
+ setup_deltochar(Module m)
+ {
+     return 0;
+ }
+ 
+ /**/
+ int
  boot_deltochar(Module m)
  {
      w_deletetochar = addzlefunction("delete-to-char", deltochar,
***************
*** 94,113 ****
      return 0;
  }
  
- #ifdef AIXDYNAMIC
- /**/
- int
- setup_deltochar(Module m)
- {
-     return 0;
- }
- 
  /**/
  int
  finish_deltochar(Module m)
  {
      return 0;
  }
- #endif
  
  #endif
--- 101,111 ----
diff -cr os/Zle/zle_main.c Src/Zle/zle_main.c
*** os/Zle/zle_main.c	Thu Dec 17 10:19:45 1998
--- Src/Zle/zle_main.c	Thu Dec 17 10:47:06 1998
***************
*** 603,613 ****
  	    zsfree(msg);
  	    feep();
  	} else {
! 	  startparamscope();
! 	  makezleparams();
! 	  doshfunc(w->u.fnnam, l, NULL, 0, 1);
! 	  endparamscope();
! 	  lastcmd = 0;
  	}
      }
  }
--- 603,617 ----
  	    zsfree(msg);
  	    feep();
  	} else {
! 	    int osc = sfcontext;
! 
! 	    startparamscope();
! 	    makezleparams();
! 	    sfcontext = SFC_WIDGET;
! 	    doshfunc(w->u.fnnam, l, NULL, 0, 1);
! 	    sfcontext = osc;
! 	    endparamscope();
! 	    lastcmd = 0;
  	}
      }
  }
***************
*** 856,862 ****
  
  /**/
  int
! boot_zle(Module m)
  {
      /* Set up editor entry points */
      trashzleptr = trashzle;
--- 860,866 ----
  
  /**/
  int
! setup_zle(Module m)
  {
      /* Set up editor entry points */
      trashzleptr = trashzle;
***************
*** 875,880 ****
--- 879,891 ----
      /* initialise the keymap system */
      init_keymaps();
  
+     return 0;
+ }
+ 
+ /**/
+ int
+ boot_zle(Module m)
+ {
      addbuiltins(m->nam, bintab, sizeof(bintab)/sizeof(*bintab));
      return 0;
  }
***************
*** 885,899 ****
  int
  cleanup_zle(Module m)
  {
-     int i;
- 
      if(zleactive) {
  	zerrnam(m->nam, "can't unload the zle module while zle is active",
  	    NULL, 0);
  	return 1;
      }
- 
      deletebuiltins(m->nam, bintab, sizeof(bintab)/sizeof(*bintab));
      cleanup_keymaps();
      deletehashtable(thingytab);
  
--- 896,916 ----
  int
  cleanup_zle(Module m)
  {
      if(zleactive) {
  	zerrnam(m->nam, "can't unload the zle module while zle is active",
  	    NULL, 0);
  	return 1;
      }
      deletebuiltins(m->nam, bintab, sizeof(bintab)/sizeof(*bintab));
+     return 0;
+ }
+ 
+ /**/
+ int
+ finish_zle(Module m)
+ {
+     int i;
+ 
      cleanup_keymaps();
      deletehashtable(thingytab);
  
***************
*** 916,936 ****
  
      return 0;
  }
- 
- #ifdef AIXDYNAMIC
- /**/
- int
- setup_zle(Module m)
- {
-     return 0;
- }
- 
- /**/
- int
- finish_zle(Module m)
- {
-     return 0;
- }
- #endif
  
  #endif /* MODULE */
--- 933,937 ----
diff -cr os/Zle/zle_tricky.c Src/Zle/zle_tricky.c
*** os/Zle/zle_tricky.c	Thu Dec 17 10:19:46 1998
--- Src/Zle/zle_tricky.c	Thu Dec 17 10:48:31 1998
***************
*** 4090,4095 ****
--- 4090,4096 ----
  	if ((list = getshfunc(cc->func)) != &dummy_list) {
  	    /* We have it, so build a argument list. */
  	    LinkList args = newlinklist();
+ 	    int osc = sfcontext;
  
  	    addlinknode(args, cc->func);
  
***************
*** 4107,4114 ****
--- 4108,4117 ----
  
  	    /* This flag allows us to use read -l and -c. */
  	    incompctlfunc = 1;
+ 	    sfcontext = SFC_COMPLETE;
  	    /* Call the function. */
  	    doshfunc(cc->func, list, args, 0, 1);
+ 	    sfcontext = osc;
  	    incompctlfunc = 0;
  	    /* And get the result from the reply parameter. */
  	    if ((r = get_user_var("reply")))
***************
*** 4254,4259 ****
--- 4257,4263 ----
  	    LinkList args = newlinklist();
  	    LinkNode ln;
  	    Cmatch m;
+ 	    int osc = sfcontext;
  
  	    addlinknode(args, cc->ylist);
  	    for (ln = firstnode(matches); ln; ln = nextnode(ln)) {
***************
*** 4271,4277 ****
--- 4275,4283 ----
  
  	    /* No harm in allowing read -l and -c here, too */
  	    incompctlfunc = 1;
+ 	    sfcontext = SFC_COMPLETE;
  	    doshfunc(cc->ylist, list, args, 0, 1);
+ 	    sfcontext = osc;
  	    incompctlfunc = 0;
  	    uv = "reply";
  	}
diff -cr os/builtin.c Src/builtin.c
*** os/builtin.c	Thu Dec 17 09:00:07 1998
--- Src/builtin.c	Thu Dec 17 10:50:29 1998
***************
*** 992,1000 ****
--- 992,1004 ----
  
      /* execute the chpwd function */
      if ((l = getshfunc("chpwd")) != &dummy_list) {
+ 	int osc = sfcontext;
+ 
  	fflush(stdout);
  	fflush(stderr);
+ 	sfcontext = SFC_HOOK;
  	doshfunc("chpwd", l, NULL, 0, 1);
+ 	sfcontext = osc;
      }
  
      dirstacksize = getiparam("DIRSTACKSIZE");
diff -cr os/exec.c Src/exec.c
*** os/exec.c	Thu Dec 17 09:00:07 1998
--- Src/exec.c	Thu Dec 17 10:44:36 1998
***************
*** 113,119 ****
   
  /**/
  int cmdoutval;
!  
  /* Stack to save some variables before executing a signal handler function */
  
  /**/
--- 113,124 ----
   
  /**/
  int cmdoutval;
! 
! /* The context in which a shell function is called, see SFC_* in zsh.h. */ 
! 
! /**/
! int sfcontext;
! 
  /* Stack to save some variables before executing a signal handler function */
  
  /**/
diff -cr os/init.c Src/init.c
*** os/init.c	Thu Dec 17 09:00:07 1998
--- Src/init.c	Thu Dec 17 10:49:53 1998
***************
*** 111,123 ****
--- 111,127 ----
  	    if (toplevel && (prelist = getshfunc("preexec")) != &dummy_list) {
  		Histent he = gethistent(curhist);
  		LinkList args;
+ 		int osc = sfcontext;
+ 
  		PERMALLOC {
  		    args = newlinklist();
  		    addlinknode(args, "preexec");
  		    if (he && he->text)
  			addlinknode(args, he->text);
  		} LASTALLOC;
+ 		sfcontext = SFC_HOOK;
  		doshfunc("preexec", prelist, args, 0, 1);
+ 		sfcontext = osc;
  		freelinklist(args, (FreeFunc) NULL);
  		errflag = 0;
  	    }
***************
*** 613,618 ****
--- 617,623 ----
      breaks = loops = 0;
      lastmailcheck = time(NULL);
      locallevel = sourcelevel = 0;
+     sfcontext = SFC_DIRECT;
      trapreturn = 0;
      noerrexit = -1;
      nohistsave = 1;
diff -cr os/mkbltnmlst.sh Src/mkbltnmlst.sh
*** os/mkbltnmlst.sh	Thu Dec 17 10:20:12 1998
--- Src/mkbltnmlst.sh	Thu Dec 17 10:20:41 1998
***************
*** 45,51 ****
      echo "/* linked-in module \`$bin_mod' */"
      eval "loc=\$loc_$bin_mod"
      unset moddeps
-     hassetup=0
      . $srcdir/../$loc/${bin_mod}.mdd
      for dep in $moddeps; do
  	case $done_mods in
--- 45,50 ----
***************
*** 56,65 ****
  		exit 1 ;;
  	esac
      done
!     if [ $hassetup != 0 ]; then
!         echo "    mod.nam = \"$bin_mod\"; setup_$bin_mod(&mod); boot_$bin_mod(&mod);"
!     else
!         echo "    mod.nam = \"$bin_mod\"; boot_$bin_mod(&mod);"
!     fi
      done_mods="$done_mods$bin_mod "
  done
--- 55,60 ----
  		exit 1 ;;
  	esac
      done
!     echo "    mod.nam = \"$bin_mod\"; setup_$bin_mod(&mod); boot_$bin_mod(&mod);"
      done_mods="$done_mods$bin_mod "
  done
diff -cr os/module.c Src/module.c
*** os/module.c	Thu Dec 17 09:00:08 1998
--- Src/module.c	Thu Dec 17 11:06:05 1998
***************
*** 36,41 ****
--- 36,48 ----
  
  /**/
  int
+ setup_zsh(Module m)
+ {
+     return 0;
+ }
+ 
+ /**/
+ int
  boot_zsh(Module m)
  {
      return 0;
***************
*** 389,398 ****
  #ifdef AIXDYNAMIC
  
  /**/
! static void
  setup_module(Module m)
  {
!     ((int (*)_((int,Module))) m->handle)(0, m);
  }
  
  /**/
--- 396,405 ----
  #ifdef AIXDYNAMIC
  
  /**/
! static int
  setup_module(Module m)
  {
!     return ((int (*)_((int,Module))) m->handle)(0, m);
  }
  
  /**/
***************
*** 410,419 ****
  }
  
  /**/
! static void
  finish_module(Module m)
  {
!     ((int (*)_((int,Module))) m->handle)(3, m);
  }
  
  #else
--- 417,426 ----
  }
  
  /**/
! static int
  finish_module(Module m)
  {
!     return ((int (*)_((int,Module))) m->handle)(3, m);
  }
  
  #else
***************
*** 446,458 ****
  }
  
  /**/
! static void
  setup_module(Module m)
  {
      Module_func fn = module_func(m, STR_SETUP, STR_SETUP_S);
  
      if (fn)
! 	fn(m);
  }
  
  /**/
--- 453,467 ----
  }
  
  /**/
! static int
  setup_module(Module m)
  {
      Module_func fn = module_func(m, STR_SETUP, STR_SETUP_S);
  
      if (fn)
! 	return fn(m);
!     zwarnnam(m->nam, "no setup function", NULL, 0);
!     return 1;
  }
  
  /**/
***************
*** 479,494 ****
      return 1;
  }
  
  /**/
! static void
  finish_module(Module m)
  {
      Module_func fn = module_func(m, STR_FINISH, STR_FINISH_S);
  
      if (fn)
! 	fn(m);
! 
      dlclose(m->handle);
  }
  
  #endif /* !AIXDYNAMIC */
--- 488,511 ----
      return 1;
  }
  
+ /* Note that this function does more than just calling finish_foo(), *
+  * it really unloads the module. */
+ 
  /**/
! static int
  finish_module(Module m)
  {
      Module_func fn = module_func(m, STR_FINISH, STR_FINISH_S);
+     int r;
  
      if (fn)
! 	r = fn(m);
!     else {
! 	zwarnnam(m->nam, "no finish function", NULL, 0);
! 	r = 1;
!     }
      dlclose(m->handle);
+     return r;
  }
  
  #endif /* !AIXDYNAMIC */
***************
*** 507,514 ****
  	m = zcalloc(sizeof(*m));
  	m->nam = ztrdup(name);
  	m->handle = handle;
! 	setup_module(m);
! 	if (init_module(m)) {
  	    finish_module(m);
  	    zsfree(m->nam);
  	    zfree(m, sizeof(*m));
--- 524,530 ----
  	m = zcalloc(sizeof(*m));
  	m->nam = ztrdup(name);
  	m->handle = handle;
! 	if (setup_module(m) || init_module(m)) {
  	    finish_module(m);
  	    zsfree(m->nam);
  	    zfree(m, sizeof(*m));
***************
*** 539,545 ****
      if (!m->handle) {
  	if (!(m->handle = do_load_module(name)))
  	    return NULL;
! 	setup_module(m);
      }
      if (init_module(m)) {
  	finish_module(m->handle);
--- 555,565 ----
      if (!m->handle) {
  	if (!(m->handle = do_load_module(name)))
  	    return NULL;
! 	if (setup_module(m)) {
! 	    finish_module(m->handle);
! 	    m->handle = NULL;
! 	    return NULL;
! 	}
      }
      if (init_module(m)) {
  	finish_module(m->handle);
diff -cr os/signals.c Src/signals.c
*** os/signals.c	Thu Dec 17 09:00:09 1998
--- Src/signals.c	Thu Dec 17 10:45:26 1998
***************
*** 703,708 ****
--- 703,710 ----
      execsave();
      breaks = 0;
      if (*sigtr & ZSIG_FUNC) {
+ 	int osc = sfcontext;
+ 
  	PERMALLOC {
  	    args = newlinklist();
  	    name = (char *) zalloc(5 + strlen(sigs[sig]));
***************
*** 712,718 ****
--- 714,722 ----
  	    addlinknode(args, num);
  	} LASTALLOC;
  	trapreturn = -1;
+ 	sfcontext = SFC_SIGNAL;
  	doshfunc(name, sigfn, args, 0, 1);
+ 	sfcontext = osc;
  	freelinklist(args, (FreeFunc) NULL);
  	zsfree(name);
      } else HEAPALLOC {
diff -cr os/utils.c Src/utils.c
*** os/utils.c	Thu Dec 17 09:00:09 1998
--- Src/utils.c	Thu Dec 17 10:51:26 1998
***************
*** 630,637 ****
  
      /* 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;
  
--- 630,642 ----
  
      /* If a shell function named "precmd" exists, *
       * then execute it.                           */
!     if ((list = getshfunc("precmd")) != &dummy_list) {
! 	int osc = sfcontext;
! 
! 	sfcontext = SFC_HOOK;
  	doshfunc("precmd", list, NULL, 0, 1);
+ 	sfcontext = osc;
+     }
      if (errflag)
  	return;
  
***************
*** 640,646 ****
--- 645,655 ----
       * executed "periodic", then execute it now.                    */
      if (period && (time(NULL) > lastperiodic + period) &&
  	(list = getshfunc("periodic")) != &dummy_list) {
+ 	int osc = sfcontext;
+ 
+ 	sfcontext = SFC_HOOK;
  	doshfunc("periodic", list, NULL, 0, 1);
+ 	sfcontext = osc;
  	lastperiodic = time(NULL);
      }
      if (errflag)
diff -cr os/zsh.h Src/zsh.h
*** os/zsh.h	Thu Dec 17 09:00:10 1998
--- Src/zsh.h	Thu Dec 17 10:46:18 1998
***************
*** 772,777 ****
--- 772,785 ----
      List funcdef;		/* function definition    */
  };
  
+ /* Shell function context types. */
+ 
+ #define SFC_DIRECT   0		/* called directly from the user */
+ #define SFC_SIGNAL   1		/* signal handler */
+ #define SFC_HOOK     2		/* one of the special functions */
+ #define SFC_WIDGET   3		/* user defined widget */
+ #define SFC_COMPLETE 4		/* called from completion code */
+ 
  /* node in list of function call wrappers */
  
  typedef int (*WrapFunc) _((List, FuncWrap, char *));
*** Util/zsh-development-guide.old	Thu Dec 17 10:54:30 1998
--- Util/zsh-development-guide	Thu Dec 17 11:34:21 1998
***************
*** 115,129 ****
  Modules
  -------
  
! Modules should define should define two functions which will
! automatically called by the zsh core. The first one, named `boot_foo'
! for a module name `foo', should register all builtins, conditional
! codes, and function wrappers. The second one, named `cleanup_foo' for
! module `foo' is called when the module is unloaded and should
! de-register the builtins etc. Since this second function is only
! executed when the module is used as an dynamically loaded module you
! should surround it bei `#ifdef MODULE' and `#endif'.
! Both of these functions should return zero if they succeded and
  non-zero otherwise.
  
  Builtins are described in a table, for example:
--- 115,157 ----
  Modules
  -------
  
! Modules are described by a file named `foo.mdd' for a module
! `foo'. This file is actually a shell script that will sourced when zsh 
! is build. To describe the module it can/should set the following shell 
! variables:
! 
!   - moddeps       modules on which this module depends (default none)
!   - nozshdep      non-empty indicates no dependence on the `zsh' pseudo-module
!   - alwayslink    if non-empty, always link the module into the executable
!   - autobins      builtins defined by the module, for autoloading
!   - objects       .o files making up this module (*must* be defined)
!   - proto         .pro files for this module (default generated from $objects)
!   - headers       extra headers for this module (default none)
!   - hdrdeps       extra headers on which the .mdh depends (default none)
!   - otherincs     extra headers that are included indirectly (default none)
! 
! Be sure to put the values in quotes. For further enlightenment have a
! look at the `mkmakemod.sh' script in the Src directory of the
! distribution.
! 
! Modules have to define four functions which will automatically called
! by the zsh core. The first one, named `setup_foo' for a module named
! `foo', should set up any data needed in the module, at least any data
! other modules may be interested in. The second one, named `boot_foo',
! should register all builtins, conditional codes, and function wrappers
! (i.e. anything that will be visible to the user) and will be called
! after the `setup'-function. 
! The third one, named `cleanup_foo' for module `foo' is called when the
! user tries to unload a module and should de-register the builtins
! etc. The last function, `finish_foo' is called when the module is
! actually unloaded and should finalize all the data initialized in the 
! `setup'-function. Since the last two functions are only executed when
! the module is used as an dynamically loaded module you can surround
! it with `#ifdef MODULE' and `#endif'.
! In short, the `cleanup'-function should undo what the `boot'-function
! did, and the `finish'-function should undo what the `setup'-function
! did.
! All of these functions should return zero if they succeeded and
  non-zero otherwise.
  
  Builtins are described in a table, for example:
***************
*** 335,372 ****
      return 1;
    }
  
  There is a problem when the user tries to unload a module that has
! defined wrapper from a shell function. In this case the module can't
  be unloaded immediately since the wrapper function is still on the
  call stack. The zsh code delays unloading modules until all wrappers
  from them have finished. To hide this from the user, the module's
  cleanup function is run immediatly so that all builtins, condition
  codes, and wrapper function defined by the module are
  de-registered. But if there is some module-global state that has to be 
! finalised (e.g. some memory that has to be freed) and that is used by
  the wrapper functions finalizing this data in the cleanup function
  won't work.
! Therefore two more module-functions may be called from zsh. When a
! module is really loaded zsh first tries to run the function
! `setup_foo' (for module `foo'). After that the function `boot_foo' is
! run and this function is also run if a module is still in memory but
! the user issued a `zmodload -u' call for it (i.e. zsh detected that it 
! can't immediately unload the module). Correspondingly, the cleanup
! function is run whenever the user calls `zmodload -u' for a module and 
! the function `finish_foo' (for module `foo') only if the module is
! actually unloaded. So, if you have some state accessed by a wrapper
! function put the initialization for it in the setup-function and the
! finalization for it in the finish-function. The boot- and
! cleanup-function are then only used to register and de-register
! builtins, condition codes, and wrapper functions. This way it is
! guaranteed that the data needed by the wrapper function is still valid 
! when wrappers are active and that the user-visible interface defined
! by the module disappears as soon as the user tries to unload a module.
! Modules other modules which are currently delayed unloaded depend upon 
! are unloaded delayed, too. This means that whenever you write a module 
! that exports some data or functions which might be interesting to
! other modules you make sure that they are initialized and finalized in 
! the setup- und finish-functions, not in the boot- and cleanup-functions.
  
  Documentation
  -------------
--- 363,404 ----
      return 1;
    }
  
+ Inside these wrapper functions the global variable `sfcontext' will be 
+ set to a vlue indicating the circumstances under which the shell
+ function was called. It can have any of the following values:
+ 
+   - SFC_DIRECT:   the function was invoked directly by the user
+   - SFC_SIGNAL:   the function was invoked as a signal handler
+   - SFC_HOOK:     the function was automatically invoked as one of the
+                   special functions known by the shell (like `chpwd')
+   - SFC_WIDGET:   the function was called from the zsh line editor as a
+                   user-defined widget
+   - SFC_COMPLETE: the function was called from the completion code
+                   (e.g. with `compctl -K func')
+ 
+ If a module invokes a shell function (e.g. as a hook function), the
+ value of this variable should only be changed temporarily and restored
+ to its previous value after the shell function has finished.
+ 
  There is a problem when the user tries to unload a module that has
! defined wrappers from a shell function. In this case the module can't
  be unloaded immediately since the wrapper function is still on the
  call stack. The zsh code delays unloading modules until all wrappers
  from them have finished. To hide this from the user, the module's
  cleanup function is run immediatly so that all builtins, condition
  codes, and wrapper function defined by the module are
  de-registered. But if there is some module-global state that has to be 
! finalized (e.g. some memory that has to be freed) and that is used by
  the wrapper functions finalizing this data in the cleanup function
  won't work.
! This is why ther are two functions each for the initialization and
! finalization of modules. The `boot'- and `cleanup'-functions are run
! whenever the user calls `zmodload' or `zmodload -u' and should only
! register or de-register the module's interface that is visible to the
! user. Anything else should be done in the `setup'- and
! `finish'-functions. Otherwise modules that other modules depend upon
! may destroy their state too early and wrapper functions in the latter
! modules may stop working since the state they use is already destroyed.
  
  Documentation
  -------------


--
Sven Wischnowsky                         wischnow@xxxxxxxxxxxxxxxxxxxxxxx



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