Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
CFLAGS = --std=c99 -O2 -pedantic -Wall -Wextra -Wshadow
CFLAGS += -Wstrict-prototypes -Wmissing-prototypes -Wundef
CFLAGS += -Wpointer-arith -Wcast-align -Wcast-qual -Wredundant-decls

%_check: %.out %.gold
cmp $^
Expand Down
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ Motivation

I was recently working on an embedded project with a STM32 MCU.
The chip had 32kB of flash memory - that's heaps for a microcontroller!
How surprised I was when the linker suddelnly failed saying that
How surprised I was when the linker suddenly failed saying that
the program is too big and won't fit! How come?!

It's just some USB, I2C, GPIO, a few timers ... and snprintf()
Expand Down Expand Up @@ -88,12 +88,13 @@ All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the auhor nor the names of its contributors
* Neither the name of the author nor the names of its contributors
may be used to endorse or promote products derived from this software
without specific prior written permission.

Expand Down
39 changes: 30 additions & 9 deletions mini-printf.c
Original file line number Diff line number Diff line change
Expand Up @@ -53,11 +53,11 @@ mini_strlen(const char *s)

static unsigned int
mini_itoa(int value, unsigned int radix, unsigned int uppercase, unsigned int unsig,
char *buffer, unsigned int zero_pad)
char *buffer, unsigned int zero_pad, unsigned int width)
{
char *pbuffer = buffer;
int negative = 0;
unsigned int i, len;
char *pbuffer = buffer;
int negative = 0;
unsigned int i, len;

/* No support for unusual radixes. */
if (radix > 16)
Expand All @@ -81,6 +81,9 @@ mini_itoa(int value, unsigned int radix, unsigned int uppercase, unsigned int un
if (negative)
*(pbuffer++) = '-';

for (i = (pbuffer - buffer); i < width; i++)
*(pbuffer++) = ' ';

*(pbuffer) = '\0';

/* ... now we reverse it (could do it recursively but will
Expand Down Expand Up @@ -137,18 +140,30 @@ mini_vsnprintf(char *buffer, unsigned int buffer_len, const char *fmt, va_list v
b.pbuffer = buffer;
b.buffer_len = buffer_len;

if (buffer_len > 0) *buffer = 0;

while ((ch=*(fmt++))) {
if ((unsigned int)((b.pbuffer - b.buffer) + 1) >= b.buffer_len)
break;
if (ch!='%')
_putc(ch, &b);
else {
char zero_pad = 0;
unsigned int zero_pad = 0;
char *ptr;
unsigned int len;
unsigned int width = 0;

ch=*(fmt++);
ch=*(fmt++); // step over the %

/* Format width */
if (ch>'0' && ch<='9') {
width = ch-'0';
while (ch=*(fmt++), ch>='0' && ch<='9') {
width = width*10 + ch - '0';
}
if (ch == '\0')
goto end;
}
/* Zero padding requested */
if (ch=='0') {
ch=*(fmt++);
Expand All @@ -165,13 +180,15 @@ mini_vsnprintf(char *buffer, unsigned int buffer_len, const char *fmt, va_list v

case 'u':
case 'd':
len = mini_itoa(va_arg(va, unsigned int), 10, 0, (ch=='u'), bf, zero_pad);
if (width > sizeof bf) width = sizeof bf; /* prevent buffer overflow */
len = mini_itoa(va_arg(va, unsigned int), 10, 0, (ch=='u'), bf, zero_pad, width);
_puts(bf, len, &b);
break;

case 'x':
case 'X':
len = mini_itoa(va_arg(va, unsigned int), 16, (ch=='X'), 1, bf, zero_pad);
if (width > sizeof bf) width = sizeof bf; /* prevent buffer overflow */
len = mini_itoa(va_arg(va, unsigned int), 16, (ch=='X'), 1, bf, zero_pad, width);
_puts(bf, len, &b);
break;

Expand All @@ -181,7 +198,11 @@ mini_vsnprintf(char *buffer, unsigned int buffer_len, const char *fmt, va_list v

case 's' :
ptr = va_arg(va, char*);
_puts(ptr, mini_strlen(ptr), &b);
{
unsigned l = mini_strlen(ptr);
for (unsigned ix=l; ix<width; ix++) _putc(' ', &b);
_puts(ptr, l, &b);
}
break;

default:
Expand Down
31 changes: 26 additions & 5 deletions test1.c
Original file line number Diff line number Diff line change
@@ -1,18 +1,39 @@
#include <stdio.h>
#ifndef _LIBC_REVERT
#include "mini-printf.h"
#define snprintf mini_snprintf
#endif

int main(void)
{
char buff[30];
mini_snprintf(buff, sizeof buff, "testing %d %d %07d", 1, 2, 3);
snprintf(buff, sizeof buff, "testing %d %d %07d", 1, 2, 3);
puts(buff);
mini_snprintf(buff, sizeof buff, "faster %s %ccheaper%c", "and", 34, 34);
snprintf(buff, sizeof buff, "faster %s %ccheaper%c", "and", 34, 34);
puts(buff);
mini_snprintf(buff, sizeof buff, "%x %% %X", 0xdeadf00d, 0xdeadf00d);
snprintf(buff, sizeof buff, "%x %% %X", 0xdeadf00d, 0xdeadf00d);
puts(buff);
mini_snprintf(buff, sizeof buff, "%09d%09d%09d%09d%09d", 1, 2, 3, 4, 5);
snprintf(buff, sizeof buff, "%09d%09d%09d%09d%09d", 1, 2, 3, 4, 5);
puts(buff);
mini_snprintf(buff, sizeof buff, "%d %u %d %u", 50, 50, -50, -50);
snprintf(buff, sizeof buff, "%d %u %d %u", 50, 50, -50, -50);
puts(buff);
snprintf(buff, sizeof buff, "%0");
puts(buff);
snprintf(buff, sizeof buff, "a%0");
puts(buff);
snprintf(buff, sizeof buff, "%");
puts(buff);
snprintf(buff, sizeof buff, "b%");
puts(buff);
snprintf(buff, 0, "%s", "hello");
puts(buff);
snprintf(buff, sizeof buff, "");
puts(buff);
snprintf(buff, sizeof buff, "(%6d) (%12d)", 78, 78);
puts(buff);
snprintf(buff, sizeof buff, "(%s) (%12s) (%s)", "a", "b", "xcccccccccccccccx");
puts(buff);
snprintf(buff, sizeof buff, "(%s)", "xcccccccccccccccx");
puts(buff);
return 0;
}
9 changes: 9 additions & 0 deletions test1.gold
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,12 @@ faster and "cheaper"
deadf00d % DEADF00D
00000000100000000200000000300
50 50 -50 4294967246

a

b
b

( 78) ( 78)
(a) ( b) (xcccccccc
(xcccccccccccccccx)