?? snprintf.c
字號:
/*
* Copyright (c) 1983, 1995, 1996 Eric P. Allman
* Copyright (c) 1988, 1993
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. 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.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#if 0
static char sccsid[] = "@(#)$Id: snprintf.c,v 1.2 1998/05/11 09:18:44 bero Exp $ excerpted from conf.c 8.333 (Berkeley) 1/21/97";
#endif
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include <sys/socket.h> /* __inline */
#define VA_LOCAL_DECL va_list ap;
#define VA_START(f) va_start(ap, f)
#define VA_END va_end(ap)
/*
* ** SNPRINTF, VSNPRINT -- counted versions of printf
* **
* ** These versions have been grabbed off the net. They have been
* ** cleaned up to compile properly and support for .precision and
* ** %lx has been added.
*/
/**************************************************************
* Original:
* Patrick Powell Tue Apr 11 09:48:21 PDT 1995
* A bombproof version of doprnt (dopr) included.
* Sigh. This sort of thing is always nasty do deal with. Note that
* the version here does not include floating point...
*
* snprintf() is used instead of sprintf() as it does limit checks
* for string length. This covers a nasty loophole.
*
* The other functions are there to prevent NULL pointers from
* causing nast effects.
**************************************************************/
static void fmtstr (char *value, int ljust, int len, int zpad, int maxwidth);
static void fmtnum (long value, int base, int dosign, int ljust, int len, int zpad);
static void dostr (char *, int);
static void dopr (char *, const char *, va_list);
static char *output, *end;
int vsnprintf (char *str, size_t count, const char *fmt, va_list args)
{
str[0] = 0;
end = str + count - 1;
dopr (str, fmt, args);
if (count > 0)
end[0] = 0;
return strlen (str);
}
int snprintf (char *str, size_t count, const char *fmt, ...)
{
int len;
VA_LOCAL_DECL VA_START (fmt);
len = vsnprintf (str, count, fmt, ap);
VA_END;
return (len);
}
static __inline void dopr_outch (int c)
{
if (end == 0 || output < end)
*output++ = c;
}
static void dostr (char *str, int cut)
{
if (cut)
while (*str && cut-- > 0) dopr_outch (*str++);
else while (*str) dopr_outch (*str++);
}
/*
* dopr(): poor man's version of doprintf
*/
static void dopr (char *buffer, const char *format, va_list args)
{
int ch;
long value;
int longflag = 0;
int pointflag = 0;
int maxwidth = 0;
char *strvalue;
int ljust;
int len;
int zpad;
output = buffer;
while ((ch = *format++) != '\0')
{
switch (ch)
{
case '%':
ljust = len = zpad = maxwidth = 0;
longflag = pointflag = 0;
nextch:
ch = *format++;
switch (ch)
{
case 0:
dostr ("**end of format**", 0);
return;
case '-':
ljust = 1;
goto nextch;
case '0': /* set zero padding if len not set */
if (len == 0 && !pointflag)
zpad = '0';
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
if (pointflag)
maxwidth = maxwidth * 10 + ch - '0';
else len = len * 10 + ch - '0';
goto nextch;
case '*':
if (pointflag)
maxwidth = va_arg (args, int);
else len = va_arg (args, int);
goto nextch;
case '.':
pointflag = 1;
goto nextch;
case 'l':
longflag = 1;
goto nextch;
case 'u':
case 'U':
if (longflag)
value = va_arg (args, long);
else value = va_arg (args, int);
fmtnum (value, 10, 0, ljust, len, zpad);
break;
case 'o':
case 'O':
if (longflag)
value = va_arg (args, long);
else value = va_arg (args, int);
fmtnum (value, 8, 0, ljust, len, zpad);
break;
case 'd':
case 'D':
if (longflag)
value = va_arg (args, long);
else value = va_arg (args, int);
fmtnum (value, 10, 1, ljust, len, zpad);
break;
case 'x':
if (longflag)
value = va_arg (args, long);
else value = va_arg (args, int);
fmtnum (value, 16, 0, ljust, len, zpad);
break;
case 'X':
if (longflag)
value = va_arg (args, long);
else value = va_arg (args, int);
fmtnum (value, -16, 0, ljust, len, zpad);
break;
case 's':
strvalue = va_arg (args, char *);
if (maxwidth > 0 || !pointflag)
{
if (pointflag && len > maxwidth)
len = maxwidth; /* Adjust padding */
fmtstr (strvalue, ljust, len, zpad, maxwidth);
}
break;
case 'c':
ch = va_arg (args, int);
dopr_outch (ch);
break;
case '%':
dopr_outch (ch);
continue;
default:
dostr ("???????", 0);
}
break;
default:
dopr_outch (ch);
break;
}
}
*output = 0;
}
static void fmtstr (char *value, int ljust, int len, int zpad, int maxwidth)
{
int padlen, strlen; /* amount to pad */
if (value == 0)
value = "<NULL>";
for (strlen = 0; value[strlen]; ++strlen) ; /* strlen */
if (strlen > maxwidth && maxwidth)
strlen = maxwidth;
padlen = len - strlen;
if (padlen < 0)
padlen = 0;
if (ljust)
padlen = -padlen;
while (padlen > 0)
{
dopr_outch (' ');
--padlen;
}
dostr (value, maxwidth);
while (padlen < 0)
{
dopr_outch (' ');
++padlen;
}
}
static void fmtnum (long value, int base, int dosign, int ljust, int len, int zpad)
{
unsigned long uvalue;
char convert[20];
int signvalue = 0;
int place = 0;
int padlen = 0; /* amount to pad */
int caps = 0;
/* DEBUGP(("value 0x%x, base %d, dosign %d, ljust %d, len %d, zpad %d\n",
* value, base, dosign, ljust, len, zpad ));
*/
uvalue = value;
if (dosign)
{
if (value < 0)
{
signvalue = '-';
uvalue = -value;
}
}
if (base < 0)
{
caps = 1;
base = -base;
}
do
{
convert[place++] = (caps ? "0123456789ABCDEF" :
"0123456789abcdef")[uvalue % (unsigned) base];
uvalue = (uvalue / (unsigned) base);
}
while (uvalue);
convert[place] = 0;
padlen = len - place;
if (padlen < 0)
padlen = 0;
if (ljust)
padlen = -padlen;
/* DEBUGP(( "str '%s', place %d, sign %c, padlen %d\n",
* convert,place,signvalue,padlen));
*/
if (zpad && padlen > 0)
{
if (signvalue)
{
dopr_outch (signvalue);
--padlen;
signvalue = 0;
}
while (padlen > 0)
{
dopr_outch (zpad);
--padlen;
}
}
while (padlen > 0)
{
dopr_outch (' ');
--padlen;
}
if (signvalue)
dopr_outch (signvalue);
while (place > 0)
dopr_outch (convert[--place]);
while (padlen < 0)
{
dopr_outch (' ');
++padlen;
}
}
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -