001: /*
002: * Copyright 2002-2006 Sun Microsystems, Inc. All Rights Reserved.
003: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004: *
005: * This code is free software; you can redistribute it and/or modify it
006: * under the terms of the GNU General Public License version 2 only, as
007: * published by the Free Software Foundation. Sun designates this
008: * particular file as subject to the "Classpath" exception as provided
009: * by Sun in the LICENSE file that accompanied this code.
010: *
011: * This code is distributed in the hope that it will be useful, but WITHOUT
012: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
014: * version 2 for more details (a copy is included in the LICENSE file that
015: * accompanied this code).
016: *
017: * You should have received a copy of the GNU General Public License version
018: * 2 along with this work; if not, write to the Free Software Foundation,
019: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
020: *
021: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
022: * CA 95054 USA or visit www.sun.com if you need additional information or
023: * have any questions.
024: */
025:
026: package com.sun.tools.javah;
027:
028: import com.sun.javadoc.*;
029:
030: /**
031: * A utility for mangling java identifiers into C names. Should make
032: * this more fine grained and distribute the functionality to the
033: * generators.
034: *
035: * @author Sucheta Dambalkar(Revised)
036: */
037: class Mangle {
038:
039: public static class Type {
040:
041: public static final int CLASS = 1;
042: public static final int FIELDSTUB = 2;
043: public static final int FIELD = 3;
044: public static final int JNI = 4;
045: public static final int SIGNATURE = 5;
046: public static final int METHOD_JDK_1 = 6;
047: public static final int METHOD_JNI_SHORT = 7;
048: public static final int METHOD_JNI_LONG = 8;
049: };
050:
051: public static final String mangle(String name, int mtype) {
052: StringBuffer result = new StringBuffer(100);
053: int length = name.length();
054:
055: for (int i = 0; i < length; i++) {
056: char ch = name.charAt(i);
057: if (isalnum(ch)) {
058: result.append(ch);
059: } else if ((ch == '.') && mtype == Mangle.Type.CLASS) {
060: result.append('_');
061: } else if ((ch == '$') && mtype == Mangle.Type.CLASS) {
062: result.append('_');
063: result.append('_');
064: } else if (ch == '_' && mtype == Mangle.Type.FIELDSTUB) {
065: result.append('_');
066: } else if (ch == '_' && mtype == Mangle.Type.CLASS) {
067: result.append('_');
068: } else if (mtype == Mangle.Type.JNI) {
069: String esc = null;
070: if (ch == '_')
071: esc = "_1";
072: else if (ch == '.')
073: esc = "_";
074: else if (ch == ';')
075: esc = "_2";
076: else if (ch == '[')
077: esc = "_3";
078: if (esc != null) {
079: result.append(esc);
080: } else {
081: result.append(mangleChar(ch));
082: }
083: } else if (mtype == Mangle.Type.SIGNATURE) {
084: if (isprint(ch)) {
085: result.append(ch);
086: } else {
087: result.append(mangleChar(ch));
088: }
089: } else {
090: result.append(mangleChar(ch));
091: }
092: }
093:
094: return result.toString();
095: }
096:
097: public static String mangleMethod(MethodDoc method, RootDoc root,
098: ClassDoc clazz, int mtype) {
099: StringBuffer result = new StringBuffer(100);
100: result.append("Java_");
101:
102: if (mtype == Mangle.Type.METHOD_JDK_1) {
103: result.append(mangle(clazz.qualifiedName(),
104: Mangle.Type.CLASS));
105: result.append('_');
106: result.append(mangle(method.name(), Mangle.Type.FIELD));
107: result.append("_stub");
108: return result.toString();
109: }
110:
111: /* JNI */
112: result.append(mangle(getInnerQualifiedName(clazz),
113: Mangle.Type.JNI));
114: result.append('_');
115: result.append(mangle(method.name(), Mangle.Type.JNI));
116: if (mtype == Mangle.Type.METHOD_JNI_LONG) {
117: result.append("__");
118: String typesig = method.signature();
119: TypeSignature newTypeSig = new TypeSignature(root);
120: String sig = newTypeSig.getTypeSignature(typesig, method
121: .returnType());
122: sig = sig.substring(1);
123: sig = sig.substring(0, sig.lastIndexOf(')'));
124: sig = sig.replace('/', '.');
125: result.append(mangle(sig, Mangle.Type.JNI));
126: }
127:
128: return result.toString();
129: }
130:
131: //where
132: private static String getInnerQualifiedName(ClassDoc clazz) {
133: ClassDoc encl = clazz.containingClass();
134: if (encl == null)
135: return clazz.qualifiedName();
136: else
137: return getInnerQualifiedName(encl) + '$'
138: + clazz.simpleTypeName();
139: }
140:
141: public static final String mangleChar(char ch) {
142: String s = Integer.toHexString(ch);
143: int nzeros = 5 - s.length();
144: char[] result = new char[6];
145: result[0] = '_';
146: for (int i = 1; i <= nzeros; i++)
147: result[i] = '0';
148: for (int i = nzeros + 1, j = 0; i < 6; i++, j++)
149: result[i] = s.charAt(j);
150: return new String(result);
151: }
152:
153: /* Warning: Intentional ASCII operation. */
154: private static final boolean isalnum(char ch) {
155: return ch <= 0x7f
156: && /* quick test */
157: ((ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z') || (ch >= '0' && ch <= '9'));
158: }
159:
160: /* Warning: Intentional ASCII operation. */
161: private static final boolean isprint(char ch) {
162: return ch >= 32 && ch <= 126;
163: }
164: }
|