#include "ircsprintf.h"
char num[12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
char itoa_tab[10] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' };
char xtoa_tab[16] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
'a', 'b', 'c', 'd', 'e', 'f' };
char nullstring[]="(null)";
#ifdef WANT_SNPRINTF
inline int irc_printf(char *str, size_t size, const char *pattern, va_list vl)
#else
inline int irc_printf(char *str, const char *pattern, va_list vl)
#endif
{
char *s;
char *buf=str;
const char *format=pattern;
unsigned long i, u;
int len=0;
va_list ap;
VA_COPY(ap, vl);
#ifdef WANT_SNPRINTF
if(!size)
{
#endif
while(*format)
{
u = 0;
switch(*format)
{
case '%':
format++;
switch(*format)
{
case 's': /* most popular ;) */
s=va_arg(ap, char *);
while(*s)
buf[len++]=*s++;
format++;
break;
case 'u':
format--; /* falls through and is caught below */
case 'l':
if (*(format+1) == 'u')
{
u=1;
format++;
}
else if (*(format+1) == 'd')
{
u=0;
format++;
}
else
u=0;
/* fallthrough */
case 'd':
case 'i':
i=va_arg(ap, unsigned long);
if(!u)
if(i&0x80000000)
{
buf[len++]='-'; /* it's negative.. */
i = 0x80000000 - (i & ~0x80000000);
}
s=&num[11];
do
{
*--s=itoa_tab[i%10];
i/=10;
} while(i!=0);
while(*s)
buf[len++]=*s++;
format++;
break;
case 'n':
/* oo, sneaky...it really is just a long, though! */
case 'x':
case 'X':
i=va_arg(ap, long);
buf[len++]='0';
buf[len++]='x';
s=&num[11];
do
{
*--s=xtoa_tab[i%16];
i/=16;
} while(i!=0);
while(*s)
buf[len++]=*s++;
format++;
break;
case 'c':
buf[len++]= (char) va_arg(ap, int);
format++;
break;
default:
/* yick, unknown type...default to returning what our
s[n]printf friend would */
return vsprintf(str, pattern, vl);
break;
}
break;
default:
buf[len++]=*format++;
break;
}
}
buf[len]=0;
return len;
#ifdef WANT_SNPRINTF
}
else
{
while(*format && len<size)
{
u = 0;
switch(*format)
{
case '%':
format++;
switch(*format)
{
case 's': /* most popular ;) */
s=va_arg(ap, char *);
if(s==NULL)
s=nullstring;
while(*s && len<size)
buf[len++]=*s++;
format++;
break;
case 'u':
format--; /* now fall through and it's caught, cool */
case 'l':
if (*(format+1) == 'u')
{
u=1;
format++;
}
else if (*(format+1) == 'd')
{
u=0;
format++;
}
else
u=0;
/* fallthrough */
case 'd':
case 'i':
i=va_arg(ap, unsigned long);
if(!u)
if(i&0x80000000)
{
buf[len++]='-'; /* it's negative.. */
i = 0x80000000 - (i & ~0x80000000);
}
s=&num[11];
do
{
*--s=itoa_tab[i%10];
i/=10;
} while(i!=0);
while(*s && len<size)
buf[len++]=*s++;
format++;
break;
case 'n':
/* oo, sneaky...it really is just a long, though! */
case 'x':
case 'X':
i=va_arg(ap, long);
buf[len++]='0';
if(len<size)
buf[len++]='x';
else
break;
s=&num[11];
do
{
*--s=xtoa_tab[i%16];
i/=16;
} while(i!=0);
while(*s && len<size)
buf[len++]=*s++;
format++;
break;
case 'c':
buf[len++]= (char) va_arg(ap, int);
format++;
break;
default:
/* yick, unknown type...default to returning what our
s[n]printf friend would */
return vsnprintf(str, size, pattern, vl);
break;
}
break;
default:
buf[len++]=*format++;
break;
}
}
buf[len]=0;
return len;
}
#endif /* WANT_SNPRINTF */
}
int ircsprintf(char *str, const char *format, ...)
{
int ret;
va_list vl;
va_start(vl, format);
#ifdef WANT_SNPRINTF
ret=irc_printf(str, 0, format, vl);
#else
ret=irc_printf(str, format, vl);
#endif
va_end(vl);
return ret;
}
#ifdef WANT_SNPRINTF
int ircsnprintf(char *str, size_t size, const char *format, ...)
{
int ret;
va_list vl;
va_start(vl, format);
ret=irc_printf(str, size, format, vl);
va_end(vl);
return ret;
}
#endif
int ircvsprintf(char *str, const char *format, va_list ap)
{
int ret;
#ifdef WANT_SNPRINTF
ret=irc_printf(str, 0, format, ap);
#else
ret=irc_printf(str, format, ap);
#endif
return ret;
}
#ifdef WANT_SNPRINTF
int ircvsnprintf(char *str, size_t size, const char *format, va_list ap)
{
int ret;
ret=irc_printf(str, size, format, ap);
return ret;
}
#endif
syntax highlighted by Code2HTML, v. 0.9.1