xref: /titanic_53/usr/src/contrib/ast/src/lib/libsum/sumlib.c (revision 906afcb89d0412cc073b95c2d701a804a8cdb62c)
1*906afcb8SAndy Fiddaman /***********************************************************************
2*906afcb8SAndy Fiddaman *                                                                      *
3*906afcb8SAndy Fiddaman *               This software is part of the ast package               *
4*906afcb8SAndy Fiddaman *          Copyright (c) 1996-2011 AT&T Intellectual Property          *
5*906afcb8SAndy Fiddaman *                      and is licensed under the                       *
6*906afcb8SAndy Fiddaman *                 Eclipse Public License, Version 1.0                  *
7*906afcb8SAndy Fiddaman *                    by AT&T Intellectual Property                     *
8*906afcb8SAndy Fiddaman *                                                                      *
9*906afcb8SAndy Fiddaman *                A copy of the License is available at                 *
10*906afcb8SAndy Fiddaman *          http://www.eclipse.org/org/documents/epl-v10.html           *
11*906afcb8SAndy Fiddaman *         (with md5 checksum b35adb5213ca9657e911e9befb180842)         *
12*906afcb8SAndy Fiddaman *                                                                      *
13*906afcb8SAndy Fiddaman *              Information and Software Systems Research               *
14*906afcb8SAndy Fiddaman *                            AT&T Research                             *
15*906afcb8SAndy Fiddaman *                           Florham Park NJ                            *
16*906afcb8SAndy Fiddaman *                                                                      *
17*906afcb8SAndy Fiddaman *                 Glenn Fowler <gsf@research.att.com>                  *
18*906afcb8SAndy Fiddaman *                                                                      *
19*906afcb8SAndy Fiddaman ***********************************************************************/
20*906afcb8SAndy Fiddaman #pragma prototyped
21*906afcb8SAndy Fiddaman /*
22*906afcb8SAndy Fiddaman  * Glenn Fowler
23*906afcb8SAndy Fiddaman  * AT&T Research
24*906afcb8SAndy Fiddaman  *
25*906afcb8SAndy Fiddaman  * man this is sum library
26*906afcb8SAndy Fiddaman  */
27*906afcb8SAndy Fiddaman 
28*906afcb8SAndy Fiddaman static const char id[] = "\n@(#)$Id: sumlib (AT&T Research) 2009-09-28 $\0\n";
29*906afcb8SAndy Fiddaman 
30*906afcb8SAndy Fiddaman #define _SUM_PRIVATE_	\
31*906afcb8SAndy Fiddaman 			struct Method_s*	method;	\
32*906afcb8SAndy Fiddaman 			uintmax_t		total_count;	\
33*906afcb8SAndy Fiddaman 			uintmax_t		total_size;	\
34*906afcb8SAndy Fiddaman 			uintmax_t		size;
35*906afcb8SAndy Fiddaman 
36*906afcb8SAndy Fiddaman #include <sum.h>
37*906afcb8SAndy Fiddaman #include <ctype.h>
38*906afcb8SAndy Fiddaman #include <swap.h>
39*906afcb8SAndy Fiddaman #include <hashpart.h>
40*906afcb8SAndy Fiddaman 
41*906afcb8SAndy Fiddaman #define SCALE(n,m)	(((n)+(m)-1)/(m))
42*906afcb8SAndy Fiddaman 
43*906afcb8SAndy Fiddaman typedef struct Method_s
44*906afcb8SAndy Fiddaman {
45*906afcb8SAndy Fiddaman 	const char*	match;
46*906afcb8SAndy Fiddaman 	const char*	description;
47*906afcb8SAndy Fiddaman 	const char*	options;
48*906afcb8SAndy Fiddaman 	Sum_t*		(*open)(const struct Method_s*, const char*);
49*906afcb8SAndy Fiddaman 	int		(*init)(Sum_t*);
50*906afcb8SAndy Fiddaman 	int		(*block)(Sum_t*, const void*, size_t);
51*906afcb8SAndy Fiddaman 	int		(*data)(Sum_t*, Sumdata_t*);
52*906afcb8SAndy Fiddaman 	int		(*print)(Sum_t*, Sfio_t*, int, size_t);
53*906afcb8SAndy Fiddaman 	int		(*done)(Sum_t*);
54*906afcb8SAndy Fiddaman 	int		scale;
55*906afcb8SAndy Fiddaman } Method_t;
56*906afcb8SAndy Fiddaman 
57*906afcb8SAndy Fiddaman typedef struct Map_s
58*906afcb8SAndy Fiddaman {
59*906afcb8SAndy Fiddaman 	const char*	match;
60*906afcb8SAndy Fiddaman 	const char*	description;
61*906afcb8SAndy Fiddaman 	const char*	map;
62*906afcb8SAndy Fiddaman } Map_t;
63*906afcb8SAndy Fiddaman 
64*906afcb8SAndy Fiddaman /*
65*906afcb8SAndy Fiddaman  * 16 and 32 bit common code
66*906afcb8SAndy Fiddaman  */
67*906afcb8SAndy Fiddaman 
68*906afcb8SAndy Fiddaman #define _INTEGRAL_PRIVATE_ \
69*906afcb8SAndy Fiddaman 	uint32_t	sum; \
70*906afcb8SAndy Fiddaman 	uint32_t	total_sum;
71*906afcb8SAndy Fiddaman 
72*906afcb8SAndy Fiddaman typedef struct Integral_s
73*906afcb8SAndy Fiddaman {
74*906afcb8SAndy Fiddaman 	_SUM_PUBLIC_
75*906afcb8SAndy Fiddaman 	_SUM_PRIVATE_
76*906afcb8SAndy Fiddaman 	_INTEGRAL_PRIVATE_
77*906afcb8SAndy Fiddaman } Integral_t;
78*906afcb8SAndy Fiddaman 
79*906afcb8SAndy Fiddaman static Sum_t*
long_open(const Method_t * method,const char * name)80*906afcb8SAndy Fiddaman long_open(const Method_t* method, const char* name)
81*906afcb8SAndy Fiddaman {
82*906afcb8SAndy Fiddaman 	Integral_t*	p;
83*906afcb8SAndy Fiddaman 
84*906afcb8SAndy Fiddaman 	if (p = newof(0, Integral_t, 1, 0))
85*906afcb8SAndy Fiddaman 	{
86*906afcb8SAndy Fiddaman 		p->method = (Method_t*)method;
87*906afcb8SAndy Fiddaman 		p->name = name;
88*906afcb8SAndy Fiddaman 	}
89*906afcb8SAndy Fiddaman 	return (Sum_t*)p;
90*906afcb8SAndy Fiddaman }
91*906afcb8SAndy Fiddaman 
92*906afcb8SAndy Fiddaman static int
long_init(Sum_t * p)93*906afcb8SAndy Fiddaman long_init(Sum_t* p)
94*906afcb8SAndy Fiddaman {
95*906afcb8SAndy Fiddaman 	((Integral_t*)p)->sum = 0;
96*906afcb8SAndy Fiddaman 	return 0;
97*906afcb8SAndy Fiddaman }
98*906afcb8SAndy Fiddaman 
99*906afcb8SAndy Fiddaman static int
long_done(Sum_t * p)100*906afcb8SAndy Fiddaman long_done(Sum_t* p)
101*906afcb8SAndy Fiddaman {
102*906afcb8SAndy Fiddaman 	register Integral_t*	x = (Integral_t*)p;
103*906afcb8SAndy Fiddaman 
104*906afcb8SAndy Fiddaman 	x->total_sum ^= (x->sum &= 0xffffffff);
105*906afcb8SAndy Fiddaman 	return 0;
106*906afcb8SAndy Fiddaman }
107*906afcb8SAndy Fiddaman 
108*906afcb8SAndy Fiddaman static int
short_done(Sum_t * p)109*906afcb8SAndy Fiddaman short_done(Sum_t* p)
110*906afcb8SAndy Fiddaman {
111*906afcb8SAndy Fiddaman 	register Integral_t*	x = (Integral_t*)p;
112*906afcb8SAndy Fiddaman 
113*906afcb8SAndy Fiddaman 	x->total_sum ^= (x->sum &= 0xffff);
114*906afcb8SAndy Fiddaman 	return 0;
115*906afcb8SAndy Fiddaman }
116*906afcb8SAndy Fiddaman 
117*906afcb8SAndy Fiddaman static int
long_print(Sum_t * p,Sfio_t * sp,register int flags,size_t scale)118*906afcb8SAndy Fiddaman long_print(Sum_t* p, Sfio_t* sp, register int flags, size_t scale)
119*906afcb8SAndy Fiddaman {
120*906afcb8SAndy Fiddaman 	register Integral_t*	x = (Integral_t*)p;
121*906afcb8SAndy Fiddaman 	register uint32_t	c;
122*906afcb8SAndy Fiddaman 	register uintmax_t	z;
123*906afcb8SAndy Fiddaman 	register size_t		n;
124*906afcb8SAndy Fiddaman 
125*906afcb8SAndy Fiddaman 	c = (flags & SUM_TOTAL) ? x->total_sum : x->sum;
126*906afcb8SAndy Fiddaman 	sfprintf(sp, "%.*I*u", (flags & SUM_LEGACY) ? 5 : 1, sizeof(c), c);
127*906afcb8SAndy Fiddaman 	if (flags & SUM_SIZE)
128*906afcb8SAndy Fiddaman 	{
129*906afcb8SAndy Fiddaman 		z = (flags & SUM_TOTAL) ? x->total_size : x->size;
130*906afcb8SAndy Fiddaman 		if ((flags & SUM_SCALE) && ((n = scale) || (n = x->method->scale)))
131*906afcb8SAndy Fiddaman 			z = SCALE(z, n);
132*906afcb8SAndy Fiddaman 		sfprintf(sp, " %*I*u", (flags & SUM_LEGACY) ? 6 : 0, sizeof(z), z);
133*906afcb8SAndy Fiddaman 	}
134*906afcb8SAndy Fiddaman 	if (flags & SUM_TOTAL)
135*906afcb8SAndy Fiddaman 		sfprintf(sp, " %*I*u", (flags & SUM_LEGACY) ? 6 : 0, sizeof(x->total_count), x->total_count);
136*906afcb8SAndy Fiddaman 	return 0;
137*906afcb8SAndy Fiddaman }
138*906afcb8SAndy Fiddaman 
139*906afcb8SAndy Fiddaman static int
long_data(Sum_t * p,Sumdata_t * data)140*906afcb8SAndy Fiddaman long_data(Sum_t* p, Sumdata_t* data)
141*906afcb8SAndy Fiddaman {
142*906afcb8SAndy Fiddaman 	register Integral_t*	x = (Integral_t*)p;
143*906afcb8SAndy Fiddaman 
144*906afcb8SAndy Fiddaman 	data->size = sizeof(data->num);
145*906afcb8SAndy Fiddaman 	data->num = x->sum;
146*906afcb8SAndy Fiddaman 	data->buf = 0;
147*906afcb8SAndy Fiddaman 	return 0;
148*906afcb8SAndy Fiddaman }
149*906afcb8SAndy Fiddaman 
150*906afcb8SAndy Fiddaman #include "FEATURE/sum"
151*906afcb8SAndy Fiddaman 
152*906afcb8SAndy Fiddaman #include "sum-att.c"
153*906afcb8SAndy Fiddaman #include "sum-ast4.c"
154*906afcb8SAndy Fiddaman #include "sum-bsd.c"
155*906afcb8SAndy Fiddaman #include "sum-crc.c"
156*906afcb8SAndy Fiddaman #include "sum-prng.c"
157*906afcb8SAndy Fiddaman 
158*906afcb8SAndy Fiddaman #if _LIB_md && _lib_MD5Init && _hdr_md5 && _lib_SHA2Init && _hdr_sha2
159*906afcb8SAndy Fiddaman 
160*906afcb8SAndy Fiddaman #include "sum-lmd.c"
161*906afcb8SAndy Fiddaman 
162*906afcb8SAndy Fiddaman #else
163*906afcb8SAndy Fiddaman 
164*906afcb8SAndy Fiddaman #include "sum-md5.c"
165*906afcb8SAndy Fiddaman #include "sum-sha1.c"
166*906afcb8SAndy Fiddaman #include "sum-sha2.c"
167*906afcb8SAndy Fiddaman 
168*906afcb8SAndy Fiddaman #endif
169*906afcb8SAndy Fiddaman 
170*906afcb8SAndy Fiddaman /*
171*906afcb8SAndy Fiddaman  * now the library interface
172*906afcb8SAndy Fiddaman  */
173*906afcb8SAndy Fiddaman 
174*906afcb8SAndy Fiddaman #undef	METHOD		/* solaris <sys/localedef.h>! */
175*906afcb8SAndy Fiddaman #define METHOD(x)	x##_match,x##_description,x##_options,x##_open,x##_init,x##_block,x##_data,x##_print,x##_done,x##_scale
176*906afcb8SAndy Fiddaman 
177*906afcb8SAndy Fiddaman static const Method_t	methods[] =
178*906afcb8SAndy Fiddaman {
179*906afcb8SAndy Fiddaman 	METHOD(att),
180*906afcb8SAndy Fiddaman 	METHOD(ast4),
181*906afcb8SAndy Fiddaman 	METHOD(bsd),
182*906afcb8SAndy Fiddaman 	METHOD(crc),
183*906afcb8SAndy Fiddaman 	METHOD(prng),
184*906afcb8SAndy Fiddaman #ifdef md4_description
185*906afcb8SAndy Fiddaman 	METHOD(md4),
186*906afcb8SAndy Fiddaman #endif
187*906afcb8SAndy Fiddaman #ifdef md5_description
188*906afcb8SAndy Fiddaman 	METHOD(md5),
189*906afcb8SAndy Fiddaman #endif
190*906afcb8SAndy Fiddaman #ifdef sha1_description
191*906afcb8SAndy Fiddaman 	METHOD(sha1),
192*906afcb8SAndy Fiddaman #endif
193*906afcb8SAndy Fiddaman #ifdef sha256_description
194*906afcb8SAndy Fiddaman 	METHOD(sha256),
195*906afcb8SAndy Fiddaman #endif
196*906afcb8SAndy Fiddaman #ifdef sha384_description
197*906afcb8SAndy Fiddaman 	METHOD(sha384),
198*906afcb8SAndy Fiddaman #endif
199*906afcb8SAndy Fiddaman #ifdef sha512_description
200*906afcb8SAndy Fiddaman 	METHOD(sha512),
201*906afcb8SAndy Fiddaman #endif
202*906afcb8SAndy Fiddaman };
203*906afcb8SAndy Fiddaman 
204*906afcb8SAndy Fiddaman static const Map_t	maps[] =
205*906afcb8SAndy Fiddaman {
206*906afcb8SAndy Fiddaman 	{
207*906afcb8SAndy Fiddaman 		"posix|cksum|std|standard",
208*906afcb8SAndy Fiddaman 		"The posix 1003.2-1992 32 bit crc checksum. This is the"
209*906afcb8SAndy Fiddaman 		" default \bcksum\b(1)  method.",
210*906afcb8SAndy Fiddaman 		"crc-0x04c11db7-rotate-done-size"
211*906afcb8SAndy Fiddaman 	},
212*906afcb8SAndy Fiddaman 	{
213*906afcb8SAndy Fiddaman 		"zip",
214*906afcb8SAndy Fiddaman 		"The \bzip\b(1) crc.",
215*906afcb8SAndy Fiddaman 		"crc-0xedb88320-init-done"
216*906afcb8SAndy Fiddaman 	},
217*906afcb8SAndy Fiddaman 	{
218*906afcb8SAndy Fiddaman 		"fddi",
219*906afcb8SAndy Fiddaman 		"The FDDI crc.",
220*906afcb8SAndy Fiddaman 		"crc-0xedb88320-size=0xcc55cc55"
221*906afcb8SAndy Fiddaman 	},
222*906afcb8SAndy Fiddaman 	{
223*906afcb8SAndy Fiddaman 		"fnv|fnv1",
224*906afcb8SAndy Fiddaman 		"The Fowler-Noll-Vo 32 bit PRNG hash with non-zero"
225*906afcb8SAndy Fiddaman 		" initializer (FNV-1).",
226*906afcb8SAndy Fiddaman 		"prng-0x01000193-init=0x811c9dc5"
227*906afcb8SAndy Fiddaman 	},
228*906afcb8SAndy Fiddaman 	{
229*906afcb8SAndy Fiddaman 		"ast|strsum",
230*906afcb8SAndy Fiddaman 		"The \bast\b \bstrsum\b(3) PRNG hash.",
231*906afcb8SAndy Fiddaman 		"prng-0x63c63cd9-add=0x9c39c33d"
232*906afcb8SAndy Fiddaman 	},
233*906afcb8SAndy Fiddaman };
234*906afcb8SAndy Fiddaman 
235*906afcb8SAndy Fiddaman /*
236*906afcb8SAndy Fiddaman  * simple alternation prefix match
237*906afcb8SAndy Fiddaman  */
238*906afcb8SAndy Fiddaman 
239*906afcb8SAndy Fiddaman static int
match(register const char * s,register const char * p)240*906afcb8SAndy Fiddaman match(register const char* s, register const char* p)
241*906afcb8SAndy Fiddaman {
242*906afcb8SAndy Fiddaman 	register const char*	b = s;
243*906afcb8SAndy Fiddaman 
244*906afcb8SAndy Fiddaman 	for (;;)
245*906afcb8SAndy Fiddaman 	{
246*906afcb8SAndy Fiddaman 		do
247*906afcb8SAndy Fiddaman 		{
248*906afcb8SAndy Fiddaman 			if (*p == '|' || *p == 0)
249*906afcb8SAndy Fiddaman 				return 1;
250*906afcb8SAndy Fiddaman 		} while (*s++ == *p++);
251*906afcb8SAndy Fiddaman 		for (;;)
252*906afcb8SAndy Fiddaman 		{
253*906afcb8SAndy Fiddaman 			switch (*p++)
254*906afcb8SAndy Fiddaman 			{
255*906afcb8SAndy Fiddaman 			case 0:
256*906afcb8SAndy Fiddaman 				return 0;
257*906afcb8SAndy Fiddaman 			case '|':
258*906afcb8SAndy Fiddaman 				break;
259*906afcb8SAndy Fiddaman 			default:
260*906afcb8SAndy Fiddaman 				continue;
261*906afcb8SAndy Fiddaman 			}
262*906afcb8SAndy Fiddaman 			break;
263*906afcb8SAndy Fiddaman 		}
264*906afcb8SAndy Fiddaman 		s = b;
265*906afcb8SAndy Fiddaman 	}
266*906afcb8SAndy Fiddaman 	return 0;
267*906afcb8SAndy Fiddaman }
268*906afcb8SAndy Fiddaman 
269*906afcb8SAndy Fiddaman /*
270*906afcb8SAndy Fiddaman  * open sum method name
271*906afcb8SAndy Fiddaman  */
272*906afcb8SAndy Fiddaman 
273*906afcb8SAndy Fiddaman Sum_t*
sumopen(register const char * name)274*906afcb8SAndy Fiddaman sumopen(register const char* name)
275*906afcb8SAndy Fiddaman {
276*906afcb8SAndy Fiddaman 	register int	n;
277*906afcb8SAndy Fiddaman 
278*906afcb8SAndy Fiddaman 	if (!name || !name[0] || name[0] == '-' && !name[1])
279*906afcb8SAndy Fiddaman 		name = "default";
280*906afcb8SAndy Fiddaman 	for (n = 0; n < elementsof(maps); n++)
281*906afcb8SAndy Fiddaman 		if (match(name, maps[n].match))
282*906afcb8SAndy Fiddaman 		{
283*906afcb8SAndy Fiddaman 			name = maps[n].map;
284*906afcb8SAndy Fiddaman 			break;
285*906afcb8SAndy Fiddaman 		}
286*906afcb8SAndy Fiddaman 	for (n = 0; n < elementsof(methods); n++)
287*906afcb8SAndy Fiddaman 		if (match(name, methods[n].match))
288*906afcb8SAndy Fiddaman 			return (*methods[n].open)(&methods[n], name);
289*906afcb8SAndy Fiddaman 	return 0;
290*906afcb8SAndy Fiddaman }
291*906afcb8SAndy Fiddaman 
292*906afcb8SAndy Fiddaman /*
293*906afcb8SAndy Fiddaman  * initialize for a new run of blocks
294*906afcb8SAndy Fiddaman  */
295*906afcb8SAndy Fiddaman 
296*906afcb8SAndy Fiddaman int
suminit(Sum_t * p)297*906afcb8SAndy Fiddaman suminit(Sum_t* p)
298*906afcb8SAndy Fiddaman {
299*906afcb8SAndy Fiddaman 	p->size = 0;
300*906afcb8SAndy Fiddaman 	return (*p->method->init)(p);
301*906afcb8SAndy Fiddaman }
302*906afcb8SAndy Fiddaman 
303*906afcb8SAndy Fiddaman /*
304*906afcb8SAndy Fiddaman  * compute the running sum on buf
305*906afcb8SAndy Fiddaman  */
306*906afcb8SAndy Fiddaman 
307*906afcb8SAndy Fiddaman int
sumblock(Sum_t * p,const void * buf,size_t siz)308*906afcb8SAndy Fiddaman sumblock(Sum_t* p, const void* buf, size_t siz)
309*906afcb8SAndy Fiddaman {
310*906afcb8SAndy Fiddaman 	p->size += siz;
311*906afcb8SAndy Fiddaman 	return (*p->method->block)(p, buf, siz);
312*906afcb8SAndy Fiddaman }
313*906afcb8SAndy Fiddaman 
314*906afcb8SAndy Fiddaman /*
315*906afcb8SAndy Fiddaman  * done with this run of blocks
316*906afcb8SAndy Fiddaman  */
317*906afcb8SAndy Fiddaman 
318*906afcb8SAndy Fiddaman int
sumdone(Sum_t * p)319*906afcb8SAndy Fiddaman sumdone(Sum_t* p)
320*906afcb8SAndy Fiddaman {
321*906afcb8SAndy Fiddaman 	p->total_count++;
322*906afcb8SAndy Fiddaman 	p->total_size += p->size;
323*906afcb8SAndy Fiddaman 	return (*p->method->done)(p);
324*906afcb8SAndy Fiddaman }
325*906afcb8SAndy Fiddaman 
326*906afcb8SAndy Fiddaman /*
327*906afcb8SAndy Fiddaman  * print the sum [size] on sp
328*906afcb8SAndy Fiddaman  */
329*906afcb8SAndy Fiddaman 
330*906afcb8SAndy Fiddaman int
sumprint(Sum_t * p,Sfio_t * sp,int flags,size_t scale)331*906afcb8SAndy Fiddaman sumprint(Sum_t* p, Sfio_t* sp, int flags, size_t scale)
332*906afcb8SAndy Fiddaman {
333*906afcb8SAndy Fiddaman 	return (*p->method->print)(p, sp, flags, scale);
334*906afcb8SAndy Fiddaman }
335*906afcb8SAndy Fiddaman 
336*906afcb8SAndy Fiddaman /*
337*906afcb8SAndy Fiddaman  * return the current sum (internal) data
338*906afcb8SAndy Fiddaman  */
339*906afcb8SAndy Fiddaman 
340*906afcb8SAndy Fiddaman int
sumdata(Sum_t * p,Sumdata_t * d)341*906afcb8SAndy Fiddaman sumdata(Sum_t* p, Sumdata_t* d)
342*906afcb8SAndy Fiddaman {
343*906afcb8SAndy Fiddaman 	return (*p->method->data)(p, d);
344*906afcb8SAndy Fiddaman }
345*906afcb8SAndy Fiddaman 
346*906afcb8SAndy Fiddaman /*
347*906afcb8SAndy Fiddaman  * close an open sum handle
348*906afcb8SAndy Fiddaman  */
349*906afcb8SAndy Fiddaman 
350*906afcb8SAndy Fiddaman int
sumclose(Sum_t * p)351*906afcb8SAndy Fiddaman sumclose(Sum_t* p)
352*906afcb8SAndy Fiddaman {
353*906afcb8SAndy Fiddaman 	free(p);
354*906afcb8SAndy Fiddaman 	return 0;
355*906afcb8SAndy Fiddaman }
356*906afcb8SAndy Fiddaman 
357*906afcb8SAndy Fiddaman /*
358*906afcb8SAndy Fiddaman  * print the checksum method optget(3) usage on sp and return the length
359*906afcb8SAndy Fiddaman  */
360*906afcb8SAndy Fiddaman 
361*906afcb8SAndy Fiddaman int
sumusage(Sfio_t * sp)362*906afcb8SAndy Fiddaman sumusage(Sfio_t* sp)
363*906afcb8SAndy Fiddaman {
364*906afcb8SAndy Fiddaman 	register int	i;
365*906afcb8SAndy Fiddaman 	register int	n;
366*906afcb8SAndy Fiddaman 
367*906afcb8SAndy Fiddaman 	for (i = n = 0; i < elementsof(methods); i++)
368*906afcb8SAndy Fiddaman 	{
369*906afcb8SAndy Fiddaman 		n += sfprintf(sp, "[+%s?%s]", methods[i].match, methods[i].description);
370*906afcb8SAndy Fiddaman 		if (methods[i].options)
371*906afcb8SAndy Fiddaman 			n += sfprintf(sp, "{\n%s\n}", methods[i].options);
372*906afcb8SAndy Fiddaman 	}
373*906afcb8SAndy Fiddaman 	for (i = 0; i < elementsof(maps); i++)
374*906afcb8SAndy Fiddaman 		n += sfprintf(sp, "[+%s?%s Shorthand for \b%s\b.]", maps[i].match, maps[i].description, maps[i].map);
375*906afcb8SAndy Fiddaman 	return n;
376*906afcb8SAndy Fiddaman }
377