/* $Id: qprintf.c,v 1.3 2004/04/12 11:12:26 reinelt Exp $ * * simple but quick snprintf() replacement * * Copyright 2004 Michael Reinelt * Copyright 2004 The LCD4Linux Team * * derived from a patch from Martin Hejl which is * Copyright 2003 Martin Hejl (martin@hejl.de) * * This file is part of LCD4Linux. * * LCD4Linux is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * LCD4Linux is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * * * $Log: qprintf.c,v $ * Revision 1.3 2004/04/12 11:12:26 reinelt * added plugin_isdn, removed old ISDN client * fixed some real bad bugs in the evaluator * * Revision 1.2 2004/04/08 10:48:25 reinelt * finished plugin_exec * modified thread handling * added '%x' format to qprintf (hexadecimal) * * Revision 1.1 2004/02/27 07:06:26 reinelt * new function 'qprintf()' (simple but quick snprintf() replacement) * */ /* * exported functions: * * int qprintf(char *str, size_t size, const char *format, ...) * works like snprintf(), but format only knows about %d and %s */ #include "config.h" #include #include #include #include static char *itoa(char* buffer, size_t size, int value) { char *p; int sign; // sanity checks if (buffer==NULL || size<2) return (NULL); // remember sign of value sign = 0; if (value < 0) { sign = 1; value = -value; } // p points to last char p = buffer+size-1; // set terminating zero *p='\0'; do { *--p = value%10 + '0'; value = value/10; } while (value!=0 && p>buffer); if (sign && p>buffer) *--p = '-'; return p; } static char *utoa(char* buffer, size_t size, unsigned int value) { char *p; // sanity checks if (buffer==NULL || size<2) return (NULL); // p points to last char p = buffer+size-1; // set terminating zero *p='\0'; do { *--p = value%10 + '0'; value = value/10; } while (value!=0 && p>buffer); return p; } static char *utox(char* buffer, size_t size, unsigned int value) { char *p; int digit; // sanity checks if (buffer==NULL || size<2) return (NULL); // p points to last char p = buffer+size-1; // set terminating zero *p='\0'; do { digit = value%16; value = value/16; *--p = (digit < 10 ? '0' : 'a'-10) + digit; } while (value!=0 && p>buffer); return p; } int qprintf(char *str, size_t size, const char *format, ...) { va_list ap; const char *src; char *dst; int len; src = format; dst = str; len = 0; // leave room for terminating zero size--; va_start(ap, format); while (len < size) { if (*src=='%') { char buf[12], *s; int d; unsigned int u; switch (*++src) { case 's': src++; s = va_arg(ap, char *); while (len < size && *s != '\0') { len++; *dst++ = *s++; } break; case 'd': src++; d = va_arg(ap, int); s = itoa (buf, sizeof(buf), d); while (len < size && *s != '\0') { len++; *dst++ = *s++; } break; case 'u': src++; u = va_arg(ap, unsigned int); s = utoa (buf, sizeof(buf), u); while (len < size && *s != '\0') { len++; *dst++ = *s++; } break; case 'x': src++; u = va_arg(ap, unsigned int); s = utox (buf, sizeof(buf), u); while (len < size && *s != '\0') { len++; *dst++ = *s++; } break; default: len++; *dst++ = '%'; } } else { len++; *dst++ = *src; if (*src++ == '\0') break; } } va_end(ap); // enforce terminating zero if (len>=size && *(dst-1)!='\0') { len++; *dst='\0'; } // do not count terminating zero return len-1; }