diff options
Diffstat (limited to 'pki/base/silent/src/com/netscape/pkisilent/argparser/StringScanner.java')
-rw-r--r-- | pki/base/silent/src/com/netscape/pkisilent/argparser/StringScanner.java | 651 |
1 files changed, 651 insertions, 0 deletions
diff --git a/pki/base/silent/src/com/netscape/pkisilent/argparser/StringScanner.java b/pki/base/silent/src/com/netscape/pkisilent/argparser/StringScanner.java new file mode 100644 index 000000000..fae67c791 --- /dev/null +++ b/pki/base/silent/src/com/netscape/pkisilent/argparser/StringScanner.java @@ -0,0 +1,651 @@ +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; + boolean signed; + double value = 0; + + skipWhiteSpace(); + if (idx == len) + { exception = new StringScanException ("end of input"); + } + else + { + if ((c=buf[idx]) == '-' || c == '+') + { signed = true; + 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 = true; + 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++; + } + } + + private int skipWhiteSpace(int k) + { + while (Character.isWhitespace(buf[k])) + { k++; + } + return k; + } + + 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); + } + } +} |