mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 769310 - Windows paths. r=taras
This commit is contained in:
parent
d7c9e2fe98
commit
20f50ad90f
@ -26,5 +26,6 @@ libs::
|
||||
$(NSINSTALL) $(srcdir)/osfile_shared.jsm $(FINAL_TARGET)/modules/osfile
|
||||
$(NSINSTALL) $(srcdir)/osfile_unix_back.jsm $(FINAL_TARGET)/modules/osfile
|
||||
$(NSINSTALL) $(srcdir)/osfile_unix_front.jsm $(FINAL_TARGET)/modules/osfile
|
||||
$(NSINSTALL) $(srcdir)/ospath_win_back.jsm $(FINAL_TARGET)/modules/osfile
|
||||
$(NSINSTALL) $(srcdir)/osfile_win_back.jsm $(FINAL_TARGET)/modules/osfile
|
||||
$(NSINSTALL) $(srcdir)/osfile_win_front.jsm $(FINAL_TARGET)/modules/osfile
|
||||
|
@ -308,254 +308,6 @@
|
||||
/*overlapped*/Types.void_t.inout_ptr // FIXME: Implement?
|
||||
);
|
||||
|
||||
/**
|
||||
* Utility function: check that a path is not a UNC path,
|
||||
* as the current implementation of |Path| does not support
|
||||
* UNC grammars.
|
||||
*
|
||||
* We consider that any path starting with "\\\\" is a UNC path.
|
||||
*/
|
||||
let ensureNotUNC = function ensureNotUNC(path) {
|
||||
if (!path) {
|
||||
throw new TypeError("Expecting a non-null path");
|
||||
}
|
||||
if (path.length >= 2 && path[0] == "\\" && path[1] == "\\") {
|
||||
throw new Error("Module Path cannot handle UNC-formatted paths yet: " + path);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Utility function: Remove any leading/trailing backslashes
|
||||
* from a string.
|
||||
*/
|
||||
let trimBackslashes = function trimBackslashes(string) {
|
||||
return string.replace(/^\\+|\\+$/g,'');
|
||||
};
|
||||
|
||||
/**
|
||||
* Handling native paths.
|
||||
*
|
||||
* This module contains a number of functions destined to simplify
|
||||
* working with native paths through a cross-platform API. Functions
|
||||
* of this module will only work with the following assumptions:
|
||||
*
|
||||
* - paths are valid;
|
||||
* - paths are defined with one of the grammars that this module can
|
||||
* parse (see later);
|
||||
* - all path concatenations go through function |join|.
|
||||
*
|
||||
* Limitations of this implementation.
|
||||
*
|
||||
* Windows supports 6 distinct grammars for paths. For the moment, this
|
||||
* implementation supports the following subset:
|
||||
*
|
||||
* - drivename:backslash-separated components
|
||||
* - backslash-separated components
|
||||
*
|
||||
* Additionally, |normalize| can convert a path containing slash-
|
||||
* separated components to a path containing backslash-separated
|
||||
* components.
|
||||
*/
|
||||
exports.OS.Win.Path = {
|
||||
/**
|
||||
* Return the final part of the path.
|
||||
* The final part of the path is everything after the last "\\".
|
||||
*/
|
||||
basename: function basename(path) {
|
||||
ensureNotUNC(path);
|
||||
return path.slice(Math.max(path.lastIndexOf("\\"),
|
||||
path.lastIndexOf(":")) + 1);
|
||||
},
|
||||
|
||||
/**
|
||||
* Return the directory part of the path. The directory part
|
||||
* of the path is everything before the last "\\", including
|
||||
* the drive/server name.
|
||||
*
|
||||
* If the path contains no directory, return the drive letter,
|
||||
* or "." if the path contains no drive letter or if option
|
||||
* |winNoDrive| is set.
|
||||
*
|
||||
* @param {string} path The path.
|
||||
* @param {*=} options Platform-specific options controlling the behavior
|
||||
* of this function. This implementation supports the following options:
|
||||
* - |winNoDrive| If |true|, also remove the letter from the path name.
|
||||
*/
|
||||
dirname: function dirname(path, options) {
|
||||
ensureNotUNC(path);
|
||||
let noDrive = (options && options.winNoDrive);
|
||||
|
||||
// Find the last occurrence of "\\"
|
||||
let index = path.lastIndexOf("\\");
|
||||
if (index == -1) {
|
||||
// If there is no directory component...
|
||||
if (!noDrive) {
|
||||
// Return the drive path if possible, falling back to "."
|
||||
return this.winGetDrive(path) || ".";
|
||||
} else {
|
||||
// Or just "."
|
||||
return ".";
|
||||
}
|
||||
}
|
||||
|
||||
// Ignore any occurrence of "\\: immediately before that one
|
||||
while (index >= 0 && path[index] == "\\") {
|
||||
--index;
|
||||
}
|
||||
|
||||
// Compute what is left, removing the drive name if necessary
|
||||
let start;
|
||||
if (noDrive) {
|
||||
start = (this.winGetDrive(path) || "").length;
|
||||
} else {
|
||||
start = 0;
|
||||
}
|
||||
return path.slice(start, index + 1);
|
||||
},
|
||||
|
||||
/**
|
||||
* Join path components.
|
||||
* This is the recommended manner of getting the path of a file/subdirectory
|
||||
* in a directory.
|
||||
*
|
||||
* Example: Obtaining $TMP/foo/bar in an OS-independent manner
|
||||
* var tmpDir = OS.Path.to("TmpD");
|
||||
* var path = OS.Path.join(tmpDir, "foo", "bar");
|
||||
*
|
||||
* Under Windows, this will return "$TMP\foo\bar".
|
||||
*/
|
||||
join: function join(path /*...*/) {
|
||||
let paths = [];
|
||||
let root;
|
||||
let absolute = false;
|
||||
for each(let subpath in arguments) {
|
||||
let drive = this.winGetDrive(subpath);
|
||||
let abs = this.winIsAbsolute(subpath);
|
||||
if (drive) {
|
||||
root = drive;
|
||||
paths = [trimBackslashes(subpath.slice(drive.length))];
|
||||
absolute = abs;
|
||||
} else if (abs) {
|
||||
paths = [trimBackslashes(subpath)];
|
||||
absolute = true;
|
||||
} else {
|
||||
paths.push(trimBackslashes(subpath));
|
||||
}
|
||||
}
|
||||
let result = "";
|
||||
if (root) {
|
||||
result += root;
|
||||
}
|
||||
if (absolute) {
|
||||
result += "\\";
|
||||
}
|
||||
result += paths.join("\\");
|
||||
return result;
|
||||
},
|
||||
|
||||
/**
|
||||
* Return the drive letter of a path, or |null| if the
|
||||
* path does not contain a drive letter.
|
||||
*/
|
||||
winGetDrive: function winGetDrive(path) {
|
||||
ensureNotUNC(path);
|
||||
let index = path.indexOf(":");
|
||||
if (index <= 0) return null;
|
||||
return path.slice(0, index + 1);
|
||||
},
|
||||
|
||||
/**
|
||||
* Return |true| if the path is absolute, |false| otherwise.
|
||||
*
|
||||
* We consider that a path is absolute if it starts with "\\"
|
||||
* or "driveletter:\\".
|
||||
*/
|
||||
winIsAbsolute: function winIsAbsolute(path) {
|
||||
ensureNotUNC(path);
|
||||
return this._winIsAbsolute(path);
|
||||
},
|
||||
/**
|
||||
* As |winIsAbsolute|, but does not check for UNC.
|
||||
* Useful mostly as an internal utility, for normalization.
|
||||
*/
|
||||
_winIsAbsolute: function _winIsAbsolute(path) {
|
||||
let index = path.indexOf(":");
|
||||
return path.length > index + 1 && path[index + 1] == "\\";
|
||||
},
|
||||
|
||||
/**
|
||||
* Normalize a path by removing any unneeded ".", "..", "\\".
|
||||
* Also convert any "/" to a "\\".
|
||||
*/
|
||||
normalize: function normalize(path) {
|
||||
let stack = [];
|
||||
|
||||
// Remove the drive (we will put it back at the end)
|
||||
let root = this.winGetDrive(path);
|
||||
if (root) {
|
||||
path = path.slice(root.length);
|
||||
}
|
||||
|
||||
// Remember whether we need to restore a leading "\\".
|
||||
let absolute = this._winIsAbsolute(path);
|
||||
|
||||
// Normalize "/" to "\\"
|
||||
path = path.replace("/", "\\");
|
||||
|
||||
// And now, fill |stack| from the components,
|
||||
// popping whenever there is a ".."
|
||||
path.split("\\").forEach(function loop(v) {
|
||||
switch (v) {
|
||||
case "": case ".": // Ignore
|
||||
break;
|
||||
case "..":
|
||||
if (stack.length == 0) {
|
||||
if (absolute) {
|
||||
throw new Error("Path is ill-formed: attempting to go past root");
|
||||
} else {
|
||||
stack.push("..");
|
||||
}
|
||||
} else {
|
||||
stack.pop();
|
||||
}
|
||||
break;
|
||||
default:
|
||||
stack.push(v);
|
||||
}
|
||||
});
|
||||
|
||||
// Put everything back together
|
||||
let result = stack.join("\\");
|
||||
if (absolute) {
|
||||
result = "\\" + result;
|
||||
}
|
||||
if (root) {
|
||||
result = root + result;
|
||||
}
|
||||
return result;
|
||||
},
|
||||
|
||||
/**
|
||||
* Return the components of a path.
|
||||
* You should generally apply this function to a normalized path.
|
||||
*
|
||||
* @return {{
|
||||
* {bool} absolute |true| if the path is absolute, |false| otherwise
|
||||
* {array} components the string components of the path
|
||||
* {string?} winDrive the drive or server for this path
|
||||
* }}
|
||||
*
|
||||
* Other implementations may add additional OS-specific informations.
|
||||
*/
|
||||
split: function split(path) {
|
||||
return {
|
||||
absolute: this.winIsAbsolute(path),
|
||||
winDrive: this.winGetDrive(path),
|
||||
components: path.split("\\")
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
// Export useful stuff for extensibility
|
||||
|
||||
exports.OS.Win.libc = libc;
|
||||
|
@ -18,6 +18,7 @@
|
||||
|
||||
importScripts("resource://gre/modules/osfile/osfile_shared.jsm");
|
||||
importScripts("resource://gre/modules/osfile/osfile_win_back.jsm");
|
||||
importScripts("resource://gre/modules/osfile/ospath_win_back.jsm");
|
||||
|
||||
(function(exports) {
|
||||
"use strict";
|
||||
|
259
toolkit/components/osfile/ospath_win_back.jsm
Normal file
259
toolkit/components/osfile/ospath_win_back.jsm
Normal file
@ -0,0 +1,259 @@
|
||||
/**
|
||||
* Handling native paths.
|
||||
*
|
||||
* This module contains a number of functions destined to simplify
|
||||
* working with native paths through a cross-platform API. Functions
|
||||
* of this module will only work with the following assumptions:
|
||||
*
|
||||
* - paths are valid;
|
||||
* - paths are defined with one of the grammars that this module can
|
||||
* parse (see later);
|
||||
* - all path concatenations go through function |join|.
|
||||
*
|
||||
* Limitations of this implementation.
|
||||
*
|
||||
* Windows supports 6 distinct grammars for paths. For the moment, this
|
||||
* implementation supports the following subset:
|
||||
*
|
||||
* - drivename:backslash-separated components
|
||||
* - backslash-separated components
|
||||
*
|
||||
* Additionally, |normalize| can convert a path containing slash-
|
||||
* separated components to a path containing backslash-separated
|
||||
* components.
|
||||
*/
|
||||
(function(exports) {
|
||||
"use strict";
|
||||
if (!exports.OS) {
|
||||
exports.OS = {};
|
||||
}
|
||||
if (!exports.OS.Win) {
|
||||
exports.OS.Win = {};
|
||||
}
|
||||
if (exports.OS.Win.Path) {
|
||||
return; // Avoid double-initialization
|
||||
}
|
||||
exports.OS.Win.Path = {
|
||||
/**
|
||||
* Return the final part of the path.
|
||||
* The final part of the path is everything after the last "\\".
|
||||
*/
|
||||
basename: function basename(path) {
|
||||
ensureNotUNC(path);
|
||||
return path.slice(Math.max(path.lastIndexOf("\\"),
|
||||
path.lastIndexOf(":")) + 1);
|
||||
},
|
||||
|
||||
/**
|
||||
* Return the directory part of the path. The directory part
|
||||
* of the path is everything before the last "\\", including
|
||||
* the drive/server name.
|
||||
*
|
||||
* If the path contains no directory, return the drive letter,
|
||||
* or "." if the path contains no drive letter or if option
|
||||
* |winNoDrive| is set.
|
||||
*
|
||||
* @param {string} path The path.
|
||||
* @param {*=} options Platform-specific options controlling the behavior
|
||||
* of this function. This implementation supports the following options:
|
||||
* - |winNoDrive| If |true|, also remove the letter from the path name.
|
||||
*/
|
||||
dirname: function dirname(path, options) {
|
||||
ensureNotUNC(path);
|
||||
let noDrive = (options && options.winNoDrive);
|
||||
|
||||
// Find the last occurrence of "\\"
|
||||
let index = path.lastIndexOf("\\");
|
||||
if (index == -1) {
|
||||
// If there is no directory component...
|
||||
if (!noDrive) {
|
||||
// Return the drive path if possible, falling back to "."
|
||||
return this.winGetDrive(path) || ".";
|
||||
} else {
|
||||
// Or just "."
|
||||
return ".";
|
||||
}
|
||||
}
|
||||
|
||||
// Ignore any occurrence of "\\: immediately before that one
|
||||
while (index >= 0 && path[index] == "\\") {
|
||||
--index;
|
||||
}
|
||||
|
||||
// Compute what is left, removing the drive name if necessary
|
||||
let start;
|
||||
if (noDrive) {
|
||||
start = (this.winGetDrive(path) || "").length;
|
||||
} else {
|
||||
start = 0;
|
||||
}
|
||||
return path.slice(start, index + 1);
|
||||
},
|
||||
|
||||
/**
|
||||
* Join path components.
|
||||
* This is the recommended manner of getting the path of a file/subdirectory
|
||||
* in a directory.
|
||||
*
|
||||
* Example: Obtaining $TMP/foo/bar in an OS-independent manner
|
||||
* var tmpDir = OS.Path.to("TmpD");
|
||||
* var path = OS.Path.join(tmpDir, "foo", "bar");
|
||||
*
|
||||
* Under Windows, this will return "$TMP\foo\bar".
|
||||
*/
|
||||
join: function join(path /*...*/) {
|
||||
let paths = [];
|
||||
let root;
|
||||
let absolute = false;
|
||||
for each(let subpath in arguments) {
|
||||
let drive = this.winGetDrive(subpath);
|
||||
let abs = this.winIsAbsolute(subpath);
|
||||
if (drive) {
|
||||
root = drive;
|
||||
paths = [trimBackslashes(subpath.slice(drive.length))];
|
||||
absolute = abs;
|
||||
} else if (abs) {
|
||||
paths = [trimBackslashes(subpath)];
|
||||
absolute = true;
|
||||
} else {
|
||||
paths.push(trimBackslashes(subpath));
|
||||
}
|
||||
}
|
||||
let result = "";
|
||||
if (root) {
|
||||
result += root;
|
||||
}
|
||||
if (absolute) {
|
||||
result += "\\";
|
||||
}
|
||||
result += paths.join("\\");
|
||||
return result;
|
||||
},
|
||||
|
||||
/**
|
||||
* Return the drive letter of a path, or |null| if the
|
||||
* path does not contain a drive letter.
|
||||
*/
|
||||
winGetDrive: function winGetDrive(path) {
|
||||
ensureNotUNC(path);
|
||||
let index = path.indexOf(":");
|
||||
if (index <= 0) return null;
|
||||
return path.slice(0, index + 1);
|
||||
},
|
||||
|
||||
/**
|
||||
* Return |true| if the path is absolute, |false| otherwise.
|
||||
*
|
||||
* We consider that a path is absolute if it starts with "\\"
|
||||
* or "driveletter:\\".
|
||||
*/
|
||||
winIsAbsolute: function winIsAbsolute(path) {
|
||||
ensureNotUNC(path);
|
||||
return this._winIsAbsolute(path);
|
||||
},
|
||||
/**
|
||||
* As |winIsAbsolute|, but does not check for UNC.
|
||||
* Useful mostly as an internal utility, for normalization.
|
||||
*/
|
||||
_winIsAbsolute: function _winIsAbsolute(path) {
|
||||
let index = path.indexOf(":");
|
||||
return path.length > index + 1 && path[index + 1] == "\\";
|
||||
},
|
||||
|
||||
/**
|
||||
* Normalize a path by removing any unneeded ".", "..", "\\".
|
||||
* Also convert any "/" to a "\\".
|
||||
*/
|
||||
normalize: function normalize(path) {
|
||||
let stack = [];
|
||||
|
||||
// Remove the drive (we will put it back at the end)
|
||||
let root = this.winGetDrive(path);
|
||||
if (root) {
|
||||
path = path.slice(root.length);
|
||||
}
|
||||
|
||||
// Remember whether we need to restore a leading "\\".
|
||||
let absolute = this._winIsAbsolute(path);
|
||||
|
||||
// Normalize "/" to "\\"
|
||||
path = path.replace("/", "\\");
|
||||
|
||||
// And now, fill |stack| from the components,
|
||||
// popping whenever there is a ".."
|
||||
path.split("\\").forEach(function loop(v) {
|
||||
switch (v) {
|
||||
case "": case ".": // Ignore
|
||||
break;
|
||||
case "..":
|
||||
if (stack.length == 0) {
|
||||
if (absolute) {
|
||||
throw new Error("Path is ill-formed: attempting to go past root");
|
||||
} else {
|
||||
stack.push("..");
|
||||
}
|
||||
} else {
|
||||
stack.pop();
|
||||
}
|
||||
break;
|
||||
default:
|
||||
stack.push(v);
|
||||
}
|
||||
});
|
||||
|
||||
// Put everything back together
|
||||
let result = stack.join("\\");
|
||||
if (absolute) {
|
||||
result = "\\" + result;
|
||||
}
|
||||
if (root) {
|
||||
result = root + result;
|
||||
}
|
||||
return result;
|
||||
},
|
||||
|
||||
/**
|
||||
* Return the components of a path.
|
||||
* You should generally apply this function to a normalized path.
|
||||
*
|
||||
* @return {{
|
||||
* {bool} absolute |true| if the path is absolute, |false| otherwise
|
||||
* {array} components the string components of the path
|
||||
* {string?} winDrive the drive or server for this path
|
||||
* }}
|
||||
*
|
||||
* Other implementations may add additional OS-specific informations.
|
||||
*/
|
||||
split: function split(path) {
|
||||
return {
|
||||
absolute: this.winIsAbsolute(path),
|
||||
winDrive: this.winGetDrive(path),
|
||||
components: path.split("\\")
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Utility function: check that a path is not a UNC path,
|
||||
* as the current implementation of |Path| does not support
|
||||
* UNC grammars.
|
||||
*
|
||||
* We consider that any path starting with "\\\\" is a UNC path.
|
||||
*/
|
||||
let ensureNotUNC = function ensureNotUNC(path) {
|
||||
if (!path) {
|
||||
throw new TypeError("Expecting a non-null path");
|
||||
}
|
||||
if (path.length >= 2 && path[0] == "\\" && path[1] == "\\") {
|
||||
throw new Error("Module Path cannot handle UNC-formatted paths yet: " + path);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Utility function: Remove any leading/trailing backslashes
|
||||
* from a string.
|
||||
*/
|
||||
let trimBackslashes = function trimBackslashes(string) {
|
||||
return string.replace(/^\\+|\\+$/g,'');
|
||||
};
|
||||
}(this));
|
Loading…
Reference in New Issue
Block a user