[net.emacs] Unipress V2.0x bug fix

gallaher@topaz.ARPA (Mike Gallaher) (04/07/85)

Fix for Emacs version:	V2.00, V2.01

Description:

	The ++, --, and assignment/operation operator MLisp
	functions (+=, -=, etc.) do not work properly when given
	system variables as arguments.

Fix:

There are three files that need to be patched: mlvars.h, mlarith.c,
and mlargs.c.

mlvars.h
--------
1) Change
	extern Expression *GetArg1();
   to
	extern BINDING *GetArg1();

2) Add the following code to mlvars.h, just after the definition
   of struct Binding.  This defines macros for referencing, reading,
   and setting MLisp variables, taking into account whether they are
   system or MLisp-defined.
   

-------------------- start of patch to mlvars.h --------------------

/* Macros for referencing variable values. */

#define	    IntVarVal(b)	(b)->b_exp->exp_int
#define	    StrVarPtr(b)	(b)->b_exp->exp_v.v_string
#define	    StrVarLen(b)	(b)->b_exp->exp_int

#define	    SysIntVarVal(b)	*(int *)((b)->b_exp->exp_v.v_string)
#define	    SysStrVarPtr(b)	(b)->b_exp->exp_v.v_string
#define	    SysStrVarLen(b)	strlen(SysStrVarPtr(b))


/* Macros for reading and setting variable values */

#define	    GetIntVarVal(b)	((b)->IsSystem ? SysIntVarVal(b) \
					       : IntVarVal(b))

#define	    SetIntVarVal(b,n)	if ((b)->IsSystem) \
				    SysIntVarVal(b) = (n);\
				else \
				    IntVarVal(b) = (n)

-------------------- end of patch to mlvars.h --------------------




mlargs.c
--------

Change GetArg1 to return the binding of the first argument rather
than the expression within that binding by doing the following:

1) Change the declared type of the function GetArg from Expression *
   to BINDING *.

2) Change the return(e) in GetArg1 [there is only one such return
   in this function] to return(b).




mlarith.c
--------- 

Change plusplus, minusminus, and AsgOp to use the new variable value
macros, and to reflect the change of the type of GetArg1 from Expression to
BINDING.  The simplest way to do this is to replace their definitions
entirely with the code below.  Following this code in the source file
should be the calls to AsgOp.

-------- begin patch to mlarith.c ------------------------------
/*
 * This implements the `++' prefix operator in C.  It requires its
 * arg to be a varname. It returns the incremented value. (friedl at kentvax)
 */
hidden int
plusplus()
{
register BINDING *b;
register int n;

  if ((b = GetArg1()) != NULL) {
    n = GetIntVarVal(b);
    MLvalue->exp_int = ++n;
    SetIntVarVal(b, n);
  }
  return(NULL);
}

/*
 * minusminus()
 *
 * This implements the -- prefix operator in C.  It requires its
 * arg to be a varname. It returns the decremented value. (friedl at kentvax)
 */
hidden int
minusminus()
{
register BINDING *b;
register int n;

  if ((b = GetArg1()) != NULL) {
    n = GetIntVarVal(b);
    MLvalue->exp_int = --n;
    SetIntVarVal(b, n);
  }
  return(NULL);
}

/*
 * AsgOp(OPNAME, OP)
 *
 * This macro implements the assignment operator - just
 * like those in C.  They are of the form
 *
 *	(OP var e1 e2 ...)
 *
 * where all the expressions are optional.  All of them
 * return integer values (friedl at Kentvax).
 */
#define	AsgOp(OPNAME, OP) \
hidden int \
OPNAME()\
{\
register BINDING *b;\
	if ((b = GetArg1()) != NULL)\
	{\
	register int n = GetIntVarVal(b);\
		while (!Emacs_Err && EI.ArgN < EI.ArgMax)\
	          n OP NumericArg(EI.Nis);\
		MLvalue->exp_int = n;\
		SetIntVarVal(b, n);\
	}\
	return(NULL);\
}

-------- end patch to mlarith.c ------------------------------