@@ -2772,263 +2772,41 @@ mch_check_win(
27722772#endif
27732773}
27742774
2775-
27762775/*
2777- * fname_casew(): Wide version of fname_case(). Set the case of the file name,
2778- * if it already exists. When "len" is > 0, also expand short to long
2779- * filenames.
2780- * Return FAIL if wide functions are not available, OK otherwise.
2781- * NOTE: much of this is identical to fname_case(), keep in sync!
2782- */
2783- static int
2784- fname_casew (
2785- WCHAR * name ,
2786- int len )
2787- {
2788- WCHAR szTrueName [_MAX_PATH + 2 ];
2789- WCHAR szTrueNameTemp [_MAX_PATH + 2 ];
2790- WCHAR * ptrue , * ptruePrev ;
2791- WCHAR * porig , * porigPrev ;
2792- int flen ;
2793- WIN32_FIND_DATAW fb ;
2794- HANDLE hFind = INVALID_HANDLE_VALUE ;
2795- int c ;
2796- int slen ;
2797-
2798- flen = (int )wcslen (name );
2799- if (flen > _MAX_PATH )
2800- return OK ;
2801-
2802- /* slash_adjust(name) not needed, already adjusted by fname_case(). */
2803-
2804- /* Build the new name in szTrueName[] one component at a time. */
2805- porig = name ;
2806- ptrue = szTrueName ;
2807-
2808- if (iswalpha (porig [0 ]) && porig [1 ] == L':' )
2809- {
2810- /* copy leading drive letter */
2811- * ptrue ++ = * porig ++ ;
2812- * ptrue ++ = * porig ++ ;
2813- }
2814- * ptrue = NUL ; /* in case nothing follows */
2815-
2816- while (* porig != NUL )
2817- {
2818- /* copy \ characters */
2819- while (* porig == psepc )
2820- * ptrue ++ = * porig ++ ;
2821-
2822- ptruePrev = ptrue ;
2823- porigPrev = porig ;
2824- while (* porig != NUL && * porig != psepc )
2825- {
2826- * ptrue ++ = * porig ++ ;
2827- }
2828- * ptrue = NUL ;
2829-
2830- /* To avoid a slow failure append "\*" when searching a directory,
2831- * server or network share. */
2832- wcscpy (szTrueNameTemp , szTrueName );
2833- slen = (int )wcslen (szTrueNameTemp );
2834- if (* porig == psepc && slen + 2 < _MAX_PATH )
2835- wcscpy (szTrueNameTemp + slen , L"\\*" );
2836-
2837- /* Skip "", "." and "..". */
2838- if (ptrue > ptruePrev
2839- && (ptruePrev [0 ] != L'.'
2840- || (ptruePrev [1 ] != NUL
2841- && (ptruePrev [1 ] != L'.' || ptruePrev [2 ] != NUL )))
2842- && (hFind = FindFirstFileW (szTrueNameTemp , & fb ))
2843- != INVALID_HANDLE_VALUE )
2844- {
2845- c = * porig ;
2846- * porig = NUL ;
2847-
2848- /* Only use the match when it's the same name (ignoring case) or
2849- * expansion is allowed and there is a match with the short name
2850- * and there is enough room. */
2851- if (_wcsicoll (porigPrev , fb .cFileName ) == 0
2852- || (len > 0
2853- && (_wcsicoll (porigPrev , fb .cAlternateFileName ) == 0
2854- && (int )(ptruePrev - szTrueName )
2855- + (int )wcslen (fb .cFileName ) < len )))
2856- {
2857- wcscpy (ptruePrev , fb .cFileName );
2858-
2859- /* Look for exact match and prefer it if found. Must be a
2860- * long name, otherwise there would be only one match. */
2861- while (FindNextFileW (hFind , & fb ))
2862- {
2863- if (* fb .cAlternateFileName != NUL
2864- && (wcscoll (porigPrev , fb .cFileName ) == 0
2865- || (len > 0
2866- && (_wcsicoll (porigPrev ,
2867- fb .cAlternateFileName ) == 0
2868- && (int )(ptruePrev - szTrueName )
2869- + (int )wcslen (fb .cFileName ) < len ))))
2870- {
2871- wcscpy (ptruePrev , fb .cFileName );
2872- break ;
2873- }
2874- }
2875- }
2876- FindClose (hFind );
2877- * porig = c ;
2878- ptrue = ptruePrev + wcslen (ptruePrev );
2879- }
2880- }
2881-
2882- wcscpy (name , szTrueName );
2883- return OK ;
2884- }
2885-
2886- /*
2887- * fname_case(): Set the case of the file name, if it already exists.
2776+ * Set the case of the file name, if it already exists.
28882777 * When "len" is > 0, also expand short to long filenames.
2889- * NOTE: much of this is identical to fname_casew(), keep in sync!
28902778 */
28912779 void
28922780fname_case (
28932781 char_u * name ,
28942782 int len )
28952783{
2896- char szTrueName [_MAX_PATH + 2 ];
2897- char szTrueNameTemp [_MAX_PATH + 2 ];
2898- char * ptrue , * ptruePrev ;
2899- char * porig , * porigPrev ;
2900- int flen ;
2901- WIN32_FIND_DATA fb ;
2902- HANDLE hFind ;
2903- int c ;
2904- int slen ;
2784+ int flen ;
2785+ WCHAR * p ;
2786+ WCHAR buf [_MAX_PATH + 1 ];
29052787
29062788 flen = (int )STRLEN (name );
29072789 if (flen == 0 )
29082790 return ;
29092791
29102792 slash_adjust (name );
29112793
2912- if (enc_codepage >= 0 && (int )GetACP () != enc_codepage )
2913- {
2914- WCHAR * p = enc_to_utf16 (name , NULL );
2915-
2916- if (p != NULL )
2917- {
2918- char_u * q ;
2919- WCHAR buf [_MAX_PATH + 1 ];
2920-
2921- wcsncpy (buf , p , _MAX_PATH );
2922- buf [_MAX_PATH ] = L'\0' ;
2923- vim_free (p );
2924-
2925- if (fname_casew (buf , (len > 0 ) ? _MAX_PATH : 0 ) == OK )
2926- {
2927- q = utf16_to_enc (buf , NULL );
2928- if (q != NULL )
2929- {
2930- vim_strncpy (name , q , (len > 0 ) ? len - 1 : flen );
2931- vim_free (q );
2932- return ;
2933- }
2934- }
2935- }
2936- return ;
2937- }
2938-
2939- /* If 'enc' is utf-8, flen can be larger than _MAX_PATH.
2940- * So we should check this after calling wide function. */
2941- if (flen > _MAX_PATH )
2794+ p = enc_to_utf16 (name , NULL );
2795+ if (p == NULL )
29422796 return ;
29432797
2944- /* Build the new name in szTrueName[] one component at a time. */
2945- porig = (char * )name ;
2946- ptrue = szTrueName ;
2947-
2948- if (isalpha (porig [0 ]) && porig [1 ] == ':' )
2798+ if (GetLongPathNameW (p , buf , _MAX_PATH ))
29492799 {
2950- /* copy leading drive letter */
2951- * ptrue ++ = * porig ++ ;
2952- * ptrue ++ = * porig ++ ;
2953- }
2954- * ptrue = NUL ; /* in case nothing follows */
2800+ char_u * q = utf16_to_enc (buf , NULL );
29552801
2956- while (* porig != NUL )
2957- {
2958- /* copy \ characters */
2959- while (* porig == psepc )
2960- * ptrue ++ = * porig ++ ;
2961-
2962- ptruePrev = ptrue ;
2963- porigPrev = porig ;
2964- while (* porig != NUL && * porig != psepc )
2802+ if (q != NULL )
29652803 {
2966- int l ;
2967-
2968- if (enc_dbcs )
2969- {
2970- l = (* mb_ptr2len )((char_u * )porig );
2971- while (-- l >= 0 )
2972- * ptrue ++ = * porig ++ ;
2973- }
2974- else
2975- * ptrue ++ = * porig ++ ;
2976- }
2977- * ptrue = NUL ;
2978-
2979- /* To avoid a slow failure append "\*" when searching a directory,
2980- * server or network share. */
2981- STRCPY (szTrueNameTemp , szTrueName );
2982- slen = (int )strlen (szTrueNameTemp );
2983- if (* porig == psepc && slen + 2 < _MAX_PATH )
2984- STRCPY (szTrueNameTemp + slen , "\\*" );
2985-
2986- /* Skip "", "." and "..". */
2987- if (ptrue > ptruePrev
2988- && (ptruePrev [0 ] != '.'
2989- || (ptruePrev [1 ] != NUL
2990- && (ptruePrev [1 ] != '.' || ptruePrev [2 ] != NUL )))
2991- && (hFind = FindFirstFile (szTrueNameTemp , & fb ))
2992- != INVALID_HANDLE_VALUE )
2993- {
2994- c = * porig ;
2995- * porig = NUL ;
2996-
2997- /* Only use the match when it's the same name (ignoring case) or
2998- * expansion is allowed and there is a match with the short name
2999- * and there is enough room. */
3000- if (_stricoll (porigPrev , fb .cFileName ) == 0
3001- || (len > 0
3002- && (_stricoll (porigPrev , fb .cAlternateFileName ) == 0
3003- && (int )(ptruePrev - szTrueName )
3004- + (int )strlen (fb .cFileName ) < len )))
3005- {
3006- STRCPY (ptruePrev , fb .cFileName );
3007-
3008- /* Look for exact match and prefer it if found. Must be a
3009- * long name, otherwise there would be only one match. */
3010- while (FindNextFile (hFind , & fb ))
3011- {
3012- if (* fb .cAlternateFileName != NUL
3013- && (strcoll (porigPrev , fb .cFileName ) == 0
3014- || (len > 0
3015- && (_stricoll (porigPrev ,
3016- fb .cAlternateFileName ) == 0
3017- && (int )(ptruePrev - szTrueName )
3018- + (int )strlen (fb .cFileName ) < len ))))
3019- {
3020- STRCPY (ptruePrev , fb .cFileName );
3021- break ;
3022- }
3023- }
3024- }
3025- FindClose (hFind );
3026- * porig = c ;
3027- ptrue = ptruePrev + strlen (ptruePrev );
2804+ if (len > 0 || flen >= (int )STRLEN (q ))
2805+ vim_strncpy (name , q , (len > 0 ) ? len - 1 : flen );
2806+ vim_free (q );
30282807 }
30292808 }
3030-
3031- STRCPY (name , szTrueName );
2809+ vim_free (p );
30322810}
30332811
30342812
0 commit comments