001: package freemarker.template;
002:
003: import java.util.ArrayList;
004: import java.util.HashMap;
005:
006: import freemarker.core.ParseException;
007: import freemarker.template.utility.StringUtil;
008:
009: /**
010: * Helper class for parsing setting values given with string.
011: */
012: class SettingStringParser {
013: private String text;
014: private int p;
015: private int ln;
016:
017: SettingStringParser(String text) {
018: this .text = text;
019: this .p = 0;
020: this .ln = text.length();
021: }
022:
023: ArrayList parseAsList() throws ParseException {
024: char c;
025: ArrayList seq = new ArrayList();
026: while (true) {
027: c = skipWS();
028: if (c == ' ')
029: break;
030: seq.add(fetchStringValue());
031: c = skipWS();
032: if (c == ' ')
033: break;
034: if (c != ',')
035: throw new ParseException(
036: "Expected \",\" or the end of text but "
037: + "found \"" + c + "\"", 0, 0);
038: p++;
039: }
040: return seq;
041: }
042:
043: HashMap parseAsImportList() throws ParseException {
044: char c;
045: HashMap map = new HashMap();
046: while (true) {
047: c = skipWS();
048: if (c == ' ')
049: break;
050: String lib = fetchStringValue();
051:
052: c = skipWS();
053: if (c == ' ')
054: throw new ParseException(
055: "Unexpected end of text: expected \"as\"", 0, 0);
056: String s = fetchKeyword();
057: if (!s.equalsIgnoreCase("as"))
058: throw new ParseException("Expected \"as\", but found "
059: + StringUtil.jQuote(s), 0, 0);
060:
061: c = skipWS();
062: if (c == ' ')
063: throw new ParseException(
064: "Unexpected end of text: expected gate hash name",
065: 0, 0);
066: String ns = fetchStringValue();
067:
068: map.put(ns, lib);
069:
070: c = skipWS();
071: if (c == ' ')
072: break;
073: if (c != ',')
074: throw new ParseException(
075: "Expected \",\" or the end of text but "
076: + "found \"" + c + "\"", 0, 0);
077: p++;
078: }
079: return map;
080: }
081:
082: String fetchStringValue() throws ParseException {
083: String w = fetchWord();
084: if (w.startsWith("'") || w.startsWith("\"")) {
085: w = w.substring(1, w.length() - 1);
086: }
087: return StringUtil.FTLStringLiteralDec(w);
088: }
089:
090: String fetchKeyword() throws ParseException {
091: String w = fetchWord();
092: if (w.startsWith("'") || w.startsWith("\"")) {
093: throw new ParseException(
094: "Keyword expected, but a string value found: " + w,
095: 0, 0);
096: }
097: return w;
098: }
099:
100: char skipWS() {
101: char c;
102: while (p < ln) {
103: c = text.charAt(p);
104: if (!Character.isWhitespace(c))
105: return c;
106: p++;
107: }
108: return ' ';
109: }
110:
111: private String fetchWord() throws ParseException {
112: if (p == ln)
113: throw new ParseException("Unexpeced end of text", 0, 0);
114:
115: char c = text.charAt(p);
116: int b = p;
117: if (c == '\'' || c == '"') {
118: boolean escaped = false;
119: char q = c;
120: p++;
121: while (p < ln) {
122: c = text.charAt(p);
123: if (!escaped) {
124: if (c == '\\') {
125: escaped = true;
126: } else if (c == q) {
127: break;
128: }
129: } else {
130: escaped = false;
131: }
132: p++;
133: }
134: if (p == ln) {
135: throw new ParseException("Missing " + q, 0, 0);
136: }
137: p++;
138: return text.substring(b, p);
139: } else {
140: do {
141: c = text.charAt(p);
142: if (!(Character.isLetterOrDigit(c) || c == '/'
143: || c == '\\' || c == '_' || c == '.'
144: || c == '-' || c == '!' || c == '*' || c == '?'))
145: break;
146: p++;
147: } while (p < ln);
148: if (b == p) {
149: throw new ParseException("Unexpected character: " + c,
150: 0, 0);
151: } else {
152: return text.substring(b, p);
153: }
154: }
155: }
156: }
|