Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/utils/lib/file-bootstrap.js
blob: 1ee69e652323f9c8fba7c49d7ed982c81b8e6fab (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170

// NOTE: this file is used is the bootstrapping process,
// so any "requires" must be accounted for in narwhal.js

// use the "file" module as the exports object.
var exports = require("file");

/* path manipulation, needed by the sandbox module in the 
 * bootstrapping process before "require" is ready for use */

if (/\bwindows\b/i.test(system.os)) {
    exports.ROOT = "\\";
    exports.SEPARATOR = "\\";
    exports.ALT_SEPARATOR = "/";
} else {
    exports.ROOT = "/";
    exports.SEPARATOR = "/";
    exports.ALT_SEPARATOR = undefined;
}

// we need to make sure the separator regex is always in sync with the separators.
// this caches the generated regex and rebuild if either separator changes.
exports.SEPARATORS_RE = function() {
    if (separatorCached !== exports.SEPARATOR || altSeparatorCached !== exports.ALT_SEPARATOR) {
        separatorCached = exports.SEPARATOR;
        altSeparatorCached = exports.ALT_SEPARATOR;
        separatorReCached = new RegExp("[" +
            (separatorCached || '').replace(/[-[\]{}()*+?.\\^$|,#\s]/g, "\\$&") +
            (altSeparatorCached || '').replace(/[-[\]{}()*+?.\\^$|,#\s]/g, "\\$&") +
        "]", "g");
    }
    return separatorReCached;
}
var separatorCached, altSeparatorCached, separatorReCached;

exports.join = function () {
    return exports.normal(Array.prototype.join.call(arguments, exports.SEPARATOR));
};

exports.split = function (path) {
    var parts;
    try {
        parts =  String(path).split(exports.SEPARATORS_RE());
    } catch (exception) {
        throw new Error("Cannot split " + (typeof path) + ', "' + path + '"');
    }
    // this special case helps isAbsolute
    // distinguish an empty path from an absolute path
    if (parts.length == 1 && parts[0] == "")
        return [];
    return parts;
};

exports.resolve = function () {
    var root = "";
    var parents = [];
    var children = [];
    var leaf = "";
    for (var i = 0; i < arguments.length; i++) {
        var path = String(arguments[i]);
        if (path == "")
            continue;
        var parts = path.split(exports.SEPARATORS_RE());
        if (exports.isAbsolute(path)) {
            root = parts.shift() + exports.SEPARATOR;
            parents = [];
            children = [];
        }
        leaf = parts.pop();
        if (leaf == "." || leaf == "..") {
            parts.push(leaf);
            leaf = "";
        }
        for (var j = 0; j < parts.length; j++) {
            var part = parts[j];
            if (part == "." || part == '') {
            } else if (part == "..") {
                if (children.length) {
                    children.pop();
                } else {
                    if (root) {
                    } else {
                        parents.push("..");
                    }
                }
            } else {
                children.push(part);
            }
        };
    }
    path = parents.concat(children).join(exports.SEPARATOR);
    if (path) leaf = exports.SEPARATOR + leaf;
    return root + path + leaf;
};

exports.normal = function (path) {
    return exports.resolve(path);
};

// XXX not standard
exports.isAbsolute = function (path) {
    // for absolute paths on any operating system,
    // the first path component always determines
    // whether it is relative or absolute.  On Unix,
    // it is empty, so ['', 'foo'].join('/') == '/foo',
    // '/foo'.split('/') == ['', 'foo'].
    var parts = exports.split(path);
    // split('') == [].  '' is not absolute.
    // split('/') == ['', ''] is absolute.
    // split(?) == [''] does not occur.
    if (parts.length == 0)
        return false;
    var first = parts[0];
    if (/\bwindows\b/i.test(system.os)) {
        return /:$/.test(first);
    } else {
        return first == "";
    }
};

// XXX not standard
exports.isRelative = function (path) {
    return !exports.isAbsolute(path);
};

/*** root
    returns the Unix root path
    or corresponding Windows drive
    for a given path.
*/
// XXX not standard
exports.root = function (path) {
    if (!exports.isAbsolute(path))
        path = require("file").absolute(path);
    var parts = exports.split(path);
    return exports.join(parts[0], '');
};

exports.dirname = function (path) {
    var parts = exports.split(path);
    // XXX needs to be sensitive to the root for
    // Windows compatibility
    parts.pop();
    return exports.join.apply(null, parts) || ".";
};

// XXX the extension argument is not standard
exports.basename = function (path, extension) {
    var basename = path.split(exports.SEPARATORS_RE()).pop();
    if (extension)
        basename = basename.replace(
            new RegExp(RegExp.escape(extension) + '$'),
            ''
        );
    return basename;
};

exports.extension = function (path) {
    path = exports.basename(path);
    path = path.replace(/^\.*/, '');
    var index = path.lastIndexOf(".");
    return index <= 0 ? "" : path.substring(index);
};

// XXX not standard, deprecated
exports.extname = function (path) {
    system.log.warn('extname is deprecated in favor of extension');
    return exports.extension(path);
};