Mercurial > hg > tema
changeset 32:bdd1c8d6b560
Do not read EOF more than once, report unexpected EOF in function data.
author | Mikhail Kryshen <mikhail@kryshen.net> |
---|---|
date | Fri, 25 Sep 2009 02:37:16 +0400 |
parents | 3e77076621a8 |
children | b637a4491862 |
files | nbproject/ide-targets.xml nbproject/project.xml src/kryshen/tema/FunctionDataParser.java src/kryshen/tema/TemplateParser.java src/kryshen/tema/io/TemplateReader.java |
diffstat | 5 files changed, 132 insertions(+), 24 deletions(-) [+] |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/nbproject/ide-targets.xml Fri Sep 25 02:37:16 2009 +0400 @@ -0,0 +1,23 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project basedir=".." name="tema-IDE"> + <import file="../build.xml"/> + <!-- TODO: edit the following target according to your needs --> + <!-- (more info: http://www.netbeans.org/kb/articles/freeform-config.html#debugj2se) --> + <target depends="compile" name="debug-nb"> + <nbjpdastart addressproperty="jpda.address" name="tema" transport="dt_socket"> + <classpath> + <pathelement location="${build}"/> + <path refid="project.libs"/> + </classpath> + </nbjpdastart> + <java classname="${main_class}" fork="true"> + <classpath> + <pathelement location="${build}"/> + <path refid="project.libs"/> + </classpath> + <arg value="-demo"/> + <jvmarg value="-Xdebug"/> + <jvmarg value="-Xrunjdwp:transport=dt_socket,address=${jpda.address}"/> + </java> + </target> +</project>
--- a/nbproject/project.xml Sun Aug 30 02:51:15 2009 +0400 +++ b/nbproject/project.xml Fri Sep 25 02:37:16 2009 +0400 @@ -35,6 +35,10 @@ <action name="run"> <target>run.demo</target> </action> + <action name="debug"> + <script>nbproject/ide-targets.xml</script> + <target>debug-nb</target> + </action> </ide-actions> <export> <type>folder</type> @@ -65,6 +69,7 @@ <label>Compile manual</label> <target>doc.manual</target> </action> + <ide-action name="debug"/> </context-menu> </view> <subprojects/>
--- a/src/kryshen/tema/FunctionDataParser.java Sun Aug 30 02:51:15 2009 +0400 +++ b/src/kryshen/tema/FunctionDataParser.java Fri Sep 25 02:37:16 2009 +0400 @@ -103,7 +103,12 @@ } else { r = tp.parse(in, out, fd, null); } - + + if (r.terminator == Terminator.EOF) { + throw new TemplateException + ("Unexpected end of instruction data", in); + } + if (r.terminator != Terminator.SEPARATOR) available = false; // No more function data available.
--- a/src/kryshen/tema/TemplateParser.java Sun Aug 30 02:51:15 2009 +0400 +++ b/src/kryshen/tema/TemplateParser.java Fri Sep 25 02:37:16 2009 +0400 @@ -271,9 +271,7 @@ int c = in.read(); if (c != s.charAt(k)) { - if (c >= 0) { - in.unread(c); - } + in.unread(c); for (int j = k - 1; j >= 0; j--) { in.unread(s.charAt(j)); @@ -290,10 +288,7 @@ readLoop: while (true) { int c = in.read(); - - if (c < 0) - break; - + for (int i = 0; i < chars.length; i++) { if (c == chars[i]) continue readLoop; @@ -307,11 +302,8 @@ private void skipEscaped(TemplateReader in) throws IOException { if (matchInput(in, ESCAPE_WHITESPACE)) { int c = in.read(); - - if (c < 0) - return; - - if (!Character.isWhitespace(c)) { + + if (c < 0 || !Character.isWhitespace(c)) { in.unread(c); in.unread(ESCAPE_WHITESPACE); return; @@ -319,10 +311,9 @@ do { c = in.read(); - } while (Character.isWhitespace(c)); + } while (c > 0 && Character.isWhitespace(c)); - if (c >= 0) - in.unread(c); + in.unread(c); return; }
--- a/src/kryshen/tema/io/TemplateReader.java Sun Aug 30 02:51:15 2009 +0400 +++ b/src/kryshen/tema/io/TemplateReader.java Fri Sep 25 02:37:16 2009 +0400 @@ -20,10 +20,10 @@ package kryshen.tema.io; +import java.io.FilterReader; import java.io.IOException; import java.io.Reader; import java.io.LineNumberReader; -import java.io.PushbackReader; import kryshen.tema.TemplateParser; /** @@ -32,7 +32,7 @@ * * @author Mikhail Kryshen */ -public class TemplateReader extends PushbackReader { +public class TemplateReader extends FilterReader { static final int UNREAD_BUFFER_SIZE; /* Calculate UNREAD_BUFFER_SIZE value. */ @@ -50,13 +50,16 @@ max = Math.max(max, TemplateParser.ESCAPE_NEWLINE.length() + 2); max = Math.max(max, TemplateParser.ESCAPE_WHITESPACE.length()); - UNREAD_BUFFER_SIZE = max; + UNREAD_BUFFER_SIZE = max + 1; } - + private final String source; private final LineNumberReader lnReader; private final TemplateReader parentReader; - + + private final int[] unreadBuffer = new int[UNREAD_BUFFER_SIZE]; + private int unread = 0; + public TemplateReader(Reader in) { this(new LineNumberReader(in)); } @@ -70,7 +73,7 @@ } public TemplateReader(LineNumberReader in, String source) { - super(in, UNREAD_BUFFER_SIZE); + super(in); this.parentReader = null; this.lnReader = in; @@ -78,7 +81,7 @@ } public TemplateReader(Reader in, TemplateReader parent) { - super(in, UNREAD_BUFFER_SIZE); + super(in); this.parentReader = parent; this.lnReader = null; @@ -98,8 +101,89 @@ return parentReader.getLineNumber(); } - + + @Override + public int read() throws IOException { + if (unread == 0) { + return super.read(); + } + + return unreadBuffer[--unread]; + } + + @Override + public int read(char[] cbuf, int off, int len) throws IOException { + int n = 0; + + while (unread > 0) { + cbuf[off + n++] = (char) unreadBuffer[--unread]; + + if (n == len) { + return n; + } + } + + return n + super.read(cbuf, off + n, len - n); + } + + @Override + public long skip(long n) throws IOException { + if (n <= unread) { + unread -= n; + return n; + } + + n -= unread; + long ret = super.skip(n) + unread; + unread = 0; + + return ret; + } + + public void unread(String s) throws IOException { unread(s.toCharArray()); } + + public void unread(int c) { + if (unread + 1 > UNREAD_BUFFER_SIZE) { + throw new IndexOutOfBoundsException(); + } + + unreadBuffer[unread++] = c; + } + + public void unread(char[] buff) { + unread(buff, 0, buff.length); + } + + public void unread(char[] buff, int off, int len) { + if (unread + len > UNREAD_BUFFER_SIZE) { + throw new IndexOutOfBoundsException(); + } + + for (int i = off + len - 1; i >= off; i--) { + unreadBuffer[unread++] = buff[i]; + } + } + + @Override + public boolean ready() throws IOException { + return unread > 0 || super.ready(); + } + + @Override + public void mark(int readAheadLimit) throws IOException { + throw new IOException("Not supported"); + } + + @Override + public void reset() throws IOException { + throw new IOException("Not supported"); + } + + @Override + public boolean markSupported() { + return false; + } }