/* Fully extensible Emacs, running on Unix, intended for GNU.
-Copyright (C) 1985-1987, 1993-1995, 1997-1999, 2001-2013 Free Software
-Foundation, Inc.
+Copyright (C) 1985-1987, 1993-1995, 1997-1999, 2001-2013
+ Free Software Foundation, Inc.
This file is part of GNU Emacs.
You should have received a copy of the GNU General Public License
along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
-
+#define INLINE EXTERN_INLINE
#include <config.h>
+
#include <errno.h>
#include <stdio.h>
#include <close-stream.h>
+#define MAIN_PROGRAM
#include "lisp.h"
#ifdef WINDOWSNT
#include <fcntl.h>
#include <sys/socket.h>
+#include <mbstring.h>
#include "w32.h"
#include "w32heap.h"
#endif
#include "termhooks.h"
#include "keyboard.h"
#include "keymap.h"
+#include "category.h"
+#include "charset.h"
+#include "composite.h"
+#include "dispextern.h"
+#include "syntax.h"
+#include "systime.h"
#ifdef HAVE_GNUTLS
#include "gnutls.h"
FILE visit FILE using find-file\n\
+LINE go to line LINE in next FILE\n\
+LINE:COLUMN go to line LINE, column COLUMN, in next FILE\n\
---directory, -L DIR add DIR to variable load-path\n\
+--directory, -L DIR prepend DIR to load-path (with :DIR, append DIR)\n\
--eval EXPR evaluate Emacs Lisp expression EXPR\n\
--execute EXPR evaluate Emacs Lisp expression EXPR\n\
",
abbreviation for a --option.\n\
\n\
Various environment variables and window system resources also affect\n\
-Emacs' operation. See the main documentation.\n\
+the operation of Emacs. See the main documentation.\n\
\n\
Report bugs to bug-gnu-emacs@gnu.org. First, please see the Bugs\n\
section of the Emacs manual or the file BUGS.\n"
/* Code for dealing with Lisp access to the Unix command line. */
static void
-init_cmdargs (int argc, char **argv, int skip_args)
+init_cmdargs (int argc, char **argv, int skip_args, char *original_pwd)
{
register int i;
Lisp_Object name, dir, handler;
initial_argv = argv;
initial_argc = argc;
- raw_name = build_string (argv[0]);
+#ifdef WINDOWSNT
+ /* Must use argv[0] converted to UTF-8, as it begets many standard
+ file and directory names. */
+ {
+ char argv0[MAX_UTF8_PATH];
+
+ if (filename_from_ansi (argv[0], argv0) == 0)
+ raw_name = build_unibyte_string (argv0);
+ else
+ raw_name = build_unibyte_string (argv[0]);
+ }
+#else
+ raw_name = build_unibyte_string (argv[0]);
+#endif
/* Add /: to the front of the name
if it would otherwise be treated as magic. */
&& NILP (Ffile_name_absolute_p (Vinvocation_directory)))
/* Emacs was started with relative path, like ./emacs.
Make it absolute. */
- Vinvocation_directory = Fexpand_file_name (Vinvocation_directory, Qnil);
+ {
+ Lisp_Object odir =
+ original_pwd ? build_unibyte_string (original_pwd) : Qnil;
+
+ Vinvocation_directory = Fexpand_file_name (Vinvocation_directory, odir);
+ }
Vinstallation_directory = Qnil;
#endif
char *ch_to_dir;
+ /* If we use --chdir, this records the original directory. */
+ char *original_pwd = 0;
+
#if GC_MARK_STACK
stack_base = &dummy;
#endif
}
if (argmatch (argv, argc, "-chdir", "--chdir", 4, &ch_to_dir, &skip_args))
- if (chdir (ch_to_dir) == -1)
- {
- fprintf (stderr, "%s: Can't chdir to %s: %s\n",
- argv[0], ch_to_dir, strerror (errno));
- exit (1);
- }
+ {
+#ifdef WINDOWSNT
+ /* argv[] array is kept in its original ANSI codepage encoding,
+ we need to convert to UTF-8, for chdir to work. */
+ char newdir[MAX_UTF8_PATH];
+
+ filename_from_ansi (ch_to_dir, newdir);
+ ch_to_dir = newdir;
+#endif
+ original_pwd = get_current_dir_name ();
+ if (chdir (ch_to_dir) != 0)
+ {
+ fprintf (stderr, "%s: Can't chdir to %s: %s\n",
+ argv[0], ch_to_dir, strerror (errno));
+ exit (1);
+ }
+ }
dumping = !initialized && (strcmp (argv[argc - 1], "dump") == 0
|| strcmp (argv[argc - 1], "bootstrap") == 0);
if (!noninteractive)
{
#ifdef NS_IMPL_COCOA
+ /* Started from GUI? */
+ /* FIXME: Do the right thing if getenv returns NULL, or if
+ chdir fails. */
+ if (! inhibit_window_system && ! isatty (0))
+ chdir (getenv ("HOME"));
if (skip_args < argc)
{
- /* FIXME: Do the right thing if getenv returns NULL, or if
- chdir fails. */
if (!strncmp (argv[skip_args], "-psn", 4))
{
skip_args += 1;
init_buffer (); /* Init default directory of main buffer. */
init_callproc_1 (); /* Must precede init_cmdargs and init_sys_modes. */
- init_cmdargs (argc, argv, skip_args); /* Must precede init_lread. */
+
+ /* Must precede init_lread. */
+ init_cmdargs (argc, argv, skip_args, original_pwd);
if (initialized)
{
char *file;
/* Handle -l loadup, args passed by Makefile. */
if (argmatch (argv, argc, "-l", "--load", 3, &file, &skip_args))
- Vtop_level = list2 (intern_c_string ("load"), build_string (file));
+ {
+#ifdef WINDOWSNT
+ char file_utf8[MAX_UTF8_PATH];
+
+ if (filename_from_ansi (file, file_utf8) == 0)
+ file = file_utf8;
+#endif
+ Vtop_level = list2 (intern_c_string ("load"),
+ build_unibyte_string (file));
+ }
/* Unless next switch is -nl, load "loadup.el" first thing. */
if (! no_loadup)
Vtop_level = list2 (intern_c_string ("load"),
CHECK_STRING (filename);
filename = Fexpand_file_name (filename, Qnil);
+ filename = ENCODE_FILE (filename);
if (!NILP (symfile))
{
CHECK_STRING (symfile);
if (SCHARS (symfile))
- symfile = Fexpand_file_name (symfile, Qnil);
+ {
+ symfile = Fexpand_file_name (symfile, Qnil);
+ symfile = ENCODE_FILE (symfile);
+ }
}
tem = Vpurify_flag;
Lisp_Object lpath, element, tem;
#ifdef WINDOWSNT
bool defaulted = 0;
- const char *emacs_dir = egetenv ("emacs_dir");
static const char *emacs_dir_env = "%emacs_dir%/";
const size_t emacs_dir_len = strlen (emacs_dir_env);
+ const char *edir = egetenv ("emacs_dir");
+ char emacs_dir[MAX_UTF8_PATH];
+
+ /* egetenv looks in process-environment, which holds the variables
+ in their original system-locale encoding. We need emacs_dir to
+ be in UTF-8. */
+ filename_from_ansi (edir, emacs_dir);
#endif
/* It's okay to use getenv here, because this function is only used
/* Ensure values from the environment use the proper directory separator. */
if (path)
{
- char *path_copy = alloca (strlen (path) + 1);
+ char *path_copy;
+
+#ifdef WINDOWSNT
+ char *path_utf8, *q, *d;
+ int cnv_result;
+
+ /* Convert each element of PATH to UTF-8. */
+ p = path_copy = alloca (strlen (path) + 1);
+ strcpy (path_copy, path);
+ d = path_utf8 = alloca (4 * strlen (path) + 1);
+ *d = '\0';
+ do {
+ q = _mbschr (p, SEPCHAR);
+ if (q)
+ *q = '\0';
+ cnv_result = filename_from_ansi (p, d);
+ if (q)
+ {
+ *q++ = SEPCHAR;
+ p = q;
+ /* If conversion of this PATH elements fails, make sure
+ destination pointer will stay put, thus effectively
+ ignoring the offending element. */
+ if (cnv_result == 0)
+ {
+ d += strlen (d);
+ *d++ = SEPCHAR;
+ }
+ }
+ else if (cnv_result != 0 && d > path_utf8)
+ d[-1] = '\0'; /* remove last semi-colon and null-terminate PATH */
+ } while (q);
+ path_copy = path_utf8;
+#else /* MSDOS */
+ path_copy = alloca (strlen (path) + 1);
strcpy (path_copy, path);
- dostounix_filename (path_copy, 0);
+#endif
+ dostounix_filename (path_copy);
path = path_copy;
}
#endif
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
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