diff options
author | hunt <hunt> | 2005-05-31 20:26:38 +0000 |
---|---|---|
committer | hunt <hunt> | 2005-05-31 20:26:38 +0000 |
commit | 55a163fc934622ec2b94551b8cd0e57a33b1a905 (patch) | |
tree | f5127eb771caa4cfb4c5c69f75cb293992e93d2d /runtime/map.c | |
parent | f541970f10c03b788141b359689e2a847b7684c4 (diff) | |
download | systemtap-steved-55a163fc934622ec2b94551b8cd0e57a33b1a905.tar.gz systemtap-steved-55a163fc934622ec2b94551b8cd0e57a33b1a905.tar.xz systemtap-steved-55a163fc934622ec2b94551b8cd0e57a33b1a905.zip |
2005-05-31 Martin Hunt <hunt@redhat.com>
* map.c (_stp_map_print): Now takes a format string instead of a name.
* map.h (foreach): Update macro.
* string.c (_stp_string_cat_char): New function. Append a char
to a string.
Diffstat (limited to 'runtime/map.c')
-rw-r--r-- | runtime/map.c | 194 |
1 files changed, 160 insertions, 34 deletions
diff --git a/runtime/map.c b/runtime/map.c index dfb98bfb..98ed6af9 100644 --- a/runtime/map.c +++ b/runtime/map.c @@ -6,6 +6,7 @@ */ #include "alloc.c" +#include "sym.c" static int map_sizes[] = { sizeof(int64_t), @@ -514,53 +515,178 @@ void _stp_map_print_histogram (MAP map, stat *s) val = 1; else val *= 2; - _stp_print_flush(); } } #endif /* NEED_STAT_VALS */ -void _stp_map_print (MAP map, const char *name) -{ - struct map_node *ptr; - int type, n, first; - key_data kd; +/* Print stuff until a format specification is found. */ +/* Return pointer to that. */ +static char *next_fmt(char *fmt, int *num) +{ + char *f = fmt; + int in_fmt = 0; + dbug ("next_fmt %s\n", fmt); + *num = 0; + while (*f) { + if (in_fmt) { + if (*f == '%') { + _stp_string_cat_char(_stp_stdout,'%'); + in_fmt = 0; + } else if (*f > '0' && *f <= '9') { + *num = *f - '0'; + f++; + return f; + } else + return f; + } else if (*f == '%') + in_fmt = 1; + else + _stp_string_cat_char(_stp_stdout,*f); + f++; + } + return f; +} + +/* print type based on format. Valid formats are: +--- KEYS and RESULTS --- +%p - address (hex padded to sizeof(void *)) +%P - symbolic address +%x - hex int64 +%X - HEX int64 +%d - decimal int64 +%s - string +--- STATS --- +%m - min +%M - max +%A - avg +%S - sum +%H - histogram +%C - count +--- MISC --- +%% - print '%' +*/ +static int print_keytype (char *fmt, int type, key_data *kd) +{ + dbug ("*fmt = %c\n", *fmt); + switch (type) { + case STRING: + if (*fmt != 's') + return 1; + _stp_print_cstr (kd->strp); + break; + case INT64: + if (*fmt == 'x') + _stp_printf("%llx", kd->val); + else if (*fmt == 'X') + _stp_printf("%llX", kd->val); + else if (*fmt == 'd') + _stp_printf("%lld", kd->val); + else if (*fmt == 'p') { +#if BITS_PER_LONG == 64 + _stp_printf("%016llx", kd->val); +#else + _stp_printf("%08llx", kd->val); +#endif + } else if (*fmt == 'P') + _stp_symbol_print ((unsigned long)kd->val); + else + return 1; + break; + default: + return 1; + break; + } + return 0; +} - dbug ("print map %lx\n", (long)map); - for (ptr = _stp_map_start(map); ptr; ptr = _stp_map_iter (map, ptr)) { - n = 1; first = 1; - _stp_print_cstr (name); - _stp_print_cstr ("["); - do { - kd = (*map->get_key)(ptr, n, &type); - if (type == END) - break; - if (!first) - _stp_print_cstr (", "); - first = 0; - if (type == STRING) - _stp_print_cstr (kd.strp); - else - _stp_printf("%lld", kd.val); - n++; - } while (1); - _stp_print_cstr ("] = "); - if (map->type == STRING) +static void print_valtype (MAP map, char *fmt, struct map_node *ptr) +{ + switch (map->type) { + case STRING: + if (*fmt == 's') _stp_print_cstr(_stp_get_str(ptr)); - else if (map->type == INT64) - _stp_printf("%d", _stp_get_int64(ptr)); + break; + case INT64: + { + int64_t val = _stp_get_int64(ptr); + if (*fmt == 'x') + _stp_printf("%llx", val); + else if (*fmt == 'X') + _stp_printf("%llX", val); + else if (*fmt == 'd') + _stp_printf("%lld", val); + else if (*fmt == 'p') { +#if BITS_PER_LONG == 64 + _stp_printf("%016llx", val); +#else + _stp_printf("%08llx", val); +#endif + } else if (*fmt == 'P') + _stp_symbol_print ((unsigned long)val); + break; + } #ifdef NEED_STAT_VALS - else { - stat *s = _stp_get_stat(ptr); + case STAT: + { + stat *s = _stp_get_stat(ptr); + switch (*fmt) { + case 'C': + _stp_printf("%lld", s->count); + break; + case 'm': + _stp_printf("%lld", s->min); + break; + case 'M': + _stp_printf("%lld", s->max); + break; + case 'S': + _stp_printf("%lld", s->sum); + break; + case 'A': + { int64_t avg = s->sum; do_div (avg, (int)s->count); /* FIXME: check for overflow */ - _stp_printf("count:%lld sum:%lld avg:%lld min:%lld max:%lld\n", - s->count, s->sum, avg, s->min, s->max); - _stp_print_flush(); + _stp_printf("%lld", avg); + break; + } + case 'H': _stp_map_print_histogram (map, s); + _stp_print_flush(); + break; } + break; + } + #endif + default: + break; + } +} + +void _stp_map_print (MAP map, const char *fmt) +{ + struct map_node *ptr; + int type, num; + key_data kd; + dbug ("print map %lx fmt=%s\n", (long)map, fmt); + + foreach (map, ptr) { + char *f = (char *)fmt; + while (*f) { + f = next_fmt (f, &num); + if (num) { + /* key */ + kd = (*map->get_key)(ptr, num, &type); + if (type != END) + print_keytype (f, type, &kd); + } else { + /* value */ + print_valtype (map, f, ptr); + } + if (*f) + f++; + } _stp_print_cstr ("\n"); - _stp_print_flush(); } _stp_print_cstr ("\n"); _stp_print_flush(); |