mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
* ext/json: Merge json gem 1.5.4+ (2149f4185c598fb97db1).
[Bug #5173] [ruby-core:38866] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@33122 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
2dd9d721ed
commit
b14c060dda
13 changed files with 728 additions and 288 deletions
|
@ -76,8 +76,9 @@ static VALUE mJSON, mExt, cParser, eParserError, eNestingError;
|
|||
static VALUE CNaN, CInfinity, CMinusInfinity;
|
||||
|
||||
static ID i_json_creatable_p, i_json_create, i_create_id, i_create_additions,
|
||||
i_chr, i_max_nesting, i_allow_nan, i_symbolize_names, i_object_class,
|
||||
i_array_class, i_key_p, i_deep_const_get, i_match, i_match_string, i_aset, i_leftshift;
|
||||
i_chr, i_max_nesting, i_allow_nan, i_symbolize_names, i_quirks_mode,
|
||||
i_object_class, i_array_class, i_key_p, i_deep_const_get, i_match,
|
||||
i_match_string, i_aset, i_leftshift;
|
||||
|
||||
%%{
|
||||
machine JSON_common;
|
||||
|
@ -138,13 +139,14 @@ static ID i_json_creatable_p, i_json_create, i_create_id, i_create_additions,
|
|||
|
||||
action exit { fhold; fbreak; }
|
||||
|
||||
a_pair = ignore* begin_name >parse_name
|
||||
ignore* name_separator ignore*
|
||||
begin_value >parse_value;
|
||||
pair = ignore* begin_name >parse_name ignore* name_separator ignore* begin_value >parse_value;
|
||||
next_pair = ignore* value_separator pair;
|
||||
|
||||
main := begin_object
|
||||
(a_pair (ignore* value_separator a_pair)*)?
|
||||
ignore* end_object @exit;
|
||||
main := (
|
||||
begin_object
|
||||
(pair (next_pair)*)? ignore*
|
||||
end_object
|
||||
) @exit;
|
||||
}%%
|
||||
|
||||
static char *JSON_parse_object(JSON_Parser *json, char *p, char *pe, VALUE *result)
|
||||
|
@ -178,6 +180,7 @@ static char *JSON_parse_object(JSON_Parser *json, char *p, char *pe, VALUE *resu
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
%%{
|
||||
machine JSON_value;
|
||||
include JSON_common;
|
||||
|
@ -214,7 +217,7 @@ static char *JSON_parse_object(JSON_Parser *json, char *p, char *pe, VALUE *resu
|
|||
|
||||
action parse_number {
|
||||
char *np;
|
||||
if(pe > fpc + 9 && !strncmp(MinusInfinity, fpc, 9)) {
|
||||
if(pe > fpc + 9 - json->quirks_mode && !strncmp(MinusInfinity, fpc, 9)) {
|
||||
if (json->allow_nan) {
|
||||
*result = CMinusInfinity;
|
||||
fexec p + 10;
|
||||
|
@ -282,7 +285,7 @@ static char *JSON_parse_value(JSON_Parser *json, char *p, char *pe, VALUE *resul
|
|||
|
||||
action exit { fhold; fbreak; }
|
||||
|
||||
main := '-'? ('0' | [1-9][0-9]*) (^[0-9] @exit);
|
||||
main := '-'? ('0' | [1-9][0-9]*) (^[0-9]? @exit);
|
||||
}%%
|
||||
|
||||
static char *JSON_parse_integer(JSON_Parser *json, char *p, char *pe, VALUE *result)
|
||||
|
@ -313,7 +316,7 @@ static char *JSON_parse_integer(JSON_Parser *json, char *p, char *pe, VALUE *res
|
|||
main := '-'? (
|
||||
(('0' | [1-9][0-9]*) '.' [0-9]+ ([Ee] [+\-]?[0-9]+)?)
|
||||
| (('0' | [1-9][0-9]*) ([Ee] [+\-]?[0-9]+))
|
||||
) (^[0-9Ee.\-] @exit );
|
||||
) (^[0-9Ee.\-]? @exit );
|
||||
}%%
|
||||
|
||||
static char *JSON_parse_float(JSON_Parser *json, char *p, char *pe, VALUE *result)
|
||||
|
@ -521,34 +524,6 @@ static char *JSON_parse_string(JSON_Parser *json, char *p, char *pe, VALUE *resu
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
%%{
|
||||
machine JSON;
|
||||
|
||||
write data;
|
||||
|
||||
include JSON_common;
|
||||
|
||||
action parse_object {
|
||||
char *np;
|
||||
json->current_nesting = 1;
|
||||
np = JSON_parse_object(json, fpc, pe, &result);
|
||||
if (np == NULL) { fhold; fbreak; } else fexec np;
|
||||
}
|
||||
|
||||
action parse_array {
|
||||
char *np;
|
||||
json->current_nesting = 1;
|
||||
np = JSON_parse_array(json, fpc, pe, &result);
|
||||
if (np == NULL) { fhold; fbreak; } else fexec np;
|
||||
}
|
||||
|
||||
main := ignore* (
|
||||
begin_object >parse_object |
|
||||
begin_array >parse_array
|
||||
) ignore*;
|
||||
}%%
|
||||
|
||||
/*
|
||||
* Document-class: JSON::Ext::Parser
|
||||
*
|
||||
|
@ -630,8 +605,6 @@ static VALUE convert_encoding(VALUE source)
|
|||
*/
|
||||
static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self)
|
||||
{
|
||||
char *ptr;
|
||||
long len;
|
||||
VALUE source, opts;
|
||||
GET_PARSER_INIT;
|
||||
|
||||
|
@ -639,9 +612,6 @@ static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self)
|
|||
rb_raise(rb_eTypeError, "already initialized instance");
|
||||
}
|
||||
rb_scan_args(argc, argv, "11", &source, &opts);
|
||||
source = convert_encoding(StringValue(source));
|
||||
ptr = RSTRING_PTR(source);
|
||||
len = RSTRING_LEN(source);
|
||||
if (!NIL_P(opts)) {
|
||||
opts = rb_convert_type(opts, T_HASH, "Hash", "to_hash");
|
||||
if (NIL_P(opts)) {
|
||||
|
@ -671,6 +641,13 @@ static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self)
|
|||
} else {
|
||||
json->symbolize_names = 0;
|
||||
}
|
||||
tmp = ID2SYM(i_quirks_mode);
|
||||
if (option_given_p(opts, tmp)) {
|
||||
VALUE quirks_mode = rb_hash_aref(opts, tmp);
|
||||
json->quirks_mode = RTEST(quirks_mode) ? 1 : 0;
|
||||
} else {
|
||||
json->quirks_mode = 0;
|
||||
}
|
||||
tmp = ID2SYM(i_create_additions);
|
||||
if (option_given_p(opts, tmp)) {
|
||||
json->create_additions = RTEST(rb_hash_aref(opts, tmp));
|
||||
|
@ -711,20 +688,44 @@ static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self)
|
|||
json->object_class = Qnil;
|
||||
json->array_class = Qnil;
|
||||
}
|
||||
if (!json->quirks_mode) {
|
||||
source = convert_encoding(StringValue(source));
|
||||
}
|
||||
json->current_nesting = 0;
|
||||
json->len = len;
|
||||
json->source = ptr;
|
||||
json->len = RSTRING_LEN(source);
|
||||
json->source = RSTRING_PTR(source);;
|
||||
json->Vsource = source;
|
||||
return self;
|
||||
}
|
||||
|
||||
/*
|
||||
* call-seq: parse()
|
||||
*
|
||||
* Parses the current JSON text _source_ and returns the complete data
|
||||
* structure as a result.
|
||||
*/
|
||||
static VALUE cParser_parse(VALUE self)
|
||||
%%{
|
||||
machine JSON;
|
||||
|
||||
write data;
|
||||
|
||||
include JSON_common;
|
||||
|
||||
action parse_object {
|
||||
char *np;
|
||||
json->current_nesting = 1;
|
||||
np = JSON_parse_object(json, fpc, pe, &result);
|
||||
if (np == NULL) { fhold; fbreak; } else fexec np;
|
||||
}
|
||||
|
||||
action parse_array {
|
||||
char *np;
|
||||
json->current_nesting = 1;
|
||||
np = JSON_parse_array(json, fpc, pe, &result);
|
||||
if (np == NULL) { fhold; fbreak; } else fexec np;
|
||||
}
|
||||
|
||||
main := ignore* (
|
||||
begin_object >parse_object |
|
||||
begin_array >parse_array
|
||||
) ignore*;
|
||||
}%%
|
||||
|
||||
static VALUE cParser_parse_strict(VALUE self)
|
||||
{
|
||||
char *p, *pe;
|
||||
int cs = EVIL;
|
||||
|
@ -744,6 +745,62 @@ static VALUE cParser_parse(VALUE self)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
%%{
|
||||
machine JSON_quirks_mode;
|
||||
|
||||
write data;
|
||||
|
||||
include JSON_common;
|
||||
|
||||
action parse_value {
|
||||
char *np = JSON_parse_value(json, fpc, pe, &result);
|
||||
if (np == NULL) { fhold; fbreak; } else fexec np;
|
||||
}
|
||||
|
||||
main := ignore* (
|
||||
begin_value >parse_value
|
||||
) ignore*;
|
||||
}%%
|
||||
|
||||
static VALUE cParser_parse_quirks_mode(VALUE self)
|
||||
{
|
||||
char *p, *pe;
|
||||
int cs = EVIL;
|
||||
VALUE result = Qnil;
|
||||
GET_PARSER;
|
||||
|
||||
%% write init;
|
||||
p = json->source;
|
||||
pe = p + json->len;
|
||||
%% write exec;
|
||||
|
||||
if (cs >= JSON_quirks_mode_first_final && p == pe) {
|
||||
return result;
|
||||
} else {
|
||||
rb_raise(eParserError, "%u: unexpected token at '%s'", __LINE__, p);
|
||||
return Qnil;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* call-seq: parse()
|
||||
*
|
||||
* Parses the current JSON text _source_ and returns the complete data
|
||||
* structure as a result.
|
||||
*/
|
||||
static VALUE cParser_parse(VALUE self)
|
||||
{
|
||||
GET_PARSER;
|
||||
|
||||
if (json->quirks_mode) {
|
||||
return cParser_parse_quirks_mode(self);
|
||||
} else {
|
||||
return cParser_parse_strict(self);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static JSON_Parser *JSON_allocate()
|
||||
{
|
||||
JSON_Parser *json = ALLOC(JSON_Parser);
|
||||
|
@ -783,6 +840,18 @@ static VALUE cParser_source(VALUE self)
|
|||
return rb_str_dup(json->Vsource);
|
||||
}
|
||||
|
||||
/*
|
||||
* call-seq: quirks_mode?()
|
||||
*
|
||||
* Returns a true, if this parser is in quirks_mode, false otherwise.
|
||||
*/
|
||||
static VALUE cParser_quirks_mode_p(VALUE self)
|
||||
{
|
||||
GET_PARSER;
|
||||
return json->quirks_mode ? Qtrue : Qfalse;
|
||||
}
|
||||
|
||||
|
||||
void Init_parser()
|
||||
{
|
||||
rb_require("json/common");
|
||||
|
@ -795,6 +864,7 @@ void Init_parser()
|
|||
rb_define_method(cParser, "initialize", cParser_initialize, -1);
|
||||
rb_define_method(cParser, "parse", cParser_parse, 0);
|
||||
rb_define_method(cParser, "source", cParser_source, 0);
|
||||
rb_define_method(cParser, "quirks_mode?", cParser_quirks_mode_p, 0);
|
||||
|
||||
CNaN = rb_const_get(mJSON, rb_intern("NaN"));
|
||||
CInfinity = rb_const_get(mJSON, rb_intern("Infinity"));
|
||||
|
@ -808,6 +878,7 @@ void Init_parser()
|
|||
i_max_nesting = rb_intern("max_nesting");
|
||||
i_allow_nan = rb_intern("allow_nan");
|
||||
i_symbolize_names = rb_intern("symbolize_names");
|
||||
i_quirks_mode = rb_intern("quirks_mode");
|
||||
i_object_class = rb_intern("object_class");
|
||||
i_array_class = rb_intern("array_class");
|
||||
i_match = rb_intern("match");
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue