1
0
mirror of https://github.com/cc65/cc65.git synced 2024-11-19 06:31: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 <stdio.h>
#include <stddef.h> #include <stddef.h>
#include <string.h> #include <string.h>
#include <limits.h>
/* common */
#include "chartype.h" #include "chartype.h"
#include "check.h" #include "check.h"
#include "inttypes.h"
#include "xsprintf.h" #include "xsprintf.h"
@ -53,8 +56,8 @@
* features only the basic format specifiers (especially the floating point * features only the basic format specifiers (especially the floating point
* stuff is missing), but may be extended if required. Reason for supplying * stuff is missing), but may be extended if required. Reason for supplying
* my own implementation is that vsnprintf is standard but not implemented by * 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 * older compilers, and some that implement it, don't adhere to the standard
* adhere to the standard (for example Microsoft with its _vsnprintf). * (for example Microsoft with its _vsnprintf).
*/ */
typedef struct { typedef struct {
@ -104,13 +107,13 @@ typedef struct {
lmShort, lmShort,
lmInt, lmInt,
lmLong, lmLong,
lmIntMax,
lmSizeT, lmSizeT,
lmPtrDiffT, lmPtrDiffT,
lmLongDouble, lmLongDouble,
/* Unsupported modifiers */ /* Unsupported modifiers */
lmLongLong = lmLong, lmLongLong = lmLong,
lmIntMax = lmLong,
/* Default length is integer */ /* Default length is integer */
lmDefault = lmInt 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 */ /* Read the next integer value from the variable argument list */
{ {
switch (P->LengthMod) { switch (P->LengthMod) {
@ -148,7 +151,8 @@ static long NextIVal (PrintfCtrl*P)
case lmShort: return (short) va_arg (P->ap, int); case lmShort: return (short) va_arg (P->ap, int);
case lmInt: return (int) va_arg (P->ap, int); case lmInt: return (int) va_arg (P->ap, int);
case lmLong: return (long) va_arg (P->ap, long); 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); case lmPtrDiffT: return (long) va_arg (P->ap, ptrdiff_t);
default: FAIL ("Invalid type size in NextIVal"); 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 */ /* Read the next unsigned integer value from the variable argument list */
{ {
switch (P->LengthMod) { switch (P->LengthMod) {
case lmChar: return (unsigned char) va_arg (P->ap, unsigned); case lmChar: return (unsigned char) va_arg (P->ap, unsigned);
case lmShort: return (unsigned short) 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 lmInt: return (unsigned int) va_arg (P->ap, unsigned int);
case lmLong: return va_arg (P->ap, unsigned long); case lmLong: return (unsigned long) va_arg (P->ap, unsigned long);
case lmSizeT: return (unsigned long) va_arg (P->ap, size_t); case lmIntMax: return va_arg (P->ap, uintmax_t);
case lmPtrDiffT: return (long) va_arg (P->ap, ptrdiff_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"); 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 */ /* Convert the given value to a (reversed) string */
{ {
char* S = P->ArgBuf; 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 */ /* Convert the integer value */
{ {
char Lead[5]; char Lead[5];
@ -199,8 +204,8 @@ static void FormatInt (PrintfCtrl* P, unsigned long Val)
P->CharTable = (P->Flags & fUpcase)? "0123456789ABCDEF" : "0123456789abcedf"; P->CharTable = (P->Flags & fUpcase)? "0123456789ABCDEF" : "0123456789abcedf";
/* Check if the value is negative */ /* Check if the value is negative */
if ((P->Flags & fUnsigned) == 0 && ((long) Val) < 0) { if ((P->Flags & fUnsigned) == 0 && ((intmax_t) Val) < 0) {
Val = -((long) Val); Val = -((intmax_t) Val);
Lead[LeadCount++] = '-'; Lead[LeadCount++] = '-';
} else if ((P->Flags & fPlus) != 0) { } else if ((P->Flags & fPlus) != 0) {
Lead[LeadCount++] = '+'; Lead[LeadCount++] = '+';
@ -212,7 +217,7 @@ static void FormatInt (PrintfCtrl* P, unsigned long Val)
ToStr (P, Val); ToStr (P, Val);
/* The default precision for all integer conversions is one. This means /* 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. * later on.
*/ */
if ((P->Flags & fPrec) == 0) { 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) int xvsnprintf (char* Buf, size_t Size, const char* Format, va_list ap)
/* A basic vsnprintf implementation. Does currently only support integer /* A basic vsnprintf implementation. Does currently only support integer
* formats. * formats.
@ -543,6 +565,18 @@ int xvsnprintf (char* Buf, size_t Size, const char* Format, va_list ap)
FormatStr (&P, SPtr); FormatStr (&P, SPtr);
break; 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: default:
/* Invalid format spec */ /* Invalid format spec */
FAIL ("Invalid format specifier in xvsnprintf"); FAIL ("Invalid format specifier in xvsnprintf");