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