Remove archiver-utils dependency

This commit is contained in:
advplyr 2022-07-08 18:11:09 -05:00
parent bca2cfda13
commit 3c5bf376b5
86 changed files with 17236 additions and 210 deletions

View file

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2013 Julian Gruber <julian@juliangruber.com>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View file

@ -0,0 +1,235 @@
const balanced = require('../balancedMatch');
const escSlash = '\0SLASH' + Math.random() + '\0';
const escOpen = '\0OPEN' + Math.random() + '\0';
const escClose = '\0CLOSE' + Math.random() + '\0';
const escComma = '\0COMMA' + Math.random() + '\0';
const escPeriod = '\0PERIOD' + Math.random() + '\0';
/**
* @return {number}
*/
function numeric(str) {
return parseInt(str, 10) == str
? parseInt(str, 10)
: str.charCodeAt(0);
}
/**
* @param {string} str
*/
function escapeBraces(str) {
return str.split('\\\\').join(escSlash)
.split('\\{').join(escOpen)
.split('\\}').join(escClose)
.split('\\,').join(escComma)
.split('\\.').join(escPeriod);
}
/**
* @param {string} str
*/
function unescapeBraces(str) {
return str.split(escSlash).join('\\')
.split(escOpen).join('{')
.split(escClose).join('}')
.split(escComma).join(',')
.split(escPeriod).join('.');
}
/**
* Basically just str.split(","), but handling cases
* where we have nested braced sections, which should be
* treated as individual members, like {a,{b,c},d}
* @param {string} str
*/
function parseCommaParts(str) {
if (!str)
return [''];
const parts = [];
const m = balanced('{', '}', str);
if (!m)
return str.split(',');
const { pre, body, post } = m;
const p = pre.split(',');
p[p.length - 1] += '{' + body + '}';
const postParts = parseCommaParts(post);
if (post.length) {
p[p.length - 1] += postParts.shift();
p.push.apply(p, postParts);
}
parts.push.apply(parts, p);
return parts;
}
/**
* @param {string} str
*/
function expandTop(str) {
if (!str)
return [];
// I don't know why Bash 4.3 does this, but it does.
// Anything starting with {} will have the first two bytes preserved
// but *only* at the top level, so {},a}b will not expand to anything,
// but a{},b}c will be expanded to [a}c,abc].
// One could argue that this is a bug in Bash, but since the goal of
// this module is to match Bash's rules, we escape a leading {}
if (str.slice(0, 2) === '{}') {
str = '\\{\\}' + str.slice(2);
}
return expand(escapeBraces(str), true).map(unescapeBraces);
}
/**
* @param {string} str
*/
function embrace(str) {
return '{' + str + '}';
}
/**
* @param {string} el
*/
function isPadded(el) {
return /^-?0\d/.test(el);
}
/**
* @param {number} i
* @param {number} y
*/
function lte(i, y) {
return i <= y;
}
/**
* @param {number} i
* @param {number} y
*/
function gte(i, y) {
return i >= y;
}
/**
* @param {string} str
* @param {boolean} [isTop]
*/
function expand(str, isTop) {
/** @type {string[]} */
const expansions = [];
const m = balanced('{', '}', str);
if (!m) return [str];
// no need to expand pre, since it is guaranteed to be free of brace-sets
const pre = m.pre;
const post = m.post.length
? expand(m.post, false)
: [''];
if (/\$$/.test(m.pre)) {
for (let k = 0; k < post.length; k++) {
const expansion = pre + '{' + m.body + '}' + post[k];
expansions.push(expansion);
}
} else {
const isNumericSequence = /^-?\d+\.\.-?\d+(?:\.\.-?\d+)?$/.test(m.body);
const isAlphaSequence = /^[a-zA-Z]\.\.[a-zA-Z](?:\.\.-?\d+)?$/.test(m.body);
const isSequence = isNumericSequence || isAlphaSequence;
const isOptions = m.body.indexOf(',') >= 0;
if (!isSequence && !isOptions) {
// {a},b}
if (m.post.match(/,.*\}/)) {
str = m.pre + '{' + m.body + escClose + m.post;
return expand(str);
}
return [str];
}
let n;
if (isSequence) {
n = m.body.split(/\.\./);
} else {
n = parseCommaParts(m.body);
if (n.length === 1) {
// x{{a,b}}y ==> x{a}y x{b}y
n = expand(n[0], false).map(embrace);
if (n.length === 1) {
return post.map(function (p) {
return m.pre + n[0] + p;
});
}
}
}
// at this point, n is the parts, and we know it's not a comma set
// with a single entry.
let N;
if (isSequence) {
const x = numeric(n[0]);
const y = numeric(n[1]);
const width = Math.max(n[0].length, n[1].length)
let incr = n.length == 3
? Math.abs(numeric(n[2]))
: 1;
let test = lte;
const reverse = y < x;
if (reverse) {
incr *= -1;
test = gte;
}
const pad = n.some(isPadded);
N = [];
for (let i = x; test(i, y); i += incr) {
let c;
if (isAlphaSequence) {
c = String.fromCharCode(i);
if (c === '\\')
c = '';
} else {
c = String(i);
if (pad) {
const need = width - c.length;
if (need > 0) {
const z = new Array(need + 1).join('0');
if (i < 0)
c = '-' + z + c.slice(1);
else
c = z + c;
}
}
}
N.push(c);
}
} else {
N = [];
for (let j = 0; j < n.length; j++) {
N.push.apply(N, expand(n[j], false));
}
}
for (let j = 0; j < N.length; j++) {
for (let k = 0; k < post.length; k++) {
const expansion = pre + N[j] + post[k];
if (!isTop || isSequence || expansion)
expansions.push(expansion);
}
}
}
return expansions;
}
module.exports = expandTop;