xref: /onnv-gate/usr/src/lib/libast/common/string/fmtfmt.c (revision 12068:08a39a083754)
14887Schin /***********************************************************************
24887Schin *                                                                      *
34887Schin *               This software is part of the ast package               *
4*12068SRoger.Faulkner@Oracle.COM *          Copyright (c) 1985-2010 AT&T Intellectual Property          *
54887Schin *                      and is licensed under the                       *
64887Schin *                  Common Public License, Version 1.0                  *
78462SApril.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 /*
254887Schin  * Glenn Fowler
264887Schin  * AT&T Research
274887Schin  *
284887Schin  * return printf(3) format signature given format string
294887Schin  * the format signature contains one char per format optionally preceded
304887Schin  * by the number of `*' args
314887Schin  *	c	char
324887Schin  *	d	double
334887Schin  *	D	long double
344887Schin  *	f	float
354887Schin  *	h	short
364887Schin  *	i	int
374887Schin  *	j	long long
384887Schin  *	l	long
394887Schin  *	p	void*
404887Schin  *	s	string
414887Schin  *	t	ptrdiff_t
424887Schin  *	z	size_t
434887Schin  *	?	unknown
444887Schin  */
454887Schin 
464887Schin #include <ast.h>
474887Schin #include <ctype.h>
484887Schin 
494887Schin char*
fmtfmt(const char * as)504887Schin fmtfmt(const char* as)
514887Schin {
524887Schin 	register char*	s = (char*)as;
534887Schin 	char*		buf;
544887Schin 	int		i;
554887Schin 	int		c;
564887Schin 	int		a;
574887Schin 	int		q;
584887Schin 	int		x;
594887Schin 	int		t;
604887Schin 	int		m;
614887Schin 	int		n;
624887Schin 	int		z;
634887Schin 	char		formats[256];
644887Schin 	unsigned int	extra[elementsof(formats)];
654887Schin 
664887Schin 	z = 1;
674887Schin 	i = m = 0;
684887Schin 	for (;;)
694887Schin 	{
704887Schin 		switch (*s++)
714887Schin 		{
724887Schin 		case 0:
734887Schin 			break;
744887Schin 		case '%':
754887Schin 			if (*s == '%')
764887Schin 				continue;
774887Schin 			n = 0;
784887Schin 			a = 0;
794887Schin 			q = 0;
804887Schin 			t = '?';
814887Schin 			x = 0;
824887Schin 			for (;;)
834887Schin 			{
844887Schin 				switch (c = *s++)
854887Schin 				{
864887Schin 				case 0:
874887Schin 					s--;
884887Schin 					break;
894887Schin 				case '(':
904887Schin 					q++;
914887Schin 					continue;
924887Schin 				case ')':
934887Schin 					if (--q <= 0)
944887Schin 						n = 0;
954887Schin 					continue;
964887Schin 				case '0': case '1': case '2': case '3':
974887Schin 				case '4': case '5': case '6': case '7':
984887Schin 				case '8': case '9':
994887Schin 					n = n * 10 + (c - '0');
1004887Schin 					continue;
1014887Schin 				case '$':
1024887Schin 					a = n;
1034887Schin 					n = 0;
1044887Schin 					continue;
1054887Schin 				case '*':
1064887Schin 					x++;
1074887Schin 					n = 0;
1084887Schin 					continue;
1094887Schin 				case 'h':
1104887Schin 					if (!q)
1114887Schin 						t = t == 'h' ? 'c' : 'h';
1124887Schin 					continue;
1134887Schin 				case 'l':
1144887Schin 					if (!q)
1154887Schin 						t = t == 'l' ? 'j' : 'l';
1164887Schin 					continue;
1174887Schin 				case 'j':
1184887Schin 				case 't':
1194887Schin 				case 'z':
1204887Schin 					if (!q)
1214887Schin 						t = c;
1224887Schin 					continue;
1234887Schin 				case 'c':
1244887Schin 				case 'p':
1254887Schin 				case 's':
1264887Schin 					if (!q)
1274887Schin 					{
1284887Schin 						t = c;
1294887Schin 						break;
1304887Schin 					}
1314887Schin 					continue;
1324887Schin 				case 'e':
1334887Schin 				case 'g':
1344887Schin 					if (!q)
1354887Schin 					{
1364887Schin 						switch (t)
1374887Schin 						{
1384887Schin 						case 'j':
1394887Schin 							t = 'D';
1404887Schin 							break;
1414887Schin 						default:
1424887Schin 							t = 'd';
1434887Schin 							break;
1444887Schin 						}
1454887Schin 						break;
1464887Schin 					}
1474887Schin 					continue;
1484887Schin 				case 'f':
1494887Schin 					if (!q)
1504887Schin 					{
1514887Schin 						switch (t)
1524887Schin 						{
1534887Schin 						case 'j':
1544887Schin 							t = 'D';
1554887Schin 							break;
1564887Schin 						case 'l':
1574887Schin 							t = 'd';
1584887Schin 							break;
1594887Schin 						default:
1604887Schin 							t = c;
1614887Schin 							break;
1624887Schin 						}
1634887Schin 						break;
1644887Schin 					}
1654887Schin 					continue;
1664887Schin 				default:
1674887Schin 					if (!q && isalpha(c))
1684887Schin 					{
1694887Schin 						if (t == '?')
1704887Schin 							t = 'i';
1714887Schin 						break;
1724887Schin 					}
1734887Schin 					n = 0;
1744887Schin 					continue;
1754887Schin 				}
1764887Schin 				break;
1774887Schin 			}
1784887Schin 			if (a)
1794887Schin 				i = a;
1804887Schin 			else
1814887Schin 				i++;
1824887Schin 			if (i < elementsof(formats))
1834887Schin 			{
1844887Schin 				formats[i] = t;
1854887Schin 				if (extra[i] = x)
1864887Schin 					do z++; while (x /= 10);
1874887Schin 				if (m < i)
1884887Schin 					m = i;
1894887Schin 			}
1904887Schin 			continue;
1914887Schin 		default:
1924887Schin 			continue;
1934887Schin 		}
1944887Schin 		break;
1954887Schin 	}
1964887Schin 	s = buf = fmtbuf(m + z);
1974887Schin 	for (i = 1; i <= m; i++)
1984887Schin 	{
1994887Schin 		if (extra[i])
2004887Schin 			s += sfsprintf(s, 10, "%d", extra[m]);
2014887Schin 		*s++ = formats[i];
2024887Schin 	}
2034887Schin 	*s = 0;
2044887Schin 	return buf;
2054887Schin }
206