Sat, 01 Dec 2007 00:00:00 +0000
Initial load
1 /*
2 * Copyright 2002-2006 Sun Microsystems, Inc. All Rights Reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Sun designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Sun in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
22 * CA 95054 USA or visit www.sun.com if you need additional information or
23 * have any questions.
24 */
27 package com.sun.tools.javah;
29 import com.sun.javadoc.*;
31 /**
32 * A utility for mangling java identifiers into C names. Should make
33 * this more fine grained and distribute the functionality to the
34 * generators.
35 *
36 * @author Sucheta Dambalkar(Revised)
37 */
38 class Mangle {
40 public static class Type {
42 public static final int CLASS = 1;
43 public static final int FIELDSTUB = 2;
44 public static final int FIELD = 3;
45 public static final int JNI = 4;
46 public static final int SIGNATURE = 5;
47 public static final int METHOD_JDK_1 = 6;
48 public static final int METHOD_JNI_SHORT = 7;
49 public static final int METHOD_JNI_LONG = 8;
50 };
53 public static final String mangle(String name, int mtype) {
54 StringBuffer result = new StringBuffer(100);
55 int length = name.length();
57 for (int i = 0; i < length; i++) {
58 char ch = name.charAt(i);
59 if (isalnum(ch)) {
60 result.append(ch);
61 } else if ((ch == '.') &&
62 mtype == Mangle.Type.CLASS) {
63 result.append('_');
64 } else if (( ch == '$') &&
65 mtype == Mangle.Type.CLASS) {
66 result.append('_');
67 result.append('_');
68 } else if (ch == '_' && mtype == Mangle.Type.FIELDSTUB) {
69 result.append('_');
70 } else if (ch == '_' && mtype == Mangle.Type.CLASS) {
71 result.append('_');
72 } else if (mtype == Mangle.Type.JNI) {
73 String esc = null;
74 if (ch == '_')
75 esc = "_1";
76 else if (ch == '.')
77 esc = "_";
78 else if (ch == ';')
79 esc = "_2";
80 else if (ch == '[')
81 esc = "_3";
82 if (esc != null) {
83 result.append(esc);
84 } else {
85 result.append(mangleChar(ch));
86 }
87 } else if (mtype == Mangle.Type.SIGNATURE) {
88 if (isprint(ch)) {
89 result.append(ch);
90 } else {
91 result.append(mangleChar(ch));
92 }
93 } else {
94 result.append(mangleChar(ch));
95 }
96 }
98 return result.toString();
99 }
101 public static String mangleMethod(MethodDoc method, RootDoc root, ClassDoc clazz,
102 int mtype) {
103 StringBuffer result = new StringBuffer(100);
104 result.append("Java_");
106 if (mtype == Mangle.Type.METHOD_JDK_1) {
107 result.append(mangle(clazz.qualifiedName(), Mangle.Type.CLASS));
108 result.append('_');
109 result.append(mangle(method.name(),
110 Mangle.Type.FIELD));
111 result.append("_stub");
112 return result.toString();
113 }
115 /* JNI */
116 result.append(mangle(getInnerQualifiedName(clazz), Mangle.Type.JNI));
117 result.append('_');
118 result.append(mangle(method.name(),
119 Mangle.Type.JNI));
120 if (mtype == Mangle.Type.METHOD_JNI_LONG) {
121 result.append("__");
122 String typesig = method.signature();
123 TypeSignature newTypeSig = new TypeSignature(root);
124 String sig = newTypeSig.getTypeSignature(typesig, method.returnType());
125 sig = sig.substring(1);
126 sig = sig.substring(0, sig.lastIndexOf(')'));
127 sig = sig.replace('/', '.');
128 result.append(mangle(sig, Mangle.Type.JNI));
129 }
131 return result.toString();
132 }
133 //where
134 private static String getInnerQualifiedName(ClassDoc clazz) {
135 ClassDoc encl = clazz.containingClass();
136 if (encl == null)
137 return clazz.qualifiedName();
138 else
139 return getInnerQualifiedName(encl) + '$' + clazz.simpleTypeName();
140 }
142 public static final String mangleChar(char ch) {
143 String s = Integer.toHexString(ch);
144 int nzeros = 5 - s.length();
145 char[] result = new char[6];
146 result[0] = '_';
147 for (int i = 1; i <= nzeros; i++)
148 result[i] = '0';
149 for (int i = nzeros+1, j = 0; i < 6; i++, j++)
150 result[i] = s.charAt(j);
151 return new String(result);
152 }
154 /* Warning: Intentional ASCII operation. */
155 private static final boolean isalnum(char ch) {
156 return ch <= 0x7f && /* quick test */
157 ((ch >= 'A' && ch <= 'Z') ||
158 (ch >= 'a' && ch <= 'z') ||
159 (ch >= '0' && ch <= '9'));
160 }
162 /* Warning: Intentional ASCII operation. */
163 private static final boolean isprint(char ch) {
164 return ch >= 32 && ch <= 126;
165 }
166 }