Changeset 14659


Ignore:
Timestamp:
03/24/14 16:39:23 (3 years ago)
Author:
mevenson
Message:

Fix Uniform Naming Convention (aka "UNC" or "network") paths under Windows.

DIRECTORY now works again on UNC paths.

UNC paths may be either specified with either back slash (#
) or
forward slash (#\/) doubled as the first character in a Pathname
namestring.

The patterns in

<server>/<share>/[directories-and-files]

are parsed as

<server> is stored as HOST.

<share> is stored as DEVICE.

[directories-and-files] gets parsed as per the normal rules under
Windows.

Mixing namestrings with both backslash and slash characters can lead
to unpredictable results. It is recommended not to use backslash
characters in namestrings if it can be avoided. The pathname printed
representation is always normalized to using forward slash delimiters.

Location:
trunk/abcl/src/org/armedbear/lisp
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/abcl/src/org/armedbear/lisp/Pathname.java

    r14624 r14659  
    243243        }
    244244        if (Utilities.isPlatformWindows) {
    245             if (s.startsWith("\\\\")) { // XXX What if string starts with '//'?
    246                 //UNC path support
    247                 // match \\<server>\<share>\[directories-and-files]
    248 
    249                 int shareIndex = s.indexOf('\\', 2);
    250                 int dirIndex = s.indexOf('\\', shareIndex + 1);
    251 
    252                 if (shareIndex == -1 || dirIndex == -1) {
    253                     error(new LispError("Unsupported UNC path format: \"" + s + '"'));
    254                 }
    255 
    256                 host = new SimpleString(s.substring(2, shareIndex));
    257                 device = new SimpleString(s.substring(shareIndex + 1, dirIndex));
    258 
    259                 Pathname p = new Pathname(s.substring(dirIndex));
    260                 directory = p.directory;
    261                 name = p.name;
    262                 type = p.type;
    263                 version = p.version;
    264                 invalidateNamestring();
    265                 return;
    266             }
     245          if (s.startsWith("\\\\") || s.startsWith("//")) {
     246            // UNC path support
     247            int shareIndex;
     248            int dirIndex;
     249            // match \\<server>\<share>\[directories-and-files]
     250            if (s.startsWith("\\\\")) {
     251              shareIndex = s.indexOf('\\', 2);
     252              dirIndex = s.indexOf('\\', shareIndex + 1);
     253              // match //<server>/<share>/[directories-and-files]
     254            } else {
     255              shareIndex = s.indexOf('/', 2);
     256              dirIndex = s.indexOf('/', shareIndex + 1);
     257            }
     258            if (shareIndex == -1 || dirIndex == -1) {
     259              error(new LispError("Unsupported UNC path format: \"" + s + '"'));
     260            }
     261
     262            host = new SimpleString(s.substring(2, shareIndex));
     263            device = new SimpleString(s.substring(shareIndex + 1, dirIndex));
     264
     265            Pathname p = new Pathname(s.substring(dirIndex));
     266            directory = p.directory;
     267            name = p.name;
     268            type = p.type;
     269            version = p.version;
     270            invalidateNamestring();
     271            return;
     272          }
    267273        }
    268274       
     
    382388                String uriPath = uri.getPath();
    383389                if (null == uriPath) {
    384           // Under Windows, deal with pathnames containing
    385           // devices expressed as "file:z:/foo/path"
    386           uriPath = uri.getSchemeSpecificPart();
    387           if (uriPath == null || uriPath.equals("")) {
     390                                  // Under Windows, deal with pathnames containing
     391                                  // devices expressed as "file:z:/foo/path"
     392                                  uriPath = uri.getSchemeSpecificPart();
     393                                  if (uriPath == null || uriPath.equals("")) {
    388394                    error(new LispError("The URI has no path: " + uri));
    389395                  }
     
    652658                sb.append(':');
    653659            } else {
    654                 // UNC paths now use unprintable representation
    655                 return null;
     660              // A UNC path
     661              sb.append("//").append(host.getStringValue()).append("/");
    656662            }
    657663        }
     
    664670            for (int i = 0; i < jars.length; i++) {
    665671                prefix.append("jar:");
    666         LispObject component = jars[i];
    667         if (!(component instanceof Pathname)) {
    668            return null; // If DEVICE is a CONS, it should only contain Pathname
    669         }
     672                LispObject component = jars[i];
     673                if (!(component instanceof Pathname)) {
     674                  return null; // If DEVICE is a CONS, it should only contain Pathname
     675                }
    670676                if (! ((Pathname)component).isURL() && i == 0) {
    671                     sb.append("file:");
    672                     uriEncoded = true;
     677                  sb.append("file:");
     678                  uriEncoded = true;
    673679                }
    674680                Pathname jar = (Pathname) component;
    675681                String encodedNamestring;
    676682                if (uriEncoded) {
    677                     encodedNamestring = uriEncode(jar.getNamestring());
     683                  encodedNamestring = uriEncode(jar.getNamestring());
    678684                } else {
    679                     encodedNamestring = jar.getNamestring();
     685                  encodedNamestring = jar.getNamestring();
    680686                }
    681687                sb.append(encodedNamestring);
     
    686692            sb.append(device.getStringValue());
    687693            if (this instanceof LogicalPathname
    688               || host == NIL) {
    689                 sb.append(':'); // non-UNC paths
     694                || host == NIL) {
     695              sb.append(':'); // non-UNC paths
    690696            }
    691697        } else {
  • trunk/abcl/src/org/armedbear/lisp/directory.lisp

    r14624 r14659  
    122122              (when (and namestring (> (length namestring) 0))
    123123                (when (featurep :windows)
    124                   (let ((device (pathname-device pathname)))
    125                     (when device
    126                       (setq namestring (concatenate 'string device ":" namestring)))))
     124                  (let ((host (pathname-host pathname))
     125                        (device (pathname-device pathname)))
     126                    (cond
     127                      ((and host device)
     128                       (setq namestring
     129                             (concatenate 'string "//" host "/" device  namestring)))
     130                      (device
     131                       (setq namestring
     132                             (concatenate 'string device ":" namestring))))))
    127133                (let ((entries (list-directories-with-wildcards
    128134                                namestring nil resolve-symlinks))
Note: See TracChangeset for help on using the changeset viewer.