summaryrefslogtreecommitdiffstats
path: root/base/silent/src/com/netscape/pkisilent/argparser/StringScanner.java
diff options
context:
space:
mode:
Diffstat (limited to 'base/silent/src/com/netscape/pkisilent/argparser/StringScanner.java')
-rw-r--r--base/silent/src/com/netscape/pkisilent/argparser/StringScanner.java567
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);
+ }
+ }
+}