Files
QNX/lib/c/stdio/xgetint.c
2025-08-20 19:02:58 +08:00

204 lines
4.4 KiB
C

/* _Getint function */
#include <stdlib.h>
#include <string.h>
#include "xstdio.h"
_STD_BEGIN
#define ACSIZE 32 /* holds only prefix, m.s. digits */
int _Getint(_Sft *px, void *pans)
{ /* get an integer value for _Scanf */
char ac[ACSIZE], *p, seen;
int base, ch, dlen;
static const char digits[] = "0123456789abcdefABCDEF";
static const char flit[] = "diouxXp";
static const char barr[] = {10, 0, 8, 10, 16, 16, 16};
px->nget = 0 < px->width ? px->width : INT_MAX;
p = ac, ch = GETN(px);
if (ch == '+' || ch == '-')
*p++ = (char)ch, ch = GETN(px);
seen = 0;
base = barr[(const char *)strchr(&flit[0], *px->s) - flit];
if (ch == '0')
{ /* match possible prefix and strip it */
seen = 1;
ch = GETN(px);
if ((ch == 'x' || ch == 'X')
&& (base == 0 || base == 16))
base = 16, ch = GETN(px), seen = 0;
else if (base == 0)
base = 8;
}
dlen = base == 0 || base == 10 ? 10
: base == 8 ? 8 : 16 + 6;
for (; ch == '0'; seen = 1)
ch = GETN(px);
if (seen)
*p++ = '0';
for (; ch != EOF && memchr(&digits[0], ch, dlen);
ch = GETN(px), seen = 1)
if (p < &ac[ACSIZE - 1])
*p++ = (char)ch;
UNGETN(px, ch);
if (!seen)
return (p == ac && ch == EOF ? EOF : 0);
*p = '\0';
if (px->noconv)
;
else if (*px->s == 'd' || *px->s == 'i')
{ /* deliver a signed integer */
const _Longlong lval = _Stoll(ac, 0, base);
px->stored = 1;
switch (px->qual)
{ /* store in specified integer type */
case 'b':
if (pans != 0)
*(signed char *)pans = (signed char)lval;
else
*va_arg(px->ap, signed char *) = (signed char)lval;
break;
case 'q':
if (pans != 0)
*(_Longlong *)pans = lval;
else
*va_arg(px->ap, _Longlong *) = lval;
break;
case 'j':
if (pans != 0)
*(intmax_t *)pans = lval;
else
*va_arg(px->ap, intmax_t *) = lval;
break;
case 't':
if (pans != 0)
*(ptrdiff_t *)pans = (ptrdiff_t)lval;
else
*va_arg(px->ap, ptrdiff_t *) = (ptrdiff_t)lval;
break;
case 'z':
if (pans != 0)
*(ptrdiff_t *)pans = (ptrdiff_t)lval;
else
*va_arg(px->ap, ptrdiff_t *) = (ptrdiff_t)lval;
break;
case 'h':
if (pans != 0)
*(short *)pans = (short)lval;
else
*va_arg(px->ap, short *) = (short)lval;
break;
case 'l':
if (pans != 0)
*(long *)pans = (long)lval;
else
*va_arg(px->ap, long *) = (long)lval;
break;
default:
if (pans != 0)
*(int *)pans = (int)lval;
else
*va_arg(px->ap, int *) = (int)lval;
}
}
else
{ /* deliver an unsigned integer */
const _ULonglong ulval = _Stoull(ac, 0, base);
px->stored = 1;
if (*px->s == 'p')
#if defined(__BORLANDC__) && !__EDG__
if (pans != 0)
*(void **)pans = (void *)ulval;
else
*va_arg(px->ap, void **) =
(void *)ulval; /* quiet diagnostic */
#else /* defined(__BORLANDC__) && !__EDG__ */
if (pans != 0)
*(void **)pans = (void *)((char *)0 + ulval);
else
*va_arg(px->ap, void **) = (void *)((char *)0 + ulval);
#endif /* defined(__BORLANDC__) && !__EDG__ */
else
switch (px->qual)
{ /* store in specified integer type */
case 'b':
if (pans != 0)
*(unsigned char *)pans = (unsigned char)ulval;
else
*va_arg(px->ap, unsigned char *) = (unsigned char)ulval;
break;
case 'q':
if (pans != 0)
*(_ULonglong *)pans = ulval;
else
*va_arg(px->ap, _ULonglong *) = ulval;
break;
case 'j':
if (pans != 0)
*(uintmax_t *)pans = ulval;
else
*va_arg(px->ap, uintmax_t *) = ulval;
break;
case 't':
if (pans != 0)
*(size_t *)pans = (size_t)ulval;
else
*va_arg(px->ap, size_t *) = (size_t)ulval;
break;
case 'z':
if (pans != 0)
*(size_t *)pans = (size_t)ulval;
else
*va_arg(px->ap, size_t *) = (size_t)ulval;
break;
case 'h':
if (pans != 0)
*(unsigned short *)pans = (unsigned short)ulval;
else
*va_arg(px->ap, unsigned short *) = (unsigned short)ulval;
break;
case 'l':
if (pans != 0)
*(unsigned long *)pans = (unsigned long)ulval;
else
*va_arg(px->ap, unsigned long *) = (unsigned long)ulval;
break;
default:
if (pans != 0)
*(unsigned int *)pans = (unsigned int)ulval;
else
*va_arg(px->ap, unsigned int *) = (unsigned int)ulval;
}
}
return (1);
}
_STD_END
/*
* Copyright (c) 1992-2006 by P.J. Plauger. ALL RIGHTS RESERVED.
* Consult your license regarding permissions and restrictions.
V5.00:1296 */
__SRCVERSION("xgetint.c $Rev: 153052 $");