langtools/src/share/classes/com/sun/tools/javah/Mangle.java
changeset 10 06bc494ca11e
child 3996 dc676a9093b3
equal deleted inserted replaced
0:fd16c54261b3 10:06bc494ca11e
       
     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  */
       
    25 
       
    26 
       
    27 package com.sun.tools.javah;
       
    28 
       
    29 import com.sun.javadoc.*;
       
    30 
       
    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 {
       
    39 
       
    40     public static class Type {
       
    41 
       
    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     };
       
    51 
       
    52 
       
    53     public static final String mangle(String name, int mtype) {
       
    54         StringBuffer result = new StringBuffer(100);
       
    55         int length = name.length();
       
    56 
       
    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         }
       
    97 
       
    98         return result.toString();
       
    99     }
       
   100 
       
   101     public static String mangleMethod(MethodDoc method, RootDoc root, ClassDoc clazz,
       
   102                                       int mtype) {
       
   103         StringBuffer result = new StringBuffer(100);
       
   104         result.append("Java_");
       
   105 
       
   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         }
       
   114 
       
   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         }
       
   130 
       
   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         }
       
   141 
       
   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     }
       
   153 
       
   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     }
       
   161 
       
   162     /* Warning: Intentional ASCII operation. */
       
   163     private static final boolean isprint(char ch) {
       
   164         return ch >= 32 && ch <= 126;
       
   165     }
       
   166 }