make/scripts/fixpath.pl
changeset 21759 e24e22311718
parent 21510 0b432ae58dd5
child 21760 9f542d8601a8
equal deleted inserted replaced
21510:0b432ae58dd5 21759:e24e22311718
     1 #!/bin/perl
       
     2 
       
     3 #
       
     4 # Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
       
     5 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
       
     6 #
       
     7 # This code is free software; you can redistribute it and/or modify it
       
     8 # under the terms of the GNU General Public License version 2 only, as
       
     9 # published by the Free Software Foundation.  Oracle designates this
       
    10 # particular file as subject to the "Classpath" exception as provided
       
    11 # by Oracle in the LICENSE file that accompanied this code.
       
    12 #
       
    13 # This code is distributed in the hope that it will be useful, but WITHOUT
       
    14 # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
       
    15 # FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
       
    16 # version 2 for more details (a copy is included in the LICENSE file that
       
    17 # accompanied this code).
       
    18 #
       
    19 # You should have received a copy of the GNU General Public License version
       
    20 # 2 along with this work; if not, write to the Free Software Foundation,
       
    21 # Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
       
    22 #
       
    23 # Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
       
    24 # or visit www.oracle.com if you need additional information or have any
       
    25 # questions.
       
    26 #
       
    27 
       
    28 # Crunch down the input(s) to Windows short (mangled) form.
       
    29 # Any elements not actually found in the filesystem will be dropped.
       
    30 #
       
    31 # This script needs three modes:
       
    32 #   1) DOS mode with drive letter followed by : and ; path separator
       
    33 #   2) Cygwin mode with /cygdrive/<drive letter>/ and : path separator
       
    34 #   3) MinGW/MSYS mode with /<drive letter>/ and : path separator
       
    35 
       
    36 use strict;
       
    37 use warnings;
       
    38 use Getopt::Std;
       
    39 
       
    40 sub Usage() {
       
    41     print ("Usage:\n $0 -d | -c | -m \<PATH\>\n");
       
    42     print ("            -d DOS style (drive letter, :, and ; path separator)\n");
       
    43     print ("            -c Cywgin style (/cygdrive/drive/ and : path separator)\n");
       
    44     print ("            -m MinGW style (/drive/ and : path separator)\n");
       
    45     exit 1;
       
    46 }
       
    47 # Process command line options:
       
    48 my %opts;
       
    49 getopts('dcm', \%opts) || Usage();
       
    50 
       
    51 if (scalar(@ARGV) != 1) {Usage()};
       
    52 
       
    53 # Translate drive letters such as C:/
       
    54 #   if MSDOS, Win32::GetShortPathName() does the work (see below).
       
    55 #   if Cygwin, use the /cygdrive/c/ form.
       
    56 #   if MinGW, use the /c/ form.
       
    57 my $path0;
       
    58 my $sep2;
       
    59 if (defined ($opts{'d'})) {
       
    60     #MSDOS
       
    61     $path0 = '';
       
    62     $sep2 = ';';
       
    63 } elsif (defined ($opts{'c'})) {
       
    64     #Cygwin
       
    65     $path0 = '/cygdrive';
       
    66     $sep2 = ':';
       
    67 } elsif (defined ($opts{'m'})) {
       
    68     #MinGW/MSYS
       
    69     $path0 = '';
       
    70     $sep2 = ':';
       
    71 } else {
       
    72     Usage();
       
    73 }
       
    74 
       
    75 my $input = $ARGV[0];
       
    76 my $sep1;
       
    77 
       
    78 # Is the input ';' separated, or ':' separated, or a simple string?
       
    79 if (($input =~ tr/;/;/) > 0) {
       
    80     # One or more ';' implies Windows style path.
       
    81     $sep1 = ';';
       
    82 } elsif (($input =~ tr/:/:/) > 1) {
       
    83     # Two or more ':' implies Cygwin or MinGW/MSYS style path.
       
    84     $sep1 = ':';
       
    85 } else {
       
    86     # Otherwise, this is not a path - take up to the end of string in
       
    87     # one piece.
       
    88     $sep1 = '/$/';
       
    89 }
       
    90 
       
    91 # Split the input on $sep1 PATH separator and process the pieces.
       
    92 my @pieces;
       
    93 for (split($sep1, $input)) {
       
    94     my $try = $_;
       
    95 
       
    96     if (($try =~ /^\/cygdrive\/(.)\/(.*)$/) || ($try =~ /^\/(.)\/(.*)$/)) {
       
    97         # Special case #1: This is a Cygwin /cygrive/<drive letter/ path.
       
    98         # Special case #2: This is a MinGW/MSYS /<drive letter/ path.
       
    99         $try = $1.':/'.$2;
       
   100     } elsif ($try =~ /^\/(.*)$/) {
       
   101         # Special case #3: check for a Cygwin or MinGW/MSYS form with a
       
   102         # leading '/' for example '/usr/bin/bash'.
       
   103         # Look up where this is mounted and rebuild the
       
   104         # $try string with that information
       
   105         my $cmd = "df --portability --all --human-readable $try";
       
   106         my $line = qx ($cmd);
       
   107         my $status = $?; 
       
   108         if ($status == 0) {
       
   109             my @lines = split ('\n', $line);
       
   110             my ($device, $junk, $mountpoint);
       
   111             # $lines[0] is the df header.
       
   112             # Example string for split - we want the first and last elements:
       
   113             # C:\jprt\products\P1\MinGW\msys\1.0  200G   78G  123G  39% /usr
       
   114             ($device, $junk, $junk, $junk, $junk, $mountpoint) = split (/\s+/, $lines[1]);
       
   115             # Replace $mountpoint with $device/ in the original string
       
   116             $try =~ s|$mountpoint|$device/|;
       
   117         } else {
       
   118             printf ("Error %d from command %s\n%s\n", $status, $cmd, $line);
       
   119         }
       
   120     }
       
   121 
       
   122     my $str = Win32::GetShortPathName($try);
       
   123     if (!defined($str)){
       
   124         # Special case #4: If the lookup did not work, loop through
       
   125         # adding extensions listed in PATHEXT, looking for the first
       
   126         # match.
       
   127         for (split(';', $ENV{'PATHEXT'})) {
       
   128             $str = Win32::GetShortPathName($try.$_);
       
   129             if (defined($str)) {
       
   130                 last;
       
   131             }
       
   132         }
       
   133     }
       
   134 
       
   135     if (defined($str)){
       
   136         if (!defined($opts{'d'})) {
       
   137             # If not MSDOS, change C: to [/cygdrive]/c/
       
   138             if ($str =~ /^(\S):(.*)$/) {
       
   139                 my $path1 = $1;
       
   140                 my $path2 = $2;
       
   141                 $str = $path0 . '/' . $path1 . '/' . $path2;
       
   142             }
       
   143         }
       
   144         push (@pieces, $str);
       
   145     }
       
   146 }
       
   147 
       
   148 # If input was a PATH, join the pieces back together with $sep2 path
       
   149 # separator.
       
   150 my $result;
       
   151 if (scalar(@pieces > 1)) {
       
   152     $result = join ($sep2, @pieces);
       
   153 } else {
       
   154     $result = $pieces[0];
       
   155 }
       
   156 
       
   157 if (defined ($result)) {
       
   158 
       
   159     # Change all '\' to '/'
       
   160     $result =~ s/\\/\//g;
       
   161 
       
   162     # Remove duplicate '/'
       
   163     $result =~ s/\/\//\//g;
       
   164 
       
   165     # Map to lower case
       
   166     $result =~ tr/A-Z/a-z/;
       
   167 
       
   168     print ("$result\n");
       
   169 }