1
0
mirror of https://github.com/cc65/cc65.git synced 2024-12-27 00:29:31 +00:00

Use inttypes.h and the intmax_t/uintmax_t types

git-svn-id: svn://svn.cc65.org/cc65/trunk@3332 b7a2c559-68d2-44c3-8de9-860c34a00d81
This commit is contained in:
cuz 2004-12-16 22:38:07 +00:00
parent 3dab55e339
commit 41ec19b72a

View File

@ -36,9 +36,12 @@
#include <stdio.h>
#include <stddef.h>
#include <string.h>
#include <limits.h>
/* common */
#include "chartype.h"
#include "check.h"
#include "inttypes.h"
#include "xsprintf.h"
@ -53,8 +56,8 @@
* features only the basic format specifiers (especially the floating point
* stuff is missing), but may be extended if required. Reason for supplying
* my own implementation is that vsnprintf is standard but not implemented by
* older compilers, and some that implement it in some way or the other, don't
* adhere to the standard (for example Microsoft with its _vsnprintf).
* older compilers, and some that implement it, don't adhere to the standard
* (for example Microsoft with its _vsnprintf).
*/
typedef struct {
@ -104,13 +107,13 @@ typedef struct {
lmShort,
lmInt,
lmLong,
lmIntMax,
lmSizeT,
lmPtrDiffT,
lmLongDouble,
/* Unsupported modifiers */
lmLongLong = lmLong,
lmIntMax = lmLong,
/* Default length is integer */
lmDefault = lmInt
@ -140,7 +143,7 @@ static void AddPadding (PrintfCtrl* P, char C, unsigned Count)
static long NextIVal (PrintfCtrl*P)
static intmax_t NextIVal (PrintfCtrl*P)
/* Read the next integer value from the variable argument list */
{
switch (P->LengthMod) {
@ -148,7 +151,8 @@ static long NextIVal (PrintfCtrl*P)
case lmShort: return (short) va_arg (P->ap, int);
case lmInt: return (int) va_arg (P->ap, int);
case lmLong: return (long) va_arg (P->ap, long);
case lmSizeT: return (unsigned long) va_arg (P->ap, size_t);
case lmIntMax: return va_arg (P->ap, intmax_t);
case lmSizeT: return (uintmax_t) va_arg (P->ap, size_t);
case lmPtrDiffT: return (long) va_arg (P->ap, ptrdiff_t);
default: FAIL ("Invalid type size in NextIVal");
}
@ -156,23 +160,24 @@ static long NextIVal (PrintfCtrl*P)
static unsigned long NextUVal (PrintfCtrl*P)
static uintmax_t NextUVal (PrintfCtrl*P)
/* Read the next unsigned integer value from the variable argument list */
{
switch (P->LengthMod) {
case lmChar: return (unsigned char) va_arg (P->ap, unsigned);
case lmShort: return (unsigned short) va_arg (P->ap, unsigned);
case lmInt: return (unsigned int) va_arg (P->ap, unsigned int);
case lmLong: return va_arg (P->ap, unsigned long);
case lmSizeT: return (unsigned long) va_arg (P->ap, size_t);
case lmPtrDiffT: return (long) va_arg (P->ap, ptrdiff_t);
case lmLong: return (unsigned long) va_arg (P->ap, unsigned long);
case lmIntMax: return va_arg (P->ap, uintmax_t);
case lmSizeT: return va_arg (P->ap, size_t);
case lmPtrDiffT: return (intmax_t) va_arg (P->ap, ptrdiff_t);
default: FAIL ("Invalid type size in NextUVal");
}
}
static void ToStr (PrintfCtrl* P, unsigned long Val)
static void ToStr (PrintfCtrl* P, uintmax_t Val)
/* Convert the given value to a (reversed) string */
{
char* S = P->ArgBuf;
@ -185,7 +190,7 @@ static void ToStr (PrintfCtrl* P, unsigned long Val)
static void FormatInt (PrintfCtrl* P, unsigned long Val)
static void FormatInt (PrintfCtrl* P, uintmax_t Val)
/* Convert the integer value */
{
char Lead[5];
@ -199,8 +204,8 @@ static void FormatInt (PrintfCtrl* P, unsigned long Val)
P->CharTable = (P->Flags & fUpcase)? "0123456789ABCDEF" : "0123456789abcedf";
/* Check if the value is negative */
if ((P->Flags & fUnsigned) == 0 && ((long) Val) < 0) {
Val = -((long) Val);
if ((P->Flags & fUnsigned) == 0 && ((intmax_t) Val) < 0) {
Val = -((intmax_t) Val);
Lead[LeadCount++] = '-';
} else if ((P->Flags & fPlus) != 0) {
Lead[LeadCount++] = '+';
@ -212,7 +217,7 @@ static void FormatInt (PrintfCtrl* P, unsigned long Val)
ToStr (P, Val);
/* The default precision for all integer conversions is one. This means
* that the fPrec flag is always set and does not need to be checked
* that the fPrec flag is always set and does not need to be checked
* later on.
*/
if ((P->Flags & fPrec) == 0) {
@ -337,6 +342,23 @@ static void FormatStr (PrintfCtrl* P, const char* Val)
static void StoreOffset (PrintfCtrl* P)
/* Store the current output offset (%n format spec) */
{
switch (P->LengthMod) {
case lmChar: *va_arg (P->ap, int*) = P->BufFill;
case lmShort: *va_arg (P->ap, int*) = P->BufFill;
case lmInt: *va_arg (P->ap, int*) = P->BufFill;
case lmLong: *va_arg (P->ap, long*) = P->BufFill;
case lmIntMax: *va_arg (P->ap, intmax_t*) = P->BufFill;
case lmSizeT: *va_arg (P->ap, size_t*) = P->BufFill;
case lmPtrDiffT: *va_arg (P->ap, ptrdiff_t*) = P->BufFill;
default: FAIL ("Invalid size modifier for %n format spec in xvsnprintf");
}
}
int xvsnprintf (char* Buf, size_t Size, const char* Format, va_list ap)
/* A basic vsnprintf implementation. Does currently only support integer
* formats.
@ -543,6 +565,18 @@ int xvsnprintf (char* Buf, size_t Size, const char* Format, va_list ap)
FormatStr (&P, SPtr);
break;
case 'p':
/* Use hex format for pointers */
P.Flags |= (fUnsigned | fPrec);
P.Prec = ((sizeof (void*) * CHAR_BIT) + 3) / 4;
P.Base = 16;
FormatInt (&P, (uintptr_t) va_arg (P.ap, void*));
break;
case 'n':
StoreOffset (&P);
break;
default:
/* Invalid format spec */
FAIL ("Invalid format specifier in xvsnprintf");