summaryrefslogtreecommitdiffabout
path: root/src/builtin/sprintf.bi
Unidiff
Diffstat (limited to 'src/builtin/sprintf.bi') (more/less context) (ignore whitespace changes)
-rw-r--r--src/builtin/sprintf.bi96
1 files changed, 49 insertions, 47 deletions
diff --git a/src/builtin/sprintf.bi b/src/builtin/sprintf.bi
index 11effd5..0a927dd 100644
--- a/src/builtin/sprintf.bi
+++ b/src/builtin/sprintf.bi
@@ -34,14 +34,15 @@ typedef enum {
34 fmts_conv /* Expect conversion specifier */ 34 fmts_conv /* Expect conversion specifier */
35} printf_format_state; 35} printf_format_state;
36 36
37char * 37static int
38get_num(char *p, unsigned *pn) 38get_num(const char *p, int i, unsigned *pn)
39{ 39{
40 unsigned n = 0; 40 unsigned n = 0;
41 for (; *p && mu_isdigit(*p); p++) 41
42 n = n * 10 + *p - '0'; 42 for (; p[i] && mu_isdigit(p[i]); i++)
43 n = n * 10 + p[i] - '0';
43 *pn = n; 44 *pn = n;
44 return p; 45 return i;
45} 46}
46 47
47#define __MF_MAX(a,b) ((a)>(b) ? (a) : (b)) 48#define __MF_MAX(a,b) ((a)>(b) ? (a) : (b))
@@ -50,8 +51,8 @@ get_num(char *p, unsigned *pn)
50MF_DEFUN_VARARGS_NO_PROM(sprintf, STRING, STRING format) 51MF_DEFUN_VARARGS_NO_PROM(sprintf, STRING, STRING format)
51{ 52{
52 int i = 0; 53 int i = 0;
53 char *p = format; 54 int cur = 0;
54 char *start; 55 int start;
55 char buf[SPRINTF_BUF_SIZE]; 56 char buf[SPRINTF_BUF_SIZE];
56 printf_format_state state = fmts_copy; 57 printf_format_state state = fmts_copy;
57 int flags = 0; 58 int flags = 0;
@@ -61,7 +62,7 @@ MF_DEFUN_VARARGS_NO_PROM(sprintf, STRING, STRING format)
61 62
62 MF_OBSTACK_BEGIN(); 63 MF_OBSTACK_BEGIN();
63 MF_VA_START(); 64 MF_VA_START();
64 while (*p) { 65 while (format[cur]) {
65 unsigned n; 66 unsigned n;
66 char *str; 67 char *str;
67 long num; 68 long num;
@@ -71,31 +72,31 @@ MF_DEFUN_VARARGS_NO_PROM(sprintf, STRING, STRING format)
71 switch (state) { 72 switch (state) {
72 case fmts_copy: 73 case fmts_copy:
73 /* Expect `%', and copy all the rest verbatim */ 74 /* Expect `%', and copy all the rest verbatim */
74 if (*p == '%') { 75 if (format[cur] == '%') {
75 start = p; 76 start = cur;
76 state = fmts_pos; 77 state = fmts_pos;
77 flags = 0; 78 flags = 0;
78 width = 0; 79 width = 0;
79 prec = 0; 80 prec = 0;
80 } else 81 } else
81 MF_OBSTACK_1GROW(*p); 82 MF_OBSTACK_1GROW(format[cur]);
82 p++; 83 cur++;
83 break; 84 break;
84 85
85 case fmts_pos: 86 case fmts_pos:
86 /* Expect '%' or an argument position -- %_% or %_2$ */ 87 /* Expect '%' or an argument position -- %_% or %_2$ */
87 if (*p == '%') { 88 if (format[cur] == '%') {
88 MF_OBSTACK_1GROW('%'); 89 MF_OBSTACK_1GROW('%');
89 p++; 90 cur++;
90 state = fmts_copy; 91 state = fmts_copy;
91 break; 92 break;
92 } 93 }
93 if (mu_isdigit(*p)) { 94 if (mu_isdigit(format[cur])) {
94 char *q = get_num(p, &n); 95 int pos = get_num(format, cur, &n);
95 if (*q == '$') { 96 if (format[pos] == '$') {
96 argnum = n - 1; 97 argnum = n - 1;
97 flags |= FMT_ALTPOS; 98 flags |= FMT_ALTPOS;
98 p = q + 1; 99 cur = pos + 1;
99 } 100 }
100 } 101 }
101 state = fmts_flags; 102 state = fmts_flags;
@@ -103,30 +104,30 @@ MF_DEFUN_VARARGS_NO_PROM(sprintf, STRING, STRING format)
103 104
104 case fmts_flags: 105 case fmts_flags:
105 /* Expect flags -- %2$_# */ 106 /* Expect flags -- %2$_# */
106 switch (*p) { 107 switch (format[cur]) {
107 case '#': 108 case '#':
108 flags |= FMT_ALTERNATE; 109 flags |= FMT_ALTERNATE;
109 p++; 110 cur++;
110 break; 111 break;
111 112
112 case '0': 113 case '0':
113 flags |= FMT_PADZERO; 114 flags |= FMT_PADZERO;
114 p++; 115 cur++;
115 break; 116 break;
116 117
117 case '-': 118 case '-':
118 flags |= FMT_ADJUST_LEFT; 119 flags |= FMT_ADJUST_LEFT;
119 p++; 120 cur++;
120 break; 121 break;
121 122
122 case ' ': 123 case ' ':
123 flags |= FMT_SPACEPFX; 124 flags |= FMT_SPACEPFX;
124 p++; 125 cur++;
125 break; 126 break;
126 127
127 case '+': 128 case '+':
128 flags |= FMT_SIGNPFX; 129 flags |= FMT_SIGNPFX;
129 p++; 130 cur++;
130 break; 131 break;
131 132
132 default: 133 default:
@@ -136,11 +137,11 @@ MF_DEFUN_VARARGS_NO_PROM(sprintf, STRING, STRING format)
136 137
137 case fmts_width: 138 case fmts_width:
138 /* Expect width -- %2$#_8 or %2$#_* */ 139 /* Expect width -- %2$#_8 or %2$#_* */
139 if (mu_isdigit(*p)) { 140 if (mu_isdigit(format[cur])) {
140 p = get_num(p, &width); 141 cur = get_num(format, cur, &width);
141 state = fmts_prec; 142 state = fmts_prec;
142 } else if (*p == '*') { 143 } else if (format[cur] == '*') {
143 p++; 144 cur++;
144 state = fmts_width_arg; 145 state = fmts_width_arg;
145 } else 146 } else
146 state = fmts_prec; 147 state = fmts_prec;
@@ -149,11 +150,11 @@ MF_DEFUN_VARARGS_NO_PROM(sprintf, STRING, STRING format)
149 case fmts_width_arg: 150 case fmts_width_arg:
150 /* Expect width argument position -- %2$#*_1$ */ 151 /* Expect width argument position -- %2$#*_1$ */
151 state = fmts_prec; 152 state = fmts_prec;
152 if (mu_isdigit(*p)) { 153 if (mu_isdigit(format[cur])) {
153 char *q = get_num(p, &n); 154 int pos = get_num(format, cur, &n);
154 if (*q == '$') { 155 if (format[pos] == '$') {
155 MF_VA_ARG(n-1, NUMBER, num); 156 MF_VA_ARG(n-1, NUMBER, num);
156 p = q + 1; 157 cur = pos + 1;
157 if (num < 0) { 158 if (num < 0) {
158 flags |= FMT_SPACEPFX; 159 flags |= FMT_SPACEPFX;
159 num = - num; 160 num = - num;
@@ -176,12 +177,12 @@ MF_DEFUN_VARARGS_NO_PROM(sprintf, STRING, STRING format)
176 case fmts_prec: 177 case fmts_prec:
177 /* Expect precision -- %2$#*1$_. */ 178 /* Expect precision -- %2$#*1$_. */
178 state = fmts_conv; 179 state = fmts_conv;
179 if (*p == '.') { 180 if (format[cur] == '.') {
180 p++; 181 cur++;
181 if (mu_isdigit(*p)) { 182 if (mu_isdigit(format[cur])) {
182 p = get_num(p, &prec); 183 cur = get_num(format, cur, &prec);
183 } else if (*p == '*') { 184 } else if (format[cur] == '*') {
184 p++; 185 cur++;
185 state = fmts_prec_arg; 186 state = fmts_prec_arg;
186 } 187 }
187 } 188 }
@@ -191,13 +192,13 @@ MF_DEFUN_VARARGS_NO_PROM(sprintf, STRING, STRING format)
191 /* Expect precision argument position -- 192 /* Expect precision argument position --
192 %2$#*1$.*_3$ */ 193 %2$#*1$.*_3$ */
193 state = fmts_conv; 194 state = fmts_conv;
194 if (mu_isdigit(*p)) { 195 if (mu_isdigit(format[cur])) {
195 char *q = get_num(p, &n); 196 int pos = get_num(format, cur, &n);
196 if (*q == '$') { 197 if (format[pos] == '$') {
197 MF_VA_ARG(n-1, NUMBER, num); 198 MF_VA_ARG(n-1, NUMBER, num);
198 if (num > 0) 199 if (num > 0)
199 prec = (unsigned) num; 200 prec = (unsigned) num;
200 p = q + 1; 201 cur = pos + 1;
201 break; 202 break;
202 } 203 }
203 } 204 }
@@ -210,7 +211,7 @@ MF_DEFUN_VARARGS_NO_PROM(sprintf, STRING, STRING format)
210 case fmts_conv: /* Expect conversion specifier */ 211 case fmts_conv: /* Expect conversion specifier */
211 if (!(flags & FMT_ALTPOS)) 212 if (!(flags & FMT_ALTPOS))
212 argnum = i++; 213 argnum = i++;
213 switch (*p) { 214 switch (format[cur]) {
214 case 's': 215 case 's':
215 MF_VA_ARG(argnum, STRING, str); 216 MF_VA_ARG(argnum, STRING, str);
216 n = strlen(str); 217 n = strlen(str);
@@ -331,7 +332,7 @@ MF_DEFUN_VARARGS_NO_PROM(sprintf, STRING, STRING format)
331 /* A - overrides a 0 if both are given.*/ 332 /* A - overrides a 0 if both are given.*/
332 if (prec || (flags & FMT_ADJUST_LEFT)) 333 if (prec || (flags & FMT_ADJUST_LEFT))
333 flags &= ~FMT_PADZERO; 334 flags &= ~FMT_PADZERO;
334 fmtbuf[1] = *p; 335 fmtbuf[1] = format[cur];
335 snprintf(buf+2, sizeof(buf)-2, fmtbuf, num); 336 snprintf(buf+2, sizeof(buf)-2, fmtbuf, num);
336 str = buf + 2; 337 str = buf + 2;
337 n = strlen(str); 338 n = strlen(str);
@@ -342,7 +343,7 @@ MF_DEFUN_VARARGS_NO_PROM(sprintf, STRING, STRING format)
342 } 343 }
343 344
344 if (flags & FMT_ALTERNATE) { 345 if (flags & FMT_ALTERNATE) {
345 *--str = *p; 346 *--str = format[cur];
346 *--str = '0'; 347 *--str = '0';
347 n += 2; 348 n += 2;
348 } 349 }
@@ -406,10 +407,11 @@ MF_DEFUN_VARARGS_NO_PROM(sprintf, STRING, STRING format)
406 break; 407 break;
407 408
408 default: 409 default:
409 MF_OBSTACK_GROW(start, p - start + 1); 410 MF_OBSTACK_GROW(&format[start],
411 cur - start + 1);
410 } 412 }
411 413
412 p++; 414 cur++;
413 state = fmts_copy; 415 state = fmts_copy;
414 } 416 }
415 } 417 }

Return to:

Send suggestions and report system problems to the System administrator.