aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorEli Zaretskii <[email protected]>2013-11-04 19:30:33 +0200
committerEli Zaretskii <[email protected]>2013-11-04 19:30:33 +0200
commitd0065ff1244871c9eb40420b88fc89f9f008b587 (patch)
treea869fa565b559c7b0a9390fd6045d7d827d001ec /src
parent7397c58760779a3aa83ff58164455761d77cd642 (diff)
Fix bug #15260 with building and installing Emacs in non-ASCII directories.
src/xdisp.c (message3_nolog, message_with_string): Encode the string before writing it to the terminal in a non-interactive session. src/lread.c (openp): If both FILENAME and SUFFIX are unibyte, make sure we concatenate them into a unibyte string. src/fileio.c (make_temp_name): Encode PREFIX, and decode the resulting temporary name before returning it to the caller. (Fexpand_file_name): If NAME is pure-ASCII and DEFAULT_DIRECTORY is a unibyte string, convert NAME to a unibyte string to ensure that the result is also a unibyte string. src/emacs.c (init_cmdargs): Use build_unibyte_string to make sure we create unibyte strings from default paths and directory/file names. src/coding.h (ENCODE_FILE): Do not attempt to encode a unibyte string. src/callproc.c (init_callproc): Use build_unibyte_string to make sure we create unibyte strings from default paths and directory/file names. src/buffer.c (init_buffer): Don't store default-directory of *scratch* in multibyte form. The original problem which led to that is described in http://lists.gnu.org/archive/html/emacs-pretest-bug/2004-11/msg00532.html, but it was solved long ago. lisp/startup.el (normal-top-level): Move setting eol-mnemonic-unix, eol-mnemonic-mac, eol-mnemonic-dos, and also setup of the locale environment and decoding all of the default-directory's to here from command-line. (command-line): Decode also argv[0]. lisp/loadup.el: Error out if default-directory is a multibyte string when we are dumping. lisp/Makefile.in (emacs): Don't set LC_ALL=C. leim/Makefile.in (RUN_EMACS): Don't set LC_ALL=C. configure.ac: Don't disallow builds in non-ASCII directories.
Diffstat (limited to 'src')
-rw-r--r--src/ChangeLog31
-rw-r--r--src/buffer.c9
-rw-r--r--src/callproc.c6
-rw-r--r--src/coding.h18
-rw-r--r--src/emacs.c10
-rw-r--r--src/fileio.c36
-rw-r--r--src/lread.c18
-rw-r--r--src/xdisp.c14
8 files changed, 107 insertions, 35 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index 1c56a7c599..f6f4dc3ef8 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,34 @@
+2013-11-04 Eli Zaretskii <[email protected]>
+
+ * xdisp.c (message3_nolog, message_with_string): Encode the string
+ before writing it to the terminal in a non-interactive session.
+
+ * lread.c (openp): If both FILENAME and SUFFIX are unibyte, make
+ sure we concatenate them into a unibyte string.
+
+ * fileio.c (make_temp_name): Encode PREFIX, and decode the
+ resulting temporary name before returning it to the caller.
+ (Fexpand_file_name): If NAME is pure-ASCII and DEFAULT_DIRECTORY
+ is a unibyte string, convert NAME to a unibyte string to ensure
+ that the result is also a unibyte string.
+
+ * emacs.c (init_cmdargs): Use build_unibyte_string to make sure we
+ create unibyte strings from default paths and directory/file
+ names.
+
+ * coding.h (ENCODE_FILE): Do not attempt to encode a unibyte
+ string.
+
+ * callproc.c (init_callproc): Use build_unibyte_string to make
+ sure we create unibyte strings from default paths and
+ directory/file names.
+
+ * buffer.c (init_buffer): Don't store default-directory of
+ 8scratch* in multibyte form. The original problem which led to
+ that is described in
+ http://lists.gnu.org/archive/html/emacs-pretest-bug/2004-11/msg00532.html,
+ but it was solved long ago. (Bug#15260)
+
2013-11-04 Paul Eggert <[email protected]>
Port to stricter C99 platforms.
diff --git a/src/buffer.c b/src/buffer.c
index e5a8af93cf..63198cd101 100644
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -5349,13 +5349,10 @@ init_buffer (void)
len++;
}
+ /* At this moment, we still don't know how to decode the directory
+ name. So, we keep the bytes in unibyte form so that file I/O
+ routines correctly get the original bytes. */
bset_directory (current_buffer, make_unibyte_string (pwd, len));
- if (! NILP (BVAR (&buffer_defaults, enable_multibyte_characters)))
- /* At this moment, we still don't know how to decode the
- directory name. So, we keep the bytes in multibyte form so
- that ENCODE_FILE correctly gets the original bytes. */
- bset_directory
- (current_buffer, string_to_multibyte (BVAR (current_buffer, directory)));
/* Add /: to the front of the name
if it would otherwise be treated as magic. */
diff --git a/src/callproc.c b/src/callproc.c
index d4b4a26ec3..2740779f51 100644
--- a/src/callproc.c
+++ b/src/callproc.c
@@ -1612,14 +1612,14 @@ init_callproc (void)
Lisp_Object tem, tem1, srcdir;
srcdir = Fexpand_file_name (build_string ("../src/"),
- build_string (PATH_DUMPLOADSEARCH));
+ build_unibyte_string (PATH_DUMPLOADSEARCH));
tem = Fexpand_file_name (build_string ("GNU"), Vdata_directory);
tem1 = Ffile_exists_p (tem);
if (!NILP (Fequal (srcdir, Vinvocation_directory)) || NILP (tem1))
{
Lisp_Object newdir;
newdir = Fexpand_file_name (build_string ("../etc/"),
- build_string (PATH_DUMPLOADSEARCH));
+ build_unibyte_string (PATH_DUMPLOADSEARCH));
tem = Fexpand_file_name (build_string ("GNU"), newdir);
tem1 = Ffile_exists_p (tem);
if (!NILP (tem1))
@@ -1646,7 +1646,7 @@ init_callproc (void)
#ifdef DOS_NT
Vshared_game_score_directory = Qnil;
#else
- Vshared_game_score_directory = build_string (PATH_GAME);
+ Vshared_game_score_directory = build_unibyte_string (PATH_GAME);
if (NILP (Ffile_accessible_directory_p (Vshared_game_score_directory)))
Vshared_game_score_directory = Qnil;
#endif
diff --git a/src/coding.h b/src/coding.h
index 0472bec99d..5a921e4495 100644
--- a/src/coding.h
+++ b/src/coding.h
@@ -670,14 +670,16 @@ struct coding_system
(code) = (s1 << 8) | s2; \
} while (0)
-/* Encode the file name NAME using the specified coding system
- for file names, if any. */
-#define ENCODE_FILE(name) \
- (! NILP (Vfile_name_coding_system) \
- ? code_convert_string_norecord (name, Vfile_name_coding_system, 1) \
- : (! NILP (Vdefault_file_name_coding_system) \
- ? code_convert_string_norecord (name, Vdefault_file_name_coding_system, 1) \
- : name))
+/* Encode the file name NAME using the specified coding system for
+ file names, if any. If NAME is a unibyte string, return NAME. */
+#define ENCODE_FILE(name) \
+ (! STRING_MULTIBYTE (name) \
+ ? name \
+ : (! NILP (Vfile_name_coding_system) \
+ ? code_convert_string_norecord (name, Vfile_name_coding_system, 1) \
+ : (! NILP (Vdefault_file_name_coding_system) \
+ ? code_convert_string_norecord (name, Vdefault_file_name_coding_system, 1) \
+ : name)))
/* Decode the file name NAME using the specified coding system
diff --git a/src/emacs.c b/src/emacs.c
index 928babb417..52d2e76dc8 100644
--- a/src/emacs.c
+++ b/src/emacs.c
@@ -393,7 +393,7 @@ init_cmdargs (int argc, char **argv, int skip_args, char *original_pwd)
initial_argv = argv;
initial_argc = argc;
- raw_name = build_string (argv[0]);
+ raw_name = build_unibyte_string (argv[0]);
/* Add /: to the front of the name
if it would otherwise be treated as magic. */
@@ -427,7 +427,9 @@ init_cmdargs (int argc, char **argv, int skip_args, char *original_pwd)
/* Emacs was started with relative path, like ./emacs.
Make it absolute. */
{
- Lisp_Object odir = original_pwd ? build_string (original_pwd) : Qnil;
+ Lisp_Object odir =
+ original_pwd ? build_unibyte_string (original_pwd) : Qnil;
+
Vinvocation_directory = Fexpand_file_name (Vinvocation_directory, odir);
}
@@ -2206,7 +2208,7 @@ decode_env_path (const char *evarname, const char *defalt)
p = strchr (path, SEPCHAR);
if (!p)
p = path + strlen (path);
- element = (p - path ? make_string (path, p - path)
+ element = (p - path ? make_unibyte_string (path, p - path)
: build_string ("."));
#ifdef WINDOWSNT
/* Relative file names in the default path are interpreted as
@@ -2216,7 +2218,7 @@ decode_env_path (const char *evarname, const char *defalt)
element = Fexpand_file_name (Fsubstring (element,
make_number (emacs_dir_len),
Qnil),
- build_string (emacs_dir));
+ build_unibyte_string (emacs_dir));
#endif
/* Add /: to the front of the name
diff --git a/src/fileio.c b/src/fileio.c
index a1dcb72b4e..884af25f9f 100644
--- a/src/fileio.c
+++ b/src/fileio.c
@@ -732,8 +732,8 @@ static unsigned make_temp_name_count, make_temp_name_count_initialized_p;
Lisp_Object
make_temp_name (Lisp_Object prefix, bool base64_p)
{
- Lisp_Object val;
- int len, clen;
+ Lisp_Object val, encoded_prefix;
+ int len;
printmax_t pid;
char *p, *data;
char pidbuf[INT_BUFSIZE_BOUND (printmax_t)];
@@ -767,12 +767,11 @@ make_temp_name (Lisp_Object prefix, bool base64_p)
#endif
}
- len = SBYTES (prefix); clen = SCHARS (prefix);
- val = make_uninit_multibyte_string (clen + 3 + pidlen, len + 3 + pidlen);
- if (!STRING_MULTIBYTE (prefix))
- STRING_SET_UNIBYTE (val);
+ encoded_prefix = ENCODE_FILE (prefix);
+ len = SBYTES (encoded_prefix);
+ val = make_uninit_string (len + 3 + pidlen);
data = SSDATA (val);
- memcpy (data, SSDATA (prefix), len);
+ memcpy (data, SSDATA (encoded_prefix), len);
p = data + len;
memcpy (p, pidbuf, pidlen);
@@ -810,7 +809,7 @@ make_temp_name (Lisp_Object prefix, bool base64_p)
{
/* We want to return only if errno is ENOENT. */
if (errno == ENOENT)
- return val;
+ return DECODE_FILE (val);
else
/* The error here is dubious, but there is little else we
can do. The alternatives are to return nil, which is
@@ -987,7 +986,26 @@ filesystem tree, not (expand-file-name ".." dirname). */)
if (multibyte != STRING_MULTIBYTE (default_directory))
{
if (multibyte)
- default_directory = string_to_multibyte (default_directory);
+ {
+ unsigned char *p = SDATA (name);
+
+ while (*p && ASCII_BYTE_P (*p))
+ p++;
+ if (*p == '\0')
+ {
+ /* NAME is a pure ASCII string, and DEFAULT_DIRECTORY is
+ unibyte. Do not convert DEFAULT_DIRECTORY to
+ multibyte; instead, convert NAME to a unibyte string,
+ so that the result of this function is also a unibyte
+ string. This is needed during bootstraping and
+ dumping, when Emacs cannot decode file names, because
+ the locale environment is not set up. */
+ name = make_unibyte_string (SSDATA (name), SBYTES (name));
+ multibyte = 0;
+ }
+ else
+ default_directory = string_to_multibyte (default_directory);
+ }
else
{
name = string_to_multibyte (name);
diff --git a/src/lread.c b/src/lread.c
index b42ac5908e..618b0cadb5 100644
--- a/src/lread.c
+++ b/src/lread.c
@@ -1500,7 +1500,8 @@ openp (Lisp_Object path, Lisp_Object str, Lisp_Object suffixes,
for (tail = NILP (suffixes) ? list1 (empty_unibyte_string) : suffixes;
CONSP (tail); tail = XCDR (tail))
{
- ptrdiff_t fnlen, lsuffix = SBYTES (XCAR (tail));
+ Lisp_Object suffix = XCAR (tail);
+ ptrdiff_t fnlen, lsuffix = SBYTES (suffix);
Lisp_Object handler;
/* Concatenate path element/specified name with the suffix.
@@ -1511,7 +1512,7 @@ openp (Lisp_Object path, Lisp_Object str, Lisp_Object suffixes,
? 2 : 0);
fnlen = SBYTES (filename) - prefixlen;
memcpy (fn, SDATA (filename) + prefixlen, fnlen);
- memcpy (fn + fnlen, SDATA (XCAR (tail)), lsuffix + 1);
+ memcpy (fn + fnlen, SDATA (suffix), lsuffix + 1);
fnlen += lsuffix;
/* Check that the file exists and is not a directory. */
/* We used to only check for handlers on non-absolute file names:
@@ -1521,7 +1522,18 @@ openp (Lisp_Object path, Lisp_Object str, Lisp_Object suffixes,
handler = Ffind_file_name_handler (filename, Qfile_exists_p);
It's not clear why that was the case and it breaks things like
(load "/bar.el") where the file is actually "/bar.el.gz". */
- string = make_string (fn, fnlen);
+ /* make_string has its own ideas on when to return a unibyte
+ string and when a multibyte string, but we know better.
+ We must have a unibyte string when dumping, since
+ file-name encoding is shaky at best at that time, and in
+ particular default-file-name-coding-system is reset
+ several times during loadup. We therefore don't want to
+ encode the file before passing it to file I/O library
+ functions. */
+ if (!STRING_MULTIBYTE (filename) && !STRING_MULTIBYTE (suffix))
+ string = make_unibyte_string (fn, fnlen);
+ else
+ string = make_string (fn, fnlen);
handler = Ffind_file_name_handler (string, Qfile_exists_p);
if ((!NILP (handler) || !NILP (predicate)) && !NATNUMP (predicate))
{
diff --git a/src/xdisp.c b/src/xdisp.c
index 9992fa4776..382f9e7a8e 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -9728,7 +9728,11 @@ message3_nolog (Lisp_Object m)
putc ('\n', stderr);
noninteractive_need_newline = 0;
if (STRINGP (m))
- fwrite (SDATA (m), SBYTES (m), 1, stderr);
+ {
+ Lisp_Object s = ENCODE_SYSTEM (m);
+
+ fwrite (SDATA (s), SBYTES (s), 1, stderr);
+ }
if (cursor_in_echo_area == 0)
fprintf (stderr, "\n");
fflush (stderr);
@@ -9803,13 +9807,19 @@ message_with_string (const char *m, Lisp_Object string, int log)
{
if (m)
{
+ /* ENCODE_SYSTEM below can GC and/or relocate the Lisp
+ String whose data pointer might be passed to us in M. So
+ we use a local copy. */
+ char *fmt = xstrdup (m);
+
if (noninteractive_need_newline)
putc ('\n', stderr);
noninteractive_need_newline = 0;
- fprintf (stderr, m, SDATA (string));
+ fprintf (stderr, fmt, SDATA (ENCODE_SYSTEM (string)));
if (!cursor_in_echo_area)
fprintf (stderr, "\n");
fflush (stderr);
+ xfree (fmt);
}
}
else if (INTERACTIVE)