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:
parent
3dab55e339
commit
41ec19b72a
@ -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");
|
||||||
|
Loading…
Reference in New Issue
Block a user