486 lines
15 KiB
JavaScript
486 lines
15 KiB
JavaScript
// Generated by CoffeeScript 1.12.4
|
|
var DumpException, Escaper, Inline, ParseException, ParseMore, Pattern, Unescaper, Utils,
|
|
indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; };
|
|
|
|
Pattern = require('./Pattern');
|
|
|
|
Unescaper = require('./Unescaper');
|
|
|
|
Escaper = require('./Escaper');
|
|
|
|
Utils = require('./Utils');
|
|
|
|
ParseException = require('./Exception/ParseException');
|
|
|
|
ParseMore = require('./Exception/ParseMore');
|
|
|
|
DumpException = require('./Exception/DumpException');
|
|
|
|
Inline = (function() {
|
|
function Inline() {}
|
|
|
|
Inline.REGEX_QUOTED_STRING = '(?:"(?:[^"\\\\]*(?:\\\\.[^"\\\\]*)*)"|\'(?:[^\']*(?:\'\'[^\']*)*)\')';
|
|
|
|
Inline.PATTERN_TRAILING_COMMENTS = new Pattern('^\\s*#.*$');
|
|
|
|
Inline.PATTERN_QUOTED_SCALAR = new Pattern('^' + Inline.REGEX_QUOTED_STRING);
|
|
|
|
Inline.PATTERN_THOUSAND_NUMERIC_SCALAR = new Pattern('^(-|\\+)?[0-9,]+(\\.[0-9]+)?$');
|
|
|
|
Inline.PATTERN_SCALAR_BY_DELIMITERS = {};
|
|
|
|
Inline.settings = {};
|
|
|
|
Inline.configure = function(exceptionOnInvalidType, objectDecoder) {
|
|
if (exceptionOnInvalidType == null) {
|
|
exceptionOnInvalidType = null;
|
|
}
|
|
if (objectDecoder == null) {
|
|
objectDecoder = null;
|
|
}
|
|
this.settings.exceptionOnInvalidType = exceptionOnInvalidType;
|
|
this.settings.objectDecoder = objectDecoder;
|
|
};
|
|
|
|
Inline.parse = function(value, exceptionOnInvalidType, objectDecoder) {
|
|
var context, result;
|
|
if (exceptionOnInvalidType == null) {
|
|
exceptionOnInvalidType = false;
|
|
}
|
|
if (objectDecoder == null) {
|
|
objectDecoder = null;
|
|
}
|
|
this.settings.exceptionOnInvalidType = exceptionOnInvalidType;
|
|
this.settings.objectDecoder = objectDecoder;
|
|
if (value == null) {
|
|
return '';
|
|
}
|
|
value = Utils.trim(value);
|
|
if (0 === value.length) {
|
|
return '';
|
|
}
|
|
context = {
|
|
exceptionOnInvalidType: exceptionOnInvalidType,
|
|
objectDecoder: objectDecoder,
|
|
i: 0
|
|
};
|
|
switch (value.charAt(0)) {
|
|
case '[':
|
|
result = this.parseSequence(value, context);
|
|
++context.i;
|
|
break;
|
|
case '{':
|
|
result = this.parseMapping(value, context);
|
|
++context.i;
|
|
break;
|
|
default:
|
|
result = this.parseScalar(value, null, ['"', "'"], context);
|
|
}
|
|
if (this.PATTERN_TRAILING_COMMENTS.replace(value.slice(context.i), '') !== '') {
|
|
throw new ParseException('Unexpected characters near "' + value.slice(context.i) + '".');
|
|
}
|
|
return result;
|
|
};
|
|
|
|
Inline.dump = function(value, exceptionOnInvalidType, objectEncoder) {
|
|
var ref, result, type;
|
|
if (exceptionOnInvalidType == null) {
|
|
exceptionOnInvalidType = false;
|
|
}
|
|
if (objectEncoder == null) {
|
|
objectEncoder = null;
|
|
}
|
|
if (value == null) {
|
|
return 'null';
|
|
}
|
|
type = typeof value;
|
|
if (type === 'object') {
|
|
if (value instanceof Date) {
|
|
return value.toISOString();
|
|
} else if (objectEncoder != null) {
|
|
result = objectEncoder(value);
|
|
if (typeof result === 'string' || (result != null)) {
|
|
return result;
|
|
}
|
|
}
|
|
return this.dumpObject(value);
|
|
}
|
|
if (type === 'boolean') {
|
|
return (value ? 'true' : 'false');
|
|
}
|
|
if (Utils.isDigits(value)) {
|
|
return (type === 'string' ? "'" + value + "'" : String(parseInt(value)));
|
|
}
|
|
if (Utils.isNumeric(value)) {
|
|
return (type === 'string' ? "'" + value + "'" : String(parseFloat(value)));
|
|
}
|
|
if (type === 'number') {
|
|
return (value === 2e308 ? '.Inf' : (value === -2e308 ? '-.Inf' : (isNaN(value) ? '.NaN' : value)));
|
|
}
|
|
if (Escaper.requiresDoubleQuoting(value)) {
|
|
return Escaper.escapeWithDoubleQuotes(value);
|
|
}
|
|
if (Escaper.requiresSingleQuoting(value)) {
|
|
return Escaper.escapeWithSingleQuotes(value);
|
|
}
|
|
if ('' === value) {
|
|
return '""';
|
|
}
|
|
if (Utils.PATTERN_DATE.test(value)) {
|
|
return "'" + value + "'";
|
|
}
|
|
if ((ref = value.toLowerCase()) === 'null' || ref === '~' || ref === 'true' || ref === 'false') {
|
|
return "'" + value + "'";
|
|
}
|
|
return value;
|
|
};
|
|
|
|
Inline.dumpObject = function(value, exceptionOnInvalidType, objectSupport) {
|
|
var j, key, len1, output, val;
|
|
if (objectSupport == null) {
|
|
objectSupport = null;
|
|
}
|
|
if (value instanceof Array) {
|
|
output = [];
|
|
for (j = 0, len1 = value.length; j < len1; j++) {
|
|
val = value[j];
|
|
output.push(this.dump(val));
|
|
}
|
|
return '[' + output.join(', ') + ']';
|
|
} else {
|
|
output = [];
|
|
for (key in value) {
|
|
val = value[key];
|
|
output.push(this.dump(key) + ': ' + this.dump(val));
|
|
}
|
|
return '{' + output.join(', ') + '}';
|
|
}
|
|
};
|
|
|
|
Inline.parseScalar = function(scalar, delimiters, stringDelimiters, context, evaluate) {
|
|
var i, joinedDelimiters, match, output, pattern, ref, ref1, strpos, tmp;
|
|
if (delimiters == null) {
|
|
delimiters = null;
|
|
}
|
|
if (stringDelimiters == null) {
|
|
stringDelimiters = ['"', "'"];
|
|
}
|
|
if (context == null) {
|
|
context = null;
|
|
}
|
|
if (evaluate == null) {
|
|
evaluate = true;
|
|
}
|
|
if (context == null) {
|
|
context = {
|
|
exceptionOnInvalidType: this.settings.exceptionOnInvalidType,
|
|
objectDecoder: this.settings.objectDecoder,
|
|
i: 0
|
|
};
|
|
}
|
|
i = context.i;
|
|
if (ref = scalar.charAt(i), indexOf.call(stringDelimiters, ref) >= 0) {
|
|
output = this.parseQuotedScalar(scalar, context);
|
|
i = context.i;
|
|
if (delimiters != null) {
|
|
tmp = Utils.ltrim(scalar.slice(i), ' ');
|
|
if (!(ref1 = tmp.charAt(0), indexOf.call(delimiters, ref1) >= 0)) {
|
|
throw new ParseException('Unexpected characters (' + scalar.slice(i) + ').');
|
|
}
|
|
}
|
|
} else {
|
|
if (!delimiters) {
|
|
output = scalar.slice(i);
|
|
i += output.length;
|
|
strpos = output.indexOf(' #');
|
|
if (strpos !== -1) {
|
|
output = Utils.rtrim(output.slice(0, strpos));
|
|
}
|
|
} else {
|
|
joinedDelimiters = delimiters.join('|');
|
|
pattern = this.PATTERN_SCALAR_BY_DELIMITERS[joinedDelimiters];
|
|
if (pattern == null) {
|
|
pattern = new Pattern('^(.+?)(' + joinedDelimiters + ')');
|
|
this.PATTERN_SCALAR_BY_DELIMITERS[joinedDelimiters] = pattern;
|
|
}
|
|
if (match = pattern.exec(scalar.slice(i))) {
|
|
output = match[1];
|
|
i += output.length;
|
|
} else {
|
|
throw new ParseException('Malformed inline YAML string (' + scalar + ').');
|
|
}
|
|
}
|
|
if (evaluate) {
|
|
output = this.evaluateScalar(output, context);
|
|
}
|
|
}
|
|
context.i = i;
|
|
return output;
|
|
};
|
|
|
|
Inline.parseQuotedScalar = function(scalar, context) {
|
|
var i, match, output;
|
|
i = context.i;
|
|
if (!(match = this.PATTERN_QUOTED_SCALAR.exec(scalar.slice(i)))) {
|
|
throw new ParseMore('Malformed inline YAML string (' + scalar.slice(i) + ').');
|
|
}
|
|
output = match[0].substr(1, match[0].length - 2);
|
|
if ('"' === scalar.charAt(i)) {
|
|
output = Unescaper.unescapeDoubleQuotedString(output);
|
|
} else {
|
|
output = Unescaper.unescapeSingleQuotedString(output);
|
|
}
|
|
i += match[0].length;
|
|
context.i = i;
|
|
return output;
|
|
};
|
|
|
|
Inline.parseSequence = function(sequence, context) {
|
|
var e, i, isQuoted, len, output, ref, value;
|
|
output = [];
|
|
len = sequence.length;
|
|
i = context.i;
|
|
i += 1;
|
|
while (i < len) {
|
|
context.i = i;
|
|
switch (sequence.charAt(i)) {
|
|
case '[':
|
|
output.push(this.parseSequence(sequence, context));
|
|
i = context.i;
|
|
break;
|
|
case '{':
|
|
output.push(this.parseMapping(sequence, context));
|
|
i = context.i;
|
|
break;
|
|
case ']':
|
|
return output;
|
|
case ',':
|
|
case ' ':
|
|
case "\n":
|
|
break;
|
|
default:
|
|
isQuoted = ((ref = sequence.charAt(i)) === '"' || ref === "'");
|
|
value = this.parseScalar(sequence, [',', ']'], ['"', "'"], context);
|
|
i = context.i;
|
|
if (!isQuoted && typeof value === 'string' && (value.indexOf(': ') !== -1 || value.indexOf(":\n") !== -1)) {
|
|
try {
|
|
value = this.parseMapping('{' + value + '}');
|
|
} catch (error) {
|
|
e = error;
|
|
}
|
|
}
|
|
output.push(value);
|
|
--i;
|
|
}
|
|
++i;
|
|
}
|
|
throw new ParseMore('Malformed inline YAML string ' + sequence);
|
|
};
|
|
|
|
Inline.parseMapping = function(mapping, context) {
|
|
var done, i, key, len, output, shouldContinueWhileLoop, value;
|
|
output = {};
|
|
len = mapping.length;
|
|
i = context.i;
|
|
i += 1;
|
|
shouldContinueWhileLoop = false;
|
|
while (i < len) {
|
|
context.i = i;
|
|
switch (mapping.charAt(i)) {
|
|
case ' ':
|
|
case ',':
|
|
case "\n":
|
|
++i;
|
|
context.i = i;
|
|
shouldContinueWhileLoop = true;
|
|
break;
|
|
case '}':
|
|
return output;
|
|
}
|
|
if (shouldContinueWhileLoop) {
|
|
shouldContinueWhileLoop = false;
|
|
continue;
|
|
}
|
|
key = this.parseScalar(mapping, [':', ' ', "\n"], ['"', "'"], context, false);
|
|
i = context.i;
|
|
done = false;
|
|
while (i < len) {
|
|
context.i = i;
|
|
switch (mapping.charAt(i)) {
|
|
case '[':
|
|
value = this.parseSequence(mapping, context);
|
|
i = context.i;
|
|
if (output[key] === void 0) {
|
|
output[key] = value;
|
|
}
|
|
done = true;
|
|
break;
|
|
case '{':
|
|
value = this.parseMapping(mapping, context);
|
|
i = context.i;
|
|
if (output[key] === void 0) {
|
|
output[key] = value;
|
|
}
|
|
done = true;
|
|
break;
|
|
case ':':
|
|
case ' ':
|
|
case "\n":
|
|
break;
|
|
default:
|
|
value = this.parseScalar(mapping, [',', '}'], ['"', "'"], context);
|
|
i = context.i;
|
|
if (output[key] === void 0) {
|
|
output[key] = value;
|
|
}
|
|
done = true;
|
|
--i;
|
|
}
|
|
++i;
|
|
if (done) {
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
throw new ParseMore('Malformed inline YAML string ' + mapping);
|
|
};
|
|
|
|
Inline.evaluateScalar = function(scalar, context) {
|
|
var cast, date, exceptionOnInvalidType, firstChar, firstSpace, firstWord, objectDecoder, raw, scalarLower, subValue, trimmedScalar;
|
|
scalar = Utils.trim(scalar);
|
|
scalarLower = scalar.toLowerCase();
|
|
switch (scalarLower) {
|
|
case 'null':
|
|
case '':
|
|
case '~':
|
|
return null;
|
|
case 'true':
|
|
return true;
|
|
case 'false':
|
|
return false;
|
|
case '.inf':
|
|
return 2e308;
|
|
case '.nan':
|
|
return 0/0;
|
|
case '-.inf':
|
|
return 2e308;
|
|
default:
|
|
firstChar = scalarLower.charAt(0);
|
|
switch (firstChar) {
|
|
case '!':
|
|
firstSpace = scalar.indexOf(' ');
|
|
if (firstSpace === -1) {
|
|
firstWord = scalarLower;
|
|
} else {
|
|
firstWord = scalarLower.slice(0, firstSpace);
|
|
}
|
|
switch (firstWord) {
|
|
case '!':
|
|
if (firstSpace !== -1) {
|
|
return parseInt(this.parseScalar(scalar.slice(2)));
|
|
}
|
|
return null;
|
|
case '!str':
|
|
return Utils.ltrim(scalar.slice(4));
|
|
case '!!str':
|
|
return Utils.ltrim(scalar.slice(5));
|
|
case '!!int':
|
|
return parseInt(this.parseScalar(scalar.slice(5)));
|
|
case '!!bool':
|
|
return Utils.parseBoolean(this.parseScalar(scalar.slice(6)), false);
|
|
case '!!float':
|
|
return parseFloat(this.parseScalar(scalar.slice(7)));
|
|
case '!!timestamp':
|
|
return Utils.stringToDate(Utils.ltrim(scalar.slice(11)));
|
|
default:
|
|
if (context == null) {
|
|
context = {
|
|
exceptionOnInvalidType: this.settings.exceptionOnInvalidType,
|
|
objectDecoder: this.settings.objectDecoder,
|
|
i: 0
|
|
};
|
|
}
|
|
objectDecoder = context.objectDecoder, exceptionOnInvalidType = context.exceptionOnInvalidType;
|
|
if (objectDecoder) {
|
|
trimmedScalar = Utils.rtrim(scalar);
|
|
firstSpace = trimmedScalar.indexOf(' ');
|
|
if (firstSpace === -1) {
|
|
return objectDecoder(trimmedScalar, null);
|
|
} else {
|
|
subValue = Utils.ltrim(trimmedScalar.slice(firstSpace + 1));
|
|
if (!(subValue.length > 0)) {
|
|
subValue = null;
|
|
}
|
|
return objectDecoder(trimmedScalar.slice(0, firstSpace), subValue);
|
|
}
|
|
}
|
|
if (exceptionOnInvalidType) {
|
|
throw new ParseException('Custom object support when parsing a YAML file has been disabled.');
|
|
}
|
|
return null;
|
|
}
|
|
break;
|
|
case '0':
|
|
if ('0x' === scalar.slice(0, 2)) {
|
|
return Utils.hexDec(scalar);
|
|
} else if (Utils.isDigits(scalar)) {
|
|
return Utils.octDec(scalar);
|
|
} else if (Utils.isNumeric(scalar)) {
|
|
return parseFloat(scalar);
|
|
} else {
|
|
return scalar;
|
|
}
|
|
break;
|
|
case '+':
|
|
if (Utils.isDigits(scalar)) {
|
|
raw = scalar;
|
|
cast = parseInt(raw);
|
|
if (raw === String(cast)) {
|
|
return cast;
|
|
} else {
|
|
return raw;
|
|
}
|
|
} else if (Utils.isNumeric(scalar)) {
|
|
return parseFloat(scalar);
|
|
} else if (this.PATTERN_THOUSAND_NUMERIC_SCALAR.test(scalar)) {
|
|
return parseFloat(scalar.replace(',', ''));
|
|
}
|
|
return scalar;
|
|
case '-':
|
|
if (Utils.isDigits(scalar.slice(1))) {
|
|
if ('0' === scalar.charAt(1)) {
|
|
return -Utils.octDec(scalar.slice(1));
|
|
} else {
|
|
raw = scalar.slice(1);
|
|
cast = parseInt(raw);
|
|
if (raw === String(cast)) {
|
|
return -cast;
|
|
} else {
|
|
return -raw;
|
|
}
|
|
}
|
|
} else if (Utils.isNumeric(scalar)) {
|
|
return parseFloat(scalar);
|
|
} else if (this.PATTERN_THOUSAND_NUMERIC_SCALAR.test(scalar)) {
|
|
return parseFloat(scalar.replace(',', ''));
|
|
}
|
|
return scalar;
|
|
default:
|
|
if (date = Utils.stringToDate(scalar)) {
|
|
return date;
|
|
} else if (Utils.isNumeric(scalar)) {
|
|
return parseFloat(scalar);
|
|
} else if (this.PATTERN_THOUSAND_NUMERIC_SCALAR.test(scalar)) {
|
|
return parseFloat(scalar.replace(',', ''));
|
|
}
|
|
return scalar;
|
|
}
|
|
}
|
|
};
|
|
|
|
return Inline;
|
|
|
|
})();
|
|
|
|
module.exports = Inline;
|