From: curtis AT pdi DOT com (Curtis Galloway) Subject: Re: Case sensitive filenames 24 Jan 1998 15:44:41 -0800 Message-ID: <34C7DD8B.B71693B1.cygnus.gnu-win32@pdi.com> References: <19980120135538 DOT 4361 DOT qmail AT hotmail DOT com> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit To: Earnie Boyd Cc: nathan AT alexandria DOT lcs DOT mit DOT edu, gnu-win32 AT cygnus DOT com This has gone around and around. My opinion is that gnuwin32 is broken if it imposes semantics on the filesystem that the filesystem doesn't support. I'm a UNIX programmer, and I think it's a pain. It's also pretty easy to fix. I posted a patch back in May of last year to do this; apparently no one like it enough to incorporate it into the official sources. I have included my original message below. --Curtis Earnie Boyd wrote: > [snip] > TOO BAD > WIN32 ISN'T CASE SENSITIVE. ==== my original message: ===== Subject: Re: Fix to readline for case-insensitive file-name completion Date: Wed, 21 May 1997 08:55:02 -0700 From: Curtis Galloway To: "gnu-win32 AT cygnus DOT com" You can argue this several ways, but my opinion is that the function of the shell should follow the function of the OS. On UNIX, I want my shell to be case-sensitive; on Win32, I want it to be case-insensitive. But I can see why you would want the filename completion to pay attention to case. I think it's even possible to have a case-sensitive filesystem on a Win32 machine with an NFS client. Here are diffs to do case-insensitive globbing and filename completion. They are set to be case-insensitive by default on Win32, but can be turned off by unsetting the special variables "glob_case_fold" and "completion_case_fold". --Curtis Galloway *** subst.c.00 Tue May 20 16:25:54 1997 --- subst.c Wed May 21 07:28:22 1997 *************** *** 74,79 **** --- 74,83 ---- extern int no_line_editing; extern int hostname_list_initialized; #endif + #if defined(__GO32__) || defined(__CYGWIN32__) + extern int glob_case_fold; + extern int completion_case_fold; + #endif #if !defined (USE_POSIX_GLOB_LIBRARY) extern int glob_dot_filenames, noglob_dot_filenames; *************** *** 4477,4482 **** --- 4481,4491 ---- sv_glob_dot_filenames (), sv_nolinks (), sv_noclobber (), sv_allow_null_glob_expansion (), sv_strict_posix (); + #if defined(__GO32__) || defined(__CYGWIN32__) + void sv_glob_case_fold (); + void sv_completion_case_fold (); + #endif + #if defined (READLINE) void sv_terminal (), sv_hostname_completion_file (); #endif *************** *** 4549,4554 **** --- 4558,4567 ---- { "allow_null_glob_expansion", sv_allow_null_glob_expansion }, { "noclobber", sv_noclobber }, { "nolinks", sv_nolinks }, + #if defined(__GO32__) || defined(__CYGWIN32__) + { "glob_case_fold", sv_glob_case_fold }, + { "completion_case_fold", sv_completion_case_fold }, + #endif /* __GO32__ || __CYGWIN32__ */ { (char *)0x00, (VFunction *)0x00 } }; *************** *** 4865,4867 **** --- 4878,4896 ---- posix_readline_initialize (posixly_correct); #endif /* READLINE */ } + + #if defined(__GO32__) || defined(__CYGWIN32__) + void + sv_glob_case_fold (name) + char *name; + { + SET_INT_VAR (name, glob_case_fold); + } + + void + sv_completion_case_fold (name) + char *name; + { + SET_INT_VAR (name, completion_case_fold); + } + #endif /* __GO32__ || __CYGWIN32__ */ *** variables.c.00 Wed May 21 07:17:27 1997 --- variables.c Wed May 21 07:28:42 1997 *************** *** 44,49 **** --- 44,53 ---- extern char *primary_prompt, *secondary_prompt; extern Function *this_shell_builtin; extern time_t shell_start_time; + #if defined(__GO32__) || defined(__CYGWIN32__) + extern int glob_case_fold; + extern int completion_case_fold; + #endif /* The list of shell variables that the user has created, or that came from the environment. */ *************** *** 249,254 **** --- 253,263 ---- bind_variable ("OPTIND", "1"); bind_variable ("OPTERR", "1"); #endif /* GETOPTS_BUILTIN */ + + #if defined(__GO32__) || defined(__CYGWIN32__) + bind_variable ("glob_case_fold", itos(glob_case_fold)); + bind_variable ("completion_case_fold", itos(completion_case_fold)); + #endif /* Get the full pathname to THIS shell, and set the BASH variable to it. */ *** lib/glob/fnmatch.c.00 Fri May 09 15:10:00 1997 --- lib/glob/fnmatch.c Wed May 21 07:26:41 1997 *************** *** 25,30 **** --- 25,36 ---- # endif /* !errno */ #endif + #if defined(__GO32__) || defined (__CYGWIN32__) + int glob_case_fold = 1; + #else + int glob_case_fold = 0; + #endif + /* Match STRING against the filename pattern PATTERN, returning zero if it matches, FNM_NOMATCH if not. */ int *************** *** 59,66 **** case '\\': if (!(flags & FNM_NOESCAPE)) c = *p++; ! if (*n != c) ! return (FNM_NOMATCH); break; case '*': --- 65,77 ---- case '\\': if (!(flags & FNM_NOESCAPE)) c = *p++; ! if (glob_case_fold) { ! if (tolower(c) != tolower(*n)) ! return (FNM_NOMATCH); ! } else { ! if (c != *n) ! return (FNM_NOMATCH); ! } break; case '*': *************** *** 175,182 **** break; default: ! if (c != *n) ! return (FNM_NOMATCH); } ++n; --- 186,198 ---- break; default: ! if (glob_case_fold) { ! if (tolower(c) != tolower(*n)) ! return (FNM_NOMATCH); ! } else { ! if (c != *n) ! return (FNM_NOMATCH); ! } } ++n; *** lib/readline/complete.c.00 Fri May 09 15:10:10 1997 --- lib/readline/complete.c Tue May 20 08:49:58 1997 *************** *** 1077,1083 **** --- 1077,1087 ---- /* **************************************************************** */ /* Non-zero means that case is not significant in completion. */ + #if defined (__GO32__) || defined (__CYGWIN32__) + int completion_case_fold = 1; + #else int completion_case_fold = 0; + #endif /* Return an array of (char *) which is a list of completions for TEXT. If there are no completions, return a NULL pointer. *************** *** 1265,1274 **** --- 1269,1285 ---- { /* Otherwise, if these match up to the length of filename, then it is a match. */ + if (completion_case_fold) { + if ((tolower(entry->d_name[0]) == tolower(filename[0])) && + (((int)D_NAMLEN (entry)) >= filename_len) && + (strncasecmp (filename, entry->d_name, filename_len) == 0)) + break; + } else { if ((entry->d_name[0] == filename[0]) && (((int)D_NAMLEN (entry)) >= filename_len) && (strncmp (filename, entry->d_name, filename_len) == 0)) break; + } } } - For help on using this list (especially unsubscribing), send a message to "gnu-win32-request AT cygnus DOT com" with one line of text: "help".