1238438Sdteske/*- 2238438Sdteske * Copyright (c) 2002-2007 Sam Leffler, Errno Consulting 3238438Sdteske * All rights reserved. 4238438Sdteske * 5238438Sdteske * Redistribution and use in source and binary forms, with or without 6238438Sdteske * modification, are permitted provided that the following conditions 7238438Sdteske * are met: 8238438Sdteske * 1. Redistributions of source code must retain the above copyright 9238438Sdteske * notice, this list of conditions and the following disclaimer, 10238438Sdteske * without modification. 11238438Sdteske * 2. Redistributions in binary form must reproduce at minimum a disclaimer 12238438Sdteske * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any 13238438Sdteske * redistribution must be conditioned upon including a substantially 14238438Sdteske * similar Disclaimer requirement for further binary redistribution. 15238438Sdteske * 16238438Sdteske * NO WARRANTY 17238438Sdteske * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18238438Sdteske * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19238438Sdteske * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY 20238438Sdteske * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 21238438Sdteske * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, 22238438Sdteske * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23238438Sdteske * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24238438Sdteske * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER 25238438Sdteske * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26238438Sdteske * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 27238438Sdteske * THE POSSIBILITY OF SUCH DAMAGES. 28238438Sdteske * 29238438Sdteske * $FreeBSD: releng/10.3/tools/tools/ath/athstats/statfoo.c 231863 2012-02-17 08:24:58Z adrian $ 30238438Sdteske */ 31238438Sdteske 32238438Sdteske#include <stdio.h> 33238438Sdteske#include <string.h> 34238438Sdteske 35238438Sdteske#include "statfoo.h" 36238438Sdteske 37238438Sdteskestatic void 38238438Sdteskestatfoo_setfmt(struct statfoo *sf, const char *fmt0) 39238438Sdteske{ 40238438Sdteske#define N(a) (sizeof(a)/sizeof(a[0])) 41238438Sdteske char fmt[4096]; 42238438Sdteske char *fp, *tok; 43238438Sdteske int i, j; 44238438Sdteske 45238438Sdteske j = 0; 46238438Sdteske strlcpy(fmt, fmt0, sizeof(fmt)); 47238438Sdteske for (fp = fmt; (tok = strsep(&fp, ", ")) != NULL;) { 48238438Sdteske for (i = 0; i < sf->nstats; i++) 49238438Sdteske if (strcasecmp(tok, sf->stats[i].name) == 0) 50238438Sdteske break; 51238438Sdteske if (i >= sf->nstats) { 52238438Sdteske fprintf(stderr, "%s: unknown statistic name \"%s\" " 53238438Sdteske "skipped\n", sf->name, tok); 54238438Sdteske continue; 55238438Sdteske } 56238438Sdteske if (j+3 > sizeof(sf->fmts)) { 57238438Sdteske fprintf(stderr, "%s: not enough room for all stats; " 58238438Sdteske "stopped at %s\n", sf->name, tok); 59238438Sdteske break; 60238438Sdteske } 61238438Sdteske if (j != 0) 62238438Sdteske sf->fmts[j++] = ' '; 63238438Sdteske sf->fmts[j++] = FMTS_IS_STAT; 64238438Sdteske sf->fmts[j++] = i & 0xff; 65238438Sdteske sf->fmts[j++] = (i >> 8) & 0xff; 66238438Sdteske } 67238438Sdteske sf->fmts[j] = '\0'; 68238438Sdteske#undef N 69238438Sdteske} 70238438Sdteske 71238438Sdteskestatic void 72238438Sdteskestatfoo_collect(struct statfoo *sf) 73238438Sdteske{ 74238438Sdteske fprintf(stderr, "%s: don't know how to collect data\n", sf->name); 75238438Sdteske} 76238438Sdteske 77238438Sdteskestatic void 78238438Sdteskestatfoo_update_tot(struct statfoo *sf) 79238438Sdteske{ 80238438Sdteske fprintf(stderr, "%s: don't know how to update total data\n", sf->name); 81238438Sdteske} 82238438Sdteske 83238438Sdteskestatic int 84238438Sdteskestatfoo_get(struct statfoo *sf, int s, char b[], size_t bs) 85238438Sdteske{ 86238438Sdteske fprintf(stderr, "%s: don't know how to get stat #%u\n", sf->name, s); 87238438Sdteske return 0; 88238438Sdteske} 89238438Sdteske 90238438Sdteskestatic void 91238438Sdteskestatfoo_print_header(struct statfoo *sf, FILE *fd) 92238438Sdteske{ 93238438Sdteske const unsigned char *cp; 94238438Sdteske int i; 95238438Sdteske const struct fmt *f; 96238438Sdteske 97238438Sdteske for (cp = sf->fmts; *cp != '\0'; cp++) { 98 if (*cp == FMTS_IS_STAT) { 99 i = *(++cp); 100 i |= ((int) *(++cp)) << 8; 101 f = &sf->stats[i]; 102 fprintf(fd, "%*s", f->width, f->label); 103 } else 104 putc(*cp, fd); 105 } 106 putc('\n', fd); 107} 108 109static void 110statfoo_print_current(struct statfoo *sf, FILE *fd) 111{ 112 char buf[32]; 113 const unsigned char *cp; 114 int i; 115 const struct fmt *f; 116 117 for (cp = sf->fmts; *cp != '\0'; cp++) { 118 if (*cp == FMTS_IS_STAT) { 119 i = *(++cp); 120 i |= ((int) *(++cp)) << 8; 121 f = &sf->stats[i]; 122 if (sf->get_curstat(sf, i, buf, sizeof(buf))) 123 fprintf(fd, "%*s", f->width, buf); 124 } else 125 putc(*cp, fd); 126 } 127 putc('\n', fd); 128} 129 130static void 131statfoo_print_total(struct statfoo *sf, FILE *fd) 132{ 133 char buf[32]; 134 const unsigned char *cp; 135 const struct fmt *f; 136 int i; 137 138 for (cp = sf->fmts; *cp != '\0'; cp++) { 139 if (*cp == FMTS_IS_STAT) { 140 i = *(++cp); 141 i |= ((int) *(++cp)) << 8; 142 f = &sf->stats[i]; 143 if (sf->get_totstat(sf, i, buf, sizeof(buf))) 144 fprintf(fd, "%*s", f->width, buf); 145 } else 146 putc(*cp, fd); 147 } 148 putc('\n', fd); 149} 150 151static void 152statfoo_print_verbose(struct statfoo *sf, FILE *fd) 153{ 154 const struct fmt *f; 155 char s[32]; 156 int i, width; 157 158 width = 0; 159 for (i = 0; i < sf->nstats; i++) { 160 f = &sf->stats[i]; 161 if (f->width > width) 162 width = f->width; 163 } 164 for (i = 0; i < sf->nstats; i++) { 165 f = &sf->stats[i]; 166 if (sf->get_totstat(sf, i, s, sizeof(s)) && strcmp(s, "0")) 167 fprintf(fd, "%-*s %s\n", width, s, f->desc); 168 } 169} 170 171static void 172statfoo_print_fields(struct statfoo *sf, FILE *fd) 173{ 174 int i, w, width; 175 176 width = 0; 177 for (i = 0; i < sf->nstats; i++) { 178 w = strlen(sf->stats[i].name); 179 if (w > width) 180 width = w; 181 } 182 for (i = 0; i < sf->nstats; i++) { 183 const struct fmt *f = &sf->stats[i]; 184 if (f->width != 0) 185 fprintf(fd, "%-*s %s\n", width, f->name, f->desc); 186 } 187} 188 189void 190statfoo_init(struct statfoo *sf, const char *name, const struct fmt *stats, int nstats) 191{ 192 sf->name = name; 193 sf->stats = stats; 194 sf->nstats = nstats; 195 sf->setfmt = statfoo_setfmt; 196 sf->collect_cur = statfoo_collect; 197 sf->collect_tot = statfoo_collect; 198 sf->update_tot = statfoo_update_tot; 199 sf->get_curstat = statfoo_get; 200 sf->get_totstat = statfoo_get; 201 sf->print_header = statfoo_print_header; 202 sf->print_current = statfoo_print_current; 203 sf->print_total = statfoo_print_total; 204 sf->print_verbose = statfoo_print_verbose; 205 sf->print_fields = statfoo_print_fields; 206} 207