[net.emacs] CCA Emacs Elisp bug fix

massar@godot.UUCP (J.P. Massar) (02/14/85)

Following is a quick fix to make edefuned functions given numeric arguments
obey the documentation.

The problem is that the following:

(edefun foo (argtype argval) (print-line argtype) (print-line argval))

when invoked as follows:

C-U 5 M-X foo

produces

10
5

instead of

2
5

(where 2 is the value of the Elisp constant 'numarg').

Here is the diff:

*** e_lisp.c~	Wed Feb 13 23:52:44 1985
--- e_lisp.c	Thu Feb 14 01:32:11 1985
***************
*** 720,726
  char *s1, *s2, *s3;
  {
  	register n;
! 
  	elispinit();
  	if (c == -1)
  		n = xcnum;

--- 720,726 -----
  char *s1, *s2, *s3;
  {
  	register n;
!         int enumarg;
  	elispinit();
  	if (c == -1)
  		n = xcnum;
***************
*** 726,732
  		n = xcnum;
  	else
  		n = keytab[disp].keyset;
! 	return(el_execute_function(comtab[n].name, numarg, arg, s1, s2, s3, STD_ERROR_HANDLING));
  }
  
  

--- 726,733 -----
  		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));
  }
  
---------------------------------------------------------------------------

Any edefuned function is supposed to have 0 ('noarg') as the value of its
first argument if invoked with no C-U argument; 1 ('nullarg') if invoked
with a C-U but without any numeric value; 2 ('numarg') if invoked with
C-U followed by a numeric value; and finally 3 ('signarg') if invoked
with C-U followed by a '-'.  The signarg convention does not work; has
never worked; I don't know how to make it work and there is very little
purpose in even trying, since it is quite useless (it was only put in
to conform to certain Emacs M-X commands which somehow distinguish between
C-U -1 and C-U - (!)).

JP Massar
ihnp4!godot!massar
massar@cca-unix

massar@godot.UUCP (J.P. Massar) (02/14/85)

Bug:  Any attempt to call an Elisp edefun-ed function from within Elisp
by referring to it using '#F' syntax would could Emacs to crash or do
bizzare things.

Repeat by:

M-X Evaluate Elisp Form$(#F"Evaluate Elisp Form")

which should just prompt for 'form?' but instead dies immediately.

Fix: in the elisp subdirectory in alone.c:

---------------------------------------------------------------------------

*** alone.c~	Sun Dec  9 16:30:44 1984
--- alone.c	Thu Feb 14 03:11:45 1985
***************
*** 892,898
  			fprintf(dbgfp, "Address of function to call is: %u\n",em_fp_i);
  #endif DEBUG         
  
! 			ival = (*em_fp_i)(numargval,'\0',emacsarg1,emacsarg2,emacsarg3);
  
  #if DEBUG             
  			fprintf(dbgfp,"Integer result of call is: %d\n",ival);             

--- 892,898 -----
  			fprintf(dbgfp, "Address of function to call is: %u\n",em_fp_i);
  #endif DEBUG         
  
! 			ival = (*em_fp_i)(numargval,-1,emacsarg1,emacsarg2,emacsarg3);
  
  #if DEBUG             
  			fprintf(dbgfp,"Integer result of call is: %d\n",ival);             
------------------------------------------------------------------------------

The function call above which is being fixed is invoking the routine
elispexec which previously was looking for the name of the function to
invoke in the wrong place due to the incorrect argument.  This is probably
the cause of a lot of 'inexplicable' bugs.

JP Massar
1hnp4!godot!massar
massar@cca-unix

massar@godot.UUCP (J.P. Massar) (02/27/85)

Problem:  Typing in "ab\"c" would produce

"ab"c"

which is not correct as it cannot be read in as equal to the original
string.

Fix: 
In addition to escaping '"', the code will now escape '\' as well.
 Here is the diff:


*** output.c~	Wed Feb 27 11:31:18 1985
--- output.c	Wed Feb 27 11:42:10 1985
***************
*** 111,117
  Ptr_Port pptr;
  
  {
! 	int j;
  	for (j = 0; j < len; j++) {
                  if (*buffer == '"') llb_put_a_char('\\',pptr);
  		llb_put_a_char(afa_e_index_to_c_char(*buffer),pptr);

--- 111,117 -----
  Ptr_Port pptr;
  
  {
! 	int j,ch;
  	for (j = 0; j < len; j++) {
                  ch = *buffer;
                  if (ch == '"' || ch == '\\') llb_put_a_char('\\',pptr);
***************
*** 113,120
  {
  	int j;
  	for (j = 0; j < len; j++) {
!                 if (*buffer == '"') llb_put_a_char('\\',pptr);
! 		llb_put_a_char(afa_e_index_to_c_char(*buffer),pptr);
  		if (pptr -> at_eof)
  		{ 
  			return(T);

--- 113,121 -----
  {
  	int j,ch;
  	for (j = 0; j < len; j++) {
!                 ch = *buffer;
!                 if (ch == '"' || ch == '\\') llb_put_a_char('\\',pptr);
! 		llb_put_a_char(afa_e_index_to_c_char(ch),pptr);
  		if (pptr -> at_eof)
  		{ 
  			return(T);
-- 
-- JP Massar, Thinking Machines Corporation, Cambridge, MA
-- ihnp4!godot!massar
-- massar@cca-unix

massar@godot.UUCP (J.P. Massar) (03/01/85)

Problem:  If you type in '#()'  (the null vector) Elisp gives
you an error message!

Fix:  in the file <emacssrc>/elisp/rmacros.c:

*** rmacros.c~	Tue Nov 13 15:21:37 1984
--- rmacros.c	Wed Feb 27 23:23:47 1985
***************
*** 513,519
  {
  
  	Elisp_Val stream,ev;
! 	int vlength;
  
  	stream = Get_Nth_Arg(1,4);
  

--- 513,519 -----
  {
  
  	Elisp_Val stream,ev;
! 	int vlength = 0;
  
  	stream = Get_Nth_Arg(1,4);
  
***************
*** 518,524
  	stream = Get_Nth_Arg(1,4);
  
  	ev = std_lparen_macro();
! 	if (acg_is_cons_valid_list(ev,&vlength))
  	{ 
  		return(adi_mk_vector(vlength,ev));
  	} 

--- 518,524 -----
  	stream = Get_Nth_Arg(1,4);
  
  	ev = std_lparen_macro();
! 	if (Nil_Symbol == ev || acg_is_cons_valid_list(ev,&vlength))
  	{ 
  		return(adi_mk_vector(vlength,ev));
  	} 
-- 
-- JP Massar, Thinking Machines Corporation, Cambridge, MA
-- ihnp4!godot!massar
-- massar@cca-unix

massar@godot.UUCP (J.P. Massar) (03/03/85)

Problem:  Doubly (or more) nested MAP calls do not work.  (just MAP, not
MAPCAR, MAPCAN, etc).

Fix:  In the file <emacssrc>/elisp/seq.c:

*** oldseq.c	Sun Mar  3 13:26:30 1985
--- seq.c	Sun Mar  3 13:27:41 1985
***************
*** 822,827
  				} 
  				else if (is_null) {
  					min_len = 0;
  					continue;
  				} 
  				else {

--- 822,828 -----
  				} 
  				else if (is_null) {
  					min_len = 0;
+                                         ui[j-3] = -1;
  					continue;
  				} 
  				else {
***************
*** 888,894
  				rval = basic_function(BF_NREVERSE,1);
  			}
  
! 			abe_all_free_seq();
  
  			Pop_Elisp_Val;   /* pop the function object */
  

--- 889,896 -----
  				rval = basic_function(BF_NREVERSE,1);
  			}
  
!                         for (i = 0; i < nsequences; i++)
!                             if (ui[i] >= 0) abd_free_seq(ui[i]);
  
  			Pop_Elisp_Val;   /* pop the function object */
  

Also, the defined constant MAXSEQ in the file seq.h should be changed
from 4 to something more reasonable, like 10.

---------------------------------------------------------------------------

Actually, the entire iteration mechanism over sequences should be
rewritten, but the above fix at least fixes the most obvious problem
with it.
-- 
-- JP Massar, Thinking Machines Corporation, Cambridge, MA
-- ihnp4!godot!massar
-- massar@cca-unix

massar@think.ARPA (J.P. Massar) (04/19/85)

Following is a simple one-line fix which makes UNREAD-CHAR work
when given its optional stream argument.


*** bio.c~	Wed Apr  3 22:50:11 1985
--- bio.c	Fri Apr 19 14:42:27 1985
***************
*** 430,435
  			}   
  		} 
  		else {  
  			if (!acn_is_open_stream(arg1,MUST_BE_IN)) {
  				goto bad_arg;
  			} 

--- 430,436 -----
  			}   
  		} 
  		else {  
+                         arg1 = Get_Nth_Arg(1,nargs);
  			if (!acn_is_open_stream(arg1,MUST_BE_IN)) {
  				goto bad_arg;
  			} 
-- 
-- JP Massar, Thinking Machines Corporation, Cambridge, MA
-- mit-eddie!godot!massar, ihnp4!godot!massar, massar@think, massar@cca-unix