1 /*
2 * This file and its contents are supplied under the terms of the
3 * Common Development and Distribution License ("CDDL"), version 1.0.
4 * You may only use this file in accordance with the terms of version
5 * 1.0 of the CDDL.
6 *
7 * A full copy of the text of the CDDL should have accompanied this
8 * source. A copy of the CDDL is also available via the Internet at
9 * http://www.illumos.org/license/CDDL.
10 */
11
12 /*
13 * Copyright 2017 Jason King
14 */
15
16 #include <string.h>
17 #include <errno.h>
18 #include "sysdemangle.h"
19 #include "sysdemangle_int.h"
20
21
22 static sysdem_lang_t
23 detect_lang(const char *str)
24 {
25 size_t n = strlen(str);
26
27 if (n < 3 || str[0] != '_')
28 return (SYSDEM_LANG_AUTO);
29
30 switch (str[1]) {
31 case 'Z':
32 return (SYSDEM_LANG_CPP);
33
34 case '_':
35 break;
36
37 default:
38 return (SYSDEM_LANG_AUTO);
39 }
40
41 /* why they use ___Z sometimes is puzzling.. *sigh* */
42 if (str[2] == '_' && str[3] == 'Z')
43 return (SYSDEM_LANG_CPP);
44
45 return (SYSDEM_LANG_AUTO);
46 }
47
48 char *
49 sysdemangle(const char *str, sysdem_lang_t lang, sysdem_ops_t *ops)
50 {
51
52 if (ops == NULL)
53 ops = sysdem_ops_default;
54
55 if (lang == SYSDEM_LANG_AUTO) {
56 lang = detect_lang(str);
57 if (lang == SYSDEM_LANG_AUTO) {
58 errno = ENOSYS;
59 return (NULL);
60 }
61 }
62
63 switch (lang) {
64 case SYSDEM_LANG_CPP:
65 return (cpp_demangle(str, ops));
66
67 default:
68 break;
69 }
70
71 /* XXX: better return value? */
72 errno = ENOSYS;
73 return (NULL);
74 }