/***********************************************************************1* *2* This software is part of the ast package *3* Copyright (c) 1985-2011 AT&T Intellectual Property *4* and is licensed under the *5* Eclipse Public License, Version 1.0 *6* by AT&T Intellectual Property *7* *8* A copy of the License is available at *9* http://www.eclipse.org/org/documents/epl-v10.html *10* (with md5 checksum b35adb5213ca9657e911e9befb180842) *11* *12* Information and Software Systems Research *13* AT&T Research *14* Florham Park NJ *15* *16* Glenn Fowler <[email protected]> *17* David Korn <[email protected]> *18* Phong Vo <[email protected]> *19* *20***********************************************************************/21#pragma prototyped2223/*24* Glenn Fowler25* AT&T Research26*27* return printf(3) format signature given format string28* the format signature contains one char per format optionally preceded29* by the number of `*' args30* c char31* d double32* D long double33* f float34* h short35* i int36* j long long37* l long38* p void*39* s string40* t ptrdiff_t41* z size_t42* ? unknown43*/4445#include <ast.h>46#include <ctype.h>4748char*49fmtfmt(const char* as)50{51register char* s = (char*)as;52char* buf;53int i;54int c;55int a;56int q;57int x;58int t;59int m;60int n;61int z;62char formats[256];63unsigned int extra[elementsof(formats)];6465z = 1;66i = m = 0;67for (;;)68{69switch (*s++)70{71case 0:72break;73case '%':74if (*s == '%')75continue;76n = 0;77a = 0;78q = 0;79t = '?';80x = 0;81for (;;)82{83switch (c = *s++)84{85case 0:86s--;87break;88case '(':89q++;90continue;91case ')':92if (--q <= 0)93n = 0;94continue;95case '0': case '1': case '2': case '3':96case '4': case '5': case '6': case '7':97case '8': case '9':98n = n * 10 + (c - '0');99continue;100case '$':101a = n;102n = 0;103continue;104case '*':105x++;106n = 0;107continue;108case 'h':109if (!q)110t = t == 'h' ? 'c' : 'h';111continue;112case 'l':113if (!q)114t = t == 'l' ? 'j' : 'l';115continue;116case 'j':117case 't':118case 'z':119if (!q)120t = c;121continue;122case 'c':123case 'p':124case 's':125if (!q)126{127t = c;128break;129}130continue;131case 'e':132case 'g':133if (!q)134{135switch (t)136{137case 'j':138t = 'D';139break;140default:141t = 'd';142break;143}144break;145}146continue;147case 'f':148if (!q)149{150switch (t)151{152case 'j':153t = 'D';154break;155case 'l':156t = 'd';157break;158default:159t = c;160break;161}162break;163}164continue;165default:166if (!q && isalpha(c))167{168if (t == '?')169t = 'i';170break;171}172n = 0;173continue;174}175break;176}177if (a)178i = a;179else180i++;181if (i < elementsof(formats))182{183formats[i] = t;184if (extra[i] = x)185do z++; while (x /= 10);186if (m < i)187m = i;188}189continue;190default:191continue;192}193break;194}195s = buf = fmtbuf(m + z);196for (i = 1; i <= m; i++)197{198if (extra[i])199s += sfsprintf(s, 10, "%d", extra[m]);200*s++ = formats[i];201}202*s = 0;203return buf;204}205206207