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