Skip to content

Commit

Permalink
tweaks to make => behave properly and some more tests
Browse files Browse the repository at this point in the history
  • Loading branch information
demerphq committed May 17, 2012
1 parent bb9878d commit c404b8d
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 18 deletions.
27 changes: 17 additions & 10 deletions Undump.xs
Expand Up @@ -232,6 +232,7 @@ SV* _undump(pTHX_ const char **parse_start, const char const *parse_end, char ob
char token= TOKEN_ERROR; char token= TOKEN_ERROR;
char want_key= 0; char want_key= 0;
char allow_comma= 0; char allow_comma= 0;
char require_fat_comma= 0;
char stop_char; char stop_char;
char ch; char ch;
const char *key; const char *key;
Expand Down Expand Up @@ -263,6 +264,7 @@ SV* _undump(pTHX_ const char **parse_start, const char const *parse_end, char ob


REPARSE: REPARSE:
while (parse_ptr < parse_end) { while (parse_ptr < parse_end) {
/* warn("want_key: %d require_fat_comma: %d allow_comma: %d\n", want_key, require_fat_comma, allow_comma); */
token_start= parse_ptr; token_start= parse_ptr;
token= TOKEN_ERROR; token= TOKEN_ERROR;
ch= *(parse_ptr++); ch= *(parse_ptr++);
Expand All @@ -274,16 +276,17 @@ SV* _undump(pTHX_ const char **parse_start, const char const *parse_end, char ob
if ( *parse_ptr != '>' ) { if ( *parse_ptr != '>' ) {
ERROR(depth,token,token_start,parse_ptr,parse_end,"Encountered assignment '=' or unterminated fat comma '=>'"); ERROR(depth,token,token_start,parse_ptr,parse_end,"Encountered assignment '=' or unterminated fat comma '=>'");
} }
require_fat_comma = 0;
parse_ptr++; parse_ptr++;
/* fallthrough */ /* fallthrough */
case ',': case ',':
/* comma */ /* comma */
if ( ! allow_comma ) { if ( require_fat_comma ) {
if ( want_key ) { ERROR(depth,token,token_start,parse_ptr,parse_end,"expected fat comma after bareword");
ERROR(depth,token,token_start,parse_ptr,parse_end,"unexpected comma when expecting a key"); }
} else { else if ( ! allow_comma ) {
ERROR(depth,token,token_start,parse_ptr,parse_end,"unexpected comma when expecting a value"); ERRORf2(depth,token,token_start,parse_ptr,parse_end,"unexpected %s when expecting a %s",
} (ch=='=' ? "fat comma" : "comma"),(want_key ? "key" : "value"));
} }
allow_comma = 0; allow_comma = 0;
goto REPARSE; goto REPARSE;
Expand Down Expand Up @@ -424,6 +427,11 @@ SV* _undump(pTHX_ const char **parse_start, const char const *parse_end, char ob
token= TOKEN_BAREWORD; token= TOKEN_BAREWORD;
} }
} /* switch */ } /* switch */
if (require_fat_comma) {
ERROR(depth,token,token_start,parse_ptr,parse_end,"expected fat comma after bareword");
} else if (allow_comma && token != TOKEN_CLOSE) {
ERRORf1(depth,token,token_start,parse_ptr,parse_end,"Expecting comma got %s",token_name[token]);
}
SHOW_TOKEN(depth,token,token_start,parse_ptr); SHOW_TOKEN(depth,token,token_start,parse_ptr);
switch (token) { switch (token) {
case TOKEN_BLESS: case TOKEN_BLESS:
Expand Down Expand Up @@ -633,13 +641,13 @@ SV* _undump(pTHX_ const char **parse_start, const char const *parse_end, char ob
grok_len= esc_read - grok_start; grok_len= esc_read - grok_start;
esc_read++; /* skip '}' */ esc_read++; /* skip '}' */
} }
// warn("hex: %.*s\n", grok_len, grok_start); /* warn("hex: %.*s\n", grok_len, grok_start); */
if (grok_len) { if (grok_len) {
cp= grok_hex((char *)grok_start, &grok_len, &grok_flags, 0); cp= grok_hex((char *)grok_start, &grok_len, &grok_flags, 0);
} else { } else {
ERROR(depth,token,token_start,parse_ptr,parse_end,"empty \\x{} escape?"); ERROR(depth,token,token_start,parse_ptr,parse_end,"empty \\x{} escape?");
} }
// warn("cp: %d\n len: %d flags: %d", cp, grok_len, grok_flags); /* warn("cp: %d\n len: %d flags: %d", cp, grok_len, grok_flags); */
if ( cp < 0x100 ) { /* otherwise it would be in octal */ if ( cp < 0x100 ) { /* otherwise it would be in octal */
must_uni= 1; must_uni= 1;
} }
Expand Down Expand Up @@ -691,10 +699,9 @@ SV* _undump(pTHX_ const char **parse_start, const char const *parse_end, char ob
} }
case TOKEN_BAREWORD: case TOKEN_BAREWORD:
/* fallthrough */ /* fallthrough */
require_fat_comma= 1;
if (want_key) { if (want_key) {
DONE_KEY_SIMPLE_break; DONE_KEY_SIMPLE_break;
} else {
ERROR(depth,token,token_start,parse_ptr,parse_end,"got a bareword where it was not expected");
} }
if (got) { if (got) {
ERROR(depth,token,token_start,parse_ptr,parse_end,"Multiple objects in stream?"); ERROR(depth,token,token_start,parse_ptr,parse_end,"Multiple objects in stream?");
Expand Down
15 changes: 10 additions & 5 deletions t/01_undump.t
Expand Up @@ -12,18 +12,19 @@ our @dump;
push @dump, $_; push @dump, $_;
} }
} }
plan tests => 1 + 2 * @dump; plan tests => 1 + 3 * @dump;
pass(); pass();
sub dd { return Data::Dumper->new([$_[0]])->Purity(1)->Useqq(1)->Sortkeys(1)->Dump() } sub dd { return Data::Dumper->new([$_[0]])->Purity(1)->Useqq(1)->Sortkeys(1)->Dump() }
sub check { sub check {
my $dump= shift; my $dump= shift;
my $undumped= dd(my $struct= undump($dump)); my $undumped= dd(my $struct= undump($dump));
my $show_diag= !is( $@||undef, undef, "after undump \$\@ was false");
my $evaled= dd(eval($dump)); my $evaled= dd(eval($dump));

$show_diag += !($dump eq "undef"
$dump eq "undef"
? pass("undumping undef") ? pass("undumping undef")
: isnt($struct, undef, "undump succeeded: >>$dump<<"); : isnt($struct, undef, "undump returned something"));
return is_string($undumped,$evaled,"undump and eval agree"); $show_diag += !is_string($undumped,$evaled,"undump and eval agree");
$show_diag and diag($dump);
} }


check($_) for @dump; check($_) for @dump;
Expand Down Expand Up @@ -62,6 +63,8 @@ undef
{ foo => 'bar' } { foo => 'bar' }
{ foo => bar => baz => undef }
[ 1 ] [ 1 ]
[ 1, [ 2 ] ] [ 1, [ 2 ] ]
Expand All @@ -70,6 +73,8 @@ undef
[ 1 , 2 , [ 3 , 4 , { 5 => 6 , 7 => { 8 => [ ] } , 9 => { } } , { }, [ ] ] ] [ 1 , 2 , [ 3 , 4 , { 5 => 6 , 7 => { 8 => [ ] } , 9 => { } } , { }, [ ] ] ]
[ a => 'b' ]
{ {
foo => 123, foo => 123,
bar => -159.23 , bar => -159.23 ,
Expand Down
13 changes: 10 additions & 3 deletions t/02_error.t
Expand Up @@ -28,7 +28,7 @@ __DATA__
{ foo => [ | unterminated ARRAY constructor { foo => [ | unterminated ARRAY constructor
{ foo foo => | got a bareword where it was not expected { foo foo => | expected fat comma after bareword
"foo | unterminated double quoted string "foo | unterminated double quoted string
Expand All @@ -46,6 +46,13 @@ __DATA__
{ undef => {} } | got an undef when we wanted a key { undef => {} } | got an undef when we wanted a key
[ a => 'b' ] | got a bareword where it was not expected { a,,,b } | expected fat comma after bareword
{ a,1 } | expected fat comma after bareword
{ a => => b } | unexpected fat comma when expecting a value
{ a => x => => b } | unexpected fat comma when expecting a key
$VAR1 | Encountered variable in input. This is not eval - can not undump code
{ a,,,b } | unexpected comma when expecting a value

0 comments on commit c404b8d

Please sign in to comment.