output.c revision 273ea6d18164e35ee40524e853a6f04706d3bdff
1#include <stdio.h>
2#include <stdarg.h>
3
4#include "ltrace.h"
5#include "options.h"
6#include "output.h"
7
8static pid_t current_pid = 0;
9static int current_column = 0;
10
11static void begin_of_line(enum tof type, struct process * proc)
12{
13	current_column = 0;
14	if (!proc) {
15		return;
16	}
17	if ((output!=stderr) && (opt_p || opt_f)) {
18		current_column += fprintf(output, "%u ", proc->pid);
19	} else if (list_of_processes->next) {
20		current_column += fprintf(output, "[pid %u] ", proc->pid);
21	}
22	if (opt_i) {
23		if (type==LT_TOF_FUNCTION) {
24			current_column += fprintf(output, "[%08x] ",
25				(unsigned)proc->return_addr);
26		} else {
27			current_column += fprintf(output, "[%08x] ",
28				(unsigned)proc->instruction_pointer);
29		}
30	}
31}
32
33static struct function * name2func(char * name)
34{
35	struct function * tmp;
36
37	tmp = list_of_functions;
38	while(tmp) {
39		if (!strcmp(tmp->name, name)) {
40			return tmp;
41		}
42		tmp = tmp->next;
43	}
44	return NULL;
45}
46
47void output_line(struct process * proc, char *fmt, ...)
48{
49	va_list args;
50
51	if (current_pid) {
52		fprintf(output, " <unfinished ...>\n");
53	}
54	begin_of_line(LT_TOF_NONE, proc);
55
56        va_start(args, fmt);
57        vfprintf(output, fmt, args);
58        fprintf(output, "\n");
59        va_end(args);
60	current_pid=0;
61	current_column=0;
62}
63
64static void tabto(int col)
65{
66	if (current_column < col) {
67		fprintf(output, "%*s", col-current_column, "");
68	}
69}
70
71void output_left(enum tof type, struct process * proc, char * function_name)
72{
73	struct function * func;
74
75	if (current_pid) {
76#if 0			/* FIXME: should I do this? */
77		if (current_pid == proc->pid
78			&& proc->type_being_displayed == LT_TOF_FUNCTION
79			&& proc->type_being_displayed == type) {
80				tabto(opt_a);
81				fprintf(output, "= ???\n");
82		} else
83#endif
84			fprintf(output, " <unfinished ...>\n");
85		current_pid=0;
86		current_column=0;
87	}
88	current_pid=proc->pid;
89	proc->type_being_displayed = type;
90	begin_of_line(type, proc);
91	current_column += fprintf(output, "%s(", function_name);
92
93	func = name2func(function_name);
94	if (!func) {
95		int i;
96		for(i=0; i<4; i++) {
97			current_column += display_arg(type, proc, i, LT_PT_UNKNOWN);
98			current_column += fprintf(output, ", ");
99		}
100		current_column += display_arg(type, proc, 4, LT_PT_UNKNOWN);
101		return;
102	} else {
103		int i;
104		for(i=0; i< func->num_params - func->params_right - 1; i++) {
105			current_column += display_arg(type, proc, i, func->param_types[i]);
106			current_column += fprintf(output, ", ");
107		}
108		if (func->num_params>func->params_right) {
109			current_column += display_arg(type, proc, i, func->param_types[i]);
110			if (func->params_right) {
111				current_column += fprintf(output, ", ");
112			}
113		}
114		if (!func->params_right && func->return_type == LT_PT_VOID) {
115			current_column += fprintf(output, ") ");
116			tabto(opt_a);
117			fprintf(output, "= <void>\n");
118			current_pid = 0;
119			current_column = 0;
120		}
121	}
122}
123
124void output_right(enum tof type, struct process * proc, char * function_name)
125{
126	struct function * func = name2func(function_name);
127
128	if (func && func->params_right==0 && func->return_type == LT_PT_VOID) {
129		return;
130	}
131
132	if (current_pid && current_pid!=proc->pid) {
133		fprintf(output, " <unfinished ...>\n");
134		begin_of_line(type, proc);
135		current_column += fprintf(output, "<... %s resumed> ", function_name);
136	} else if (!current_pid) {
137		begin_of_line(type, proc);
138		current_column += fprintf(output, "<... %s resumed> ", function_name);
139	}
140
141	if (!func) {
142		current_column += fprintf(output, ") ");
143		tabto(opt_a);
144		fprintf(output, "= ");
145		display_arg(type, proc, -1, LT_PT_UNKNOWN);
146		fprintf(output, "\n");
147	} else {
148		int i;
149		for(i=func->num_params-func->params_right; i<func->num_params-1; i++) {
150			current_column += display_arg(type, proc, i, func->param_types[i]);
151			current_column += fprintf(output, ", ");
152		}
153		if (func->params_right) {
154			current_column += display_arg(type, proc, i, func->param_types[i]);
155		}
156		current_column += fprintf(output, ") ");
157			tabto(opt_a);
158			fprintf(output, "= ");
159		if (func->return_type == LT_PT_VOID) {
160			fprintf(output, "<void>");
161		} else {
162			display_arg(type, proc, -1, func->return_type);
163		}
164		fprintf(output, "\n");
165	}
166	current_pid=0;
167	current_column=0;
168}
169