diff options
| author | Eli Zaretskii | 2013-11-08 17:10:38 +0200 |
|---|---|---|
| committer | Eli Zaretskii | 2013-11-08 17:10:38 +0200 |
| commit | f5441ba43c16303b129192504a0731a0ee0df47e (patch) | |
| tree | 78c68636e8b356dba2c43e503e5e6abae6ce8188 /src | |
| parent | 80fcb9d2303d7b7064b5cf4e84a1fc2a951cd756 (diff) | |
| download | emacs-f5441ba43c16303b129192504a0731a0ee0df47e.tar.gz emacs-f5441ba43c16303b129192504a0731a0ee0df47e.zip | |
Converted map_w32_filename and its subroutines.
Diffstat (limited to 'src')
| -rw-r--r-- | src/w32.c | 134 |
1 files changed, 75 insertions, 59 deletions
| @@ -1872,9 +1872,9 @@ crlf_to_lf (register int n, register unsigned char *buf) | |||
| 1872 | /* Parse the root part of file name, if present. Return length and | 1872 | /* Parse the root part of file name, if present. Return length and |
| 1873 | optionally store pointer to char after root. */ | 1873 | optionally store pointer to char after root. */ |
| 1874 | static int | 1874 | static int |
| 1875 | parse_root (char * name, char ** pPath) | 1875 | parse_root (const char * name, const char ** pPath) |
| 1876 | { | 1876 | { |
| 1877 | char * start = name; | 1877 | const char * start = name; |
| 1878 | 1878 | ||
| 1879 | if (name == NULL) | 1879 | if (name == NULL) |
| 1880 | return 0; | 1880 | return 0; |
| @@ -1960,7 +1960,7 @@ w32_get_long_filename (char * name, char * buf, int size) | |||
| 1960 | { | 1960 | { |
| 1961 | char * o = buf; | 1961 | char * o = buf; |
| 1962 | char * p; | 1962 | char * p; |
| 1963 | char * q; | 1963 | const char * q; |
| 1964 | char full[ MAX_UTF8_PATH ]; | 1964 | char full[ MAX_UTF8_PATH ]; |
| 1965 | int len; | 1965 | int len; |
| 1966 | 1966 | ||
| @@ -1973,7 +1973,7 @@ w32_get_long_filename (char * name, char * buf, int size) | |||
| 1973 | unixtodos_filename (full); | 1973 | unixtodos_filename (full); |
| 1974 | 1974 | ||
| 1975 | /* Copy root part verbatim. */ | 1975 | /* Copy root part verbatim. */ |
| 1976 | len = parse_root (full, &p); | 1976 | len = parse_root (full, (const char **)&p); |
| 1977 | memcpy (o, full, len); | 1977 | memcpy (o, full, len); |
| 1978 | o += len; | 1978 | o += len; |
| 1979 | *o = '\0'; | 1979 | *o = '\0'; |
| @@ -2628,6 +2628,7 @@ static void | |||
| 2628 | add_volume_info (char * root_dir, volume_info_data * info) | 2628 | add_volume_info (char * root_dir, volume_info_data * info) |
| 2629 | { | 2629 | { |
| 2630 | info->root_dir = xstrdup (root_dir); | 2630 | info->root_dir = xstrdup (root_dir); |
| 2631 | unixtodos_filename (info->root_dir); | ||
| 2631 | info->next = volume_cache; | 2632 | info->next = volume_cache; |
| 2632 | volume_cache = info; | 2633 | volume_cache = info; |
| 2633 | } | 2634 | } |
| @@ -2640,14 +2641,30 @@ static volume_info_data * | |||
| 2640 | GetCachedVolumeInformation (char * root_dir) | 2641 | GetCachedVolumeInformation (char * root_dir) |
| 2641 | { | 2642 | { |
| 2642 | volume_info_data * info; | 2643 | volume_info_data * info; |
| 2643 | char default_root[ MAX_PATH ]; | 2644 | char default_root[ MAX_UTF8_PATH ]; |
| 2645 | char name[MAX_PATH+1]; | ||
| 2646 | char type[MAX_PATH+1]; | ||
| 2644 | 2647 | ||
| 2645 | /* NULL for root_dir means use root from current directory. */ | 2648 | /* NULL for root_dir means use root from current directory. */ |
| 2646 | if (root_dir == NULL) | 2649 | if (root_dir == NULL) |
| 2647 | { | 2650 | { |
| 2648 | if (GetCurrentDirectory (MAX_PATH, default_root) == 0) | 2651 | if (w32_unicode_filenames) |
| 2649 | return NULL; | 2652 | { |
| 2650 | parse_root (default_root, &root_dir); | 2653 | wchar_t curdirw[MAX_PATH]; |
| 2654 | |||
| 2655 | if (GetCurrentDirectoryW (MAX_PATH, curdirw) == 0) | ||
| 2656 | return NULL; | ||
| 2657 | filename_from_utf16 (curdirw, default_root); | ||
| 2658 | } | ||
| 2659 | else | ||
| 2660 | { | ||
| 2661 | char curdira[MAX_PATH]; | ||
| 2662 | |||
| 2663 | if (GetCurrentDirectoryA (MAX_PATH, curdira) == 0) | ||
| 2664 | return NULL; | ||
| 2665 | filename_from_ansi (curdira, default_root); | ||
| 2666 | } | ||
| 2667 | parse_root (default_root, (const char **)&root_dir); | ||
| 2651 | *root_dir = 0; | 2668 | *root_dir = 0; |
| 2652 | root_dir = default_root; | 2669 | root_dir = default_root; |
| 2653 | } | 2670 | } |
| @@ -2686,20 +2703,47 @@ GetCachedVolumeInformation (char * root_dir) | |||
| 2686 | 2703 | ||
| 2687 | if (info == NULL || ! VOLINFO_STILL_VALID (root_dir, info)) | 2704 | if (info == NULL || ! VOLINFO_STILL_VALID (root_dir, info)) |
| 2688 | { | 2705 | { |
| 2689 | char name[ 256 ]; | ||
| 2690 | DWORD serialnum; | 2706 | DWORD serialnum; |
| 2691 | DWORD maxcomp; | 2707 | DWORD maxcomp; |
| 2692 | DWORD flags; | 2708 | DWORD flags; |
| 2693 | char type[ 256 ]; | ||
| 2694 | 2709 | ||
| 2695 | /* Info is not cached, or is stale. */ | 2710 | /* Info is not cached, or is stale. */ |
| 2696 | if (!GetVolumeInformation (root_dir, | 2711 | if (w32_unicode_filenames) |
| 2697 | name, sizeof (name), | 2712 | { |
| 2698 | &serialnum, | 2713 | wchar_t root_w[MAX_PATH]; |
| 2699 | &maxcomp, | 2714 | wchar_t name_w[MAX_PATH+1]; |
| 2700 | &flags, | 2715 | wchar_t type_w[MAX_PATH+1]; |
| 2701 | type, sizeof (type))) | 2716 | |
| 2702 | return NULL; | 2717 | filename_to_utf16 (root_dir, root_w); |
| 2718 | if (!GetVolumeInformationW (root_w, | ||
| 2719 | name_w, sizeof (name_w), | ||
| 2720 | &serialnum, | ||
| 2721 | &maxcomp, | ||
| 2722 | &flags, | ||
| 2723 | type_w, sizeof (type_w))) | ||
| 2724 | return NULL; | ||
| 2725 | /* Hmm... not really 100% correct, as these 2 are not file | ||
| 2726 | names... */ | ||
| 2727 | filename_from_utf16 (name_w, name); | ||
| 2728 | filename_from_utf16 (type_w, type); | ||
| 2729 | } | ||
| 2730 | else | ||
| 2731 | { | ||
| 2732 | char root_a[MAX_PATH]; | ||
| 2733 | char name_a[MAX_PATH+1]; | ||
| 2734 | char type_a[MAX_PATH+1]; | ||
| 2735 | |||
| 2736 | filename_to_ansi (root_dir, root_a); | ||
| 2737 | if (!GetVolumeInformationA (root_a, | ||
| 2738 | name_a, sizeof (name_a), | ||
| 2739 | &serialnum, | ||
| 2740 | &maxcomp, | ||
| 2741 | &flags, | ||
| 2742 | type_a, sizeof (type_a))) | ||
| 2743 | return NULL; | ||
| 2744 | filename_from_ansi (name_a, name); | ||
| 2745 | filename_from_ansi (type_a, type); | ||
| 2746 | } | ||
| 2703 | 2747 | ||
| 2704 | /* Cache the volume information for future use, overwriting existing | 2748 | /* Cache the volume information for future use, overwriting existing |
| 2705 | entry if present. */ | 2749 | entry if present. */ |
| @@ -2715,6 +2759,7 @@ GetCachedVolumeInformation (char * root_dir) | |||
| 2715 | } | 2759 | } |
| 2716 | 2760 | ||
| 2717 | info->name = xstrdup (name); | 2761 | info->name = xstrdup (name); |
| 2762 | unixtodos_filename (info->name); | ||
| 2718 | info->serialnum = serialnum; | 2763 | info->serialnum = serialnum; |
| 2719 | info->maxcomp = maxcomp; | 2764 | info->maxcomp = maxcomp; |
| 2720 | info->flags = flags; | 2765 | info->flags = flags; |
| @@ -2737,52 +2782,22 @@ GetCachedVolumeInformation (char * root_dir) | |||
| 2737 | static int | 2782 | static int |
| 2738 | get_volume_info (const char * name, const char ** pPath) | 2783 | get_volume_info (const char * name, const char ** pPath) |
| 2739 | { | 2784 | { |
| 2740 | char temp[MAX_PATH]; | 2785 | char temp[MAX_UTF8_PATH]; |
| 2741 | char *rootname = NULL; /* default to current volume */ | 2786 | char *rootname = NULL; /* default to current volume */ |
| 2742 | volume_info_data * info; | 2787 | volume_info_data * info; |
| 2788 | int root_len = parse_root (name, pPath); | ||
| 2743 | 2789 | ||
| 2744 | if (name == NULL) | 2790 | if (name == NULL) |
| 2745 | return FALSE; | 2791 | return FALSE; |
| 2746 | 2792 | ||
| 2747 | /* Find the root name of the volume if given. */ | 2793 | /* Copy the root name of the volume, if given. */ |
| 2748 | if (isalpha (name[0]) && name[1] == ':') | 2794 | if (root_len) |
| 2749 | { | 2795 | { |
| 2796 | strncpy (temp, name, root_len); | ||
| 2797 | temp[root_len] = '\0'; | ||
| 2798 | unixtodos_filename (temp); | ||
| 2750 | rootname = temp; | 2799 | rootname = temp; |
| 2751 | temp[0] = *name++; | ||
| 2752 | temp[1] = *name++; | ||
| 2753 | temp[2] = '\\'; | ||
| 2754 | temp[3] = 0; | ||
| 2755 | } | 2800 | } |
| 2756 | else if (IS_DIRECTORY_SEP (name[0]) && IS_DIRECTORY_SEP (name[1])) | ||
| 2757 | { | ||
| 2758 | char *str = temp; | ||
| 2759 | int slashes = 4; | ||
| 2760 | int dbcs_p = max_filename_mbslen () > 1; | ||
| 2761 | |||
| 2762 | rootname = temp; | ||
| 2763 | do | ||
| 2764 | { | ||
| 2765 | if (IS_DIRECTORY_SEP (*name) && --slashes == 0) | ||
| 2766 | break; | ||
| 2767 | if (!dbcs_p) | ||
| 2768 | *str++ = *name++; | ||
| 2769 | else | ||
| 2770 | { | ||
| 2771 | const char *p = name; | ||
| 2772 | |||
| 2773 | name = CharNextExA (file_name_codepage, name, 0); | ||
| 2774 | memcpy (str, p, name - p); | ||
| 2775 | str += name - p; | ||
| 2776 | } | ||
| 2777 | } | ||
| 2778 | while ( *name ); | ||
| 2779 | |||
| 2780 | *str++ = '\\'; | ||
| 2781 | *str = 0; | ||
| 2782 | } | ||
| 2783 | |||
| 2784 | if (pPath) | ||
| 2785 | *pPath = name; | ||
| 2786 | 2801 | ||
| 2787 | info = GetCachedVolumeInformation (rootname); | 2802 | info = GetCachedVolumeInformation (rootname); |
| 2788 | if (info != NULL) | 2803 | if (info != NULL) |
| @@ -2805,18 +2820,19 @@ is_fat_volume (const char * name, const char ** pPath) | |||
| 2805 | return FALSE; | 2820 | return FALSE; |
| 2806 | } | 2821 | } |
| 2807 | 2822 | ||
| 2808 | /* Map filename to a valid 8.3 name if necessary. | 2823 | /* Convert all slashes in a filename to backslashes, and map filename |
| 2809 | The result is a pointer to a static buffer, so CAVEAT EMPTOR! */ | 2824 | to a valid 8.3 name if necessary. The result is a pointer to a |
| 2825 | static buffer, so CAVEAT EMPTOR! */ | ||
| 2810 | const char * | 2826 | const char * |
| 2811 | map_w32_filename (const char * name, const char ** pPath) | 2827 | map_w32_filename (const char * name, const char ** pPath) |
| 2812 | { | 2828 | { |
| 2813 | static char shortname[MAX_PATH]; | 2829 | static char shortname[MAX_UTF8_PATH]; |
| 2814 | char * str = shortname; | 2830 | char * str = shortname; |
| 2815 | char c; | 2831 | char c; |
| 2816 | char * path; | 2832 | char * path; |
| 2817 | const char * save_name = name; | 2833 | const char * save_name = name; |
| 2818 | 2834 | ||
| 2819 | if (strlen (name) >= MAX_PATH) | 2835 | if (strlen (name) >= sizeof (shortname)) |
| 2820 | { | 2836 | { |
| 2821 | /* Return a filename which will cause callers to fail. */ | 2837 | /* Return a filename which will cause callers to fail. */ |
| 2822 | strcpy (shortname, "?"); | 2838 | strcpy (shortname, "?"); |
| @@ -2883,7 +2899,7 @@ map_w32_filename (const char * name, const char ** pPath) | |||
| 2883 | str[-1] = c; /* replace last character of part */ | 2899 | str[-1] = c; /* replace last character of part */ |
| 2884 | /* FALLTHRU */ | 2900 | /* FALLTHRU */ |
| 2885 | default: | 2901 | default: |
| 2886 | if ( left ) | 2902 | if ( left && 'A' <= c && c <= 'Z' ) |
| 2887 | { | 2903 | { |
| 2888 | *str++ = tolower (c); /* map to lower case (looks nicer) */ | 2904 | *str++ = tolower (c); /* map to lower case (looks nicer) */ |
| 2889 | left--; | 2905 | left--; |