Fixed initialization code and default-printer-name.
[bpt/emacs.git] / src / emacs.c
index dc4c23b..22be1d8 100644 (file)
@@ -18,8 +18,9 @@ GNU General Public License for more details.
 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>
 
@@ -29,11 +30,13 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #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
@@ -72,6 +75,12 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 #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"
@@ -246,7 +255,7 @@ Action options:\n\
 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\
 ",
@@ -375,7 +384,7 @@ terminate_due_to_signal (int sig, int backtrace_limit)
 /* 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;
@@ -385,7 +394,20 @@ init_cmdargs (int argc, char **argv, int skip_args)
   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.  */
@@ -418,7 +440,12 @@ init_cmdargs (int argc, char **argv, int skip_args)
       && 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;
 
@@ -691,6 +718,9 @@ main (int argc, char **argv)
 #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
@@ -778,12 +808,23 @@ main (int argc, char **argv)
     }
 
   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);
@@ -1179,10 +1220,13 @@ Using an Emacs configured with --with-x-toolkit=lucid does not have this problem
   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;
@@ -1310,7 +1354,9 @@ Using an Emacs configured with --with-x-toolkit=lucid does not have this problem
   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)
     {
@@ -1506,7 +1552,16 @@ Using an Emacs configured with --with-x-toolkit=lucid does not have this problem
       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"),
@@ -2033,11 +2088,15 @@ You must run Emacs in batch mode in order to dump it.  */)
 
   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;
@@ -2145,9 +2204,15 @@ decode_env_path (const char *evarname, const char *defalt)
   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
@@ -2168,9 +2233,44 @@ decode_env_path (const char *evarname, const char *defalt)
   /* 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
@@ -2180,7 +2280,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
@@ -2190,7 +2290,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