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)504887Schinfmtfmt(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