1#include "dissect.h"
2
3static inline const char *show_mode(unsigned mode)
4{
5	static char str[3];
6
7	if (mode == -1)
8		return "def";
9
10#define	U(u_r)	"-rwm"[(mode / u_r) & 3]
11	str[0] = U(U_R_AOF);
12	str[1] = U(U_R_VAL);
13	str[2] = U(U_R_PTR);
14#undef	U
15
16	return str;
17}
18
19static void print_usage(struct position *pos, struct symbol *sym, unsigned mode)
20{
21	static unsigned curr_stream = -1;
22	static struct ident null;
23	struct ident *ctx = &null;
24
25	if (curr_stream != pos->stream) {
26		curr_stream = pos->stream;
27		printf("\nFILE: %s\n\n", stream_name(curr_stream));
28	}
29
30	if (dissect_ctx)
31		ctx = dissect_ctx->ident;
32
33	printf("%4d:%-3d %-16.*s %s ",
34		pos->line, pos->pos, ctx->len, ctx->name, show_mode(mode));
35
36}
37
38static char symscope(struct symbol *sym)
39{
40	if (sym_is_local(sym)) {
41		if (!dissect_ctx)
42			warning(sym->pos, "no context");
43		return '.';
44	}
45	return ' ';
46}
47
48static void r_symbol(unsigned mode, struct position *pos, struct symbol *sym)
49{
50	print_usage(pos, sym, mode);
51
52	if (!sym->ident)
53		sym->ident = built_in_ident("__asm__");
54
55	printf("%c %c %-32.*s %s\n",
56		symscope(sym), sym->kind, sym->ident->len, sym->ident->name,
57		show_typename(sym->ctype.base_type));
58
59	switch (sym->kind) {
60	case 's':
61		if (sym->type == SYM_STRUCT || sym->type == SYM_UNION)
62			break;
63		goto err;
64
65	case 'f':
66		if (sym->type != SYM_BAD && sym->ctype.base_type->type != SYM_FN)
67			goto err;
68	case 'v':
69		if (sym->type == SYM_NODE || sym->type == SYM_BAD)
70			break;
71		goto err;
72	default:
73		goto err;
74	}
75
76	return;
77err:
78	warning(*pos, "r_symbol bad sym type=%d kind=%d", sym->type, sym->kind);
79}
80
81static void r_member(unsigned mode, struct position *pos, struct symbol *sym, struct symbol *mem)
82{
83	struct ident *ni, *si, *mi;
84
85	print_usage(pos, sym, mode);
86
87	ni = built_in_ident("?");
88	si = sym->ident ?: ni;
89	/* mem == NULL means entire struct accessed */
90	mi = mem ? (mem->ident ?: ni) : built_in_ident("*");
91
92	printf("%c m %.*s.%-*.*s %s\n",
93		symscope(sym), si->len, si->name,
94		32-1 - si->len, mi->len, mi->name,
95		show_typename(mem ? mem->ctype.base_type : sym));
96
97	if (sym->ident && sym->kind != 's')
98		warning(*pos, "r_member bad sym type=%d kind=%d", sym->type, sym->kind);
99	if (mem && mem->kind != 'm')
100		warning(*pos, "r_member bad mem->kind = %d", mem->kind);
101}
102
103static void r_symdef(struct symbol *sym)
104{
105	r_symbol(-1, &sym->pos, sym);
106}
107
108static void r_memdef(struct symbol *sym, struct symbol *mem)
109{
110	r_member(-1, &mem->pos, sym, mem);
111}
112
113int main(int argc, char **argv)
114{
115	static struct reporter reporter = {
116		.r_symdef = r_symdef,
117		.r_memdef = r_memdef,
118		.r_symbol = r_symbol,
119		.r_member = r_member,
120	};
121
122	struct string_list *filelist = NULL;
123	sparse_initialize(argc, argv, &filelist);
124	dissect(&reporter, filelist);
125
126	return 0;
127}
128