Skip to content

Commit 0837e92

Browse files
committed
Add generic/Demangle.c
Signed-off-by: Kang-Che Sung <[email protected]>
1 parent 7dc5324 commit 0837e92

File tree

3 files changed

+94
-0
lines changed

3 files changed

+94
-0
lines changed

Makefile.am

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,11 @@ myhtopheaders = \
166166
Vector.h \
167167
XUtils.h
168168

169+
if HAVE_DEMANGLING
170+
myhtopheaders += generic/Demangle.h
171+
myhtopsources += generic/Demangle.c
172+
endif
173+
169174
# Linux
170175
# -----
171176

generic/Demangle.c

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
/*
2+
htop - generic/Demangle.h
3+
(C) 2025 htop dev team
4+
Released under the GNU GPLv2+, see the COPYING file
5+
in the source distribution for its full text.
6+
*/
7+
8+
#include "config.h" // IWYU pragma: keep
9+
10+
#include "generic/Demangle.h"
11+
12+
#include <stdint.h> // IWYU pragma: keep
13+
#include <stdlib.h> // IWYU pragma: keep
14+
15+
#ifdef HAVE_DEMANGLE_H
16+
# if !defined(HAVE_DECL_BASENAME)
17+
// Suppress libiberty's own declaration of basename().
18+
// It's a pity that we need this workaround as libiberty developers
19+
// refuse fix their headers and export an unwanted interface to us.
20+
// htop doesn't use basename() API. (The POSIX version is flawed by
21+
// design; libiberty's ships with GNU version of basename() that's
22+
// incompatible with POSIX.)
23+
// <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=122729>
24+
# define HAVE_DECL_BASENAME 1
25+
# endif
26+
#include <demangle.h>
27+
#endif
28+
29+
30+
#ifdef HAVE_DEMANGLING
31+
char* Generic_Demangle(const char* mangled) {
32+
# if defined(HAVE_LIBIBERTY_CPLUS_DEMANGLE)
33+
int options = DMGL_PARAMS | DMGL_AUTO;
34+
return cplus_demangle(mangled, options);
35+
# elif defined(HAVE_LIBDEMANGLE_CPLUS_DEMANGLE)
36+
// The cplus_demangle() API from libdemangle is flawed. It does not
37+
// provide us the required size of the buffer to store the demangled
38+
// name, and it leaves the buffer content undefined if the specified
39+
// buffer size is not big enough.
40+
static size_t allocSize = 8;
41+
42+
char* buf;
43+
44+
while (!!(buf = malloc(allocSize))) {
45+
int ret = cplus_demangle(mangled, buf, allocSize);
46+
if (ret == 0)
47+
break;
48+
49+
free(buf);
50+
buf = NULL;
51+
52+
if (ret != DEMANGLE_ESPACE || allocSize > SIZE_MAX / 2)
53+
break;
54+
55+
allocSize *= 2;
56+
}
57+
58+
return buf;
59+
# endif
60+
61+
// Unimplemented
62+
(void)mangled;
63+
return NULL;
64+
}
65+
#endif

generic/Demangle.h

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
#ifndef HEADER_Demangle
2+
#define HEADER_Demangle
3+
/*
4+
htop - generic/Demangle.h
5+
(C) 2025 htop dev team
6+
Released under the GNU GPLv2+, see the COPYING file
7+
in the source distribution for its full text.
8+
*/
9+
10+
#include "Macros.h"
11+
12+
13+
#ifdef HAVE_DEMANGLING
14+
ATTR_NONNULL ATTR_MALLOC
15+
char* Generic_Demangle(const char* mangled);
16+
#else
17+
ATTR_NONNULL
18+
static inline char* Generic_Demangle(const char* mangled) {
19+
(void)mangled;
20+
return NULL;
21+
}
22+
#endif
23+
24+
#endif

0 commit comments

Comments
 (0)