Skip to content

Commit 30ae4f4

Browse files
committed
o Adding support for star modifier.
This allows %*s where the leading padding is taken from an extra argument so that this: char buf[] = "0123456789"; printf("'%*s'", 5, &buf[5]); yields '56789'
1 parent c872fc5 commit 30ae4f4

File tree

2 files changed

+44
-19
lines changed

2 files changed

+44
-19
lines changed

test/all.c

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,7 @@ void check(const char *expr, int expected_sz, int actual_sz)
2121
printf("Output %s", actual_buffer);
2222
} else {
2323
failures++;
24-
printf("FAIL %s\n", expr);
25-
26-
if (!size_pass) {
27-
printf("Size fail: expected=%d, actual=%d\n", expected_sz, actual_sz);
28-
}
24+
printf("FAIL printf(%s)\n", expr);
2925

3026
if (!content_pass) {
3127
printf("libc %s\n", expected_buffer);
@@ -85,7 +81,12 @@ void main()
8581

8682
{
8783
char buf[] = "0123456789";
88-
TPRINTF("%*s", 5, &buf[5]);
84+
TPRINTF("%*s", 5, &buf[5]); /* minimum length, too long string */
85+
TPRINTF("%.*s", 5, buf); /* maximum length, too long string */
86+
TPRINTF("%.*s", 5, &buf[8]); /* maximum length, too short string */
87+
TPRINTF("%*.*s", 5, 5, &buf[8]); /* minimum and maximum, too short string*/
88+
TPRINTF("%*.*s", 5, 1, &buf[8]);
89+
TPRINTF("%*.*s", 5, 5, buf);
8990

9091
TPRINTF("%-*d", 5, 123);
9192
TPRINTF("%*d", 5, 123);

tinyprintf.c

Lines changed: 37 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -70,15 +70,16 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
7070
* Implementation
7171
*/
7272
struct param {
73-
char l:1; /**< Add leading character */
74-
char alt:1; /**< alternate form */
75-
char uc:1; /**< Upper case (for base16 only) */
76-
char align_left:1; /**< 0 == align right (default), 1 == align left */
77-
char lchr; /**< Leading character */
78-
unsigned int width; /**< field width */
79-
char sign; /**< The sign to display (if any) */
80-
unsigned int base; /**< number base (e.g.: 8, 10, 16) */
81-
char *bf; /**< Buffer to output */
73+
char l:1; /**< Add leading character */
74+
char alt:1; /**< alternate form */
75+
char uc:1; /**< Upper case (for base16 only) */
76+
char align_left:1; /**< 0 == align right (default), 1 == align left */
77+
char lchr; /**< Leading character */
78+
unsigned int width; /**< field width */
79+
unsigned int precision; /**< field precision */
80+
char sign; /**< The sign to display (if any) */
81+
unsigned int base; /**< number base (e.g.: 8, 10, 16) */
82+
char *bf; /**< Buffer to output */
8283
};
8384

8485

@@ -199,14 +200,19 @@ static char a2u(char ch, const char **src, int base, unsigned int *nump)
199200
return ch;
200201
}
201202

202-
static void putchw(void *putp, putcf putf, struct param *p)
203+
static void putchw(void *putp, putcf putf, const struct param *p)
203204
{
204205
char ch;
205206
int n = p->width;
206207
char *bf = p->bf;
208+
unsigned int precision = p->precision;
209+
210+
if (precision == 0) {
211+
precision = n;
212+
}
207213

208214
/* Number of filling characters */
209-
while (*bf++ && n > 0)
215+
while (*bf++ && n > 0 && precision--)
210216
n--;
211217
if (p->sign)
212218
n--;
@@ -241,7 +247,11 @@ static void putchw(void *putp, putcf putf, struct param *p)
241247

242248
/* Put actual buffer */
243249
bf = p->bf;
244-
while ((ch = *bf++))
250+
precision = p->precision;
251+
if (precision == 0) {
252+
precision = n;
253+
}
254+
while ((ch = *bf++) && precision--)
245255
putf(putp, ch);
246256

247257
/* Fill with space to align to the left, after string */
@@ -260,6 +270,7 @@ void tfp_format(void *putp, putcf putf, const char *fmt, va_list va)
260270
char bf[12]; /* int = 32b on some architectures */
261271
#endif
262272
char ch;
273+
int w;
263274
p.bf = bf;
264275

265276
while ((ch = *(fmt++))) {
@@ -274,6 +285,7 @@ void tfp_format(void *putp, putcf putf, const char *fmt, va_list va)
274285
p.lchr = ' ';
275286
p.alt = 0;
276287
p.width = 0;
288+
p.precision = (unsigned int)-1; /* This turns into a very large number */
277289
p.align_left = 0;
278290
p.sign = 0;
279291

@@ -292,7 +304,13 @@ void tfp_format(void *putp, putcf putf, const char *fmt, va_list va)
292304
p.alt = 1;
293305
continue;
294306
case '*':
295-
p.width = (unsigned int) va_arg(va, int);
307+
w = va_arg(va, int);
308+
if (w < 0) {
309+
p.align_left = 1;
310+
p.width = (unsigned int) -w;
311+
} else {
312+
p.width = (unsigned int) w;
313+
}
296314
continue;
297315
default:
298316
break;
@@ -319,6 +337,12 @@ void tfp_format(void *putp, putcf putf, const char *fmt, va_list va)
319337
if (num > 1) {
320338
p.lchr = '0';
321339
}
340+
} else if (ch == '*') {
341+
ch = *(fmt++);
342+
unsigned int precision = (unsigned int) va_arg(va, int);
343+
if (precision > 0) {
344+
p.precision = precision;
345+
}
322346
}
323347
}
324348

0 commit comments

Comments
 (0)