0001
0002 #include <string.h>
0003 #include <stdlib.h>
0004 #include "util/string2.h"
0005
0006 #include "demangle-ocaml.h"
0007
0008 #include <linux/ctype.h>
0009
0010 static const char *caml_prefix = "caml";
0011 static const size_t caml_prefix_len = 4;
0012
0013
0014 static bool
0015 ocaml_is_mangled(const char *sym)
0016 {
0017 return 0 == strncmp(sym, caml_prefix, caml_prefix_len)
0018 && isupper(sym[caml_prefix_len]);
0019 }
0020
0021
0022
0023
0024
0025
0026
0027
0028 char *
0029 ocaml_demangle_sym(const char *sym)
0030 {
0031 char *result;
0032 int j = 0;
0033 int i;
0034 int len;
0035
0036 if (!ocaml_is_mangled(sym)) {
0037 return NULL;
0038 }
0039
0040 len = strlen(sym);
0041
0042
0043 result = malloc(len + 1);
0044 if (!result)
0045 return NULL;
0046
0047
0048 i = caml_prefix_len;
0049
0050 while (i < len) {
0051 if (sym[i] == '_' && sym[i + 1] == '_') {
0052
0053 result[j++] = '.';
0054 i += 2;
0055 }
0056 else if (sym[i] == '$' && isxdigit(sym[i + 1]) && isxdigit(sym[i + 2])) {
0057
0058 result[j++] = (hex(sym[i + 1]) << 4) | hex(sym[i + 2]);
0059 i += 3;
0060 }
0061 else {
0062 result[j++] = sym[i++];
0063 }
0064 }
0065 result[j] = '\0';
0066
0067 return result;
0068 }