[net.emacs] CCA Emacs/Elisp bug fixes

massar@think.ARPA (J.P. Massar) (05/17/85)

Following is a rather large set of diff entries, fixing bugs or
potential bugs.


The following diff, along with the one below for elisp/alone.c, fixes a
bug in Emacs/Elisp which prevented '&' functions which should have
argument checking disabled from actually having it disabled, and hence 
attempting to call the function would sometimes result in an error
message about 'wrong number of arguments'.

The second part of the diff fixes a potential bug:  if elisp
initialization were to cause Emacs' comtab table to be reorganized (as
mine does, but the standard one does not), then a pointer into the
comtab gets trashed and you end up calling some random function.
Your source may be somewhat different, but the trick is to save the
name of the function, call elispinit, and then call elisp to execute
the function, instead of saving xcnum, which potentially becomes an
invalid index.

*** ../before_tcc/e_lisp.c	Mon Apr  8 16:46:28 1985
--- e_lisp.c	Wed May 15 01:18:56 1985
***************
*** 337,343
  
  /* Pass info about an EMACS function to Elisp */
  
! e_function_info(ifname, ofname, tindex, mx, minargs, maxargs, nocheck, retype, argtypes)
  char *ifname;
  char **ofname;
  int *tindex, *mx, *minargs, *maxargs, *nocheck, *retype;

--- 337,343 -----
  
  /* Pass info about an EMACS function to Elisp */
  
! e_function_info(ifname, ofname, tindex, mx, minargs, maxargs, check, retype, argtypes)
  char *ifname;
  char **ofname;
  int *tindex, *mx, *minargs, *maxargs, *check, *retype;
***************
*** 340,346
  e_function_info(ifname, ofname, tindex, mx, minargs, maxargs, nocheck, retype, argtypes)
  char *ifname;
  char **ofname;
! int *tindex, *mx, *minargs, *maxargs, *nocheck, *retype;
  int argtypes[];
  {
  	register i, n;

--- 340,346 -----
  e_function_info(ifname, ofname, tindex, mx, minargs, maxargs, check, retype, argtypes)
  char *ifname;
  char **ofname;
! int *tindex, *mx, *minargs, *maxargs, *check, *retype;
  int argtypes[];
  {
  	register i, n;
***************
*** 351,357
  	*tindex = n;
  	*mx = *comtab[n].name == '&' ? NOT_META_X : IS_META_X;
  	*minargs = *maxargs = (comtab[n].keyset >> LARGBIT) & 7;
! 	*nocheck = (comtab[n].keyset & LNCHECKBIT) != 0;
  	*retype = (comtab[n].keyset >> LRETBIT) & 3;
  	for (i = 0; i < *minargs; i++)
  		argtypes[i] = (comtab[n].keyset & (1 << i)) != 0;

--- 351,359 -----
  	*tindex = n;
  	*mx = *comtab[n].name == '&' ? NOT_META_X : IS_META_X;
  	*minargs = *maxargs = (comtab[n].keyset >> LARGBIT) & 7;
! 	*check = ((comtab[n].keyset >> LNCHECKBIT) & 1) == 0 ? 
!                  CHECK_ARGS :
!                  NOCHECK_ARGS;
  	*retype = (comtab[n].keyset >> LRETBIT) & 3;
  	for (i = 0; i < *minargs; i++)
  		argtypes[i] = (comtab[n].keyset & (1 << i)) != 0;
***************
*** 713,718
  char *s1, *s2, *s3;
  {
  	register n;
          int enumarg;
  	elispinit();
  	if (c == -1)

--- 715,721 -----
  char *s1, *s2, *s3;
  {
  	register n;
+         char *name;
          int enumarg;
          
          n = (c == -1) ? xcnum : keytab[disp].keyset;
***************
*** 714,724
  {
  	register n;
          int enumarg;
! 	elispinit();
! 	if (c == -1)
! 		n = xcnum;
! 	else
! 		n = keytab[disp].keyset;
          enumarg = (numarg == 10) ? NUMARG : numarg;
  	return(el_execute_function(comtab[n].name, enumarg, arg, s1, s2, s3, STD_ERROR_HANDLING));
  }

--- 717,724 -----
  	register n;
          char *name;
          int enumarg;
!         
!         n = (c == -1) ? xcnum : keytab[disp].keyset;
          enumarg = (numarg == 10) ? NUMARG : numarg;
          name = comtab[n].name;
          
***************
*** 720,726
  	else
  		n = keytab[disp].keyset;
          enumarg = (numarg == 10) ? NUMARG : numarg;
! 	return(el_execute_function(comtab[n].name, enumarg, arg, s1, s2, s3, STD_ERROR_HANDLING));
  }
  
  

--- 720,732 -----
          
          n = (c == -1) ? xcnum : keytab[disp].keyset;
          enumarg = (numarg == 10) ? NUMARG : numarg;
!         name = comtab[n].name;
!         
! 	elispinit();
!         
! 	return (
!           el_execute_function (
!             name, enumarg, arg, s1, s2, s3, STD_ERROR_HANDLING));
  }
  
  
******************************************************************************
******************************************************************************

The following diff for the file elisp/alone.c fixes two Elisp bugs:
The first is the '&' problem described above.

The second is a problem that if you manage to have more than 32 distinct
Emacs functions in your Elisp code using '#F' syntax you are going to
lose because the code to increase a certain table used internally by
Elisp is wrong.   This diff includes an increase in the size of that
table to an inital 64 entries instead of 32, as well as the fix.


*** ../before_tcc/elisp/alone.c	Thu Apr 11 14:07:30 1985
--- elisp/alone.c	Fri May 17 15:53:50 1985
***************
*** 653,658
  		char *sval,*emacsarg1,*emacsarg2,*emacsarg3;
  		Em_String_Function em_fp_s;
  		Em_Integer_Function em_fp_i;
  
  		info = Get_em_info(efobj);
  

--- 653,659 -----
  		char *sval,*emacsarg1,*emacsarg2,*emacsarg3;
        	Em_String_Function em_fp_s;
  		Em_Integer_Function em_fp_i;
+                 int check;
  
  		info = Get_em_info(efobj);
  
***************
*** 921,926
  		fprintf(dbgfp,"Checking Non-Meta-X call\n");
  #endif DEBUG
  
  		minargs = Get_em_min_args(efobj);
  		maxargs = Get_em_max_args(efobj);
  

--- 922,928 -----
  		fprintf(dbgfp,"Checking Non-Meta-X call\n");
  #endif DEBUG
  
+                 check = EM_CHECK_ARGS(info);
  		minargs = Get_em_min_args(efobj);
  		maxargs = check ? Get_em_max_args(efobj) : MAX_POSSIBLE_ARGS;
  
***************
*** 922,928
  #endif DEBUG
  
  		minargs = Get_em_min_args(efobj);
! 		maxargs = Get_em_max_args(efobj);
  
  		if (nargs < minargs || nargs > maxargs || nargs > MAX_POSSIBLE_ARGS) {
  			goto bad_n_args;

--- 924,930 -----
  
                  check = EM_CHECK_ARGS(info);
  		minargs = Get_em_min_args(efobj);
! 		maxargs = check ? Get_em_max_args(efobj) : MAX_POSSIBLE_ARGS;
  
  		if (nargs < minargs || nargs > maxargs || nargs > MAX_POSSIBLE_ARGS) {
  			goto bad_n_args;
***************
*** 1927,1933
  } 
  EVar_Entry;  
  
! static int EF_Tsize = 32;      /* Current allocated size of function table */
  static int EF_Index = 0;       /* index of next free entry */
  
  static EFunc_Entry *EF_Table;  /* Emacs Function table */

--- 1929,1935 -----
  } 
  EVar_Entry;  
  
! static int EF_Tsize = 64;      /* Current allocated size of function table */
  static int EF_Index = 0;       /* index of next free entry */
  
  static EFunc_Entry *EF_Table;  /* Emacs Function table */
***************
*** 1977,1983
  
  	EF_Tsize *= 2;
  	new_table = efa_make_eftable();
! 	copy(new_table,EF_Table,EF_Tsize/2);
  	free(EF_Table);
  	EF_Table = new_table;
  

--- 1979,1985 -----
  
  	EF_Tsize *= 2;
  	new_table = efa_make_eftable();
! 	copy(new_table,EF_Table,(EF_Tsize*sizeof(EFunc_Entry))/2);
  	free(EF_Table);
  	EF_Table = new_table;
  
***************
*** 2159,2165
  
  	EV_Tsize *= 2;
  	new_table = efm_make_evtable();
! 	copy(new_table,EV_Table,EV_Tsize/2);
  	free(EV_Table);
  	EV_Table = new_table;
  

--- 2161,2167 -----
  
  	EV_Tsize *= 2;
  	new_table = efm_make_evtable();
! 	copy(new_table,EV_Table,(EV_Tsize*sizeof(EVar_Entry))/2);
  	free(EV_Table);
  	EV_Table = new_table;
  

-- 
-- JP Massar, Thinking Machines Corporation, Cambridge, MA
-- mit-eddie!godot!massar, ihnp4!godot!massar, massar@think, massar@cca-unix