forked from namhyung/uftrace
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdemangler.c
127 lines (99 loc) · 2.15 KB
/
demangler.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
#include <getopt.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include "uftrace.h"
#include "utils/utils.h"
#include "version.h"
char *demangle(char *str);
extern enum symbol_demangler demangler;
enum options {
OPT_simple = 301,
OPT_full,
OPT_no,
};
static struct option demangler_options[] = {
{ "simple", no_argument, 0, OPT_simple }, { "full", no_argument, 0, OPT_full },
{ "no", no_argument, 0, OPT_no }, { "verbose", no_argument, 0, 'v' },
{ "help", no_argument, 0, 'h' }, { 0 }
};
static const char demangler_usage[] =
"demangler " UFTRACE_VERSION "\n"
"\n"
" OPTION:\n"
" --simple Use internal simple demangler (default)\n"
" --full Use libstdc++ demangler\n"
" --no Do not use demangler\n"
" -v, --verbose Be verbose\n"
" -h, --help Display this help and exit\n"
"\n";
struct demangler_opts {
int mode;
int idx;
};
static void parse_option(int argc, char **argv, struct demangler_opts *opts)
{
bool done = false;
while (!done) {
int key, tmp;
key = getopt_long(argc, argv, "vh", demangler_options, &tmp);
switch (key) {
case OPT_simple:
opts->mode = DEMANGLE_SIMPLE;
break;
case OPT_full:
opts->mode = DEMANGLE_FULL;
break;
case OPT_no:
opts->mode = DEMANGLE_NONE;
break;
case 'v':
debug++;
dbg_domain[DBG_DEMANGLE]++;
break;
case 'h':
printf("%s", demangler_usage);
exit(0);
case -1:
done = true;
break;
default:
printf("%s", demangler_usage);
exit(1);
}
}
opts->idx = optind;
}
int main(int argc, char *argv[])
{
struct demangler_opts opts = {
.mode = DEMANGLE_SIMPLE,
};
parse_option(argc, argv, &opts);
demangler = opts.mode;
outfp = stdout;
logfp = stdout;
if (opts.idx < argc) {
int i;
for (i = opts.idx; i < argc; i++) {
char *name = demangle(argv[i]);
printf("%s\n", name);
free(name);
}
}
else {
char buf[4096];
while (fgets(buf, sizeof(buf), stdin)) {
char *name;
char *p;
buf[sizeof(buf) - 1] = '\0';
p = strchr(buf, '\n');
if (p)
*p = '\0';
name = demangle(buf);
printf("%s\n", name);
free(name);
}
}
return 0;
}