| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112 |
- // Split the input into chunks.
- module.exports = function (input, fail) {
- var len = input.length, level = 0, parenLevel = 0,
- lastOpening, lastOpeningParen, lastMultiComment, lastMultiCommentEndBrace,
- chunks = [], emitFrom = 0,
- chunkerCurrentIndex, currentChunkStartIndex, cc, cc2, matched;
- function emitChunk(force) {
- var len = chunkerCurrentIndex - emitFrom;
- if (((len < 512) && !force) || !len) {
- return;
- }
- chunks.push(input.slice(emitFrom, chunkerCurrentIndex + 1));
- emitFrom = chunkerCurrentIndex + 1;
- }
- for (chunkerCurrentIndex = 0; chunkerCurrentIndex < len; chunkerCurrentIndex++) {
- cc = input.charCodeAt(chunkerCurrentIndex);
- if (((cc >= 97) && (cc <= 122)) || (cc < 34)) {
- // a-z or whitespace
- continue;
- }
- switch (cc) {
- case 40: // (
- parenLevel++;
- lastOpeningParen = chunkerCurrentIndex;
- continue;
- case 41: // )
- if (--parenLevel < 0) {
- return fail("missing opening `(`", chunkerCurrentIndex);
- }
- continue;
- case 59: // ;
- if (!parenLevel) { emitChunk(); }
- continue;
- case 123: // {
- level++;
- lastOpening = chunkerCurrentIndex;
- continue;
- case 125: // }
- if (--level < 0) {
- return fail("missing opening `{`", chunkerCurrentIndex);
- }
- if (!level && !parenLevel) { emitChunk(); }
- continue;
- case 92: // \
- if (chunkerCurrentIndex < len - 1) { chunkerCurrentIndex++; continue; }
- return fail("unescaped `\\`", chunkerCurrentIndex);
- case 34:
- case 39:
- case 96: // ", ' and `
- matched = 0;
- currentChunkStartIndex = chunkerCurrentIndex;
- for (chunkerCurrentIndex = chunkerCurrentIndex + 1; chunkerCurrentIndex < len; chunkerCurrentIndex++) {
- cc2 = input.charCodeAt(chunkerCurrentIndex);
- if (cc2 > 96) { continue; }
- if (cc2 == cc) { matched = 1; break; }
- if (cc2 == 92) { // \
- if (chunkerCurrentIndex == len - 1) {
- return fail("unescaped `\\`", chunkerCurrentIndex);
- }
- chunkerCurrentIndex++;
- }
- }
- if (matched) { continue; }
- return fail("unmatched `" + String.fromCharCode(cc) + "`", currentChunkStartIndex);
- case 47: // /, check for comment
- if (parenLevel || (chunkerCurrentIndex == len - 1)) { continue; }
- cc2 = input.charCodeAt(chunkerCurrentIndex + 1);
- if (cc2 == 47) {
- // //, find lnfeed
- for (chunkerCurrentIndex = chunkerCurrentIndex + 2; chunkerCurrentIndex < len; chunkerCurrentIndex++) {
- cc2 = input.charCodeAt(chunkerCurrentIndex);
- if ((cc2 <= 13) && ((cc2 == 10) || (cc2 == 13))) { break; }
- }
- } else if (cc2 == 42) {
- // /*, find */
- lastMultiComment = currentChunkStartIndex = chunkerCurrentIndex;
- for (chunkerCurrentIndex = chunkerCurrentIndex + 2; chunkerCurrentIndex < len - 1; chunkerCurrentIndex++) {
- cc2 = input.charCodeAt(chunkerCurrentIndex);
- if (cc2 == 125) { lastMultiCommentEndBrace = chunkerCurrentIndex; }
- if (cc2 != 42) { continue; }
- if (input.charCodeAt(chunkerCurrentIndex + 1) == 47) { break; }
- }
- if (chunkerCurrentIndex == len - 1) {
- return fail("missing closing `*/`", currentChunkStartIndex);
- }
- chunkerCurrentIndex++;
- }
- continue;
- case 42: // *, check for unmatched */
- if ((chunkerCurrentIndex < len - 1) && (input.charCodeAt(chunkerCurrentIndex + 1) == 47)) {
- return fail("unmatched `/*`", chunkerCurrentIndex);
- }
- continue;
- }
- }
- if (level !== 0) {
- if ((lastMultiComment > lastOpening) && (lastMultiCommentEndBrace > lastMultiComment)) {
- return fail("missing closing `}` or `*/`", lastOpening);
- } else {
- return fail("missing closing `}`", lastOpening);
- }
- } else if (parenLevel !== 0) {
- return fail("missing closing `)`", lastOpeningParen);
- }
- emitChunk(true);
- return chunks;
- };
|