-*- indented-text -*-
+to 21.2 beta8 "Artemis"
+-- A bunch of Mule fixes from Martin Buchholz
+
to 21.2 beta7 "Ares"
-- mswindows modeline crash fix from Jonathan Harris
-- picon glyph fix from Gunnar Evermann
+1998-12-28 Martin Buchholz <martin@xemacs.org>
+
+ * XEmacs 21.2.8 is released.
+
+1998-12-28 Martin Buchholz <martin@xemacs.org>
+
+ * PROBLEMS: Document Linux GNU Libc 2.0 I18N crashes.
+
1998-12-24 Martin Buchholz <martin@xemacs.org>
* XEmacs 21.2.7 is released.
** Linux
+*** You get crashes in a non-C locale with Linux GNU Libc 2.0.
+
+Internationalization was not the top priority for GNU Libc 2.0.
+As of this writing (1998-12-28) you may get crashes while running
+XEmacs in a non-C locale. For example, `LC_ALL=en_US xemacs' crashes
+while `LC_ALL=C xemacs' runs fine. This happens for example with GNU
+libc 2.0.7. Installing libintl.a and libintl.h built from gettext
+0.10.35 and re-building XEmacs solves the crashes. Presumably soon
+everyone will upgrade to GNU Libc 2.1 and this problem will go away.
+
*** `C-z', or `M-x suspend-emacs' hangs instead of suspending.
If you build with `gpm' support on Linux, you cannot suspend XEmacs
+1998-12-28 Martin Buchholz <martin@xemacs.org>
+
+ * XEmacs 21.2.8 is released.
+
1998-12-24 Martin Buchholz <martin@xemacs.org>
* XEmacs 21.2.7 is released.
+1998-12-28 Martin Buchholz <martin@xemacs.org>
+
+ * XEmacs 21.2.8 is released.
+
1998-12-24 Martin Buchholz <martin@xemacs.org>
* XEmacs 21.2.7 is released.
+1998-12-28 Martin Buchholz <martin@xemacs.org>
+
+ * XEmacs 21.2.8 is released.
+
1998-12-24 Martin Buchholz <martin@xemacs.org>
* XEmacs 21.2.7 is released.
+1998-12-28 Martin Buchholz <martin@xemacs.org>
+
+ * XEmacs 21.2.8 is released.
+
1998-12-24 Martin Buchholz <martin@xemacs.org>
* XEmacs 21.2.7 is released.
+1998-12-28 Martin Buchholz <martin@xemacs.org>
+
+ * XEmacs 21.2.8 is released.
+
+1998-12-28 Martin Buchholz <martin@xemacs.org>
+
+ * editfns.c (get_home_directory):
+ (user-home-directory): Simplify.
+
+
+ * callproc.c (child_setup):
+ - Environment variables were being passed to inferior processes
+ using internal encoding.
+ - Convert to external encoding.
+ - Rename local var `tem' to better name `tail'.
+ - Use Flength instead of `manual' calculation.
+
+ * buffer.c (kill-buffer):
+ (record-buffer):
+ (set-buffer-major-mode):
+ (current-buffer):
+ - Fix up parameter names to correspond to docstrings.
+ - Don't use `bufname' when a buffer will do as well.
+ - Remove one unneeded GCPRO.
+
+ * buffer.h (initial_directory):
+ * buffer.c (init_initial_directory):
+ - use correct conversions between internal and external format.
+ (directory_is_current_directory): new function
+ (init_buffer): convert initial_directory to internal format.
+ - solve crashes when current working directory is non-ASCII.
+
+ * alloc.c (xmalloc):
+ (xcalloc):
+ (xrealloc):
+ - remove stupid casts, since XEmacs requires an ANSI C system.
+ (lrecord_type_index): replace abort() with more readable assert().
+
+ (reset_lcrecord_stats): remove.
+ (sweep_lcrecords_1):
+ - replace call to reset_lcrecord_stats() with call to xzero().
+
+1998-12-27 Martin Buchholz <martin@xemacs.org>
+
+ * process-unix.c (unix_create_process):
+ - Fix crash invoking program with non-ASCII name.
+ Try invoking xemacs with SHELL=/bin/üsh, then M-x shell.
+ - Remove unused variable `env'.
+ - Rename `temp' to better name `save_errno'.
+ - Reorganize code for clarity. But still too chicken to nuke the
+ BSD 4.2 support.
+
1998-12-24 Martin Buchholz <martin@xemacs.org>
* XEmacs 21.2.7 is released.
- Fix indentation.
- Use GET_C_STRING_FILENAME_DATA_ALLOCA with char *, not Extbyte *.
- * glyphs-x.c (x_subwindow_instantiate):
+ * glyphs-x.c (x_subwindow_instantiate):
- A image instance mask was being assigned to a image instance type!
- X_SUBWINDOW_INSTANCE_DATA (ii) is not an lvalue in C++.
-
- * glyphs-msw.c (mswindows_initialize_dibitmap_image_instance):
+
+ * glyphs-msw.c (mswindows_initialize_dibitmap_image_instance):
Fix indentation.
* glyphs-x.h: Make indentation consistent.
void *
xmalloc (size_t size)
{
- void *val = (void *) malloc (size);
+ void *val = malloc (size);
if (!val && (size != 0)) memory_full ();
return val;
static void *
xcalloc (size_t nelem, size_t elsize)
{
- void *val = (void *) calloc (nelem, elsize);
+ void *val = calloc (nelem, elsize);
if (!val && (nelem != 0)) memory_full ();
return val;
{
/* We must call malloc explicitly when BLOCK is 0, since some
reallocs don't do this. */
- void *val = (void *) (block ? realloc (block, size) : malloc (size));
+ void *val = block ? realloc (block, size) : malloc (size);
if (!val && (size != 0)) memory_full ();
return val;
if (type_index < 0 || type_index > max_lrecord_type
|| lrecord_implementations_table[type_index] != implementation)
{
- if (last_lrecord_type_index_assigned == max_lrecord_type)
- abort ();
+ assert (last_lrecord_type_index_assigned < max_lrecord_type);
type_index = ++last_lrecord_type_index_assigned;
lrecord_implementations_table[type_index] = implementation;
*(implementation->lrecord_type_index) = type_index;
int instances_on_free_list;
} lcrecord_stats [countof (lrecord_implementations_table)];
-
-static void
-reset_lcrecord_stats (void)
-{
- int i;
- for (i = 0; i < countof (lcrecord_stats); i++)
- {
- lcrecord_stats[i].instances_in_use = 0;
- lcrecord_stats[i].bytes_in_use = 0;
- lcrecord_stats[i].instances_freed = 0;
- lcrecord_stats[i].bytes_freed = 0;
- lcrecord_stats[i].instances_on_free_list = 0;
- }
-}
-
static void
tick_lcrecord_stats (CONST struct lrecord_header *h, int free_p)
{
struct lcrecord_header *header;
int num_used = 0;
/* int total_size = 0; */
- reset_lcrecord_stats ();
+
+ xzero (lcrecord_stats); /* Reset all statistics to 0. */
/* First go through and call all the finalize methods.
Then go through and free the objects. There used to
/* This is the initial (startup) directory, as used for the *scratch* buffer.
We're making this a global to make others aware of the startup directory.
+ `initial_directory' is stored in external format.
*/
char initial_directory[MAXPATHLEN+1];
}
DEFUN ("kill-buffer", Fkill_buffer, 1, 1, "bKill buffer: ", /*
-Kill the buffer BUFNAME.
+Kill the buffer BUFFER.
The argument may be a buffer or may be the name of a buffer.
An argument of nil means kill the current buffer.
Any processes that have this buffer as the `process-buffer' are killed
with `delete-process'.
*/
- (bufname))
+ (buffer))
{
/* This function can call lisp */
Lisp_Object buf;
REGISTER struct buffer *b;
struct gcpro gcpro1, gcpro2;
- if (NILP (bufname))
+ if (NILP (buffer))
buf = Fcurrent_buffer ();
- else if (BUFFERP (bufname))
- buf = bufname;
+ else if (BUFFERP (buffer))
+ buf = buffer;
else
{
- buf = get_buffer (bufname, 0);
- if (NILP (buf)) nsberror (bufname);
+ buf = get_buffer (buffer, 0);
+ if (NILP (buf)) nsberror (buffer);
}
b = XBUFFER (buf);
&& BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
{
Lisp_Object killp;
- GCPRO2 (buf, bufname);
+ GCPRO1 (buf);
killp = call1
(Qyes_or_no_p,
(emacs_doprnt_string_c
}
\f
DEFUN ("record-buffer", Frecord_buffer, 1, 1, 0, /*
-Place buffer BUF first in the buffer order.
+Place buffer BUFFER first in the buffer order.
Call this function when a buffer is selected "visibly".
This function changes the global buffer order and the per-frame buffer
of selection so that `other-buffer' will return a recently selected
buffer. See `other-buffer' for more information.
*/
- (buf))
+ (buffer))
{
REGISTER Lisp_Object lynk, prev;
struct frame *f = selected_frame ();
prev = Qnil;
for (lynk = Vbuffer_alist; CONSP (lynk); lynk = XCDR (lynk))
{
- if (EQ (XCDR (XCAR (lynk)), buf))
+ if (EQ (XCDR (XCAR (lynk)), buffer))
break;
prev = lynk;
}
prev = Qnil;
for (lynk = f->buffer_alist; CONSP (lynk); lynk = XCDR (lynk))
{
- if (EQ (XCDR (XCAR (lynk)), buf))
+ if (EQ (XCDR (XCAR (lynk)), buffer))
break;
prev = lynk;
}
Use this function before selecting the buffer, since it may need to inspect
the current buffer's major mode.
*/
- (buf))
+ (buffer))
{
int speccount = specpdl_depth ();
- REGISTER Lisp_Object function, tem;
+ Lisp_Object function = XBUFFER (Vbuffer_defaults)->major_mode;
- function = XBUFFER (Vbuffer_defaults)->major_mode;
if (NILP (function))
{
- tem = Fget (current_buffer->major_mode, Qmode_class, Qnil);
+ Lisp_Object tem = Fget (current_buffer->major_mode, Qmode_class, Qnil);
if (NILP (tem))
function = current_buffer->major_mode;
}
record_unwind_protect (Fset_buffer, Fcurrent_buffer ());
- Fset_buffer (buf);
+ Fset_buffer (buffer);
call0 (function);
return unbind_to (speccount, Qnil);
*/
())
{
- Lisp_Object buf;
- XSETBUFFER (buf, current_buffer);
- return buf;
+ Lisp_Object buffer;
+ XSETBUFFER (buffer, current_buffer);
+ return buffer;
}
\f
/* Set the current buffer to B. */
}
}
+/* Is PWD another name for `.' ? */
+static int
+directory_is_current_directory (char *pwd)
+{
+ Bufbyte *pwd_internal;
+ struct stat dotstat, pwdstat;
+
+ GET_C_CHARPTR_INT_FILENAME_DATA_ALLOCA (pwd, pwd_internal);
+
+ return (IS_DIRECTORY_SEP (*pwd_internal)
+ && stat (pwd_internal, &pwdstat) == 0
+ && stat ("." , &dotstat) == 0
+ && dotstat.st_ino == pwdstat.st_ino
+ && dotstat.st_dev == pwdstat.st_dev
+ && (int) strlen (pwd_internal) < MAXPATHLEN);
+}
+
void
init_initial_directory (void)
{
/* This function can GC */
char *pwd;
- struct stat dotstat, pwdstat;
- int rc;
initial_directory[0] = 0;
/* If PWD is accurate, use it instead of calling getcwd. This is faster
when PWD is right, and may avoid a fatal error. */
- if ((pwd = getenv ("PWD")) != 0 && IS_DIRECTORY_SEP (*pwd)
- && stat (pwd, &pwdstat) == 0
- && stat (".", &dotstat) == 0
- && dotstat.st_ino == pwdstat.st_ino
- && dotstat.st_dev == pwdstat.st_dev
- && (int) strlen (pwd) < MAXPATHLEN)
+ if ((pwd = getenv ("PWD")) != NULL
+ && directory_is_current_directory (pwd))
strcpy (initial_directory, pwd);
else if (getcwd (initial_directory, MAXPATHLEN) == NULL)
fatal ("`getcwd' failed: %s\n", strerror (errno));
- /* Maybe this should really use some standard subroutine
+ /* Make sure pwd is DIRECTORY_SEP-terminated.
+ Maybe this should really use some standard subroutine
whose definition is filename syntax dependent. */
- rc = strlen (initial_directory);
- if (!(IS_DIRECTORY_SEP (initial_directory[rc - 1])))
- {
- initial_directory[rc] = DIRECTORY_SEP;
- initial_directory[rc + 1] = '\0';
- }
+ {
+ int len = strlen (initial_directory);
+
+ if (! IS_DIRECTORY_SEP (initial_directory[len - 1]))
+ {
+ initial_directory[len] = DIRECTORY_SEP;
+ initial_directory[len + 1] = '\0';
+ }
+ }
+
/* XEmacs change: store buffer's default directory
using preferred (i.e. as defined at compile-time)
directory separator. --marcpa */
Fset_buffer (Fget_buffer_create (QSscratch));
- current_buffer->directory = build_string (initial_directory);
+ current_buffer->directory =
+ build_ext_string (initial_directory, FORMAT_FILENAME);
#if 0 /* FSFmacs */
/* #### is this correct? */
/* This is the initial (startup) directory, as used for the *scratch* buffer.
We're making this a global to make others aware of the startup directory.
+ `initial_directory' is stored in external format.
*/
extern char initial_directory[];
extern void init_initial_directory (void); /* initialize initial_directory */
}
/* Set `env' to a vector of the strings in Vprocess_environment. */
+ /* + 2 to include PWD and terminating 0. */
+ env = alloca_array (char *, XINT (Flength (Vprocess_environment)) + 2);
{
- REGISTER Lisp_Object tem;
- REGISTER char **new_env;
- REGISTER int new_length = 0;
-
- for (tem = Vprocess_environment;
- (CONSP (tem)
- && STRINGP (XCAR (tem)));
- tem = XCDR (tem))
- new_length++;
-
- /* new_length + 2 to include PWD and terminating 0. */
- env = new_env = alloca_array (char *, new_length + 2);
+ REGISTER Lisp_Object tail;
+ char **new_env = env;
/* If we have a PWD envvar and we know the real current directory,
pass one down, but with corrected value. */
*new_env++ = pwd;
/* Copy the Vprocess_environment strings into new_env. */
- for (tem = Vprocess_environment;
- (CONSP (tem)
- && STRINGP (XCAR (tem)));
- tem = XCDR (tem))
+ for (tail = Vprocess_environment;
+ CONSP (tail) && STRINGP (XCAR (tail));
+ tail = XCDR (tail))
{
char **ep = env;
- char *string = (char *) XSTRING_DATA (XCAR (tem));
- /* See if this string duplicates any string already in the env.
+ char *envvar_external;
+ Bufbyte *envvar_internal = XSTRING_DATA (XCAR (tail));
+
+ GET_C_CHARPTR_EXT_FILENAME_DATA_ALLOCA (envvar_internal, envvar_external);
+
+ /* See if envvar_external duplicates any string already in the env.
If so, don't put it in.
When an env var has multiple definitions,
we keep the definition that comes first in process-environment. */
for (; ep != new_env; ep++)
{
- char *p = *ep, *q = string;
+ char *p = *ep, *q = envvar_external;
while (1)
{
if (*q == 0)
p++, q++;
}
}
- if (pwd && !strncmp ("PWD=", string, 4))
+ if (pwd && !strncmp ("PWD=", envvar_external, 4))
{
*new_env++ = pwd;
pwd = 0;
}
else
- *new_env++ = string;
+ *new_env++ = envvar_external;
+
duplicate: ;
}
*new_env = 0;
}
+
#ifdef WINDOWSNT
prepare_standard_handles (in, out, err, handles);
set_process_dir (current_dir);
close (STDIN_FILENO);
close (STDOUT_FILENO);
close (STDERR_FILENO);
-
+
dup2 (in, STDIN_FILENO);
dup2 (out, STDOUT_FILENO);
dup2 (err, STDERR_FILENO);
-
+
close (in);
close (out);
close (err);
of a few bytes */
}
+/* Returns the home directory, in external format */
char *
get_home_directory (void)
{
}
if (initialized && output_home_warning)
{
- warn_when_safe(Quser_files_and_directories, Qwarning, "\n"
+ warn_when_safe (Quser_files_and_directories, Qwarning, "\n"
" XEmacs was unable to determine a good value for the user's $HOME\n"
" directory, and will be using the value:\n"
" %s\n"
" This is probably incorrect.",
- cached_home_directory
- );
+ cached_home_directory
+ );
}
}
- return (cached_home_directory);
+ return cached_home_directory;
}
DEFUN ("user-home-directory", Fuser_home_directory, 0, 0, 0, /*
*/
())
{
- Lisp_Object directory;
- char *path;
+ char *path = get_home_directory ();
- directory = Qnil;
- path = get_home_directory ();
- if (path != NULL)
- {
- directory =
- Fexpand_file_name (Fsubstitute_in_file_name (build_string (path)),
- Qnil);
- }
- return (directory);
+ return path == NULL ? Qnil :
+ Fexpand_file_name (Fsubstitute_in_file_name
+ (build_ext_string (path, FORMAT_FILENAME)),
+ Qnil);
}
DEFUN ("system-name", Fsystem_name, 0, 0, 0, /*
if (IS_DIRECTORY_SEP (nm[1])
|| nm[1] == 0) /* ~ by itself */
{
- if (!(newdir = (Bufbyte *) get_home_directory()))
+ char * newdir_external = get_home_directory ();
+
+ if (newdir_external == NULL)
newdir = (Bufbyte *) "";
+ else
+ GET_C_CHARPTR_INT_FILENAME_DATA_ALLOCA (newdir_external, newdir);
+
nm++;
#ifdef WINDOWSNT
collapse_newdir = 0;
}
else
{
- if (!(IS_DIRECTORY_SEP (target[0]) && IS_DIRECTORY_SEP (target[1])))
- abort ();
+ assert (IS_DIRECTORY_SEP (target[0]) && IS_DIRECTORY_SEP (target[1]));
}
CORRECT_DIR_SEPS (target);
#endif /* WINDOWSNT */
}
/*
- * Fork off a subprocess. P is a pointer to newly created subprocess
+ * Fork off a subprocess. P is a pointer to a newly created subprocess
* object. If this function signals, the caller is responsible for
* deleting (and finalizing) the process object.
*
{
/* This function rewritten by ben@xemacs.org. */
- int pid, inchannel, outchannel;
+ int pid;
+ int inchannel = -1;
+ int outchannel = -1;
/* Use volatile to protect variables from being clobbered by longjmp. */
- volatile int forkin, forkout;
+ volatile int forkin = -1;
+ volatile int forkout = -1;
volatile int pty_flag = 0;
- char **env;
- char **new_argv;
- char *current_dir;
- int i;
-
- env = environ;
-
- inchannel = outchannel = forkin = forkout = -1;
-
- /* Nothing below here GCs so our string pointers shouldn't move. */
- new_argv = alloca_array (char *, nargv + 2);
- GET_C_STRING_FILENAME_DATA_ALLOCA (program, new_argv[0]);
- for (i = 0; i < nargv; i++)
- {
- Lisp_Object tem = argv[i];
- CHECK_STRING (tem);
- new_argv[i + 1] = (char *) XSTRING_DATA (tem);
- }
- new_argv[i + 1] = 0;
- GET_C_STRING_FILENAME_DATA_ALLOCA (cur_dir, current_dir);
#ifdef HAVE_PTYS
if (!NILP (Vprocess_connection_type))
better error checking. */
#if !defined(USG)
/* On USG systems it does not work to open the pty's tty here
- and then close and reopen it in the child. */
+ and then close and reopen it in the child. */
#ifdef O_NOCTTY
/* Don't let this terminal become our controlling terminal
(in case we don't have one). */
*/
signal (SIGHUP, SIG_DFL);
}
+
+ if (pty_flag)
+ /* Set up the terminal characteristics of the pty. */
+ child_setup_tty (xforkout);
+
#endif /* HAVE_PTYS */
- signal (SIGINT, SIG_DFL);
+ signal (SIGINT, SIG_DFL);
signal (SIGQUIT, SIG_DFL);
- if (pty_flag)
- {
- /* Set up the terminal characteristics of the pty. */
- child_setup_tty (xforkout);
- }
+ {
+ char *current_dir;
+ char **new_argv = alloca_array (char *, nargv + 2);
+ int i;
- child_setup (xforkin, xforkout, xforkout, new_argv, current_dir);
- }
+ /* Nothing below here GCs so our string pointers shouldn't move. */
+ new_argv[0] = (char *) XSTRING_DATA (program);
+ for (i = 0; i < nargv; i++)
+ {
+ CHECK_STRING (argv[i]);
+ new_argv[i + 1] = (char *) XSTRING_DATA (argv[i]);
+ }
+ new_argv[i + 1] = 0;
+ GET_C_STRING_FILENAME_DATA_ALLOCA (cur_dir, current_dir);
+
+ child_setup (xforkin, xforkout, xforkout, new_argv, current_dir);
+ }
+
+ } /**** End of child code ****/
+
+ /**** Back in parent process ****/
#if !defined(__CYGWIN32__)
environ = save_environ;
#endif
io_failure:
{
- int temp = errno;
+ int save_errno = errno;
close_descriptor_pair (forkin, forkout);
close_descriptor_pair (inchannel, outchannel);
- errno = temp;
+ errno = save_errno;
report_file_error ("Opening pty or pipe", Qnil);
+ return 0; /* not reached */
}
-
- RETURN_NOT_REACHED (0);
}
/* Return nonzero if this process is a ToolTalk connection. */
#!/bin/sh
emacs_major_version=21
emacs_minor_version=2
-emacs_beta_version=7
-xemacs_codename="Ares"
+emacs_beta_version=8
+xemacs_codename="Artemis"
infodock_major_version=4
infodock_minor_version=0
infodock_build_version=1