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 }