diff options
author | Igor Pashev <pashev.igor@gmail.com> | 2012-06-24 22:28:35 +0000 |
---|---|---|
committer | Igor Pashev <pashev.igor@gmail.com> | 2012-06-24 22:28:35 +0000 |
commit | 3950ffe2a485479f6561c27364d3d7df5a21d124 (patch) | |
tree | 468c6e14449d1b1e279222ec32f676b0311917d2 /src/lib/libast/string/fmtfmt.c | |
download | ksh-upstream.tar.gz |
Imported Upstream version 93u+upstream
Diffstat (limited to 'src/lib/libast/string/fmtfmt.c')
-rw-r--r-- | src/lib/libast/string/fmtfmt.c | 205 |
1 files changed, 205 insertions, 0 deletions
diff --git a/src/lib/libast/string/fmtfmt.c b/src/lib/libast/string/fmtfmt.c new file mode 100644 index 0000000..639355b --- /dev/null +++ b/src/lib/libast/string/fmtfmt.c @@ -0,0 +1,205 @@ +/*********************************************************************** +* * +* This software is part of the ast package * +* Copyright (c) 1985-2011 AT&T Intellectual Property * +* and is licensed under the * +* Eclipse Public License, Version 1.0 * +* by AT&T Intellectual Property * +* * +* A copy of the License is available at * +* http://www.eclipse.org/org/documents/epl-v10.html * +* (with md5 checksum b35adb5213ca9657e911e9befb180842) * +* * +* Information and Software Systems Research * +* AT&T Research * +* Florham Park NJ * +* * +* Glenn Fowler <gsf@research.att.com> * +* David Korn <dgk@research.att.com> * +* Phong Vo <kpv@research.att.com> * +* * +***********************************************************************/ +#pragma prototyped + +/* + * Glenn Fowler + * AT&T Research + * + * return printf(3) format signature given format string + * the format signature contains one char per format optionally preceded + * by the number of `*' args + * c char + * d double + * D long double + * f float + * h short + * i int + * j long long + * l long + * p void* + * s string + * t ptrdiff_t + * z size_t + * ? unknown + */ + +#include <ast.h> +#include <ctype.h> + +char* +fmtfmt(const char* as) +{ + register char* s = (char*)as; + char* buf; + int i; + int c; + int a; + int q; + int x; + int t; + int m; + int n; + int z; + char formats[256]; + unsigned int extra[elementsof(formats)]; + + z = 1; + i = m = 0; + for (;;) + { + switch (*s++) + { + case 0: + break; + case '%': + if (*s == '%') + continue; + n = 0; + a = 0; + q = 0; + t = '?'; + x = 0; + for (;;) + { + switch (c = *s++) + { + case 0: + s--; + break; + case '(': + q++; + continue; + case ')': + if (--q <= 0) + n = 0; + continue; + case '0': case '1': case '2': case '3': + case '4': case '5': case '6': case '7': + case '8': case '9': + n = n * 10 + (c - '0'); + continue; + case '$': + a = n; + n = 0; + continue; + case '*': + x++; + n = 0; + continue; + case 'h': + if (!q) + t = t == 'h' ? 'c' : 'h'; + continue; + case 'l': + if (!q) + t = t == 'l' ? 'j' : 'l'; + continue; + case 'j': + case 't': + case 'z': + if (!q) + t = c; + continue; + case 'c': + case 'p': + case 's': + if (!q) + { + t = c; + break; + } + continue; + case 'e': + case 'g': + if (!q) + { + switch (t) + { + case 'j': + t = 'D'; + break; + default: + t = 'd'; + break; + } + break; + } + continue; + case 'f': + if (!q) + { + switch (t) + { + case 'j': + t = 'D'; + break; + case 'l': + t = 'd'; + break; + default: + t = c; + break; + } + break; + } + continue; + default: + if (!q && isalpha(c)) + { + if (t == '?') + t = 'i'; + break; + } + n = 0; + continue; + } + break; + } + if (a) + i = a; + else + i++; + if (i < elementsof(formats)) + { + formats[i] = t; + if (extra[i] = x) + do z++; while (x /= 10); + if (m < i) + m = i; + } + continue; + default: + continue; + } + break; + } + s = buf = fmtbuf(m + z); + for (i = 1; i <= m; i++) + { + if (extra[i]) + s += sfsprintf(s, 10, "%d", extra[m]); + *s++ = formats[i]; + } + *s = 0; + return buf; +} |