1da2e3ebdSchin /*********************************************************************** 2da2e3ebdSchin * * 3da2e3ebdSchin * This software is part of the ast package * 4*3e14f97fSRoger A. Faulkner * Copyright (c) 1985-2010 AT&T Intellectual Property * 5da2e3ebdSchin * and is licensed under the * 6da2e3ebdSchin * Common Public License, Version 1.0 * 77c2fbfb3SApril Chin * by AT&T Intellectual Property * 8da2e3ebdSchin * * 9da2e3ebdSchin * A copy of the License is available at * 10da2e3ebdSchin * http://www.opensource.org/licenses/cpl1.0.txt * 11da2e3ebdSchin * (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) * 12da2e3ebdSchin * * 13da2e3ebdSchin * Information and Software Systems Research * 14da2e3ebdSchin * AT&T Research * 15da2e3ebdSchin * Florham Park NJ * 16da2e3ebdSchin * * 17da2e3ebdSchin * Glenn Fowler <gsf@research.att.com> * 18da2e3ebdSchin * David Korn <dgk@research.att.com> * 19da2e3ebdSchin * Phong Vo <kpv@research.att.com> * 20da2e3ebdSchin * * 21da2e3ebdSchin ***********************************************************************/ 22da2e3ebdSchin #pragma prototyped 23da2e3ebdSchin 24da2e3ebdSchin /* 25da2e3ebdSchin * Glenn Fowler 26da2e3ebdSchin * AT&T Research 27da2e3ebdSchin * 28da2e3ebdSchin * return printf(3) format signature given format string 29da2e3ebdSchin * the format signature contains one char per format optionally preceded 30da2e3ebdSchin * by the number of `*' args 31da2e3ebdSchin * c char 32da2e3ebdSchin * d double 33da2e3ebdSchin * D long double 34da2e3ebdSchin * f float 35da2e3ebdSchin * h short 36da2e3ebdSchin * i int 37da2e3ebdSchin * j long long 38da2e3ebdSchin * l long 39da2e3ebdSchin * p void* 40da2e3ebdSchin * s string 41da2e3ebdSchin * t ptrdiff_t 42da2e3ebdSchin * z size_t 43da2e3ebdSchin * ? unknown 44da2e3ebdSchin */ 45da2e3ebdSchin 46da2e3ebdSchin #include <ast.h> 47da2e3ebdSchin #include <ctype.h> 48da2e3ebdSchin 49da2e3ebdSchin char* fmtfmt(const char * as)50da2e3ebdSchinfmtfmt(const char* as) 51da2e3ebdSchin { 52da2e3ebdSchin register char* s = (char*)as; 53da2e3ebdSchin char* buf; 54da2e3ebdSchin int i; 55da2e3ebdSchin int c; 56da2e3ebdSchin int a; 57da2e3ebdSchin int q; 58da2e3ebdSchin int x; 59da2e3ebdSchin int t; 60da2e3ebdSchin int m; 61da2e3ebdSchin int n; 62da2e3ebdSchin int z; 63da2e3ebdSchin char formats[256]; 64da2e3ebdSchin unsigned int extra[elementsof(formats)]; 65da2e3ebdSchin 66da2e3ebdSchin z = 1; 67da2e3ebdSchin i = m = 0; 68da2e3ebdSchin for (;;) 69da2e3ebdSchin { 70da2e3ebdSchin switch (*s++) 71da2e3ebdSchin { 72da2e3ebdSchin case 0: 73da2e3ebdSchin break; 74da2e3ebdSchin case '%': 75da2e3ebdSchin if (*s == '%') 76da2e3ebdSchin continue; 77da2e3ebdSchin n = 0; 78da2e3ebdSchin a = 0; 79da2e3ebdSchin q = 0; 80da2e3ebdSchin t = '?'; 81da2e3ebdSchin x = 0; 82da2e3ebdSchin for (;;) 83da2e3ebdSchin { 84da2e3ebdSchin switch (c = *s++) 85da2e3ebdSchin { 86da2e3ebdSchin case 0: 87da2e3ebdSchin s--; 88da2e3ebdSchin break; 89da2e3ebdSchin case '(': 90da2e3ebdSchin q++; 91da2e3ebdSchin continue; 92da2e3ebdSchin case ')': 93da2e3ebdSchin if (--q <= 0) 94da2e3ebdSchin n = 0; 95da2e3ebdSchin continue; 96da2e3ebdSchin case '0': case '1': case '2': case '3': 97da2e3ebdSchin case '4': case '5': case '6': case '7': 98da2e3ebdSchin case '8': case '9': 99da2e3ebdSchin n = n * 10 + (c - '0'); 100da2e3ebdSchin continue; 101da2e3ebdSchin case '$': 102da2e3ebdSchin a = n; 103da2e3ebdSchin n = 0; 104da2e3ebdSchin continue; 105da2e3ebdSchin case '*': 106da2e3ebdSchin x++; 107da2e3ebdSchin n = 0; 108da2e3ebdSchin continue; 109da2e3ebdSchin case 'h': 110da2e3ebdSchin if (!q) 111da2e3ebdSchin t = t == 'h' ? 'c' : 'h'; 112da2e3ebdSchin continue; 113da2e3ebdSchin case 'l': 114da2e3ebdSchin if (!q) 115da2e3ebdSchin t = t == 'l' ? 'j' : 'l'; 116da2e3ebdSchin continue; 117da2e3ebdSchin case 'j': 118da2e3ebdSchin case 't': 119da2e3ebdSchin case 'z': 120da2e3ebdSchin if (!q) 121da2e3ebdSchin t = c; 122da2e3ebdSchin continue; 123da2e3ebdSchin case 'c': 124da2e3ebdSchin case 'p': 125da2e3ebdSchin case 's': 126da2e3ebdSchin if (!q) 127da2e3ebdSchin { 128da2e3ebdSchin t = c; 129da2e3ebdSchin break; 130da2e3ebdSchin } 131da2e3ebdSchin continue; 132da2e3ebdSchin case 'e': 133da2e3ebdSchin case 'g': 134da2e3ebdSchin if (!q) 135da2e3ebdSchin { 136da2e3ebdSchin switch (t) 137da2e3ebdSchin { 138da2e3ebdSchin case 'j': 139da2e3ebdSchin t = 'D'; 140da2e3ebdSchin break; 141da2e3ebdSchin default: 142da2e3ebdSchin t = 'd'; 143da2e3ebdSchin break; 144da2e3ebdSchin } 145da2e3ebdSchin break; 146da2e3ebdSchin } 147da2e3ebdSchin continue; 148da2e3ebdSchin case 'f': 149da2e3ebdSchin if (!q) 150da2e3ebdSchin { 151da2e3ebdSchin switch (t) 152da2e3ebdSchin { 153da2e3ebdSchin case 'j': 154da2e3ebdSchin t = 'D'; 155da2e3ebdSchin break; 156da2e3ebdSchin case 'l': 157da2e3ebdSchin t = 'd'; 158da2e3ebdSchin break; 159da2e3ebdSchin default: 160da2e3ebdSchin t = c; 161da2e3ebdSchin break; 162da2e3ebdSchin } 163da2e3ebdSchin break; 164da2e3ebdSchin } 165da2e3ebdSchin continue; 166da2e3ebdSchin default: 167da2e3ebdSchin if (!q && isalpha(c)) 168da2e3ebdSchin { 169da2e3ebdSchin if (t == '?') 170da2e3ebdSchin t = 'i'; 171da2e3ebdSchin break; 172da2e3ebdSchin } 173da2e3ebdSchin n = 0; 174da2e3ebdSchin continue; 175da2e3ebdSchin } 176da2e3ebdSchin break; 177da2e3ebdSchin } 178da2e3ebdSchin if (a) 179da2e3ebdSchin i = a; 180da2e3ebdSchin else 181da2e3ebdSchin i++; 182da2e3ebdSchin if (i < elementsof(formats)) 183da2e3ebdSchin { 184da2e3ebdSchin formats[i] = t; 185da2e3ebdSchin if (extra[i] = x) 186da2e3ebdSchin do z++; while (x /= 10); 187da2e3ebdSchin if (m < i) 188da2e3ebdSchin m = i; 189da2e3ebdSchin } 190da2e3ebdSchin continue; 191da2e3ebdSchin default: 192da2e3ebdSchin continue; 193da2e3ebdSchin } 194da2e3ebdSchin break; 195da2e3ebdSchin } 196da2e3ebdSchin s = buf = fmtbuf(m + z); 197da2e3ebdSchin for (i = 1; i <= m; i++) 198da2e3ebdSchin { 199da2e3ebdSchin if (extra[i]) 200da2e3ebdSchin s += sfsprintf(s, 10, "%d", extra[m]); 201da2e3ebdSchin *s++ = formats[i]; 202da2e3ebdSchin } 203da2e3ebdSchin *s = 0; 204da2e3ebdSchin return buf; 205da2e3ebdSchin } 206