From f4791db17ced58a47164843dd102b781eaed5aa9 Mon Sep 17 00:00:00 2001 From: "psyc://psyced.org/~lynX" <@> Date: Mon, 25 Apr 2011 16:11:47 +0200 Subject: [PATCH] don't use sprintf for rendering numbers --- include/psyc/lib.h | 4 +++ src/Makefile | 7 ++-- src/itoa.c | 85 ++++++++++++++++++++++++++++++++++++++++++++++ src/render.c | 9 +++-- 4 files changed, 100 insertions(+), 5 deletions(-) create mode 100644 src/itoa.c diff --git a/include/psyc/lib.h b/include/psyc/lib.h index 1847ef5..6708e4c 100644 --- a/include/psyc/lib.h +++ b/include/psyc/lib.h @@ -15,4 +15,8 @@ void * memmem(const void *l, size_t l_len, const void *s, size_t s_len); #endif +#if !defined(_GNU_SOURCE) && !defined(__FBSDID) +int itoa(int number, char* out, int base); +#endif + #endif // PSYC_LIB_H diff --git a/src/Makefile b/src/Makefile index 86c6c09..69625c8 100644 --- a/src/Makefile +++ b/src/Makefile @@ -2,8 +2,8 @@ CFLAGS=-I../include -DDEBUG=2 -DPSYC_COMPILE_LIBRARY -g -O0 -Wall CC=cc # CC=clang -S=psyc.c parser.c match.c render.c memmem.c variable.c -O=psyc.o parser.o match.o render.o memmem.o variable.o +S=psyc.c parser.c match.c render.c memmem.c itoa.c variable.c +O=psyc.o parser.o match.o render.o memmem.o itoa.o variable.o default: @/bin/echo -e "Usage:\n\tmake diet - compile with diet libc\n\tmake lib - compile with normal gnu libc" @@ -19,6 +19,9 @@ lib: $S match: match.c ${CC} -o $@ -DDEBUG=4 -DCMDTOOL -DTEST $< +itoa: itoa.c + ${CC} -o $@ -DDEBUG=4 -DCMDTOOL -DTEST -O0 $< + it: match clean: diff --git a/src/itoa.c b/src/itoa.c new file mode 100644 index 0000000..1292d9b --- /dev/null +++ b/src/itoa.c @@ -0,0 +1,85 @@ +#define ALPHANUMS "zyxwvutsrqponmlkjihgfedcba9876543210123456789abcdefghijklmnopqrstuvwxyz" + +/** converts an integer to a string, using a base of 10 by default. + * + * if you NULL out the output buffer it will return the expected + * output string length anyway. + */ +int itoa(int number, char* out, int base) { + int t, count; + char *p, *q; + char c; + + p = q = out; + if (base < 2 || base > 36) base = 10; + + do { + t = number; + number /= base; + if (out) *p = ALPHANUMS[t+35 - number*base]; + p++; + } while (number); + + if (t < 0) { + if (out) *p = '-'; + p++; + } + count = p-out; + if (out) { + *p-- = '\0'; + while(q < p) { + c = *p; + *p-- = *q; + *q++ = c; + } + } + return count; +} + +/* This little test program shows that itoa() is roughly 3 times faster + * than sprintf --lynX + */ +#ifdef CMDTOOL + +#include +#include +#include + +int main(int argc, char **argv) { + char out[4404]; + int in[44]; + int c, i, j; + + if (argc < 3 || argc > sizeof(in)) { + printf("Usage: %s +\n\nExample: %s 999999 123 234 345 -49 -21892\n", argv[0], argv[0]); + return -1; + } + for (j=argc-1; j; j--) { +// printf("Looking at arg #%d: %s\n", j, argv[j]); + in[j] = atoi(argv[j]); +// printf("Got %d: %d\n", j, in[j]); + } + for (i=in[1]; i; i--) { + c = 0; + for (j=argc-1; j>1; j--) { +# if 0 + // use good old sprintf + c += sprintf(&out[c], " %d", in[j]); +# else +# if 1 + // use the itoa implementation + out[c++] = ' '; + c += itoa(in[j], &out[c], 10); +# else + // just count the needed space + c += itoa(in[j], NULL, 10) + 1; +# endif +# endif + } + } + printf("%d times, %d count, buffer len: %d, buffer: %s\n", + in[1], c, strlen(out), ""); // out + return 0; +} + +#endif diff --git a/src/render.c b/src/render.c index e311bd7..195549f 100644 --- a/src/render.c +++ b/src/render.c @@ -11,7 +11,8 @@ inline int PSYC_renderModifier(PSYC_Modifier *m, char *buffer) if (m->flag == PSYC_MODIFIER_NEED_LENGTH) { buffer[cur++] = ' '; - cur += sprintf(buffer + cur, "%ld", m->value.length); +// cur += sprintf(buffer + cur, "%ld", m->value.length); + cur += itoa(m->value.length, buffer + cur, 10); } memcpy(buffer + cur, m->value.ptr, m->value.length); cur += m->value.length; @@ -30,8 +31,10 @@ PSYC_RenderRC PSYC_render(PSYC_Packet *packet, char *buffer, size_t buflen) for (i = 0; i < packet->routing.lines; i++) cur += PSYC_renderModifier(packet->routing.modifiers[i], buffer + cur); - if (packet->flag == PSYC_PACKET_NEED_LENGTH) - cur += sprintf(buffer + cur, "%ld", packet->contentLength); + if (packet->flag == PSYC_PACKET_NEED_LENGTH) { +// cur += sprintf(buffer + cur, "%ld", packet->contentLength); + cur += itoa(packet->contentLength, buffer + cur, 10); + } buffer[cur++] = '\n';