1236834Sadrian/*- 2236834Sadrian * Copyright (c) 2002-2007 Sam Leffler, Errno Consulting 3236834Sadrian * All rights reserved. 4236834Sadrian * 5236834Sadrian * Redistribution and use in source and binary forms, with or without 6236834Sadrian * modification, are permitted provided that the following conditions 7236834Sadrian * are met: 8236834Sadrian * 1. Redistributions of source code must retain the above copyright 9236834Sadrian * notice, this list of conditions and the following disclaimer, 10236834Sadrian * without modification. 11236834Sadrian * 2. Redistributions in binary form must reproduce at minimum a disclaimer 12236834Sadrian * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any 13236834Sadrian * redistribution must be conditioned upon including a substantially 14236834Sadrian * similar Disclaimer requirement for further binary redistribution. 15236834Sadrian * 16236834Sadrian * NO WARRANTY 17236834Sadrian * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18236834Sadrian * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19236834Sadrian * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY 20236834Sadrian * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 21236834Sadrian * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, 22236834Sadrian * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23236834Sadrian * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24236834Sadrian * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER 25236834Sadrian * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26236834Sadrian * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 27236834Sadrian * THE POSSIBILITY OF SUCH DAMAGES. 28236834Sadrian * 29236834Sadrian * $FreeBSD$ 30236834Sadrian */ 31236834Sadrian 32236834Sadrian#include <stdio.h> 33236834Sadrian#include <string.h> 34236834Sadrian 35236834Sadrian#include "statfoo.h" 36236834Sadrian 37236834Sadrianstatic void 38236834Sadrianstatfoo_setfmt(struct statfoo *sf, const char *fmt0) 39236834Sadrian{ 40236834Sadrian#define N(a) (sizeof(a)/sizeof(a[0])) 41236834Sadrian char fmt[4096]; 42236834Sadrian char *fp, *tok; 43236834Sadrian int i, j; 44236834Sadrian 45236834Sadrian j = 0; 46236834Sadrian strlcpy(fmt, fmt0, sizeof(fmt)); 47236834Sadrian for (fp = fmt; (tok = strsep(&fp, ", ")) != NULL;) { 48236834Sadrian for (i = 0; i < sf->nstats; i++) 49236834Sadrian if (strcasecmp(tok, sf->stats[i].name) == 0) 50236834Sadrian break; 51236834Sadrian if (i >= sf->nstats) { 52236834Sadrian fprintf(stderr, "%s: unknown statistic name \"%s\" " 53236834Sadrian "skipped\n", sf->name, tok); 54236834Sadrian continue; 55236834Sadrian } 56236834Sadrian if (j+3 > sizeof(sf->fmts)) { 57236834Sadrian fprintf(stderr, "%s: not enough room for all stats; " 58236834Sadrian "stopped at %s\n", sf->name, tok); 59236834Sadrian break; 60236834Sadrian } 61236834Sadrian if (j != 0) 62236834Sadrian sf->fmts[j++] = ' '; 63236834Sadrian sf->fmts[j++] = FMTS_IS_STAT; 64236834Sadrian sf->fmts[j++] = i & 0xff; 65236834Sadrian sf->fmts[j++] = (i >> 8) & 0xff; 66236834Sadrian } 67236834Sadrian sf->fmts[j] = '\0'; 68236834Sadrian#undef N 69236834Sadrian} 70236834Sadrian 71236834Sadrianstatic void 72236834Sadrianstatfoo_collect(struct statfoo *sf) 73236834Sadrian{ 74236834Sadrian fprintf(stderr, "%s: don't know how to collect data\n", sf->name); 75236834Sadrian} 76236834Sadrian 77236834Sadrianstatic void 78236834Sadrianstatfoo_update_tot(struct statfoo *sf) 79236834Sadrian{ 80236834Sadrian fprintf(stderr, "%s: don't know how to update total data\n", sf->name); 81236834Sadrian} 82236834Sadrian 83236834Sadrianstatic int 84236834Sadrianstatfoo_get(struct statfoo *sf, int s, char b[], size_t bs) 85236834Sadrian{ 86236834Sadrian fprintf(stderr, "%s: don't know how to get stat #%u\n", sf->name, s); 87236834Sadrian return 0; 88236834Sadrian} 89236834Sadrian 90236834Sadrianstatic void 91236834Sadrianstatfoo_print_header(struct statfoo *sf, FILE *fd) 92236834Sadrian{ 93236834Sadrian const unsigned char *cp; 94236834Sadrian int i; 95236834Sadrian const struct fmt *f; 96236834Sadrian 97236834Sadrian for (cp = sf->fmts; *cp != '\0'; cp++) { 98236834Sadrian if (*cp == FMTS_IS_STAT) { 99236834Sadrian i = *(++cp); 100236834Sadrian i |= ((int) *(++cp)) << 8; 101236834Sadrian f = &sf->stats[i]; 102236834Sadrian fprintf(fd, "%*s", f->width, f->label); 103236834Sadrian } else 104236834Sadrian putc(*cp, fd); 105236834Sadrian } 106236834Sadrian putc('\n', fd); 107236834Sadrian} 108236834Sadrian 109236834Sadrianstatic void 110236834Sadrianstatfoo_print_current(struct statfoo *sf, FILE *fd) 111236834Sadrian{ 112236834Sadrian char buf[32]; 113236834Sadrian const unsigned char *cp; 114236834Sadrian int i; 115236834Sadrian const struct fmt *f; 116236834Sadrian 117236834Sadrian for (cp = sf->fmts; *cp != '\0'; cp++) { 118236834Sadrian if (*cp == FMTS_IS_STAT) { 119236834Sadrian i = *(++cp); 120236834Sadrian i |= ((int) *(++cp)) << 8; 121236834Sadrian f = &sf->stats[i]; 122236834Sadrian if (sf->get_curstat(sf, i, buf, sizeof(buf))) 123236834Sadrian fprintf(fd, "%*s", f->width, buf); 124236834Sadrian } else 125236834Sadrian putc(*cp, fd); 126236834Sadrian } 127236834Sadrian putc('\n', fd); 128236834Sadrian} 129236834Sadrian 130236834Sadrianstatic void 131236834Sadrianstatfoo_print_total(struct statfoo *sf, FILE *fd) 132236834Sadrian{ 133236834Sadrian char buf[32]; 134236834Sadrian const unsigned char *cp; 135236834Sadrian const struct fmt *f; 136236834Sadrian int i; 137236834Sadrian 138236834Sadrian for (cp = sf->fmts; *cp != '\0'; cp++) { 139236834Sadrian if (*cp == FMTS_IS_STAT) { 140236834Sadrian i = *(++cp); 141236834Sadrian i |= ((int) *(++cp)) << 8; 142236834Sadrian f = &sf->stats[i]; 143236834Sadrian if (sf->get_totstat(sf, i, buf, sizeof(buf))) 144236834Sadrian fprintf(fd, "%*s", f->width, buf); 145236834Sadrian } else 146236834Sadrian putc(*cp, fd); 147236834Sadrian } 148236834Sadrian putc('\n', fd); 149236834Sadrian} 150236834Sadrian 151236834Sadrianstatic void 152236834Sadrianstatfoo_print_verbose(struct statfoo *sf, FILE *fd) 153236834Sadrian{ 154236834Sadrian const struct fmt *f; 155236834Sadrian char s[32]; 156236834Sadrian int i, width; 157236834Sadrian 158236834Sadrian width = 0; 159236834Sadrian for (i = 0; i < sf->nstats; i++) { 160236834Sadrian f = &sf->stats[i]; 161236834Sadrian if (f->width > width) 162236834Sadrian width = f->width; 163236834Sadrian } 164236834Sadrian for (i = 0; i < sf->nstats; i++) { 165236834Sadrian f = &sf->stats[i]; 166236834Sadrian if (sf->get_totstat(sf, i, s, sizeof(s)) && strcmp(s, "0")) 167236834Sadrian fprintf(fd, "%-*s %s\n", width, s, f->desc); 168236834Sadrian } 169236834Sadrian} 170236834Sadrian 171236834Sadrianstatic void 172236834Sadrianstatfoo_print_fields(struct statfoo *sf, FILE *fd) 173236834Sadrian{ 174236834Sadrian int i, w, width; 175236834Sadrian 176236834Sadrian width = 0; 177236834Sadrian for (i = 0; i < sf->nstats; i++) { 178236834Sadrian w = strlen(sf->stats[i].name); 179236834Sadrian if (w > width) 180236834Sadrian width = w; 181236834Sadrian } 182236834Sadrian for (i = 0; i < sf->nstats; i++) { 183236834Sadrian const struct fmt *f = &sf->stats[i]; 184236834Sadrian if (f->width != 0) 185236834Sadrian fprintf(fd, "%-*s %s\n", width, f->name, f->desc); 186236834Sadrian } 187236834Sadrian} 188236834Sadrian 189236834Sadrianvoid 190236834Sadrianstatfoo_init(struct statfoo *sf, const char *name, const struct fmt *stats, int nstats) 191236834Sadrian{ 192236834Sadrian sf->name = name; 193236834Sadrian sf->stats = stats; 194236834Sadrian sf->nstats = nstats; 195236834Sadrian sf->setfmt = statfoo_setfmt; 196236834Sadrian sf->collect_cur = statfoo_collect; 197236834Sadrian sf->collect_tot = statfoo_collect; 198236834Sadrian sf->update_tot = statfoo_update_tot; 199236834Sadrian sf->get_curstat = statfoo_get; 200236834Sadrian sf->get_totstat = statfoo_get; 201236834Sadrian sf->print_header = statfoo_print_header; 202236834Sadrian sf->print_current = statfoo_print_current; 203236834Sadrian sf->print_total = statfoo_print_total; 204236834Sadrian sf->print_verbose = statfoo_print_verbose; 205236834Sadrian sf->print_fields = statfoo_print_fields; 206236834Sadrian} 207