Skip to content

Commit

Permalink
perf hist: Replace ->print() routines by ->snprintf() equivalents
Browse files Browse the repository at this point in the history
Then hist_entry__fprintf will just us the newly introduced
hist_entry__snprintf, add the newline and fprintf it to the supplied
FILE descriptor.

This allows us to remove the use_browser checking in the color_printf
routines, that now got color_snprintf variants too.

The newt TUI browser (and other GUIs that may come in the future) don't
have to worry about stdio specific stuff in the strings they get from
the se->snprintf routines and instead use whatever means to do the
equivalent.

Also the newt TUI browser don't have to use the fmemopen() hack, instead
it can use the se->snprintf routines directly. For now tho use the
hist_entry__snprintf routine to reduce the patch size.

Cc: Frédéric Weisbecker <fweisbec@gmail.com>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Paul Mackerras <paulus@samba.org>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
  • Loading branch information
Arnaldo Carvalho de Melo committed Apr 2, 2010
1 parent 7016213 commit a4e3b95
Show file tree
Hide file tree
Showing 7 changed files with 149 additions and 114 deletions.
53 changes: 49 additions & 4 deletions tools/perf/util/color.c
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,31 @@ int perf_color_default_config(const char *var, const char *value, void *cb)
return perf_default_config(var, value, cb);
}

static int __color_vsnprintf(char *bf, size_t size, const char *color,
const char *fmt, va_list args, const char *trail)
{
int r = 0;

/*
* Auto-detect:
*/
if (perf_use_color_default < 0) {
if (isatty(1) || pager_in_use())
perf_use_color_default = 1;
else
perf_use_color_default = 0;
}

if (perf_use_color_default && *color)
r += snprintf(bf, size, "%s", color);
r += vsnprintf(bf + r, size - r, fmt, args);
if (perf_use_color_default && *color)
r += snprintf(bf + r, size - r, "%s", PERF_COLOR_RESET);
if (trail)
r += snprintf(bf + r, size - r, "%s", trail);
return r;
}

static int __color_vfprintf(FILE *fp, const char *color, const char *fmt,
va_list args, const char *trail)
{
Expand All @@ -191,22 +216,36 @@ static int __color_vfprintf(FILE *fp, const char *color, const char *fmt,
return r;
}

int color_vsnprintf(char *bf, size_t size, const char *color,
const char *fmt, va_list args)
{
return __color_vsnprintf(bf, size, color, fmt, args, NULL);
}

int color_vfprintf(FILE *fp, const char *color, const char *fmt, va_list args)
{
return __color_vfprintf(fp, color, fmt, args, NULL);
}

int color_snprintf(char *bf, size_t size, const char *color,
const char *fmt, ...)
{
va_list args;
int r;

va_start(args, fmt);
r = color_vsnprintf(bf, size, color, fmt, args);
va_end(args);
return r;
}

int color_fprintf(FILE *fp, const char *color, const char *fmt, ...)
{
va_list args;
int r;

va_start(args, fmt);
if (use_browser)
r = vfprintf(fp, fmt, args);
else
r = color_vfprintf(fp, color, fmt, args);
r = color_vfprintf(fp, color, fmt, args);
va_end(args);
return r;
}
Expand Down Expand Up @@ -277,3 +316,9 @@ int percent_color_fprintf(FILE *fp, const char *fmt, double percent)

return r;
}

int percent_color_snprintf(char *bf, size_t size, const char *fmt, double percent)
{
const char *color = get_percent_color(percent);
return color_snprintf(bf, size, color, fmt, percent);
}
4 changes: 4 additions & 0 deletions tools/perf/util/color.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,14 @@ int perf_color_default_config(const char *var, const char *value, void *cb);
int perf_config_colorbool(const char *var, const char *value, int stdout_is_tty);
void color_parse(const char *value, const char *var, char *dst);
void color_parse_mem(const char *value, int len, const char *var, char *dst);
int color_vsnprintf(char *bf, size_t size, const char *color,
const char *fmt, va_list args);
int color_vfprintf(FILE *fp, const char *color, const char *fmt, va_list args);
int color_fprintf(FILE *fp, const char *color, const char *fmt, ...);
int color_snprintf(char *bf, size_t size, const char *color, const char *fmt, ...);
int color_fprintf_ln(FILE *fp, const char *color, const char *fmt, ...);
int color_fwrite_lines(FILE *fp, const char *color, size_t count, const char *buf);
int percent_color_snprintf(char *bf, size_t size, const char *fmt, double percent);
int percent_color_fprintf(FILE *fp, const char *fmt, double percent);
const char *get_percent_color(double percent);

Expand Down
54 changes: 37 additions & 17 deletions tools/perf/util/hist.c
Original file line number Diff line number Diff line change
Expand Up @@ -455,16 +455,17 @@ static size_t hist_entry_callchain__fprintf(FILE *fp, struct hist_entry *self,
return ret;
}

size_t hist_entry__fprintf(struct hist_entry *self,
int hist_entry__snprintf(struct hist_entry *self,
char *s, size_t size,
struct perf_session *pair_session,
bool show_displacement,
long displacement, FILE *fp,
long displacement, bool color,
u64 session_total)
{
struct sort_entry *se;
u64 count, total;
const char *sep = symbol_conf.field_sep;
size_t ret;
int ret;

if (symbol_conf.exclude_other && !self->parent)
return 0;
Expand All @@ -477,17 +478,22 @@ size_t hist_entry__fprintf(struct hist_entry *self,
total = session_total;
}

if (total)
ret = percent_color_fprintf(fp, sep ? "%.2f" : " %6.2f%%",
(count * 100.0) / total);
else
ret = fprintf(fp, sep ? "%lld" : "%12lld ", count);
if (total) {
if (color)
ret = percent_color_snprintf(s, size,
sep ? "%.2f" : " %6.2f%%",
(count * 100.0) / total);
else
ret = snprintf(s, size, sep ? "%.2f" : " %6.2f%%",
(count * 100.0) / total);
} else
ret = snprintf(s, size, sep ? "%lld" : "%12lld ", count);

if (symbol_conf.show_nr_samples) {
if (sep)
ret += fprintf(fp, "%c%lld", *sep, count);
ret += snprintf(s + ret, size - ret, "%c%lld", *sep, count);
else
ret += fprintf(fp, "%11lld", count);
ret += snprintf(s + ret, size - ret, "%11lld", count);
}

if (pair_session) {
Expand All @@ -507,9 +513,9 @@ size_t hist_entry__fprintf(struct hist_entry *self,
snprintf(bf, sizeof(bf), " ");

if (sep)
ret += fprintf(fp, "%c%s", *sep, bf);
ret += snprintf(s + ret, size - ret, "%c%s", *sep, bf);
else
ret += fprintf(fp, "%11.11s", bf);
ret += snprintf(s + ret, size - ret, "%11.11s", bf);

if (show_displacement) {
if (displacement)
Expand All @@ -518,21 +524,35 @@ size_t hist_entry__fprintf(struct hist_entry *self,
snprintf(bf, sizeof(bf), " ");

if (sep)
ret += fprintf(fp, "%c%s", *sep, bf);
ret += snprintf(s + ret, size - ret, "%c%s", *sep, bf);
else
ret += fprintf(fp, "%6.6s", bf);
ret += snprintf(s + ret, size - ret, "%6.6s", bf);
}
}

list_for_each_entry(se, &hist_entry__sort_list, list) {
if (se->elide)
continue;

ret += fprintf(fp, "%s", sep ?: " ");
ret += se->print(fp, self, se->width ? *se->width : 0);
ret += snprintf(s + ret, size - ret, "%s", sep ?: " ");
ret += se->snprintf(self, s + ret, size - ret,
se->width ? *se->width : 0);
}

return ret + fprintf(fp, "\n");
return ret;
}

int hist_entry__fprintf(struct hist_entry *self,
struct perf_session *pair_session,
bool show_displacement,
long displacement, FILE *fp,
u64 session_total)
{
char bf[512];
hist_entry__snprintf(self, bf, sizeof(bf), pair_session,
show_displacement, displacement,
true, session_total);
return fprintf(fp, "%s\n", bf);
}

static size_t hist_entry__fprintf_callchain(struct hist_entry *self, FILE *fp,
Expand Down
7 changes: 6 additions & 1 deletion tools/perf/util/hist.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,16 @@ struct hist_entry *__perf_session__add_hist_entry(struct rb_root *hists,
u64 count, bool *hit);
extern int64_t hist_entry__cmp(struct hist_entry *, struct hist_entry *);
extern int64_t hist_entry__collapse(struct hist_entry *, struct hist_entry *);
size_t hist_entry__fprintf(struct hist_entry *self,
int hist_entry__fprintf(struct hist_entry *self,
struct perf_session *pair_session,
bool show_displacement,
long displacement, FILE *fp,
u64 session_total);
int hist_entry__snprintf(struct hist_entry *self,
char *bf, size_t size,
struct perf_session *pair_session,
bool show_displacement, long displacement,
bool color, u64 session_total);
void hist_entry__free(struct hist_entry *);

u64 perf_session__output_resort(struct rb_root *hists, u64 total_samples);
Expand Down
53 changes: 5 additions & 48 deletions tools/perf/util/newt.c
Original file line number Diff line number Diff line change
Expand Up @@ -294,60 +294,17 @@ static void hist_entry__append_callchain_browser(struct hist_entry *self,
}
}

/*
* FIXME: get lib/string.c linked with perf somehow
*/
static char *skip_spaces(const char *str)
{
while (isspace(*str))
++str;
return (char *)str;
}

static char *strim(char *s)
{
size_t size;
char *end;

s = skip_spaces(s);
size = strlen(s);
if (!size)
return s;

end = s + size - 1;
while (end >= s && isspace(*end))
end--;
*(end + 1) = '\0';

return s;
}

static size_t hist_entry__append_browser(struct hist_entry *self,
newtComponent tree, u64 total)
{
char bf[1024], *s;
FILE *fp;
char s[256];
size_t ret;

if (symbol_conf.exclude_other && !self->parent)
return 0;

fp = fmemopen(bf, sizeof(bf), "w");
if (fp == NULL)
return 0;

hist_entry__fprintf(self, NULL, false, 0, fp, total);
fclose(fp);

/*
* FIXME: We shouldn't need to trim, as the printing routines shouldn't
* add spaces it in the first place, the stdio output routines should
* call a __snprintf method instead of the current __print (that
* actually is a __fprintf) one, but get the raw string and _then_ add
* the newline, as this is a detail of stdio printing, not needed in
* other UIs, e.g. newt.
*/
s = strim(bf);

ret = hist_entry__snprintf(self, s, sizeof(s), NULL,
false, 0, false, total);
if (symbol_conf.use_callchain) {
int indexes[2];

Expand All @@ -357,7 +314,7 @@ static size_t hist_entry__append_browser(struct hist_entry *self,
} else
newtListboxAppendEntry(tree, s, &self->ms);

return strlen(s);
return ret;
}

static void map_symbol__annotate_browser(const struct map_symbol *self)
Expand Down
Loading

0 comments on commit a4e3b95

Please sign in to comment.