--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/share/classes/com/sun/tools/javah/Mangle.java Sat Dec 01 00:00:00 2007 +0000
@@ -0,0 +1,166 @@
+/*
+ * Copyright 2002-2006 Sun Microsystems, Inc. All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+
+package com.sun.tools.javah;
+
+import com.sun.javadoc.*;
+
+/**
+ * A utility for mangling java identifiers into C names. Should make
+ * this more fine grained and distribute the functionality to the
+ * generators.
+ *
+ * @author Sucheta Dambalkar(Revised)
+ */
+class Mangle {
+
+ public static class Type {
+
+ public static final int CLASS = 1;
+ public static final int FIELDSTUB = 2;
+ public static final int FIELD = 3;
+ public static final int JNI = 4;
+ public static final int SIGNATURE = 5;
+ public static final int METHOD_JDK_1 = 6;
+ public static final int METHOD_JNI_SHORT = 7;
+ public static final int METHOD_JNI_LONG = 8;
+ };
+
+
+ public static final String mangle(String name, int mtype) {
+ StringBuffer result = new StringBuffer(100);
+ int length = name.length();
+
+ for (int i = 0; i < length; i++) {
+ char ch = name.charAt(i);
+ if (isalnum(ch)) {
+ result.append(ch);
+ } else if ((ch == '.') &&
+ mtype == Mangle.Type.CLASS) {
+ result.append('_');
+ } else if (( ch == '$') &&
+ mtype == Mangle.Type.CLASS) {
+ result.append('_');
+ result.append('_');
+ } else if (ch == '_' && mtype == Mangle.Type.FIELDSTUB) {
+ result.append('_');
+ } else if (ch == '_' && mtype == Mangle.Type.CLASS) {
+ result.append('_');
+ } else if (mtype == Mangle.Type.JNI) {
+ String esc = null;
+ if (ch == '_')
+ esc = "_1";
+ else if (ch == '.')
+ esc = "_";
+ else if (ch == ';')
+ esc = "_2";
+ else if (ch == '[')
+ esc = "_3";
+ if (esc != null) {
+ result.append(esc);
+ } else {
+ result.append(mangleChar(ch));
+ }
+ } else if (mtype == Mangle.Type.SIGNATURE) {
+ if (isprint(ch)) {
+ result.append(ch);
+ } else {
+ result.append(mangleChar(ch));
+ }
+ } else {
+ result.append(mangleChar(ch));
+ }
+ }
+
+ return result.toString();
+ }
+
+ public static String mangleMethod(MethodDoc method, RootDoc root, ClassDoc clazz,
+ int mtype) {
+ StringBuffer result = new StringBuffer(100);
+ result.append("Java_");
+
+ if (mtype == Mangle.Type.METHOD_JDK_1) {
+ result.append(mangle(clazz.qualifiedName(), Mangle.Type.CLASS));
+ result.append('_');
+ result.append(mangle(method.name(),
+ Mangle.Type.FIELD));
+ result.append("_stub");
+ return result.toString();
+ }
+
+ /* JNI */
+ result.append(mangle(getInnerQualifiedName(clazz), Mangle.Type.JNI));
+ result.append('_');
+ result.append(mangle(method.name(),
+ Mangle.Type.JNI));
+ if (mtype == Mangle.Type.METHOD_JNI_LONG) {
+ result.append("__");
+ String typesig = method.signature();
+ TypeSignature newTypeSig = new TypeSignature(root);
+ String sig = newTypeSig.getTypeSignature(typesig, method.returnType());
+ sig = sig.substring(1);
+ sig = sig.substring(0, sig.lastIndexOf(')'));
+ sig = sig.replace('/', '.');
+ result.append(mangle(sig, Mangle.Type.JNI));
+ }
+
+ return result.toString();
+ }
+ //where
+ private static String getInnerQualifiedName(ClassDoc clazz) {
+ ClassDoc encl = clazz.containingClass();
+ if (encl == null)
+ return clazz.qualifiedName();
+ else
+ return getInnerQualifiedName(encl) + '$' + clazz.simpleTypeName();
+ }
+
+ public static final String mangleChar(char ch) {
+ String s = Integer.toHexString(ch);
+ int nzeros = 5 - s.length();
+ char[] result = new char[6];
+ result[0] = '_';
+ for (int i = 1; i <= nzeros; i++)
+ result[i] = '0';
+ for (int i = nzeros+1, j = 0; i < 6; i++, j++)
+ result[i] = s.charAt(j);
+ return new String(result);
+ }
+
+ /* Warning: Intentional ASCII operation. */
+ private static final boolean isalnum(char ch) {
+ return ch <= 0x7f && /* quick test */
+ ((ch >= 'A' && ch <= 'Z') ||
+ (ch >= 'a' && ch <= 'z') ||
+ (ch >= '0' && ch <= '9'));
+ }
+
+ /* Warning: Intentional ASCII operation. */
+ private static final boolean isprint(char ch) {
+ return ch >= 32 && ch <= 126;
+ }
+}