#include <sys/time.h>
#include <stdio.h>

static char local_buf[sizeof(long long)*3 + 2];

char *utoa_to_buf(unsigned n, char *buf, int buflen)
{
	char *p;
	if (buflen <= 1) // insanity?
		return buf;
	p = buf + buflen-1;
	*p = '\0';
	do {
		*--p = '0' + n%10;
		n /= 10;
	} while (n && p!=buf);
	return p;
}

char *utoa(unsigned n)
{
	return utoa_to_buf(n, local_buf, sizeof(local_buf));
}

// 0x4f bytes
void utoa_to_buf_rob(unsigned n, char *buf, int buflen)
{
        int i, out = 0;
        for (i=1000000000; i; i/=10) {
                int res = n/i;

                if (res || out || i == 1) {
                        out++;
                        n -= res*i;
                        *buf++ = '0' + res;
                }
        }
        *buf = 0;
}

// 0x28 bytes
static const unsigned pow10[] = {
	1, // 0
	10, // 1
	100, // 2
	1000, // 3
	10000, // 4
	100000, // 5
	1000000, // 6
	10000000, // 7
	100000000, // 8
	1000000000, // 9
};

// 0x41 bytes
void utoa_to_buf_rob2(unsigned n, char *buf, int buflen)
{
        int i = 10;
        while (--i)
                if (n/pow10[i])
			break;
	// Will also handle n==0 case
        while (i>=0) {
                *buf++ = '0' + n/pow10[i];
		// gcc is clever enough to reuse remainder
		// produced from previous division! Wow :)
                n %= pow10[i];
		i--;
        }
        *buf = 0;
}

// 0x4f bytes
extern void BUG_unsupported_arch(void);
void utoa_to_buf_rob2_with_check(unsigned n, char *buf, int buflen)
{
        int i = 10;
	if (sizeof(unsigned) != 4)
		BUG_unsupported_arch();
	if(!buflen)
		return;
	buflen--;
        while (--i)
                if (n/pow10[i])
			break;
	// Will also handle n==0 case
        while (i>=0) {
                char c = '0' + n/pow10[i];
		// gcc is clever enough to reuse remainder
		// produced from previous division! Wow :)
                n %= pow10[i];
		if (i < buflen)
			*buf++ = c;
		i--;
        }
        *buf = '\0';
}

int v = 12345678;

#define REP(a) \
	a a a a  a a a a  a a a a  a a a a \
	a a a a  a a a a  a a a a  a a a a \

int main()
{
	time_t t;
	int count;
	char *p;

	t = time(NULL);
	while(t == time(NULL)) /*wait*/;
	t = time(NULL); count = 0;
	while(t == time(NULL)) {
		REP( sprintf(local_buf, "%d", v); )
		count++;
	}
	printf("sprintf='%s' count=%d\n", local_buf, count);

	t = time(NULL);
	while(t == time(NULL)) /*wait*/;
	t = time(NULL); count = 0;
	while(t == time(NULL)) {
		REP( p = utoa_to_buf(v, local_buf, sizeof(local_buf)); )
		count++;
	}
	printf("utoa_to_buf='%s' count=%d\n", p, count);

	t = time(NULL);
	while(t == time(NULL)) /*wait*/;
	t = time(NULL); count = 0;
	while(t == time(NULL)) {
		REP( p = utoa(v); )
		count++;
	}
	printf("utoa='%s' count=%d\n", p, count);

	t = time(NULL);
	while(t == time(NULL)) /*wait*/;
	t = time(NULL); count = 0;
	while(t == time(NULL)) {
		REP( utoa_to_buf_rob(v, local_buf, sizeof(local_buf)); )
		count++;
	}
	printf("utoa_to_buf_rob='%s' count=%d\n", local_buf, count);

	t = time(NULL);
	while(t == time(NULL)) /*wait*/;
	t = time(NULL); count = 0;
	while(t == time(NULL)) {
		REP( utoa_to_buf_rob2(v, local_buf, sizeof(local_buf)); )
		count++;
	}
	printf("utoa_to_buf_rob2='%s' count=%d\n", local_buf, count);

	v = 0; utoa_to_buf_rob2(v, local_buf, sizeof(local_buf)); printf("utoa_to_buf_rob2(%d)='%s'\n", v, local_buf);
	v = 123; utoa_to_buf_rob2(v, local_buf, sizeof(local_buf)); printf("utoa_to_buf_rob2(%d)='%s'\n", v, local_buf);
	v = 100223; utoa_to_buf_rob2(v, local_buf, sizeof(local_buf)); printf("utoa_to_buf_rob2(%d)='%s'\n", v, local_buf);

	v = 100223; utoa_to_buf_rob2_with_check(v, local_buf, 3); printf("utoa_to_buf_rob2_with_check(%d,3)='%s'\n", v, local_buf);
	v = 100223; utoa_to_buf_rob2_with_check(v, local_buf, 2); printf("utoa_to_buf_rob2_with_check(%d,2)='%s'\n", v, local_buf);
	v = 100223; utoa_to_buf_rob2_with_check(v, local_buf, 1); printf("utoa_to_buf_rob2_with_check(%d,1)='%s'\n", v, local_buf);

	return 0;
}

