001: /*
002: *
003: *
004: * Copyright 1990-2007 Sun Microsystems, Inc. All Rights Reserved.
005: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
006: *
007: * This program is free software; you can redistribute it and/or
008: * modify it under the terms of the GNU General Public License version
009: * 2 only, as published by the Free Software Foundation.
010: *
011: * This program is distributed in the hope that it will be useful, but
012: * WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014: * General Public License version 2 for more details (a copy is
015: * included at /legal/license.txt).
016: *
017: * You should have received a copy of the GNU General Public License
018: * version 2 along with this work; if not, write to the Free Software
019: * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
020: * 02110-1301 USA
021: *
022: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
023: * Clara, CA 95054 or visit www.sun.com if you need additional
024: * information or have any questions.
025: */
026:
027: package runtime;
028:
029: import util.BufferedPrintStream;
030: import java.io.*;
031: import java.lang.reflect.Array;
032:
033: /*
034: * An I/O abstraction that adds a few often-used function
035: * to the basic PrintStream. Implemented on top of the BufferedPrintStream.
036: */
037: public class CCodeWriter {
038:
039: BufferedPrintStream out;
040:
041: public CCodeWriter(java.io.OutputStream file) {
042: out = new BufferedPrintStream(file);
043: }
044:
045: private static String hexString[];
046:
047: static {
048: hexString = new String[0x100];
049: for (int i = 0; i < 256; i++) {
050: hexString[i] = Integer.toHexString(i + 256).substring(1);
051: }
052: }
053:
054: public final void printHexInt(int v) {
055: int a, b, c, d;
056: a = v >>> 24;
057: b = (v >>> 16) & 0xff;
058: c = (v >>> 8) & 0xff;
059: d = v & 0xff;
060: print("0x");
061: if (a != 0) {
062: print(hexString[a]);
063: print(hexString[b]);
064: print(hexString[c]);
065: print(hexString[d]);
066: } else if (b != 0) {
067: print(hexString[b]);
068: print(hexString[c]);
069: print(hexString[d]);
070: } else if (c != 0) {
071: print(hexString[c]);
072: print(hexString[d]);
073: } else {
074: print(hexString[d]);
075: }
076: }
077:
078: void printSafeString(String x) {
079: final int STRING_PURE = 0;
080: final int STRING_SOME_BAD = 1;
081: final int STRING_ALL_BAD = 2;
082: // STRING_PURE means there are no problematic characters.
083: //
084: // STRING_SOME_BAD means that we should print out the string
085: // normally, but escape the uncertain characters.
086: //
087: // STRING_ALL_BAD means that we encountered a character that makes
088: // us believe that this is an encoded string, and we should print
089: // out everything except letters using escape sequences.
090:
091: int stringType = STRING_PURE;
092: int length = x.length();
093:
094: for (int i = 0; i < length; i++) {
095: char c = x.charAt(i);
096: if (c < ' ' || c > '~') {
097: stringType = STRING_ALL_BAD;
098: break;
099: }
100: if (c == '"' || c == '\\' || c == '/') {
101: stringType = STRING_SOME_BAD;
102: }
103: }
104:
105: write('"');
106: if (stringType == STRING_PURE) {
107: // There were no bad characters whatsoever. Just print it
108: print(x);
109: write('"');
110: return;
111: }
112:
113: for (int i = 0; i < length; i++) {
114: char c = x.charAt(i);
115: if (Character.isLetterOrDigit(c) && c < 128) {
116: write(c);
117: } else if ((stringType != STRING_ALL_BAD)
118: && (c >= (byte) ' ') && (c <= (byte) '~')
119: && (c != (byte) '"') && (c != (byte) '\\')
120: && (c != (byte) '/')) {
121: // the only dangers between space and ~ are " and \
122: // We must also be careful about writing */ by accident.
123: write(c);
124: } else {
125: switch (c) {
126: case '\\':
127: print("\\\\");
128: break;
129: case '\n':
130: print("\\n");
131: break;
132: case '\r':
133: print("\\r");
134: break;
135: case '\t':
136: print("\\t");
137: break;
138: case '"':
139: print("\\\"");
140: break;
141: case '/':
142: // we only have a problem if the previous char was an
143: // asterisk. It looks like we're ending the comment.
144: if (i > 0 && x.charAt(i - 1) == (byte) '*')
145: write('\\');
146: write('/');
147: break;
148: default:
149: int temp = (c & 0xFF) + 01000;
150: print("\\");
151: print(Integer.toOctalString(temp).substring(1));
152: break;
153: // end of switch
154: }
155: }
156: } // end of for
157:
158: write('"');
159: }
160:
161: public void print(Object x) {
162: print(x.toString());
163: }
164:
165: public void print(String x) {
166: int length = x.length();
167: for (int i = 0; i < length; i++) {
168: write(x.charAt(i));
169: }
170: }
171:
172: public void println(String x) {
173: print(x);
174: write('\n');
175: }
176:
177: public void println() {
178: write('\n');
179: }
180:
181: public void print(int x) {
182: print(Integer.toString(x));
183: }
184:
185: private int column = 0;
186:
187: public void write(int x) {
188: if (x == '\n') {
189: out.write(x);
190: column = 0;
191: } else if (x == '\t') {
192: do {
193: out.write(' ');
194: column++;
195: } while ((column % 4) != 0);
196: } else {
197: out.write(x);
198: column++;
199: }
200: }
201:
202: public boolean checkError() {
203: return out.checkError();
204: }
205:
206: public void flush() {
207: out.flush();
208: }
209:
210: public void close() {
211: out.close();
212: }
213:
214: }
|