DWORD flags;
char dir[ MAX_PATH ];
char *p;
+ const char *ext;
if (cp == NULL) emacs_abort ();
if (*p == '/')
*p = '\\';
+ /* CreateProcess handles batch files as exe specially. This special
+ handling fails when both the batch file and arguments are quoted.
+ We pass NULL as exe to avoid the special handling. */
+ if (exe && cmdline[0] == '"' &&
+ (ext = strrchr (exe, '.')) &&
+ (xstrcasecmp (ext, ".bat") == 0
+ || xstrcasecmp (ext, ".cmd") == 0))
+ exe = NULL;
+
flags = (!NILP (Vw32_start_process_share_console)
? CREATE_NEW_PROCESS_GROUP
: CREATE_NEW_CONSOLE);
program = ENCODE_FILE (full);
cmdname = SDATA (program);
}
+ else
+ {
+ char *p = alloca (strlen (cmdname) + 1);
+
+ /* Don't change the command name we were passed by our caller
+ (unixtodos_filename below will destructively mirror forward
+ slashes). */
+ cmdname = strcpy (p, cmdname);
+ }
/* make sure argv[0] and cmdname are both in DOS format */
unixtodos_filename (cmdname);
strcpy (cmdname, egetenv ("CMDPROXY"));
else
{
- strcpy (cmdname, SDATA (Vinvocation_directory));
+ lispstpcpy (cmdname, Vinvocation_directory);
strcat (cmdname, "cmdproxy.exe");
}
function isn't given a context pointer. */
Lisp_Object Vw32_valid_locale_ids;
-static BOOL CALLBACK
+static BOOL CALLBACK ALIGN_STACK
enum_locale_fn (LPTSTR localeNum)
{
DWORD id = int_from_hex (localeNum);
function isn't given a context pointer. */
Lisp_Object Vw32_valid_codepages;
-static BOOL CALLBACK
+static BOOL CALLBACK ALIGN_STACK
enum_codepage_fn (LPTSTR codepageNum)
{
DWORD id = atoi (codepageNum);
if (GetLocaleInfo (try_lcid, LOCALE_SABBREVLANGNAME,
locval, LOCALE_NAME_MAX_LENGTH))
{
+ /* This is for when they only specify the language, as in "ENU". */
+ if (stricmp (locval, lname) == 0)
+ {
+ found_lcid = try_lcid;
+ return FALSE;
+ }
strcat (locval, "_");
if (GetLocaleInfo (try_lcid, LOCALE_SABBREVCTRYNAME,
locval + strlen (locval), LOCALE_NAME_MAX_LENGTH))
#ifndef _NSLCMPERROR
# define _NSLCMPERROR INT_MAX
#endif
+#ifndef LINGUISTIC_IGNORECASE
+# define LINGUISTIC_IGNORECASE 0x00000010
+#endif
int
-w32_compare_strings (const char *s1, const char *s2, char *locname)
+w32_compare_strings (const char *s1, const char *s2, char *locname,
+ int ignore_case)
{
LCID lcid = GetThreadLocale ();
wchar_t *string1_w, *string2_w;
int val, needed;
extern BOOL g_b_init_compare_string_w;
static int (WINAPI *pCompareStringW)(LCID, DWORD, LPCWSTR, int, LPCWSTR, int);
+ DWORD flags = 0;
USE_SAFE_ALLOCA;
+ /* The LCID machinery doesn't seem to support the "C" locale, so we
+ need to do that by hand. */
+ if (locname
+ && ((locname[0] == 'C' && (locname[1] == '\0' || locname[1] == '.'))
+ || strcmp (locname, "POSIX") == 0))
+ return (ignore_case ? stricmp (s1, s2) : strcmp (s1, s2));
+
if (!g_b_init_compare_string_w)
{
if (os_subtype == OS_9X)
if (new_lcid > 0)
lcid = new_lcid;
+ else
+ error ("Invalid locale %s: Invalid argument", locname);
}
- /* FIXME: Need a way to control the FLAGS argument, perhaps via the
- CODESET part of LOCNAME. In particular, ls-lisp will want
- NORM_IGNORESYMBOLS and sometimes LINGUISTIC_IGNORECASE or
- NORM_IGNORECASE. */
- val = pCompareStringW (lcid, 0, string1_w, -1, string2_w, -1);
+ if (ignore_case)
+ {
+ /* NORM_IGNORECASE ignores any tertiary distinction, not just
+ case variants. LINGUISTIC_IGNORECASE is more selective, and
+ is sensitive to the locale's language, but it is not
+ available before Vista. */
+ if (w32_major_version >= 6)
+ flags |= LINGUISTIC_IGNORECASE;
+ else
+ flags |= NORM_IGNORECASE;
+ }
+ /* This approximates what glibc collation functions do when the
+ locale's codeset is UTF-8. */
+ if (!NILP (Vw32_collate_ignore_punctuation))
+ flags |= NORM_IGNORESYMBOLS;
+ val = pCompareStringW (lcid, flags, string1_w, -1, string2_w, -1);
SAFE_FREE ();
if (!val)
{
where the performance impact may be noticeable even on modern hardware. */);
Vw32_get_true_file_attributes = Qlocal;
+ DEFVAR_LISP ("w32-collate-ignore-punctuation",
+ Vw32_collate_ignore_punctuation,
+ doc: /* Non-nil causes string collation functions ignore punctuation on MS-Windows.
+On Posix platforms, `string-collate-lessp' and `string-collate-equalp'
+ignore punctuation characters when they compare strings, if the
+locale's codeset is UTF-8, as in \"en_US.UTF-8\". Binding this option
+to a non-nil value will achieve a similar effect on MS-Windows, where
+locales with UTF-8 codeset are not supported.
+
+Note that setting this to non-nil will also ignore blanks and symbols
+in the strings. So do NOT use this option when comparing file names
+for equality, only when you need to sort them. */);
+ Vw32_collate_ignore_punctuation = Qnil;
+
staticpro (&Vw32_valid_locale_ids);
staticpro (&Vw32_valid_codepages);
}