001: package org.jacorb.idl;
002:
003: /*
004: * JacORB - a free Java ORB
005: *
006: * Copyright (C) 1997-2004 Gerald Brose.
007: *
008: * This library is free software; you can redistribute it and/or
009: * modify it under the terms of the GNU Library General Public
010: * License as published by the Free Software Foundation; either
011: * version 2 of the License, or (at your option) any later version.
012: *
013: * This library is distributed in the hope that it will be useful,
014: * but WITHOUT ANY WARRANTY; without even the implied warranty of
015: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
016: * Library General Public License for more details.
017: *
018: * You should have received a copy of the GNU Library General Public
019: * License along with this library; if not, write to the Free
020: * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
021: */
022:
023: import java.io.PrintWriter;
024: import org.jacorb.idl.runtime.long_token;
025: import org.jacorb.idl.runtime.int_token;
026: import java.math.BigInteger;
027:
028: /**
029: * @author Gerald Brose
030: * @version $Id: Literal.java,v 1.25 2006/06/19 10:34:57 alphonse.bendt Exp $
031: */
032:
033: public class Literal extends IdlSymbol {
034: private static BigInteger maximum;
035: public String string;
036: public boolean wide;
037: public org.jacorb.idl.runtime.token token;
038:
039: private ConstDecl declared_in;
040:
041: public Literal(int num) {
042: super (num);
043: }
044:
045: public void setDeclaration(ConstDecl declared_in) {
046: this .declared_in = declared_in;
047: }
048:
049: public void parse() {
050: // const expressions containing literals can be declared
051: // outside cons declarations (e.g, in sequence bounds),
052: // but we care only for const declarations here.
053:
054: if (declared_in != null) {
055: TypeSpec ts = declared_in.const_type.symbol.typeSpec();
056: // If its an alias check the actual type not the alias
057: if (ts instanceof AliasTypeSpec) {
058: ts = ((AliasTypeSpec) ts).originalType();
059: }
060:
061: // If its unsigned may need to fit the value into a signed
062: // value.
063: if (ts instanceof IntType) {
064: if (((IntType) ts).unsigned
065: && ts instanceof LongLongType
066: && token instanceof fixed_token) {
067: // Need to reset the unsigned value to fit into a
068: // signed long value.
069: if (maximum == null) {
070: maximum = new BigInteger("18446744073709551615");
071: }
072: BigInteger current = new BigInteger(string);
073: if (current.compareTo(maximum) > 0) {
074: parser.error("Value too big for unsigned long");
075: } else {
076: token = new long_token(
077: ((fixed_token) token).sym,
078: ((fixed_token) token).fixed_val
079: .longValue());
080: string = Long
081: .toString(((long_token) token).long_val);
082: }
083: } else if (((IntType) ts).unsigned == true
084: && ts instanceof LongType
085: && token instanceof long_token) {
086: // Need to reset the unsigned value to fit into a
087: // signed integer value. Will need to replace the
088: // token so it is a int_token not a long.
089: if (((long_token) token).long_val > 4294967295L) {
090: parser.error("Value ("
091: + ((long_token) token).long_val
092: + ") too big for unsigned long");
093: } else {
094: token = new int_token(((long_token) token).sym,
095: (int) ((long_token) token).long_val);
096: string = Integer
097: .toString(((int_token) token).int_val);
098: }
099: }
100: // Not unsigned but still have a long token for a Java Int type
101: else if (ts instanceof LongType
102: && token instanceof long_token) {
103: parser.error("Value ("
104: + ((long_token) token).long_val
105: + ") too big for Java int");
106: }
107: // Not unsigned but still have a fixed_token for a Java Long type
108: else if (ts instanceof LongLongType
109: && token instanceof fixed_token) {
110: parser.error("Value ("
111: + ((fixed_token) token).fixed_val
112: .toString()
113: + ") too big for Java long");
114: }
115: }
116:
117: if (logger.isWarnEnabled())
118: logger.warn("Literal "
119: + ts.getClass().getName()
120: + " "
121: + (token != null ? token.getClass().getName()
122: : "<no token>"));
123:
124: if (ts instanceof FloatPtType
125: && !(token instanceof org.jacorb.idl.runtime.float_token)) {
126: parser.error("Expecting float/double constant!");
127: } else if (ts instanceof FixedPointConstType
128: && !(token instanceof fixed_token)) {
129: parser
130: .error("Expecting fixed point constant (perhaps a missing \"d\")!");
131: } else if (ts instanceof StringType) {
132: if (wide && !((StringType) ts).isWide())
133: parser
134: .error("Illegal assignment of wide string constant to string!");
135:
136: } else if ((ts instanceof LongType)
137: || (ts instanceof ShortType)) {
138: if (token instanceof org.jacorb.idl.runtime.long_token) {
139: parser.error("Illegal assignment from long long");
140: }
141: }
142: }
143: }
144:
145: public String toString() {
146: String result = string;
147:
148: if (token instanceof org.jacorb.idl.runtime.long_token) {
149: if (string.indexOf('.') > 0) {
150: result = (string + 'D');
151: } else {
152: result = (string + 'L');
153: }
154: }
155: return escapeBackslash(result);
156: }
157:
158: public void print(PrintWriter ps) {
159: ps.print(escapeBackslash(string));
160: }
161:
162: /**
163: * Doubles up instances of the backslash character in a
164: * string, to avoid them being interpreted as escape sequences
165: *
166: * @param name a <code>String</code> value
167: * @return string
168: */
169: public static String escapeBackslash(String name) {
170: StringBuffer result = new StringBuffer();
171:
172: char[] chrs = name.toCharArray();
173:
174: // Don't bother escaping if we have "xxx"
175: if (chrs[0] == '\"') {
176: return name;
177: }
178:
179: for (int i = 0; i < chrs.length; i++) {
180: switch (chrs[i]) {
181: case '\n': {
182: result.append('\\');
183: result.append('n');
184: break;
185: }
186: case '\t': {
187: result.append('\\');
188: result.append('t');
189: break;
190: }
191: case '\013': {
192: result.append('\\');
193: result.append("013");
194: break;
195: }
196: case '\b': {
197: result.append('\\');
198: result.append('b');
199: break;
200: }
201: case '\r': {
202: result.append('\\');
203: result.append('r');
204: break;
205: }
206: case '\f': {
207: result.append('\\');
208: result.append('f');
209: break;
210: }
211: case '\007': {
212: result.append('\\');
213: result.append("007");
214: break;
215: }
216: case '\\': {
217: result.append('\\');
218: result.append('\\');
219: break;
220: }
221: case '\0': {
222: result.append('\\');
223: result.append('0');
224: break;
225: }
226: case '\'': {
227: if (i == 1) {
228: result.append('\\');
229: result.append('\'');
230: } else {
231: result.append(chrs[i]);
232: }
233: break;
234: }
235: case '\"': {
236: if (i == 1) {
237: result.append('\\');
238: result.append('\"');
239: } else {
240: result.append(chrs[i]);
241: }
242: break;
243: }
244: default: {
245: result.append(chrs[i]);
246: }
247: }
248: }
249: return result.toString();
250: }
251: }
|