statfoo.c revision 174244
1161200Ssam/*-
2174244Ssam * Copyright (c) 2002-2007 Sam Leffler, Errno Consulting
3161200Ssam * All rights reserved.
4161200Ssam *
5161200Ssam * Redistribution and use in source and binary forms, with or without
6161200Ssam * modification, are permitted provided that the following conditions
7161200Ssam * are met:
8161200Ssam * 1. Redistributions of source code must retain the above copyright
9161200Ssam *    notice, this list of conditions and the following disclaimer,
10161200Ssam *    without modification.
11161200Ssam * 2. Redistributions in binary form must reproduce at minimum a disclaimer
12161200Ssam *    similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
13161200Ssam *    redistribution must be conditioned upon including a substantially
14161200Ssam *    similar Disclaimer requirement for further binary redistribution.
15161200Ssam *
16161200Ssam * NO WARRANTY
17161200Ssam * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18161200Ssam * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19161200Ssam * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
20161200Ssam * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
21161200Ssam * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
22161200Ssam * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23161200Ssam * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24161200Ssam * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
25161200Ssam * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26161200Ssam * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
27161200Ssam * THE POSSIBILITY OF SUCH DAMAGES.
28161200Ssam *
29161200Ssam * $FreeBSD: head/tools/tools/net80211/wlanstats/statfoo.c 174244 2007-12-04 05:52:01Z sam $
30161200Ssam */
31161200Ssam
32161200Ssam#include <stdio.h>
33161200Ssam#include <string.h>
34161200Ssam
35161200Ssam#include "statfoo.h"
36161200Ssam
37161200Ssamstatic void
38161200Ssamstatfoo_setfmt(struct statfoo *sf, const char *fmt0)
39161200Ssam{
40161200Ssam#define	N(a)	(sizeof(a)/sizeof(a[0]))
41161200Ssam	char fmt[4096];
42161200Ssam	char *fp, *tok;
43161200Ssam	int i, j;
44161200Ssam
45161200Ssam	j = 0;
46161200Ssam	strlcpy(fmt, fmt0, sizeof(fmt));
47161200Ssam	for (fp = fmt; (tok = strsep(&fp, ", ")) != NULL;) {
48161200Ssam		for (i = 0; i < sf->nstats; i++)
49161200Ssam			if (strcasecmp(tok, sf->stats[i].name) == 0)
50161200Ssam				break;
51161200Ssam		if (i >= sf->nstats) {
52161200Ssam			fprintf(stderr, "%s: unknown statistic name \"%s\" "
53161200Ssam				"skipped\n", sf->name, tok);
54161200Ssam			continue;
55161200Ssam		}
56161200Ssam		if (j+3 > sizeof(sf->fmts)) {
57161200Ssam			fprintf(stderr, "%s: not enough room for all stats; "
58161200Ssam				"stopped at %s\n", sf->name, tok);
59161200Ssam			break;
60161200Ssam		}
61161200Ssam		if (j != 0)
62161200Ssam			sf->fmts[j++] = ' ';
63161200Ssam		sf->fmts[j++] = 0x80 | i;
64161200Ssam	}
65161200Ssam	sf->fmts[j] = '\0';
66161200Ssam#undef N
67161200Ssam}
68161200Ssam
69161200Ssamstatic void
70161200Ssamstatfoo_collect(struct statfoo *sf)
71161200Ssam{
72161200Ssam	fprintf(stderr, "%s: don't know how to collect data\n", sf->name);
73161200Ssam}
74161200Ssam
75161200Ssamstatic void
76161200Ssamstatfoo_update_tot(struct statfoo *sf)
77161200Ssam{
78161200Ssam	fprintf(stderr, "%s: don't know how to update total data\n", sf->name);
79161200Ssam}
80161200Ssam
81161200Ssamstatic int
82161200Ssamstatfoo_get(struct statfoo *sf, int s, char b[], size_t bs)
83161200Ssam{
84161200Ssam	fprintf(stderr, "%s: don't know how to get stat #%u\n", sf->name, s);
85161200Ssam	return 0;
86161200Ssam}
87161200Ssam
88161200Ssamstatic void
89161200Ssamstatfoo_print_header(struct statfoo *sf, FILE *fd)
90161200Ssam{
91161200Ssam	const unsigned char *cp;
92161200Ssam
93161200Ssam	for (cp = sf->fmts; *cp != '\0'; cp++) {
94161200Ssam		if (*cp & 0x80) {
95161200Ssam			const struct fmt *f = &sf->stats[*cp &~ 0x80];
96161200Ssam			fprintf(fd, "%*s", f->width, f->label);
97161200Ssam		} else
98161200Ssam			putc(*cp, fd);
99161200Ssam	}
100161200Ssam	putc('\n', fd);
101161200Ssam}
102161200Ssam
103161200Ssamstatic void
104161200Ssamstatfoo_print_current(struct statfoo *sf, FILE *fd)
105161200Ssam{
106161200Ssam	char buf[32];
107161200Ssam	const unsigned char *cp;
108161200Ssam
109161200Ssam	for (cp = sf->fmts; *cp != '\0'; cp++) {
110161200Ssam		if (*cp & 0x80) {
111161200Ssam			const struct fmt *f = &sf->stats[*cp &~ 0x80];
112161200Ssam			if (sf->get_curstat(sf, *cp &~ 0x80, buf, sizeof(buf)))
113161200Ssam				fprintf(fd, "%*s", f->width, buf);
114161200Ssam		} else
115161200Ssam			putc(*cp, fd);
116161200Ssam	}
117161200Ssam	putc('\n', fd);
118161200Ssam}
119161200Ssam
120161200Ssamstatic void
121161200Ssamstatfoo_print_total(struct statfoo *sf, FILE *fd)
122161200Ssam{
123161200Ssam	char buf[32];
124161200Ssam	const unsigned char *cp;
125161200Ssam
126161200Ssam	for (cp = sf->fmts; *cp != '\0'; cp++) {
127161200Ssam		if (*cp & 0x80) {
128161200Ssam			const struct fmt *f = &sf->stats[*cp &~ 0x80];
129161200Ssam			if (sf->get_totstat(sf, *cp &~ 0x80, buf, sizeof(buf)))
130161200Ssam				fprintf(fd, "%*s", f->width, buf);
131161200Ssam		} else
132161200Ssam			putc(*cp, fd);
133161200Ssam	}
134161200Ssam	putc('\n', fd);
135161200Ssam}
136161200Ssam
137161200Ssamstatic void
138161200Ssamstatfoo_print_verbose(struct statfoo *sf, FILE *fd)
139161200Ssam{
140173305Ssam	const struct fmt *f;
141161200Ssam	char s[32];
142173305Ssam	int i, width;
143161200Ssam
144173305Ssam	width = 0;
145161200Ssam	for (i = 0; i < sf->nstats; i++) {
146173305Ssam		f = &sf->stats[i];
147173305Ssam		if (f->width > width)
148173305Ssam			width = f->width;
149173305Ssam	}
150173305Ssam	for (i = 0; i < sf->nstats; i++) {
151173305Ssam		f = &sf->stats[i];
152161200Ssam		if (sf->get_totstat(sf, i, s, sizeof(s)) && strcmp(s, "0"))
153173305Ssam			fprintf(fd, "%-*s %s\n", width, s, f->desc);
154161200Ssam	}
155161200Ssam}
156161200Ssam
157161200Ssamstatic void
158161200Ssamstatfoo_print_fields(struct statfoo *sf, FILE *fd)
159161200Ssam{
160161200Ssam	int i, w, width;
161161200Ssam
162161200Ssam	width = 0;
163161200Ssam	for (i = 0; i < sf->nstats; i++) {
164161200Ssam		w = strlen(sf->stats[i].name);
165161200Ssam		if (w > width)
166161200Ssam			width = w;
167161200Ssam	}
168161200Ssam	for (i = 0; i < sf->nstats; i++) {
169161200Ssam		const struct fmt *f = &sf->stats[i];
170161200Ssam		if (f->width != 0)
171161200Ssam			fprintf(fd, "%-*s %s\n", width, f->name, f->desc);
172161200Ssam	}
173161200Ssam}
174161200Ssam
175161200Ssamvoid
176161200Ssamstatfoo_init(struct statfoo *sf, const char *name, const struct fmt *stats, int nstats)
177161200Ssam{
178161200Ssam	sf->name = name;
179161200Ssam	sf->stats = stats;
180161200Ssam	sf->nstats = nstats;
181161200Ssam	sf->setfmt = statfoo_setfmt;
182161200Ssam	sf->collect_cur = statfoo_collect;
183161200Ssam	sf->collect_tot = statfoo_collect;
184161200Ssam	sf->update_tot = statfoo_update_tot;
185161200Ssam	sf->get_curstat = statfoo_get;
186161200Ssam	sf->get_totstat = statfoo_get;
187161200Ssam	sf->print_header = statfoo_print_header;
188161200Ssam	sf->print_current = statfoo_print_current;
189161200Ssam	sf->print_total = statfoo_print_total;
190161200Ssam	sf->print_verbose = statfoo_print_verbose;
191161200Ssam	sf->print_fields = statfoo_print_fields;
192161200Ssam}
193