14887Schin /***********************************************************************
24887Schin *                                                                      *
34887Schin *               This software is part of the ast package               *
4*8462SApril.Chin@Sun.COM *          Copyright (c) 1985-2008 AT&T Intellectual Property          *
54887Schin *                      and is licensed under the                       *
64887Schin *                  Common Public License, Version 1.0                  *
7*8462SApril.Chin@Sun.COM *                    by AT&T Intellectual Property                     *
84887Schin *                                                                      *
94887Schin *                A copy of the License is available at                 *
104887Schin *            http://www.opensource.org/licenses/cpl1.0.txt             *
114887Schin *         (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9)         *
124887Schin *                                                                      *
134887Schin *              Information and Software Systems Research               *
144887Schin *                            AT&T Research                             *
154887Schin *                           Florham Park NJ                            *
164887Schin *                                                                      *
174887Schin *                 Glenn Fowler <gsf@research.att.com>                  *
184887Schin *                  David Korn <dgk@research.att.com>                   *
194887Schin *                   Phong Vo <kpv@research.att.com>                    *
204887Schin *                                                                      *
214887Schin ***********************************************************************/
224887Schin #pragma prototyped
234887Schin /*
244887Schin  * Glenn Fowler
254887Schin  * AT&T Research
264887Schin  *
274887Schin  * return number n scaled to metric multiples of k { 1000 1024 }
284887Schin  * return string length is at most 5 chars + terminating nul
294887Schin  */
304887Schin 
314887Schin #include <ast.h>
324887Schin #include <lclib.h>
334887Schin 
344887Schin char*
354887Schin fmtscale(register Sfulong_t n, int k)
364887Schin {
374887Schin 	register Sfulong_t	m;
384887Schin 	int			r;
394887Schin 	int			z;
404887Schin 	const char*		u;
414887Schin 	char			suf[3];
424887Schin 	char*			s;
434887Schin 	char*			buf;
444887Schin 	Lc_numeric_t*		p = (Lc_numeric_t*)LCINFO(AST_LC_NUMERIC)->data;
454887Schin 
464887Schin 	static const char	scale[] = "bkMGTPE";
474887Schin 
484887Schin 	u = scale;
494887Schin 	if (n < 1000)
504887Schin 		r = 0;
514887Schin 	else
524887Schin 	{
534887Schin 		m = 0;
544887Schin 		while (n >= k && *(u + 1))
554887Schin 		{
564887Schin 			m = n;
574887Schin 			n /= k;
584887Schin 			u++;
594887Schin 		}
604887Schin 		if ((r = (10 * (m % k) + (k / 2)) / k) > 9)
614887Schin 		{
624887Schin 			r = 0;
634887Schin 			n++;
644887Schin 		}
654887Schin 		if (k == 1024 && n >= 1000)
664887Schin 		{
674887Schin 			n = 1;
684887Schin 			r = 0;
694887Schin 			u++;
704887Schin 		}
714887Schin 	}
724887Schin 	buf = fmtbuf(z = 8);
734887Schin 	s = suf;
744887Schin 	if (u > scale)
754887Schin 	{
764887Schin 		if (k == 1024)
774887Schin 		{
784887Schin 			*s++ = *u == 'k' ? 'K' : *u;
794887Schin 			*s++ = 'i';
804887Schin 		}
814887Schin 		else
824887Schin 			*s++ = *u;
834887Schin 	}
844887Schin 	*s = 0;
854887Schin 	if (n > 0 && n < 10)
864887Schin 		sfsprintf(buf, z, "%I*u%c%d%s", sizeof(n), n, p->decimal >= 0 ? p->decimal : '.', r, suf);
874887Schin 	else
884887Schin 	{
894887Schin 		if (r >= 5)
904887Schin 			n++;
914887Schin 		sfsprintf(buf, z, "%I*u%s", sizeof(n), n, suf);
924887Schin 	}
934887Schin 	return buf;
944887Schin }
95