[Japi-cvs] SF.net SVN: japi: [609] libs/argparser/trunk/src
Status: Beta
Brought to you by:
christianhujer
From: <chr...@us...> - 2007-09-10 21:36:31
|
Revision: 609 http://japi.svn.sourceforge.net/japi/?rev=609&view=rev Author: christianhujer Date: 2007-09-10 14:36:27 -0700 (Mon, 10 Sep 2007) Log Message: ----------- [ 1791713 ] quotation marks removed from @arg files [ 1791715 ] \" silently changed to \\ in argfiles Modified Paths: -------------- libs/argparser/trunk/src/net/sf/japi/io/args/TokenReader.java libs/argparser/trunk/src/test/net/sf/japi/io/args/TokenReaderTest.java Modified: libs/argparser/trunk/src/net/sf/japi/io/args/TokenReader.java =================================================================== --- libs/argparser/trunk/src/net/sf/japi/io/args/TokenReader.java 2007-09-09 17:21:28 UTC (rev 608) +++ libs/argparser/trunk/src/net/sf/japi/io/args/TokenReader.java 2007-09-10 21:36:27 UTC (rev 609) @@ -31,7 +31,13 @@ /** * A TokenReader reads arguments from a file, non-recursive. - * That means the arguments are read regarding a certain argument syntax, but remain otherwise unparsed. + * That means the arguments are read regarding a certain argument syntax which should match with bash-like Quoting, but remain otherwise unparsed. + * <h4>Quoting and Escaping</h4> + * <ul> + * <li>\ introduces an escape. The escape character will be ignored, and the character following the escape character looses its special meaning if any.</li> + * <li>" introduces a string. A string is ended with ". Inside a string, \ only escapes ".</li> + * <li>' introduces a literal string. A literal string is ended with '. Inside a literal string, only ' has special meaning.</li> + * </ul> * @author <a href="mailto:ch...@ri...">Christian Hujer</a> */ public class TokenReader implements Closeable, Iterable<String>, Iterator<String> { @@ -99,6 +105,12 @@ } else if (c == '"') { mode = Mode.STRING; tokenValid = true; + } else if (c == '\'') { + mode = Mode.CHARS; + tokenValid = true; + } else if (c == '\\') { + mode = Mode.ESCAPE; + tokenValid = true; } else { nextToken.append(c); mode = Mode.NORMAL; @@ -112,6 +124,10 @@ return nextToken.toString(); } else if (c == '"') { mode = Mode.STRING; + } else if (c == '\'') { + mode = Mode.CHARS; + } else if (c == '\\') { + mode = Mode.ESCAPE; } else { nextToken.append(c); } @@ -126,9 +142,22 @@ } break; case STRING_ESCAPE: + if (c != '"') { + nextToken.append('\\'); + } nextToken.append(c); mode = Mode.STRING; break; + case ESCAPE: + nextToken.append(c); + mode = Mode.NORMAL; + break; + case CHARS: + if (c == '\'') { + mode = Mode.NORMAL; + } else { + nextToken.append(c); + } default: assert false; } @@ -152,7 +181,13 @@ STRING, /** String Escape - \ inside "". */ - STRING_ESCAPE - } + STRING_ESCAPE, + /** Secape - after \ but outside "". */ + ESCAPE, + + /** String - inside ''. */ + CHARS + } // enum Mode + } // class TokenReader Modified: libs/argparser/trunk/src/test/net/sf/japi/io/args/TokenReaderTest.java =================================================================== --- libs/argparser/trunk/src/test/net/sf/japi/io/args/TokenReaderTest.java 2007-09-09 17:21:28 UTC (rev 608) +++ libs/argparser/trunk/src/test/net/sf/japi/io/args/TokenReaderTest.java 2007-09-10 21:36:27 UTC (rev 609) @@ -151,6 +151,148 @@ reader.next(); } + /** Tests that the TokenReader treats escaped quotes correctly. + * @see <a href="http://sourceforge.net/tracker/index.php?func=detail&aid=1791713&group_id=149894&atid=776737">[ 1791713 ] quotation marks removed from @arg files</a> + * @see <a href="http://sourceforge.net/tracker/index.php?func=detail&aid=1791715&group_id=149894&atid=776737">[ 1791715 ] \" silently changed to \\ in argfiles</a> + */ + @Test + public void testTokenEscapedQuotesRandom() { + final TokenReader reader = new TokenReader(createStream(" \\\" \\\" \\\" a\\\"a \"\\\"\" a\"\\\"\"a ")); + Assert.assertTrue("Before reading the last token, hasNext() must return true.", reader.hasNext()); + Assert.assertEquals("Expecting token", "\"", reader.next()); + Assert.assertTrue("Before reading the last token, hasNext() must return true.", reader.hasNext()); + Assert.assertEquals("Expecting token", "\"", reader.next()); + Assert.assertTrue("Before reading the last token, hasNext() must return true.", reader.hasNext()); + Assert.assertEquals("Expecting token", "\"", reader.next()); + Assert.assertTrue("Before reading the last token, hasNext() must return true.", reader.hasNext()); + Assert.assertEquals("Expecting token", "a\"a", reader.next()); + Assert.assertTrue("Before reading the last token, hasNext() must return true.", reader.hasNext()); + Assert.assertEquals("Expecting token", "\"", reader.next()); + Assert.assertTrue("Before reading the last token, hasNext() must return true.", reader.hasNext()); + Assert.assertEquals("Expecting token", "a\"a", reader.next()); + Assert.assertFalse("After reading the last token, hasNext() must return false.", reader.hasNext()); + } + + /** Tests that <samp>\n</samp> returns <samp>n</samp>. + * @see <a href="http://sourceforge.net/tracker/index.php?func=detail&aid=1791713&group_id=149894&atid=776737">[ 1791713 ] quotation marks removed from @arg files</a> + * @see <a href="http://sourceforge.net/tracker/index.php?func=detail&aid=1791715&group_id=149894&atid=776737">[ 1791715 ] \" silently changed to \\ in argfiles</a> + */ + @Test + public void testTokenReaderNormalEscape() { + final TokenReader reader = new TokenReader(createStream("\\n")); + Assert.assertTrue("Before reading the last token, hasNext() must return true.", reader.hasNext()); + Assert.assertEquals("Expecting token", "n", reader.next()); + Assert.assertFalse("After reading the last token, hasNext() must return false.", reader.hasNext()); + } + + /** Tests that <samp>\"</samp> returns <samp>"</samp>. + * @see <a href="http://sourceforge.net/tracker/index.php?func=detail&aid=1791713&group_id=149894&atid=776737">[ 1791713 ] quotation marks removed from @arg files</a> + * @see <a href="http://sourceforge.net/tracker/index.php?func=detail&aid=1791715&group_id=149894&atid=776737">[ 1791715 ] \" silently changed to \\ in argfiles</a> + */ + @Test + public void testTokenReaderNormalQuote() { + final TokenReader reader = new TokenReader(createStream("\\\"")); + Assert.assertTrue("Before reading the last token, hasNext() must return true.", reader.hasNext()); + Assert.assertEquals("Expecting token", "\"", reader.next()); + Assert.assertFalse("After reading the last token, hasNext() must return false.", reader.hasNext()); + } + + /** Tests that <samp>\'</samp> returns <samp>'</samp>. + * @see <a href="http://sourceforge.net/tracker/index.php?func=detail&aid=1791713&group_id=149894&atid=776737">[ 1791713 ] quotation marks removed from @arg files</a> + * @see <a href="http://sourceforge.net/tracker/index.php?func=detail&aid=1791715&group_id=149894&atid=776737">[ 1791715 ] \" silently changed to \\ in argfiles</a> + */ + @Test + public void testTokenReaderNormalApos() { + final TokenReader reader = new TokenReader(createStream("\\'")); + Assert.assertTrue("Before reading the last token, hasNext() must return true.", reader.hasNext()); + Assert.assertEquals("Expecting token", "'", reader.next()); + Assert.assertFalse("After reading the last token, hasNext() must return false.", reader.hasNext()); + } + + /** Tests that <samp>"\n"</samp> returns <samp>\n</samp>. + * @see <a href="http://sourceforge.net/tracker/index.php?func=detail&aid=1791713&group_id=149894&atid=776737">[ 1791713 ] quotation marks removed from @arg files</a> + * @see <a href="http://sourceforge.net/tracker/index.php?func=detail&aid=1791715&group_id=149894&atid=776737">[ 1791715 ] \" silently changed to \\ in argfiles</a> + */ + @Test + public void testTokenReaderQuotesEscape() { + final TokenReader reader = new TokenReader(createStream("\"\\n\"")); + Assert.assertTrue("Before reading the last token, hasNext() must return true.", reader.hasNext()); + Assert.assertEquals("Expecting token", "\\n", reader.next()); + Assert.assertFalse("After reading the last token, hasNext() must return false.", reader.hasNext()); + } + + /** Tests that <samp>"\""</samp> returns <samp>"</samp>. + * @see <a href="http://sourceforge.net/tracker/index.php?func=detail&aid=1791713&group_id=149894&atid=776737">[ 1791713 ] quotation marks removed from @arg files</a> + * @see <a href="http://sourceforge.net/tracker/index.php?func=detail&aid=1791715&group_id=149894&atid=776737">[ 1791715 ] \" silently changed to \\ in argfiles</a> + */ + @Test + public void testTokenReaderQuotesQuote() { + final TokenReader reader = new TokenReader(createStream("\"\\\"\"")); + Assert.assertTrue("Before reading the last token, hasNext() must return true.", reader.hasNext()); + Assert.assertEquals("Expecting token", "\"", reader.next()); + Assert.assertFalse("After reading the last token, hasNext() must return false.", reader.hasNext()); + } + + /** Tests that <samp>"'"</samp> returns <samp>'</samp>. + * @see <a href="http://sourceforge.net/tracker/index.php?func=detail&aid=1791713&group_id=149894&atid=776737">[ 1791713 ] quotation marks removed from @arg files</a> + * @see <a href="http://sourceforge.net/tracker/index.php?func=detail&aid=1791715&group_id=149894&atid=776737">[ 1791715 ] \" silently changed to \\ in argfiles</a> + */ + @Test + public void testTokenReaderQuotesApos1() { + final TokenReader reader = new TokenReader(createStream("\"'\"")); + Assert.assertTrue("Before reading the last token, hasNext() must return true.", reader.hasNext()); + Assert.assertEquals("Expecting token", "'", reader.next()); + Assert.assertFalse("After reading the last token, hasNext() must return false.", reader.hasNext()); + } + + /** Tests that <samp>"\'"</samp> returns <samp>\'</samp>. + * @see <a href="http://sourceforge.net/tracker/index.php?func=detail&aid=1791713&group_id=149894&atid=776737">[ 1791713 ] quotation marks removed from @arg files</a> + * @see <a href="http://sourceforge.net/tracker/index.php?func=detail&aid=1791715&group_id=149894&atid=776737">[ 1791715 ] \" silently changed to \\ in argfiles</a> + */ + @Test + public void testTokenReaderQuotesApos2() { + final TokenReader reader = new TokenReader(createStream("\"\\'\"")); + Assert.assertTrue("Before reading the last token, hasNext() must return true.", reader.hasNext()); + Assert.assertEquals("Expecting token", "\\'", reader.next()); + Assert.assertFalse("After reading the last token, hasNext() must return false.", reader.hasNext()); + } + + /** Tests that <samp>'\n'</samp> returns <samp>\n</samp>. + * @see <a href="http://sourceforge.net/tracker/index.php?func=detail&aid=1791713&group_id=149894&atid=776737">[ 1791713 ] quotation marks removed from @arg files</a> + * @see <a href="http://sourceforge.net/tracker/index.php?func=detail&aid=1791715&group_id=149894&atid=776737">[ 1791715 ] \" silently changed to \\ in argfiles</a> + */ + @Test + public void testTokenReaderAposEscape1() { + final TokenReader reader = new TokenReader(createStream("'\\n'")); + Assert.assertTrue("Before reading the last token, hasNext() must return true.", reader.hasNext()); + Assert.assertEquals("Expecting token", "\\n", reader.next()); + Assert.assertFalse("After reading the last token, hasNext() must return false.", reader.hasNext()); + } + + /** Tests that <samp>'\\'</samp> returns <samp>\\</samp>. + * @see <a href="http://sourceforge.net/tracker/index.php?func=detail&aid=1791713&group_id=149894&atid=776737">[ 1791713 ] quotation marks removed from @arg files</a> + * @see <a href="http://sourceforge.net/tracker/index.php?func=detail&aid=1791715&group_id=149894&atid=776737">[ 1791715 ] \" silently changed to \\ in argfiles</a> + */ + @Test + public void testTokenReaderAposEscape2() { + final TokenReader reader = new TokenReader(createStream("'\\\\'")); + Assert.assertTrue("Before reading the last token, hasNext() must return true.", reader.hasNext()); + Assert.assertEquals("Expecting token", "\\\\", reader.next()); + Assert.assertFalse("After reading the last token, hasNext() must return false.", reader.hasNext()); + } + + /** Tests that <samp>'"'</samp> returns <samp>"</samp>. + * @see <a href="http://sourceforge.net/tracker/index.php?func=detail&aid=1791713&group_id=149894&atid=776737">[ 1791713 ] quotation marks removed from @arg files</a> + * @see <a href="http://sourceforge.net/tracker/index.php?func=detail&aid=1791715&group_id=149894&atid=776737">[ 1791715 ] \" silently changed to \\ in argfiles</a> + */ + @Test + public void testTokenReaderAposQuote() { + final TokenReader reader = new TokenReader(createStream("'\"'")); + Assert.assertTrue("Before reading the last token, hasNext() must return true.", reader.hasNext()); + Assert.assertEquals("Expecting token", "\"", reader.next()); + Assert.assertFalse("After reading the last token, hasNext() must return false.", reader.hasNext()); + } + /** Creates an InputStream for reading from a String. * @param s String to read from. * @return InputStream created from s. This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |