diff options
Diffstat (limited to 'base/silent/src/com/netscape/pkisilent/argparser/StringScanner.java')
-rw-r--r-- | base/silent/src/com/netscape/pkisilent/argparser/StringScanner.java | 567 |
1 files changed, 567 insertions, 0 deletions
diff --git a/base/silent/src/com/netscape/pkisilent/argparser/StringScanner.java b/base/silent/src/com/netscape/pkisilent/argparser/StringScanner.java new file mode 100644 index 000000000..271dd0c62 --- /dev/null +++ b/base/silent/src/com/netscape/pkisilent/argparser/StringScanner.java @@ -0,0 +1,567 @@ +package com.netscape.pkisilent.argparser; + +// --- BEGIN COPYRIGHT BLOCK --- +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; version 2 of the License. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// (C) 2007 Red Hat, Inc. +// All rights reserved. +// --- END COPYRIGHT BLOCK --- + +/** + * Copyright John E. Lloyd, 2004. All rights reserved. Permission to use, + * copy, modify and redistribute is granted, provided that this copyright + * notice is retained and the author is given credit whenever appropriate. + * + * This software is distributed "as is", without any warranty, including + * any implied warranty of merchantability or fitness for a particular + * use. The author assumes no responsibility for, and shall not be liable + * for, any special, indirect, or consequential damages, or any damages + * whatsoever, arising out of or in connection with the use of this + * software. + */ + +class StringScanner { + private char[] buf; + private int idx; + private int len; + private String stringDelimiters = ""; + + public StringScanner(String s) { + buf = new char[s.length() + 1]; + s.getChars(0, s.length(), buf, 0); + len = s.length(); + buf[len] = 0; + idx = 0; + } + + public int getIndex() { + return idx; + } + + public void setIndex(int i) { + if (i < 0) { + idx = 0; + } else if (i > len) { + idx = len; + } else { + idx = i; + } + } + + public void setStringDelimiters(String s) { + stringDelimiters = s; + } + + public String getStringDelimiters() { + return stringDelimiters; + } + + public char scanChar() + throws StringScanException { + int idxSave = idx; + skipWhiteSpace(); + try { + if (buf[idx] == '\'') { + return scanQuotedChar(); + } else { + return scanUnquotedChar(); + } + } catch (StringScanException e) { + idx = idxSave; + throw e; + } + } + + public char scanQuotedChar() + throws StringScanException { + StringScanException exception = null; + char retval = 0; + int idxSave = idx; + + skipWhiteSpace(); + if (idx == len) { + exception = new StringScanException(idx, "end of input"); + } else if (buf[idx++] == '\'') { + try { + retval = scanUnquotedChar(); + } catch (StringScanException e) { + exception = e; + } + if (exception == null) { + if (idx == len) { + exception = new StringScanException + (idx, "end of input"); + } else if (buf[idx++] != '\'') { + exception = new StringScanException + (idx - 1, "unclosed quoted character"); + } + } + } else { + exception = new StringScanException + (idx - 1, "uninitialized quoted character"); + } + if (exception != null) { + idx = idxSave; + throw exception; + } + return retval; + } + + public char scanUnquotedChar() + throws StringScanException { + StringScanException exception = null; + char c, retval = 0; + int idxSave = idx; + + if (idx == len) { + exception = new StringScanException(idx, "end of input"); + } else if ((c = buf[idx++]) == '\\') { + if (idx == len) { + exception = new StringScanException(idx, "end of input"); + } else { + c = buf[idx++]; + if (c == '"') { + retval = '"'; + } else if (c == '\'') { + retval = '\''; + } else if (c == '\\') { + retval = '\\'; + } else if (c == 'n') { + retval = '\n'; + } else if (c == 't') { + retval = '\t'; + } else if (c == 'b') { + retval = '\b'; + } else if (c == 'r') { + retval = '\r'; + } else if (c == 'f') { + retval = '\f'; + } else if ('0' <= c && c < '8') { + int v = c - '0'; + for (int j = 0; j < 2; j++) { + if (idx == len) { + break; + } + c = buf[idx]; + if ('0' <= c && c < '8' && (v * 8 + (c - '0')) <= 255) { + v = v * 8 + (c - '0'); + idx++; + } else { + break; + } + } + retval = (char) v; + } else { + exception = new StringScanException + (idx - 1, "illegal escape character '" + c + "'"); + } + } + } else { + retval = c; + } + if (exception != null) { + idx = idxSave; + throw exception; + } + return retval; + } + + public String scanQuotedString() + throws StringScanException { + StringScanException exception = null; + StringBuffer sbuf = new StringBuffer(len); + char c; + int idxSave = idx; + + skipWhiteSpace(); + if (idx == len) { + exception = new StringScanException(idx, "end of input"); + } else if ((c = buf[idx++]) == '"') { + while (idx < len && (c = buf[idx]) != '"' && c != '\n') { + if (c == '\\') { + try { + c = scanUnquotedChar(); + } catch (StringScanException e) { + exception = e; + break; + } + } else { + idx++; + } + sbuf.append(c); + } + if (exception == null && idx >= len) { + exception = new StringScanException(len, "end of input"); + } else if (exception == null && c == '\n') { + exception = new StringScanException + (idx, "unclosed quoted string"); + } else { + idx++; + } + } else { + exception = new StringScanException(idx - 1, + "quoted string must start with \""); + } + if (exception != null) { + idx = idxSave; + throw exception; + } + return sbuf.toString(); + } + + public String scanNonWhiteSpaceString() + throws StringScanException { + StringBuffer sbuf = new StringBuffer(len); + int idxSave = idx; + char c; + + skipWhiteSpace(); + if (idx == len) { + StringScanException e = new StringScanException( + idx, "end of input"); + idx = idxSave; + throw e; + } else { + c = buf[idx++]; + while (idx < len && !Character.isWhitespace(c) + && stringDelimiters.indexOf(c) == -1) { + sbuf.append(c); + c = buf[idx++]; + } + if (Character.isWhitespace(c) || + stringDelimiters.indexOf(c) != -1) { + idx--; + } else { + sbuf.append(c); + } + } + return sbuf.toString(); + } + + public String scanString() + throws StringScanException { + int idxSave = idx; + skipWhiteSpace(); + try { + if (buf[idx] == '"') { + return scanQuotedString(); + } else { + return scanNonWhiteSpaceString(); + } + } catch (StringScanException e) { + idx = idxSave; + throw e; + } + } + + public String getString() + throws StringScanException { + StringBuffer sbuf = new StringBuffer(len); + while (idx < len) { + sbuf.append(buf[idx++]); + } + return sbuf.toString(); + } + + public long scanInt() + throws StringScanException { + int idxSave = idx; + char c; + int sign = 1; + + skipWhiteSpace(); + if ((c = buf[idx]) == '-' || c == '+') { + sign = (c == '-' ? -1 : 1); + idx++; + } + try { + if (idx == len) { + throw new StringScanException(len, "end of input"); + } else if ((c = buf[idx]) == '0') { + if ((c = buf[idx + 1]) == 'x' || c == 'X') { + idx += 2; + return sign * scanInt(16, false); + } else { + return sign * scanInt(8, false); + } + } else { + return sign * scanInt(10, false); + } + } catch (StringScanException e) { + idx = idxSave; + throw e; + } + } + + public long scanInt(int radix) + throws StringScanException { + return scanInt(radix, /*skipWhite=*/true); + } + + private String baseDesc(int radix) { + switch (radix) { + case 10: { + return "decimal"; + } + case 8: { + return "octal"; + } + case 16: { + return "hex"; + } + default: { + return "base " + radix; + } + } + } + + public long scanInt(int radix, boolean skipWhite) + throws StringScanException { + StringScanException exception = null; + int charval, idxSave = idx; + char c; + long val = 0; + boolean negate = false; + + if (skipWhite) { + skipWhiteSpace(); + } + if ((c = buf[idx]) == '-' || c == '+') { + negate = (c == '-'); + idx++; + } + if (idx >= len) { + exception = new StringScanException(len, "end of input"); + } else if ((charval = Character.digit(buf[idx++], radix)) == -1) { + exception = new StringScanException + (idx - 1, "malformed " + baseDesc(radix) + " integer"); + } else { + val = charval; + while ((charval = Character.digit(buf[idx], radix)) != -1) { + val = val * radix + charval; + idx++; + } + if (Character.isLetter(c = buf[idx]) || + Character.isDigit(c) || c == '_') { + exception = new StringScanException + (idx, "malformed " + baseDesc(radix) + " integer"); + } + } + if (exception != null) { + idx = idxSave; + throw exception; + } + return negate ? -val : val; + } + + public double scanDouble() + throws StringScanException { + StringScanException exception = null; + int idxSave = idx; + char c; + // parse [-][0-9]*[.][0-9]*[eE][-][0-9]* + boolean hasDigits = false; + double value = 0; + + skipWhiteSpace(); + if (idx == len) { + exception = new StringScanException("end of input"); + } else { + if ((c = buf[idx]) == '-' || c == '+') { + // signed + idx++; + } + if (matchDigits()) { + hasDigits = true; + } + if (buf[idx] == '.') { + idx++; + } + if (!hasDigits && (buf[idx] < '0' || buf[idx] > '9')) { + if (idx == len) { + exception = new StringScanException(idx, "end of input"); + } else { + exception = new StringScanException( + idx, "malformed floating number: no digits"); + } + } else { + matchDigits(); + + if ((c = buf[idx]) == 'e' || c == 'E') { + idx++; + if ((c = buf[idx]) == '-' || c == '+') { + // signed + idx++; + } + if (buf[idx] < '0' || buf[idx] > '9') { + if (idx == len) { + exception = new StringScanException( + idx, "end of input"); + } else { + exception = new StringScanException(idx, + "malformed floating number: no digits in exponent"); + } + } else { + matchDigits(); + } + } + } + } + if (exception == null) { + // if (Character.isLetterOrDigit(c=buf[idx]) || c == '_') + // { exception = new StringScanException (idx, + //"malformed floating number"); + // } + // else + { + try { + value = Double.parseDouble(new String(buf, idxSave, + idx - idxSave)); + } catch (NumberFormatException e) { + exception = new StringScanException( + idx, "malformed floating number"); + } + } + } + if (exception != null) { + idx = idxSave; + throw exception; + } + return value; + } + + public boolean scanBoolean() + throws StringScanException { + StringScanException exception = null; + int idxSave = idx; + String testStr = "false"; + boolean testval = false; + char c; + + skipWhiteSpace(); + if (buf[idx] == 't') { + testStr = "true"; + testval = true; + } else { + testval = false; + } + int i = 0; + for (i = 0; i < testStr.length(); i++) { + if (testStr.charAt(i) != buf[idx]) { + if (idx == len) { + exception = new StringScanException(idx, "end of input"); + } + break; + } + idx++; + } + if (exception == null) { + if (i < testStr.length() || + Character.isLetterOrDigit(c = buf[idx]) || c == '_') { + exception = new StringScanException(idx, "illegal boolean"); + } + } + if (exception != null) { + idx = idxSave; + throw exception; + } + return testval; + } + + public boolean matchString(String s) { + int k = idx; + for (int i = 0; i < s.length(); i++) { + if (k >= len || s.charAt(i) != buf[k++]) { + return false; + } + } + idx = k; + return true; + } + + public boolean matchDigits() { + int k = idx; + char c; + + while ((c = buf[k]) >= '0' && c <= '9') { + k++; + } + if (k > idx) { + idx = k; + return true; + } else { + return false; + } + } + + public void skipWhiteSpace() { + while (Character.isWhitespace(buf[idx])) { + idx++; + } + } + + public boolean atEnd() { + return idx == len; + } + + public boolean atBeginning() { + return idx == 0; + } + + public void ungetc() { + if (idx > 0) { + idx--; + } + } + + public char getc() { + char c = buf[idx]; + if (idx < len) { + idx++; + } + return c; + } + + public char peekc() { + return buf[idx]; + } + + public String substring(int i0, int i1) { + if (i0 < 0) { + i0 = 0; + } else if (i0 >= len) { + i0 = len - 1; + } + if (i1 < 0) { + i1 = 0; + } else if (i1 > len) { + i1 = len; + } + if (i1 <= i0) { + return ""; + } + return new String(buf, i0, i1 - i0); + } + + public String substring(int i0) { + if (i0 < 0) { + i0 = 0; + } + if (i0 >= len) { + return ""; + } else { + return new String(buf, i0, len - i0); + } + } +} |