5 Commits

Author SHA1 Message Date
Zachary Carter
5c5ad5acf0 1.5.0 2012-05-28 15:14:43 -07:00
Zachary Carter
6af4143235 add schema validation 2012-05-28 15:14:09 -07:00
Zachary Carter
cb82cc205d 1.4.1 2012-05-28 12:30:28 -07:00
Zachary Carter
3899996991 update bundle script 2012-05-28 12:30:05 -07:00
Zachary Carter
14a108f3a4 fix escaping of special characters (issue #22) 2012-05-28 12:27:08 -07:00
8 changed files with 86 additions and 29 deletions

View File

@@ -1,10 +1,13 @@
#!/usr/bin/env node
var fs = require("fs");
var path = require("path");
var parser = require("./jsonlint").parser;
var JSV = require("JSV").JSV;
var options = require("nomnom")
.scriptName("jsonlint")
.opts({
.script("jsonlint")
.options({
file: {
position: 0,
help: "file to parse; otherwise uses stdin"
@@ -14,7 +17,7 @@ var options = require("nomnom")
string: '-v, --version',
help: 'print version and exit',
callback: function() {
return JSON.parse(fs.readFileSync(__dirname + "/../package.json", "utf8")).version;
return require("../package").version;
}
},
sort : {
@@ -36,37 +39,64 @@ var options = require("nomnom")
flag : true,
string: '-c, --compact',
help : 'compact error display'
},
validate : {
string: '-V, --validate',
help : 'a JSON schema to use for validation'
},
env : {
string: '-e, --environment',
"default": "json-schema-draft-03",
help: 'which specification of JSON Schema the validation file uses'
}
})
.parseArgs();
}).parse();
if (options.compact) {
var fileName = options.file? options.file + ': ' : '';
parser.parseError = parser.lexer.parseError = function(str, hash) {
console.error(fileName + 'line '+ hash.loc.first_line +', col '+ hash.loc.last_column +', found: \''+ hash.token +'\' - expected: '+ hash.expected.join(', ') +'.');
throw new Error(str);
};
var fileName = options.file? options.file + ': ' : '';
parser.parseError = parser.lexer.parseError = function(str, hash) {
console.error(fileName + 'line '+ hash.loc.first_line +', col '+ hash.loc.last_column +', found: \''+ hash.token +'\' - expected: '+ hash.expected.join(', ') +'.');
throw new Error(str);
};
}
function parse (source) {
try {
var parsed = options.sort ?
sortObject(parser.parse(source)) :
parser.parse(source);
sortObject(parser.parse(source)) :
parser.parse(source);
if (options.validate) {
var env = JSV.createEnvironment(options.env);
var schema = JSON.parse(fs.readFileSync(path.normalize(options.validate), "utf8"));
var report = env.validate(parsed, schema);
if (report.errors.length) {
throw report.errors.reduce(schemaError, 'Validation Errors:');
}
}
return JSON.stringify(parsed,null,options.indent);
} catch (e) {
if (! options.compact) {
console.log(e);
console.error(e);
}
process.exit(1);
}
}
function schemaError (str, err) {
return str +
"\n\n"+err.message +
"\nuri: " + err.uri +
"\nschemaUri: " + err.schemaUri +
"\nattribute: " + err.attribute +
"\ndetails: " + JSON.stringify(err.details);
}
function main (args) {
var source = '';
if (options.file) {
var path = require('path').normalize(options.file);
source = parse(fs.readFileSync(path, "utf8"));
var json = path.normalize(options.file);
source = parse(fs.readFileSync(json, "utf8"));
if (options.inplace) {
fs.writeSync(fs.openSync(path,'w+'), source, 0, "utf8");
} else {

View File

@@ -9,7 +9,15 @@ performAction: function anonymous(yytext,yyleng,yylineno,yy,yystate,$$,_$) {
var $0 = $$.length - 1;
switch (yystate) {
case 1:this.$ = yytext.replace(/\\\\/g, "\\");
case 1: // replace escaped characters with actual character
this.$ = yytext.replace(/\\(\\|")/g, "$"+"1")
.replace(/\\n/g,'\n')
.replace(/\\r/g,'\r')
.replace(/\\t/g,'\t')
.replace(/\\v/g,'\v')
.replace(/\\f/g,'\f')
.replace(/\\b/g,'\b');
break;
case 2:this.$ = Number(yytext);
break;
@@ -367,13 +375,13 @@ var YYSTATE=YY_START
switch($avoiding_name_collisions) {
case 0:/* skip whitespace */
break;
case 1:return 6;
case 1:return 6
break;
case 2:yy_.yytext = yy_.yytext.substr(1,yy_.yyleng-2); return 4;
case 2:yy_.yytext = yy_.yytext.substr(1,yy_.yyleng-2); return 4
break;
case 3: return 17
case 3:return 17
break;
case 4: return 18
case 4:return 18
break;
case 5:return 23
break;

View File

@@ -8,7 +8,7 @@
"lint",
"jsonlint"
],
"version": "1.4.0",
"version": "1.5.0",
"preferGlobal": true,
"repository": {
"type": "git",
@@ -25,7 +25,8 @@
"node": ">= 0.6"
},
"dependencies": {
"nomnom": ">= 1.x.x"
"nomnom": ">= 1.5.x",
"JSV": ">= 4.0.x"
},
"devDependencies": {
"test": "*",

View File

@@ -1,9 +1,8 @@
var fs = require('fs');
var sys = require('sys');
var source = "var jsonlint = (function(){var require=true,module=false;var exports={};" +
var source = "var jsonlint = (function(){var require=true,module=false;var exports={};" +
fs.readFileSync(__dirname+'/../lib/jsonlint.js', 'utf8') +
"return exports;})()";
sys.puts(source);
console.log(source);

View File

@@ -9,7 +9,7 @@ frac "."[0-9]+
\"(?:'\\'[\\"bfnrt/]|'\\u'[a-fA-F0-9]{4}|[^\\\0-\x09\x0a-\x1f"])*\" yytext = yytext.substr(1,yyleng-2); return 'STRING'
"{" return '{'
"}" return ''
"}" return '}'
"[" return '['
"]" return ']'
"," return ','

View File

@@ -9,7 +9,15 @@
JSONString
: STRING
{$$ = yytext.replace(/\\\\/g, "\\");}
{ // replace escaped characters with actual character
$$ = yytext.replace(/\\(\\|")/g, "$"+"1")
.replace(/\\n/g,'\n')
.replace(/\\r/g,'\r')
.replace(/\\t/g,'\t')
.replace(/\\v/g,'\v')
.replace(/\\f/g,'\f')
.replace(/\\b/g,'\b');
}
;
JSONNumber

View File

@@ -12,9 +12,20 @@ exports["test escaped backslash"] = function () {
assert.deepEqual(parser.parse(json), {"foo": "\\"});
};
exports["test escaped chars"] = function () {
var json = '{"foo": "\\\\\\\""}';
assert.deepEqual(parser.parse(json), {"foo": '\\\"'});
};
exports["test escaped \\n"] = function () {
var json = '{"foo": "\\\\\\n"}';
assert.deepEqual(parser.parse(json), {"foo": '\\\n'});
};
exports["test string with escaped line break"] = function () {
var json = '{"foo": "bar\\nbar"}';
assert.deepEqual(parser.parse(json), {"foo": "bar\\nbar"});
assert.deepEqual(parser.parse(json), {"foo": "bar\nbar"});
assert.equal(JSON.stringify(parser.parse(json)).length, 18);
};
exports["test string with line break"] = function () {

File diff suppressed because one or more lines are too long