aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorEli Zaretskii2013-11-04 19:30:33 +0200
committerEli Zaretskii2013-11-04 19:30:33 +0200
commitd0065ff1244871c9eb40420b88fc89f9f008b587 (patch)
treea869fa565b559c7b0a9390fd6045d7d827d001ec /src
parent7397c58760779a3aa83ff58164455761d77cd642 (diff)
downloademacs-d0065ff1244871c9eb40420b88fc89f9f008b587.tar.gz
emacs-d0065ff1244871c9eb40420b88fc89f9f008b587.zip
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 1c56a7c5996..f6f4dc3ef88 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,34 @@
12013-11-04 Eli Zaretskii <eliz@gnu.org>
2
3 * xdisp.c (message3_nolog, message_with_string): Encode the string
4 before writing it to the terminal in a non-interactive session.
5
6 * lread.c (openp): If both FILENAME and SUFFIX are unibyte, make
7 sure we concatenate them into a unibyte string.
8
9 * fileio.c (make_temp_name): Encode PREFIX, and decode the
10 resulting temporary name before returning it to the caller.
11 (Fexpand_file_name): If NAME is pure-ASCII and DEFAULT_DIRECTORY
12 is a unibyte string, convert NAME to a unibyte string to ensure
13 that the result is also a unibyte string.
14
15 * emacs.c (init_cmdargs): Use build_unibyte_string to make sure we
16 create unibyte strings from default paths and directory/file
17 names.
18
19 * coding.h (ENCODE_FILE): Do not attempt to encode a unibyte
20 string.
21
22 * callproc.c (init_callproc): Use build_unibyte_string to make
23 sure we create unibyte strings from default paths and
24 directory/file names.
25
26 * buffer.c (init_buffer): Don't store default-directory of
27 8scratch* in multibyte form. The original problem which led to
28 that is described in
29 http://lists.gnu.org/archive/html/emacs-pretest-bug/2004-11/msg00532.html,
30 but it was solved long ago. (Bug#15260)
31
12013-11-04 Paul Eggert <eggert@cs.ucla.edu> 322013-11-04 Paul Eggert <eggert@cs.ucla.edu>
2 33
3 Port to stricter C99 platforms. 34 Port to stricter C99 platforms.
diff --git a/src/buffer.c b/src/buffer.c
index e5a8af93cf0..63198cd1018 100644
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -5349,13 +5349,10 @@ init_buffer (void)
5349 len++; 5349 len++;
5350 } 5350 }
5351 5351
5352 /* At this moment, we still don't know how to decode the directory
5353 name. So, we keep the bytes in unibyte form so that file I/O
5354 routines correctly get the original bytes. */
5352 bset_directory (current_buffer, make_unibyte_string (pwd, len)); 5355 bset_directory (current_buffer, make_unibyte_string (pwd, len));
5353 if (! NILP (BVAR (&buffer_defaults, enable_multibyte_characters)))
5354 /* At this moment, we still don't know how to decode the
5355 directory name. So, we keep the bytes in multibyte form so
5356 that ENCODE_FILE correctly gets the original bytes. */
5357 bset_directory
5358 (current_buffer, string_to_multibyte (BVAR (current_buffer, directory)));
5359 5356
5360 /* Add /: to the front of the name 5357 /* Add /: to the front of the name
5361 if it would otherwise be treated as magic. */ 5358 if it would otherwise be treated as magic. */
diff --git a/src/callproc.c b/src/callproc.c
index d4b4a26ec3a..2740779f513 100644
--- a/src/callproc.c
+++ b/src/callproc.c
@@ -1612,14 +1612,14 @@ init_callproc (void)
1612 Lisp_Object tem, tem1, srcdir; 1612 Lisp_Object tem, tem1, srcdir;
1613 1613
1614 srcdir = Fexpand_file_name (build_string ("../src/"), 1614 srcdir = Fexpand_file_name (build_string ("../src/"),
1615 build_string (PATH_DUMPLOADSEARCH)); 1615 build_unibyte_string (PATH_DUMPLOADSEARCH));
1616 tem = Fexpand_file_name (build_string ("GNU"), Vdata_directory); 1616 tem = Fexpand_file_name (build_string ("GNU"), Vdata_directory);
1617 tem1 = Ffile_exists_p (tem); 1617 tem1 = Ffile_exists_p (tem);
1618 if (!NILP (Fequal (srcdir, Vinvocation_directory)) || NILP (tem1)) 1618 if (!NILP (Fequal (srcdir, Vinvocation_directory)) || NILP (tem1))
1619 { 1619 {
1620 Lisp_Object newdir; 1620 Lisp_Object newdir;
1621 newdir = Fexpand_file_name (build_string ("../etc/"), 1621 newdir = Fexpand_file_name (build_string ("../etc/"),
1622 build_string (PATH_DUMPLOADSEARCH)); 1622 build_unibyte_string (PATH_DUMPLOADSEARCH));
1623 tem = Fexpand_file_name (build_string ("GNU"), newdir); 1623 tem = Fexpand_file_name (build_string ("GNU"), newdir);
1624 tem1 = Ffile_exists_p (tem); 1624 tem1 = Ffile_exists_p (tem);
1625 if (!NILP (tem1)) 1625 if (!NILP (tem1))
@@ -1646,7 +1646,7 @@ init_callproc (void)
1646#ifdef DOS_NT 1646#ifdef DOS_NT
1647 Vshared_game_score_directory = Qnil; 1647 Vshared_game_score_directory = Qnil;
1648#else 1648#else
1649 Vshared_game_score_directory = build_string (PATH_GAME); 1649 Vshared_game_score_directory = build_unibyte_string (PATH_GAME);
1650 if (NILP (Ffile_accessible_directory_p (Vshared_game_score_directory))) 1650 if (NILP (Ffile_accessible_directory_p (Vshared_game_score_directory)))
1651 Vshared_game_score_directory = Qnil; 1651 Vshared_game_score_directory = Qnil;
1652#endif 1652#endif
diff --git a/src/coding.h b/src/coding.h
index 0472bec99de..5a921e44950 100644
--- a/src/coding.h
+++ b/src/coding.h
@@ -670,14 +670,16 @@ struct coding_system
670 (code) = (s1 << 8) | s2; \ 670 (code) = (s1 << 8) | s2; \
671 } while (0) 671 } while (0)
672 672
673/* Encode the file name NAME using the specified coding system 673/* Encode the file name NAME using the specified coding system for
674 for file names, if any. */ 674 file names, if any. If NAME is a unibyte string, return NAME. */
675#define ENCODE_FILE(name) \ 675#define ENCODE_FILE(name) \
676 (! NILP (Vfile_name_coding_system) \ 676 (! STRING_MULTIBYTE (name) \
677 ? code_convert_string_norecord (name, Vfile_name_coding_system, 1) \ 677 ? name \
678 : (! NILP (Vdefault_file_name_coding_system) \ 678 : (! NILP (Vfile_name_coding_system) \
679 ? code_convert_string_norecord (name, Vdefault_file_name_coding_system, 1) \ 679 ? code_convert_string_norecord (name, Vfile_name_coding_system, 1) \
680 : name)) 680 : (! NILP (Vdefault_file_name_coding_system) \
681 ? code_convert_string_norecord (name, Vdefault_file_name_coding_system, 1) \
682 : name)))
681 683
682 684
683/* Decode the file name NAME using the specified coding system 685/* Decode the file name NAME using the specified coding system
diff --git a/src/emacs.c b/src/emacs.c
index 928babb417c..52d2e76dc87 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)
393 initial_argv = argv; 393 initial_argv = argv;
394 initial_argc = argc; 394 initial_argc = argc;
395 395
396 raw_name = build_string (argv[0]); 396 raw_name = build_unibyte_string (argv[0]);
397 397
398 /* Add /: to the front of the name 398 /* Add /: to the front of the name
399 if it would otherwise be treated as magic. */ 399 if it would otherwise be treated as magic. */
@@ -427,7 +427,9 @@ init_cmdargs (int argc, char **argv, int skip_args, char *original_pwd)
427 /* Emacs was started with relative path, like ./emacs. 427 /* Emacs was started with relative path, like ./emacs.
428 Make it absolute. */ 428 Make it absolute. */
429 { 429 {
430 Lisp_Object odir = original_pwd ? build_string (original_pwd) : Qnil; 430 Lisp_Object odir =
431 original_pwd ? build_unibyte_string (original_pwd) : Qnil;
432
431 Vinvocation_directory = Fexpand_file_name (Vinvocation_directory, odir); 433 Vinvocation_directory = Fexpand_file_name (Vinvocation_directory, odir);
432 } 434 }
433 435
@@ -2206,7 +2208,7 @@ decode_env_path (const char *evarname, const char *defalt)
2206 p = strchr (path, SEPCHAR); 2208 p = strchr (path, SEPCHAR);
2207 if (!p) 2209 if (!p)
2208 p = path + strlen (path); 2210 p = path + strlen (path);
2209 element = (p - path ? make_string (path, p - path) 2211 element = (p - path ? make_unibyte_string (path, p - path)
2210 : build_string (".")); 2212 : build_string ("."));
2211#ifdef WINDOWSNT 2213#ifdef WINDOWSNT
2212 /* Relative file names in the default path are interpreted as 2214 /* Relative file names in the default path are interpreted as
@@ -2216,7 +2218,7 @@ decode_env_path (const char *evarname, const char *defalt)
2216 element = Fexpand_file_name (Fsubstring (element, 2218 element = Fexpand_file_name (Fsubstring (element,
2217 make_number (emacs_dir_len), 2219 make_number (emacs_dir_len),
2218 Qnil), 2220 Qnil),
2219 build_string (emacs_dir)); 2221 build_unibyte_string (emacs_dir));
2220#endif 2222#endif
2221 2223
2222 /* Add /: to the front of the name 2224 /* Add /: to the front of the name
diff --git a/src/fileio.c b/src/fileio.c
index a1dcb72b4e4..884af25f9fc 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;
732Lisp_Object 732Lisp_Object
733make_temp_name (Lisp_Object prefix, bool base64_p) 733make_temp_name (Lisp_Object prefix, bool base64_p)
734{ 734{
735 Lisp_Object val; 735 Lisp_Object val, encoded_prefix;
736 int len, clen; 736 int len;
737 printmax_t pid; 737 printmax_t pid;
738 char *p, *data; 738 char *p, *data;
739 char pidbuf[INT_BUFSIZE_BOUND (printmax_t)]; 739 char pidbuf[INT_BUFSIZE_BOUND (printmax_t)];
@@ -767,12 +767,11 @@ make_temp_name (Lisp_Object prefix, bool base64_p)
767#endif 767#endif
768 } 768 }
769 769
770 len = SBYTES (prefix); clen = SCHARS (prefix); 770 encoded_prefix = ENCODE_FILE (prefix);
771 val = make_uninit_multibyte_string (clen + 3 + pidlen, len + 3 + pidlen); 771 len = SBYTES (encoded_prefix);
772 if (!STRING_MULTIBYTE (prefix)) 772 val = make_uninit_string (len + 3 + pidlen);
773 STRING_SET_UNIBYTE (val);
774 data = SSDATA (val); 773 data = SSDATA (val);
775 memcpy (data, SSDATA (prefix), len); 774 memcpy (data, SSDATA (encoded_prefix), len);
776 p = data + len; 775 p = data + len;
777 776
778 memcpy (p, pidbuf, pidlen); 777 memcpy (p, pidbuf, pidlen);
@@ -810,7 +809,7 @@ make_temp_name (Lisp_Object prefix, bool base64_p)
810 { 809 {
811 /* We want to return only if errno is ENOENT. */ 810 /* We want to return only if errno is ENOENT. */
812 if (errno == ENOENT) 811 if (errno == ENOENT)
813 return val; 812 return DECODE_FILE (val);
814 else 813 else
815 /* The error here is dubious, but there is little else we 814 /* The error here is dubious, but there is little else we
816 can do. The alternatives are to return nil, which is 815 can do. The alternatives are to return nil, which is
@@ -987,7 +986,26 @@ filesystem tree, not (expand-file-name ".." dirname). */)
987 if (multibyte != STRING_MULTIBYTE (default_directory)) 986 if (multibyte != STRING_MULTIBYTE (default_directory))
988 { 987 {
989 if (multibyte) 988 if (multibyte)
990 default_directory = string_to_multibyte (default_directory); 989 {
990 unsigned char *p = SDATA (name);
991
992 while (*p && ASCII_BYTE_P (*p))
993 p++;
994 if (*p == '\0')
995 {
996 /* NAME is a pure ASCII string, and DEFAULT_DIRECTORY is
997 unibyte. Do not convert DEFAULT_DIRECTORY to
998 multibyte; instead, convert NAME to a unibyte string,
999 so that the result of this function is also a unibyte
1000 string. This is needed during bootstraping and
1001 dumping, when Emacs cannot decode file names, because
1002 the locale environment is not set up. */
1003 name = make_unibyte_string (SSDATA (name), SBYTES (name));
1004 multibyte = 0;
1005 }
1006 else
1007 default_directory = string_to_multibyte (default_directory);
1008 }
991 else 1009 else
992 { 1010 {
993 name = string_to_multibyte (name); 1011 name = string_to_multibyte (name);
diff --git a/src/lread.c b/src/lread.c
index b42ac5908e9..618b0cadb53 100644
--- a/src/lread.c
+++ b/src/lread.c
@@ -1500,7 +1500,8 @@ openp (Lisp_Object path, Lisp_Object str, Lisp_Object suffixes,
1500 for (tail = NILP (suffixes) ? list1 (empty_unibyte_string) : suffixes; 1500 for (tail = NILP (suffixes) ? list1 (empty_unibyte_string) : suffixes;
1501 CONSP (tail); tail = XCDR (tail)) 1501 CONSP (tail); tail = XCDR (tail))
1502 { 1502 {
1503 ptrdiff_t fnlen, lsuffix = SBYTES (XCAR (tail)); 1503 Lisp_Object suffix = XCAR (tail);
1504 ptrdiff_t fnlen, lsuffix = SBYTES (suffix);
1504 Lisp_Object handler; 1505 Lisp_Object handler;
1505 1506
1506 /* Concatenate path element/specified name with the suffix. 1507 /* Concatenate path element/specified name with the suffix.
@@ -1511,7 +1512,7 @@ openp (Lisp_Object path, Lisp_Object str, Lisp_Object suffixes,
1511 ? 2 : 0); 1512 ? 2 : 0);
1512 fnlen = SBYTES (filename) - prefixlen; 1513 fnlen = SBYTES (filename) - prefixlen;
1513 memcpy (fn, SDATA (filename) + prefixlen, fnlen); 1514 memcpy (fn, SDATA (filename) + prefixlen, fnlen);
1514 memcpy (fn + fnlen, SDATA (XCAR (tail)), lsuffix + 1); 1515 memcpy (fn + fnlen, SDATA (suffix), lsuffix + 1);
1515 fnlen += lsuffix; 1516 fnlen += lsuffix;
1516 /* Check that the file exists and is not a directory. */ 1517 /* Check that the file exists and is not a directory. */
1517 /* We used to only check for handlers on non-absolute file names: 1518 /* 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,
1521 handler = Ffind_file_name_handler (filename, Qfile_exists_p); 1522 handler = Ffind_file_name_handler (filename, Qfile_exists_p);
1522 It's not clear why that was the case and it breaks things like 1523 It's not clear why that was the case and it breaks things like
1523 (load "/bar.el") where the file is actually "/bar.el.gz". */ 1524 (load "/bar.el") where the file is actually "/bar.el.gz". */
1524 string = make_string (fn, fnlen); 1525 /* make_string has its own ideas on when to return a unibyte
1526 string and when a multibyte string, but we know better.
1527 We must have a unibyte string when dumping, since
1528 file-name encoding is shaky at best at that time, and in
1529 particular default-file-name-coding-system is reset
1530 several times during loadup. We therefore don't want to
1531 encode the file before passing it to file I/O library
1532 functions. */
1533 if (!STRING_MULTIBYTE (filename) && !STRING_MULTIBYTE (suffix))
1534 string = make_unibyte_string (fn, fnlen);
1535 else
1536 string = make_string (fn, fnlen);
1525 handler = Ffind_file_name_handler (string, Qfile_exists_p); 1537 handler = Ffind_file_name_handler (string, Qfile_exists_p);
1526 if ((!NILP (handler) || !NILP (predicate)) && !NATNUMP (predicate)) 1538 if ((!NILP (handler) || !NILP (predicate)) && !NATNUMP (predicate))
1527 { 1539 {
diff --git a/src/xdisp.c b/src/xdisp.c
index 9992fa4776a..382f9e7a8e1 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -9728,7 +9728,11 @@ message3_nolog (Lisp_Object m)
9728 putc ('\n', stderr); 9728 putc ('\n', stderr);
9729 noninteractive_need_newline = 0; 9729 noninteractive_need_newline = 0;
9730 if (STRINGP (m)) 9730 if (STRINGP (m))
9731 fwrite (SDATA (m), SBYTES (m), 1, stderr); 9731 {
9732 Lisp_Object s = ENCODE_SYSTEM (m);
9733
9734 fwrite (SDATA (s), SBYTES (s), 1, stderr);
9735 }
9732 if (cursor_in_echo_area == 0) 9736 if (cursor_in_echo_area == 0)
9733 fprintf (stderr, "\n"); 9737 fprintf (stderr, "\n");
9734 fflush (stderr); 9738 fflush (stderr);
@@ -9803,13 +9807,19 @@ message_with_string (const char *m, Lisp_Object string, int log)
9803 { 9807 {
9804 if (m) 9808 if (m)
9805 { 9809 {
9810 /* ENCODE_SYSTEM below can GC and/or relocate the Lisp
9811 String whose data pointer might be passed to us in M. So
9812 we use a local copy. */
9813 char *fmt = xstrdup (m);
9814
9806 if (noninteractive_need_newline) 9815 if (noninteractive_need_newline)
9807 putc ('\n', stderr); 9816 putc ('\n', stderr);
9808 noninteractive_need_newline = 0; 9817 noninteractive_need_newline = 0;
9809 fprintf (stderr, m, SDATA (string)); 9818 fprintf (stderr, fmt, SDATA (ENCODE_SYSTEM (string)));
9810 if (!cursor_in_echo_area) 9819 if (!cursor_in_echo_area)
9811 fprintf (stderr, "\n"); 9820 fprintf (stderr, "\n");
9812 fflush (stderr); 9821 fflush (stderr);
9822 xfree (fmt);
9813 } 9823 }
9814 } 9824 }
9815 else if (INTERACTIVE) 9825 else if (INTERACTIVE)