1 // SPDX-License-Identifier: GPL-2.0
9 #include "demangle-java.h"
11 #include "sane_ctype.h"
18 MODE_CTYPE = 3, /* class arg */
21 #define BASE_ENT(c, n) [c - 'A']=n
22 static const char *base_types['Z' - 'A' + 1] = {
23 BASE_ENT('B', "byte" ),
24 BASE_ENT('C', "char" ),
25 BASE_ENT('D', "double" ),
26 BASE_ENT('F', "float" ),
27 BASE_ENT('I', "int" ),
28 BASE_ENT('J', "long" ),
29 BASE_ENT('S', "short" ),
30 BASE_ENT('Z', "bool" ),
34 * demangle Java symbol between str and end positions and stores
35 * up to maxlen characters into buf. The parser starts in mode.
37 * Use MODE_PREFIX to process entire prototype till end position
38 * Use MODE_TYPE to process return type if str starts on return type char
45 __demangle_java_sym(const char *str, const char *end, char *buf, int maxlen, int mode)
53 end = str + strlen(str);
55 for (q = str; q != end; q++) {
57 if (rlen == (maxlen - 1))
62 if (mode == MODE_PREFIX || mode == MODE_CTYPE) {
63 if (mode == MODE_CTYPE) {
65 rlen += scnprintf(buf + rlen, maxlen - rlen, ", ");
68 rlen += scnprintf(buf + rlen, maxlen - rlen, "class ");
69 if (mode == MODE_PREFIX)
82 if (mode == MODE_TYPE) {
84 rlen += scnprintf(buf + rlen, maxlen - rlen, ", ");
85 rlen += scnprintf(buf + rlen, maxlen - rlen, "%s", base_types[*q - 'A']);
87 rlen += scnprintf(buf + rlen, maxlen - rlen, "[]");
94 if (mode == MODE_TYPE) {
95 rlen += scnprintf(buf + rlen, maxlen - rlen, "void");
97 rlen += scnprintf(buf + rlen, maxlen - rlen, "[]");
103 if (mode != MODE_TYPE)
108 if (mode != MODE_FUNC)
114 if (mode != MODE_TYPE)
120 if (mode != MODE_CLASS && mode != MODE_CTYPE)
122 /* safe because at least one other char to process */
123 if (isalpha(*(q + 1)))
124 rlen += scnprintf(buf + rlen, maxlen - rlen, ".");
125 if (mode == MODE_CLASS)
127 else if (mode == MODE_CTYPE)
131 if (mode != MODE_CLASS && mode != MODE_CTYPE)
133 rlen += scnprintf(buf + rlen, maxlen - rlen, ".");
146 * Demangle Java function signature (openJDK, not GCJ)
148 * str: string to parse. String is not modified
149 * flags: comobination of JAVA_DEMANGLE_* flags to modify demangling
151 * if input can be demangled, then a newly allocated string is returned.
152 * if input cannot be demangled, then NULL is returned
154 * Note: caller is responsible for freeing demangled string
157 java_demangle_sym(const char *str, int flags)
166 /* find start of retunr type */
167 p = strrchr(str, ')');
172 * expansion factor estimated to 3x
174 len = strlen(str) * 3 + 1;
180 if (!(flags & JAVA_DEMANGLE_NORET)) {
182 * get return type first
184 ptr = __demangle_java_sym(p + 1, NULL, buf, len, MODE_TYPE);
188 /* add space between return type and function prototype */
193 /* process function up to return type */
194 ptr = __demangle_java_sym(str, p + 1, buf + l1, len - l1, MODE_PREFIX);