From 600c684c5c2b4068e5d297f645ce95728e6a193d Mon Sep 17 00:00:00 2001 From: Matthew Horsfall Date: Mon, 4 Feb 2019 22:07:49 -0500 Subject: [PATCH 1/2] Allow quoted arguments and bare foo/bar This assigns a string of 3 words to the argument foo: /foo "bar baz quz" Also, arguments should be identified by whitespace before them so /foo bar/baz should be one argument called 'foo' with the value bar/baz. --- lib/Synergy/Util.pm | 9 ++++--- t/switches.t | 62 ++++++++++++++++++++++++++++++++++++--------- 2 files changed, 55 insertions(+), 16 deletions(-) diff --git a/lib/Synergy/Util.pm b/lib/Synergy/Util.pm index 76020a97..e7a8616c 100644 --- a/lib/Synergy/Util.pm +++ b/lib/Synergy/Util.pm @@ -77,8 +77,6 @@ sub parse_switches ($string) { # safestr := not-slash+ spaceslash-or-end # quotestr := '"' ( qchar | not-dquote )* '"' ws-or-end # - # But for now we'll live without quotestr, because it seems very unlikley to - # come up. -- rjbs, 2019-02-04 while (length $string) { $string =~ s{\A\s+}{}g; @@ -91,12 +89,15 @@ sub parse_switches ($string) { return (undef, "bogus /command: /$1"); # push @tokens, [ badcmd => $1 ]; # next; - } elsif ($string =~ s{ \A ( [^/]+ ) (\s+/ | $) }{$2}x) { + } elsif ($string =~ s{ \A (? $1 ]; + next; + } elsif ($string =~ s{ \A ( .*? ) (\s+/ | $) }{$2}x) { push @tokens, [ lit => $1 ]; next; } - return (undef, "incomprehensible input"); + return (undef, "incomprehensible input ($string)"); } my @switches; diff --git a/t/switches.t b/t/switches.t index ed4f2a3d..102783a8 100644 --- a/t/switches.t +++ b/t/switches.t @@ -62,20 +62,39 @@ switches_fail( "text with no switch", ); -my $B = "\N{REVERSE SOLIDUS}"; +{ + my $B = "\N{REVERSE SOLIDUS}"; -# Later, we will add support for qstrings. -- rjbs, 2019-02-04 -switches_fail( - qq{/foo "bar $B/baz" /buz}, - "incomprehensible input", -); + my ($switches, $error) = parse_switches(qq{/foo "bar $B/baz" /buz}); -# Later, qstrings will allow embedded slashes, and maybe we'll allow them -# anyway if they're inside words. For now, ban them. -- rjbs, 2019-02-04 -switches_fail( - qq{/foo hunter/killer program /buz}, - "incomprehensible input", -); + is($error, undef, 'no error'); + + is_deeply( + $switches, + [ + [ foo => "bar $B/baz" ], + [ buz => undef ], + ], + "quotes", + ); +} + +{ + my $B = "\N{REVERSE SOLIDUS}"; + + my ($switches, $error) = parse_switches(qq{/foo hunter/killer program /buz}); + + is($error, undef, 'no error'); + + is_deeply( + $switches, + [ + [ foo => "hunter/killer program" ], + [ buz => undef ], + ], + "quotes", + ); +} { my ($switches, $error) = parse_switches("/f b /b f /foo /bar /foo bar"); @@ -90,6 +109,25 @@ switches_fail( [ bar => undef ], [ foo => 'bar' ], ], + "canonicalize_switches", + ); +} + +{ + my ($switches, $error) = parse_switches(q{/f b /foo /bar "some thing" /baz "some /thing" /meh a/b}); + + is($error, undef, 'no error'); + + is_deeply( + $switches, + [ + [ f => 'b' ], + [ foo => undef ], + [ bar => "some thing" ], + [ baz => "some /thing" ], + [ meh => "a/b" ], + ], + "quotes", ); } From db0cf4dbd6cf117548e00be1149b196d9f666bf3 Mon Sep 17 00:00:00 2001 From: Matthew Horsfall Date: Mon, 4 Feb 2019 22:11:47 -0500 Subject: [PATCH 2/2] Allow quotes in arguments using \" So: /foo "bar" => { foo => 'bar' }, /foo \"bar\" => { foo => '"bar"' }, /foo "\"bar\"" => { foo => '"bar"' }, --- lib/Synergy/Util.pm | 10 ++++++++-- t/switches.t | 12 ++++++------ 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/lib/Synergy/Util.pm b/lib/Synergy/Util.pm index e7a8616c..6fde9536 100644 --- a/lib/Synergy/Util.pm +++ b/lib/Synergy/Util.pm @@ -90,10 +90,16 @@ sub parse_switches ($string) { # push @tokens, [ badcmd => $1 ]; # next; } elsif ($string =~ s{ \A (? $1 ]; + my $val = $1; + $val =~ s/\\"/"/g; + + push @tokens, [ lit => $val ]; next; } elsif ($string =~ s{ \A ( .*? ) (\s+/ | $) }{$2}x) { - push @tokens, [ lit => $1 ]; + my $val = $1; + $val =~ s/\\"/"/g; + + push @tokens, [ lit => $val ]; next; } diff --git a/t/switches.t b/t/switches.t index 102783a8..26613171 100644 --- a/t/switches.t +++ b/t/switches.t @@ -114,18 +114,18 @@ switches_fail( } { - my ($switches, $error) = parse_switches(q{/f b /foo /bar "some thing" /baz "some /thing" /meh a/b}); + my ($switches, $error) = parse_switches(q{/f \\"b\\" /foo /bar "some thing" /baz "some \\" /thing\\"" /meh a/b}); is($error, undef, 'no error'); is_deeply( $switches, [ - [ f => 'b' ], - [ foo => undef ], - [ bar => "some thing" ], - [ baz => "some /thing" ], - [ meh => "a/b" ], + [ f => '"b"' ], + [ foo => undef ], + [ bar => "some thing" ], + [ baz => "some \" /thing\"" ], + [ meh => "a/b" ], ], "quotes", );