203
326
typedef int16_t trio_int16_t;
204
327
typedef int32_t trio_int32_t;
205
328
typedef int64_t trio_int64_t;
206
#elif defined(TRIO_COMPILER_SUPPORTS_UNIX98)
207
# include <inttypes.h>
330
# if defined(PREDEF_STANDARD_UNIX98)
331
# include <inttypes.h>
208
332
typedef intmax_t trio_intmax_t;
209
333
typedef uintmax_t trio_uintmax_t;
210
334
typedef int8_t trio_int8_t;
211
335
typedef int16_t trio_int16_t;
212
336
typedef int32_t trio_int32_t;
213
337
typedef int64_t trio_int64_t;
214
#elif defined(TRIO_COMPILER_SUPPORTS_MSVC_INT)
339
# if defined(TRIO_COMPILER_SUPPORTS_VISUALC_INT)
215
340
typedef trio_longlong_t trio_intmax_t;
216
341
typedef trio_ulonglong_t trio_uintmax_t;
217
342
typedef __int8 trio_int8_t;
218
343
typedef __int16 trio_int16_t;
219
344
typedef __int32 trio_int32_t;
220
345
typedef __int64 trio_int64_t;
222
347
typedef trio_longlong_t trio_intmax_t;
223
348
typedef trio_ulonglong_t trio_uintmax_t;
224
# if defined(TRIO_INT8_T)
349
# if defined(TRIO_INT8_T)
225
350
typedef TRIO_INT8_T trio_int8_t;
227
352
typedef TRIO_SIGNED char trio_int8_t;
229
# if defined(TRIO_INT16_T)
354
# if defined(TRIO_INT16_T)
230
355
typedef TRIO_INT16_T trio_int16_t;
232
357
typedef TRIO_SIGNED short trio_int16_t;
234
# if defined(TRIO_INT32_T)
359
# if defined(TRIO_INT32_T)
235
360
typedef TRIO_INT32_T trio_int32_t;
237
362
typedef TRIO_SIGNED int trio_int32_t;
239
# if defined(TRIO_INT64_T)
364
# if defined(TRIO_INT64_T)
240
365
typedef TRIO_INT64_T trio_int64_t;
242
367
typedef trio_longlong_t trio_int64_t;
246
#if !(defined(TRIO_COMPILER_SUPPORTS_C99) \
247
|| defined(TRIO_COMPILER_SUPPORTS_UNIX01))
248
# define floorl(x) floor((double)(x))
249
# define fmodl(x,y) fmod((double)(x),(double)(y))
250
# define powl(x,y) pow((double)(x),(double)(y))
253
#define TRIO_FABS(x) (((x) < 0.0) ? -(x) : (x))
373
#if defined(HAVE_FLOORL)
374
# define trio_floor(x) floorl((x))
376
# define trio_floor(x) floor((double)(x))
379
#if defined(HAVE_CEILL)
380
# define trio_ceil(x) ceill((x))
382
# define trio_ceil(x) ceil((double)(x))
385
#if defined(HAVE_FMODL)
386
# define trio_fmod(x,y) fmodl((x),(y))
388
# define trio_fmod(x,y) fmod((double)(x),(double)(y))
391
#if defined(HAVE_POWL)
392
# define trio_pow(x,y) powl((x),(y))
394
# define trio_pow(x,y) pow((double)(x),(double)(y))
397
#if defined(HAVE_LOG10L)
398
# define trio_log10(x) log10l((x))
400
# define trio_log10(x) log10((double)(x))
403
#if TRIO_FEATURE_FLOAT
404
# define TRIO_FABS(x) (((x) < 0.0) ? -(x) : (x))
255
407
/*************************************************************************
256
408
* Internal Definitions
260
# define DECIMAL_DIG DBL_DIG
411
#if TRIO_FEATURE_FLOAT
413
# if !defined(DECIMAL_DIG)
414
# define DECIMAL_DIG DBL_DIG
263
417
/* Long double sizes */
265
# define MAX_MANTISSA_DIGITS LDBL_DIG
266
# define MAX_EXPONENT_DIGITS 4
267
# define MAX_DOUBLE_DIGITS LDBL_MAX_10_EXP
269
# define MAX_MANTISSA_DIGITS DECIMAL_DIG
270
# define MAX_EXPONENT_DIGITS 3
271
# define MAX_DOUBLE_DIGITS DBL_MAX_10_EXP
274
#if defined(TRIO_COMPILER_ANCIENT) || !defined(LDBL_DIG)
276
# undef LDBL_MANT_DIG
278
# define LDBL_DIG DBL_DIG
279
# define LDBL_MANT_DIG DBL_MANT_DIG
280
# define LDBL_EPSILON DBL_EPSILON
419
# define MAX_MANTISSA_DIGITS LDBL_DIG
420
# define MAX_EXPONENT_DIGITS 4
421
# define MAX_DOUBLE_DIGITS LDBL_MAX_10_EXP
423
# define MAX_MANTISSA_DIGITS DECIMAL_DIG
424
# define MAX_EXPONENT_DIGITS 3
425
# define MAX_DOUBLE_DIGITS DBL_MAX_10_EXP
428
# if defined(TRIO_COMPILER_ANCIENT) || !defined(LDBL_DIG)
430
# undef LDBL_MANT_DIG
432
# define LDBL_DIG DBL_DIG
433
# define LDBL_MANT_DIG DBL_MANT_DIG
434
# define LDBL_EPSILON DBL_EPSILON
437
#endif /* TRIO_FEATURE_FLOAT */
283
439
/* The maximal number of digits is for base 2 */
284
440
#define MAX_CHARS_IN(x) (sizeof(x) * CHAR_BIT)
285
441
/* The width of a pointer. The number of bits in a hex digit is 4 */
286
442
#define POINTER_WIDTH ((sizeof("0x") - 1) + sizeof(trio_pointer_t) * CHAR_BIT / 4)
444
#if TRIO_FEATURE_FLOAT
288
445
/* Infinite and Not-A-Number for floating-point */
289
#define INFINITE_LOWER "inf"
290
#define INFINITE_UPPER "INF"
291
#define LONG_INFINITE_LOWER "infinite"
292
#define LONG_INFINITE_UPPER "INFINITE"
293
#define NAN_LOWER "nan"
294
#define NAN_UPPER "NAN"
446
# define INFINITE_LOWER "inf"
447
# define INFINITE_UPPER "INF"
448
# define LONG_INFINITE_LOWER "infinite"
449
# define LONG_INFINITE_UPPER "INFINITE"
450
# define NAN_LOWER "nan"
451
# define NAN_UPPER "NAN"
296
454
/* Various constants */
457
#if TRIO_FEATURE_SCANF
301
461
/* Flags. FLAGS_LAST must be less than ULONG_MAX */
1136
1378
default : return TrioLogarithm((double)base, 2);
1381
#endif /* TRIO_FEATURE_FLOAT */
1383
/*************************************************************************
1384
* TrioParseQualifiers
1387
* Parse the qualifiers of a potential conversion specifier
1391
TRIO_ARGS4((type, format, offset, parameter),
1393
TRIO_CONST char *format,
1395
trio_parameter_t *parameter)
1398
int dots = 0; /* Count number of dots in modifier part */
1401
parameter->beginOffset = offset - 1;
1402
parameter->flags = FLAGS_NEW;
1403
parameter->position = TrioGetPosition(format, &offset);
1405
/* Default values */
1406
parameter->width = NO_WIDTH;
1407
parameter->precision = NO_PRECISION;
1408
parameter->base = NO_BASE;
1409
parameter->varsize = NO_SIZE;
1411
while (TrioIsQualifier(format[offset]))
1413
ch = format[offset++];
1417
case QUALIFIER_SPACE:
1418
parameter->flags |= FLAGS_SPACE;
1421
case QUALIFIER_PLUS:
1422
parameter->flags |= FLAGS_SHOWSIGN;
1425
case QUALIFIER_MINUS:
1426
parameter->flags |= FLAGS_LEFTADJUST;
1427
parameter->flags &= ~FLAGS_NILPADDING;
1430
case QUALIFIER_ALTERNATIVE:
1431
parameter->flags |= FLAGS_ALTERNATIVE;
1435
if (dots == 0) /* Precision */
1439
/* Skip if no precision */
1440
if (QUALIFIER_DOT == format[offset])
1443
/* After the first dot we have the precision */
1444
parameter->flags |= FLAGS_PRECISION;
1445
if ((QUALIFIER_STAR == format[offset])
1446
#if defined(QUALIFIER_PARAM)
1447
|| (QUALIFIER_PARAM == format[offset])
1452
parameter->flags |= FLAGS_PRECISION_PARAMETER;
1453
parameter->precision = TrioGetPosition(format, &offset);
1457
parameter->precision = trio_to_long(&format[offset],
1460
offset = (int)(tmpformat - format);
1463
else if (dots == 1) /* Base */
1467
/* After the second dot we have the base */
1468
parameter->flags |= FLAGS_BASE;
1469
if ((QUALIFIER_STAR == format[offset])
1470
#if defined(QUALIFIER_PARAM)
1471
|| (QUALIFIER_PARAM == format[offset])
1476
parameter->flags |= FLAGS_BASE_PARAMETER;
1477
parameter->base = TrioGetPosition(format, &offset);
1481
parameter->base = trio_to_long(&format[offset],
1484
if (parameter->base > MAX_BASE)
1485
return TRIO_ERROR_RETURN(TRIO_EINVAL, offset);
1486
offset = (int)(tmpformat - format);
1491
return TRIO_ERROR_RETURN(TRIO_EINVAL, offset);
1493
break; /* QUALIFIER_DOT */
1495
#if defined(QUALIFIER_PARAM)
1496
case QUALIFIER_PARAM:
1497
parameter->type = TYPE_PRINT;
1500
case QUALIFIER_STAR:
1501
/* This has different meanings for print and scan */
1502
if (TYPE_PRINT == type)
1504
/* Read with from parameter */
1505
int width = TrioGetPosition(format, &offset);
1506
parameter->flags |= (FLAGS_WIDTH | FLAGS_WIDTH_PARAMETER);
1507
if (NO_POSITION != width)
1508
parameter->width = width;
1509
/* else keep parameter->width = NO_WIDTH which != NO_POSITION */
1511
#if TRIO_FEATURE_SCANF
1514
/* Scan, but do not store result */
1515
parameter->flags |= FLAGS_IGNORE;
1518
break; /* QUALIFIER_STAR */
1521
if (! (parameter->flags & FLAGS_LEFTADJUST))
1522
parameter->flags |= FLAGS_NILPADDING;
1524
case '1': case '2': case '3': case '4':
1525
case '5': case '6': case '7': case '8': case '9':
1526
parameter->flags |= FLAGS_WIDTH;
1528
* &format[offset - 1] is used to "rewind" the read
1529
* character from format
1531
parameter->width = trio_to_long(&format[offset - 1],
1534
offset = (int)(tmpformat - format);
1537
case QUALIFIER_SHORT:
1538
if (parameter->flags & FLAGS_SHORTSHORT)
1539
return TRIO_ERROR_RETURN(TRIO_EINVAL, offset);
1540
else if (parameter->flags & FLAGS_SHORT)
1541
parameter->flags |= FLAGS_SHORTSHORT;
1543
parameter->flags |= FLAGS_SHORT;
1546
case QUALIFIER_LONG:
1547
if (parameter->flags & FLAGS_QUAD)
1548
return TRIO_ERROR_RETURN(TRIO_EINVAL, offset);
1549
else if (parameter->flags & FLAGS_LONG)
1550
parameter->flags |= FLAGS_QUAD;
1552
parameter->flags |= FLAGS_LONG;
1555
#if TRIO_FEATURE_LONGDOUBLE
1556
case QUALIFIER_LONG_UPPER:
1557
parameter->flags |= FLAGS_LONGDOUBLE;
1561
#if TRIO_FEATURE_SIZE_T
1562
case QUALIFIER_SIZE_T:
1563
parameter->flags |= FLAGS_SIZE_T;
1564
/* Modify flags for later truncation of number */
1565
if (sizeof(size_t) == sizeof(trio_ulonglong_t))
1566
parameter->flags |= FLAGS_QUAD;
1567
else if (sizeof(size_t) == sizeof(long))
1568
parameter->flags |= FLAGS_LONG;
1572
#if TRIO_FEATURE_PTRDIFF_T
1573
case QUALIFIER_PTRDIFF_T:
1574
parameter->flags |= FLAGS_PTRDIFF_T;
1575
if (sizeof(ptrdiff_t) == sizeof(trio_ulonglong_t))
1576
parameter->flags |= FLAGS_QUAD;
1577
else if (sizeof(ptrdiff_t) == sizeof(long))
1578
parameter->flags |= FLAGS_LONG;
1582
#if TRIO_FEATURE_INTMAX_T
1583
case QUALIFIER_INTMAX_T:
1584
parameter->flags |= FLAGS_INTMAX_T;
1585
if (sizeof(trio_intmax_t) == sizeof(trio_ulonglong_t))
1586
parameter->flags |= FLAGS_QUAD;
1587
else if (sizeof(trio_intmax_t) == sizeof(long))
1588
parameter->flags |= FLAGS_LONG;
1592
#if TRIO_FEATURE_QUAD
1593
case QUALIFIER_QUAD:
1594
parameter->flags |= FLAGS_QUAD;
1598
#if TRIO_FEATURE_FIXED_SIZE
1599
case QUALIFIER_FIXED_SIZE:
1600
if (parameter->flags & FLAGS_FIXED_SIZE)
1601
return TRIO_ERROR_RETURN(TRIO_EINVAL, offset);
1603
if (parameter->flags & (FLAGS_ALL_SIZES |
1606
FLAGS_VARSIZE_PARAMETER))
1607
return TRIO_ERROR_RETURN(TRIO_EINVAL, offset);
1609
if ((format[offset] == '6') &&
1610
(format[offset + 1] == '4'))
1612
parameter->varsize = sizeof(trio_int64_t);
1615
else if ((format[offset] == '3') &&
1616
(format[offset + 1] == '2'))
1618
parameter->varsize = sizeof(trio_int32_t);
1621
else if ((format[offset] == '1') &&
1622
(format[offset + 1] == '6'))
1624
parameter->varsize = sizeof(trio_int16_t);
1627
else if (format[offset] == '8')
1629
parameter->varsize = sizeof(trio_int8_t);
1633
return TRIO_ERROR_RETURN(TRIO_EINVAL, offset);
1635
parameter->flags |= FLAGS_FIXED_SIZE;
1637
#endif /* TRIO_FEATURE_FIXED_SIZE */
1639
#if defined(QUALIFIER_WIDECHAR)
1640
case QUALIFIER_WIDECHAR:
1641
parameter->flags |= FLAGS_WIDECHAR;
1645
#if TRIO_FEATURE_SIZE_T_UPPER
1646
case QUALIFIER_SIZE_T_UPPER:
1650
#if TRIO_FEATURE_QUOTE
1651
case QUALIFIER_QUOTE:
1652
parameter->flags |= FLAGS_QUOTE;
1656
#if TRIO_FEATURE_STICKY
1657
case QUALIFIER_STICKY:
1658
parameter->flags |= FLAGS_STICKY;
1662
#if TRIO_FEATURE_VARSIZE
1663
case QUALIFIER_VARSIZE:
1664
parameter->flags |= FLAGS_VARSIZE_PARAMETER;
1668
#if TRIO_FEATURE_ROUNDING
1669
case QUALIFIER_ROUNDING_UPPER:
1670
parameter->flags |= FLAGS_ROUNDING;
1675
/* Bail out completely to make the error more obvious */
1676
return TRIO_ERROR_RETURN(TRIO_EINVAL, offset);
1678
} /* while qualifier */
1680
parameter->endOffset = offset;
1685
/*************************************************************************
1686
* TrioParseSpecifier
1689
* Parse the specifier part of a potential conversion specifier
1693
TRIO_ARGS4((type, format, offset, parameter),
1695
TRIO_CONST char *format,
1697
trio_parameter_t *parameter)
1699
parameter->baseSpecifier = NO_BASE;
1701
switch (format[offset++])
1703
#if defined(SPECIFIER_CHAR_UPPER)
1704
case SPECIFIER_CHAR_UPPER:
1705
parameter->flags |= FLAGS_WIDECHAR;
1708
case SPECIFIER_CHAR:
1709
if (parameter->flags & FLAGS_LONG)
1710
parameter->flags |= FLAGS_WIDECHAR;
1711
else if (parameter->flags & FLAGS_SHORT)
1712
parameter->flags &= ~FLAGS_WIDECHAR;
1713
parameter->type = FORMAT_CHAR;
1716
#if defined(SPECIFIER_STRING_UPPER)
1717
case SPECIFIER_STRING_UPPER:
1718
parameter->flags |= FLAGS_WIDECHAR;
1721
case SPECIFIER_STRING:
1722
if (parameter->flags & FLAGS_LONG)
1723
parameter->flags |= FLAGS_WIDECHAR;
1724
else if (parameter->flags & FLAGS_SHORT)
1725
parameter->flags &= ~FLAGS_WIDECHAR;
1726
parameter->type = FORMAT_STRING;
1729
#if defined(SPECIFIER_GROUP)
1730
case SPECIFIER_GROUP:
1731
if (TYPE_SCAN == type)
1734
parameter->type = FORMAT_GROUP;
1735
if (format[offset] == QUALIFIER_CIRCUMFLEX)
1737
if (format[offset] == SPECIFIER_UNGROUP)
1739
if (format[offset] == QUALIFIER_MINUS)
1741
/* Skip nested brackets */
1742
while (format[offset] != NIL)
1744
if (format[offset] == SPECIFIER_GROUP)
1748
else if (format[offset] == SPECIFIER_UNGROUP)
1760
#endif /* defined(SPECIFIER_GROUP) */
1762
case SPECIFIER_INTEGER:
1763
parameter->type = FORMAT_INT;
1766
case SPECIFIER_UNSIGNED:
1767
parameter->flags |= FLAGS_UNSIGNED;
1768
parameter->type = FORMAT_INT;
1771
case SPECIFIER_DECIMAL:
1772
parameter->baseSpecifier = BASE_DECIMAL;
1773
parameter->type = FORMAT_INT;
1776
case SPECIFIER_OCTAL:
1777
parameter->flags |= FLAGS_UNSIGNED;
1778
parameter->baseSpecifier = BASE_OCTAL;
1779
parameter->type = FORMAT_INT;
1782
#if TRIO_FEATURE_BINARY
1783
case SPECIFIER_BINARY_UPPER:
1784
parameter->flags |= FLAGS_UPPER;
1786
case SPECIFIER_BINARY:
1787
parameter->flags |= FLAGS_NILPADDING;
1788
parameter->baseSpecifier = BASE_BINARY;
1789
parameter->type = FORMAT_INT;
1793
case SPECIFIER_HEX_UPPER:
1794
parameter->flags |= FLAGS_UPPER;
1797
parameter->flags |= FLAGS_UNSIGNED;
1798
parameter->baseSpecifier = BASE_HEX;
1799
parameter->type = FORMAT_INT;
1802
#if defined(SPECIFIER_FLOAT_E)
1803
# if defined(SPECIFIER_FLOAT_E_UPPER)
1804
case SPECIFIER_FLOAT_E_UPPER:
1805
parameter->flags |= FLAGS_UPPER;
1808
case SPECIFIER_FLOAT_E:
1809
parameter->flags |= FLAGS_FLOAT_E;
1810
parameter->type = FORMAT_DOUBLE;
1814
#if defined(SPECIFIER_FLOAT_G)
1815
# if defined(SPECIFIER_FLOAT_G_UPPER)
1816
case SPECIFIER_FLOAT_G_UPPER:
1817
parameter->flags |= FLAGS_UPPER;
1820
case SPECIFIER_FLOAT_G:
1821
parameter->flags |= FLAGS_FLOAT_G;
1822
parameter->type = FORMAT_DOUBLE;
1826
#if defined(SPECIFIER_FLOAT_F)
1827
# if defined(SPECIFIER_FLOAT_F_UPPER)
1828
case SPECIFIER_FLOAT_F_UPPER:
1829
parameter->flags |= FLAGS_UPPER;
1832
case SPECIFIER_FLOAT_F:
1833
parameter->type = FORMAT_DOUBLE;
1837
#if defined(TRIO_COMPILER_VISUALC)
1838
# pragma warning( push )
1839
# pragma warning( disable : 4127 ) /* Conditional expression is constant */
1841
case SPECIFIER_POINTER:
1842
if (sizeof(trio_pointer_t) == sizeof(trio_ulonglong_t))
1843
parameter->flags |= FLAGS_QUAD;
1844
else if (sizeof(trio_pointer_t) == sizeof(long))
1845
parameter->flags |= FLAGS_LONG;
1846
parameter->type = FORMAT_POINTER;
1848
#if defined(TRIO_COMPILER_VISUALC)
1849
# pragma warning( pop )
1852
case SPECIFIER_COUNT:
1853
parameter->type = FORMAT_COUNT;
1856
#if TRIO_FEATURE_HEXFLOAT
1857
case SPECIFIER_HEXFLOAT_UPPER:
1858
parameter->flags |= FLAGS_UPPER;
1860
case SPECIFIER_HEXFLOAT:
1861
parameter->baseSpecifier = BASE_HEX;
1862
parameter->type = FORMAT_DOUBLE;
1866
#if TRIO_FEATURE_ERRNO
1867
case SPECIFIER_ERRNO:
1868
parameter->type = FORMAT_ERRNO;
1872
#if TRIO_FEATURE_USER_DEFINED
1873
case SPECIFIER_USER_DEFINED_BEGIN:
1876
int without_namespace = TRUE;
1877
char* tmpformat = (char *)&format[offset];
1880
parameter->type = FORMAT_USER_DEFINED;
1881
parameter->user_defined.namespace[0] = NIL;
1883
while ((ch = format[offset]) != NIL)
1886
if ((ch == SPECIFIER_USER_DEFINED_END) || (ch == SPECIFIER_USER_DEFINED_EXTRA))
1888
if (without_namespace)
1889
/* No namespace, handler will be passed as an argument */
1890
parameter->flags |= FLAGS_USER_DEFINED_PARAMETER;
1892
/* Copy the user data */
1893
max = (unsigned int)(&format[offset] - tmpformat);
1894
if (max > MAX_USER_DATA)
1895
max = MAX_USER_DATA;
1896
trio_copy_max(parameter->user_data, max, tmpformat);
1898
/* Skip extra data (which is only there to keep the compiler happy) */
1899
while ((ch != NIL) && (ch != SPECIFIER_USER_DEFINED_END))
1900
ch = format[offset++];
1905
if (ch == SPECIFIER_USER_DEFINED_SEPARATOR)
1907
without_namespace = FALSE;
1908
/* Copy the namespace for later looking-up */
1909
max = (int)(&format[offset] - tmpformat);
1910
if (max > MAX_USER_NAME)
1911
max = MAX_USER_NAME;
1912
trio_copy_max(parameter->user_defined.namespace, max, tmpformat);
1913
tmpformat = (char *)&format[offset];
1917
if (ch != SPECIFIER_USER_DEFINED_END)
1918
return TRIO_ERROR_RETURN(TRIO_EINVAL, offset);
1921
#endif /* TRIO_FEATURE_USER_DEFINED */
1924
/* Bail out completely to make the error more obvious */
1925
return TRIO_ERROR_RETURN(TRIO_EINVAL, offset);
1928
parameter->endOffset = offset;
1140
1933
/*************************************************************************
1194
1979
memset(usedEntries, 0, sizeof(usedEntries));
1196
1981
save_errno = errno;
1198
1983
parameterPosition = 0;
1199
1984
#if defined(TRIO_COMPILER_SUPPORTS_MULTIBYTE)
1200
1985
(void)mblen(NULL, 0);
1203
while (format[index])
1988
while (format[offset])
1990
TrioInitializeParameter(&workParameter);
1205
1992
#if defined(TRIO_COMPILER_SUPPORTS_MULTIBYTE)
1206
if (! isascii(format[index]))
1993
if (! isascii(format[offset]))
1209
1996
* Multibyte characters cannot be legal specifiers or
1210
1997
* modifiers, so we skip over them.
1212
charlen = mblen(&format[index], MB_LEN_MAX);
1213
index += (charlen > 0) ? charlen : 1;
1999
charlen = mblen(&format[offset], MB_LEN_MAX);
2000
offset += (charlen > 0) ? charlen : 1;
1214
2001
continue; /* while */
1216
2003
#endif /* TRIO_COMPILER_SUPPORTS_MULTIBYTE */
1217
if (CHAR_IDENTIFIER == format[index++])
2005
switch(format[offset++]) {
2007
case CHAR_IDENTIFIER:
1219
if (CHAR_IDENTIFIER == format[index])
2009
if (CHAR_IDENTIFIER == format[offset])
2011
/* skip double "%" */
1222
2013
continue; /* while */
1227
currentParam = TrioGetPosition(format, &index);
1228
positional = (NO_POSITION != currentParam);
1231
/* We have no positional, get the next counter */
1232
currentParam = parameterPosition;
1234
if(currentParam >= MAX_PARAMETERS)
1236
/* Bail out completely to make the error more obvious */
1237
return TRIO_ERROR_RETURN(TRIO_ETOOMANY, index);
1240
if (currentParam > maxParam)
1241
maxParam = currentParam;
1243
/* Default values */
1245
precision = NO_PRECISION;
1249
while (TrioIsQualifier(format[index]))
1251
ch = format[index++];
1255
case QUALIFIER_SPACE:
1256
flags |= FLAGS_SPACE;
1259
case QUALIFIER_PLUS:
1260
flags |= FLAGS_SHOWSIGN;
1263
case QUALIFIER_MINUS:
1264
flags |= FLAGS_LEFTADJUST;
1265
flags &= ~FLAGS_NILPADDING;
1268
case QUALIFIER_ALTERNATIVE:
1269
flags |= FLAGS_ALTERNATIVE;
1273
if (dots == 0) /* Precision */
1277
/* Skip if no precision */
1278
if (QUALIFIER_DOT == format[index])
1281
/* After the first dot we have the precision */
1282
flags |= FLAGS_PRECISION;
1283
if ((QUALIFIER_STAR == format[index])
1284
#if defined(QUALIFIER_PARAM)
1285
|| (QUALIFIER_PARAM == format[index])
1290
flags |= FLAGS_PRECISION_PARAMETER;
1292
precision = TrioGetPosition(format, &index);
1293
if (precision == NO_POSITION)
1295
parameterPosition++;
1297
precision = parameterPosition;
1300
precision = currentParam;
1301
currentParam = precision + 1;
1307
currentParam = precision + 1;
1308
if (width > maxParam)
1309
maxParam = precision;
1311
if (currentParam > maxParam)
1312
maxParam = currentParam;
1316
precision = trio_to_long(&format[index],
1319
index = (int)(tmpformat - format);
1322
else if (dots == 1) /* Base */
1326
/* After the second dot we have the base */
1327
flags |= FLAGS_BASE;
1328
if ((QUALIFIER_STAR == format[index])
1329
#if defined(QUALIFIER_PARAM)
1330
|| (QUALIFIER_PARAM == format[index])
1335
flags |= FLAGS_BASE_PARAMETER;
1336
base = TrioGetPosition(format, &index);
1337
if (base == NO_POSITION)
1339
parameterPosition++;
1341
base = parameterPosition;
1344
base = currentParam;
1345
currentParam = base + 1;
1351
currentParam = base + 1;
1352
if (base > maxParam)
1355
if (currentParam > maxParam)
1356
maxParam = currentParam;
1360
base = trio_to_long(&format[index],
1363
if (base > MAX_BASE)
1364
return TRIO_ERROR_RETURN(TRIO_EINVAL, index);
1365
index = (int)(tmpformat - format);
1370
return TRIO_ERROR_RETURN(TRIO_EINVAL, index);
1372
break; /* QUALIFIER_DOT */
1374
#if defined(QUALIFIER_PARAM)
1375
case QUALIFIER_PARAM:
1379
case QUALIFIER_STAR:
1380
/* This has different meanings for print and scan */
1381
if (TYPE_PRINT == type)
1383
/* Read with from parameter */
1384
flags |= (FLAGS_WIDTH | FLAGS_WIDTH_PARAMETER);
1385
width = TrioGetPosition(format, &index);
1386
if (width == NO_POSITION)
1388
parameterPosition++;
1390
width = parameterPosition;
1393
width = currentParam;
1394
currentParam = width + 1;
1400
currentParam = width + 1;
1401
if (width > maxParam)
1404
if (currentParam > maxParam)
1405
maxParam = currentParam;
1409
/* Scan, but do not store result */
1410
flags |= FLAGS_IGNORE;
1413
break; /* QUALIFIER_STAR */
1416
if (! (flags & FLAGS_LEFTADJUST))
1417
flags |= FLAGS_NILPADDING;
1419
case '1': case '2': case '3': case '4':
1420
case '5': case '6': case '7': case '8': case '9':
1421
flags |= FLAGS_WIDTH;
1422
/* &format[index - 1] is used to "rewind" the read
1423
* character from format
1425
width = trio_to_long(&format[index - 1],
1428
index = (int)(tmpformat - format);
1431
case QUALIFIER_SHORT:
1432
if (flags & FLAGS_SHORTSHORT)
1433
return TRIO_ERROR_RETURN(TRIO_EINVAL, index);
1434
else if (flags & FLAGS_SHORT)
1435
flags |= FLAGS_SHORTSHORT;
1437
flags |= FLAGS_SHORT;
1440
case QUALIFIER_LONG:
1441
if (flags & FLAGS_QUAD)
1442
return TRIO_ERROR_RETURN(TRIO_EINVAL, index);
1443
else if (flags & FLAGS_LONG)
1444
flags |= FLAGS_QUAD;
1446
flags |= FLAGS_LONG;
1449
case QUALIFIER_LONG_UPPER:
1450
flags |= FLAGS_LONGDOUBLE;
1453
#if defined(QUALIFIER_SIZE_T)
1454
case QUALIFIER_SIZE_T:
1455
flags |= FLAGS_SIZE_T;
1456
/* Modify flags for later truncation of number */
1457
if (sizeof(size_t) == sizeof(trio_ulonglong_t))
1458
flags |= FLAGS_QUAD;
1459
else if (sizeof(size_t) == sizeof(long))
1460
flags |= FLAGS_LONG;
1464
#if defined(QUALIFIER_PTRDIFF_T)
1465
case QUALIFIER_PTRDIFF_T:
1466
flags |= FLAGS_PTRDIFF_T;
1467
if (sizeof(ptrdiff_t) == sizeof(trio_ulonglong_t))
1468
flags |= FLAGS_QUAD;
1469
else if (sizeof(ptrdiff_t) == sizeof(long))
1470
flags |= FLAGS_LONG;
1474
#if defined(QUALIFIER_INTMAX_T)
1475
case QUALIFIER_INTMAX_T:
1476
flags |= FLAGS_INTMAX_T;
1477
if (sizeof(trio_intmax_t) == sizeof(trio_ulonglong_t))
1478
flags |= FLAGS_QUAD;
1479
else if (sizeof(trio_intmax_t) == sizeof(long))
1480
flags |= FLAGS_LONG;
1484
#if defined(QUALIFIER_QUAD)
1485
case QUALIFIER_QUAD:
1486
flags |= FLAGS_QUAD;
1490
#if defined(QUALIFIER_FIXED_SIZE)
1491
case QUALIFIER_FIXED_SIZE:
1492
if (flags & FLAGS_FIXED_SIZE)
1493
return TRIO_ERROR_RETURN(TRIO_EINVAL, index);
1495
if (flags & (FLAGS_ALL_SIZES | FLAGS_LONGDOUBLE |
1496
FLAGS_WIDECHAR | FLAGS_VARSIZE_PARAMETER))
1497
return TRIO_ERROR_RETURN(TRIO_EINVAL, index);
1499
if ((format[index] == '6') &&
1500
(format[index + 1] == '4'))
1502
varsize = sizeof(trio_int64_t);
1505
else if ((format[index] == '3') &&
1506
(format[index + 1] == '2'))
1508
varsize = sizeof(trio_int32_t);
1511
else if ((format[index] == '1') &&
1512
(format[index + 1] == '6'))
1514
varsize = sizeof(trio_int16_t);
1517
else if (format[index] == '8')
1519
varsize = sizeof(trio_int8_t);
1523
return TRIO_ERROR_RETURN(TRIO_EINVAL, index);
1525
flags |= FLAGS_FIXED_SIZE;
1529
#if defined(QUALIFIER_WIDECHAR)
1530
case QUALIFIER_WIDECHAR:
1531
flags |= FLAGS_WIDECHAR;
1535
#if defined(QUALIFIER_SIZE_T_UPPER)
1536
case QUALIFIER_SIZE_T_UPPER:
1540
#if defined(QUALIFIER_QUOTE)
1541
case QUALIFIER_QUOTE:
1542
flags |= FLAGS_QUOTE;
1546
#if defined(QUALIFIER_STICKY)
1547
case QUALIFIER_STICKY:
1548
flags |= FLAGS_STICKY;
1553
#if defined(QUALIFIER_VARSIZE)
1554
case QUALIFIER_VARSIZE:
1555
flags |= FLAGS_VARSIZE_PARAMETER;
1556
parameterPosition++;
1558
varsize = parameterPosition;
1561
varsize = currentParam;
1562
currentParam = varsize + 1;
1564
if (currentParam > maxParam)
1565
maxParam = currentParam;
1569
#if defined(QUALIFIER_ROUNDING_UPPER)
1570
case QUALIFIER_ROUNDING_UPPER:
1571
flags |= FLAGS_ROUNDING;
1576
/* Bail out completely to make the error more obvious */
1577
return TRIO_ERROR_RETURN(TRIO_EINVAL, index);
1579
} /* while qualifier */
1582
* Parameters only need the type and value. The value is
1585
if (flags & FLAGS_WIDTH_PARAMETER)
1587
usedEntries[width] += 1;
1588
parameters[pos].type = FORMAT_PARAMETER;
1589
parameters[pos].flags = 0;
1590
indices[width] = pos;
1593
if (flags & FLAGS_PRECISION_PARAMETER)
1595
usedEntries[precision] += 1;
1596
parameters[pos].type = FORMAT_PARAMETER;
1597
parameters[pos].flags = 0;
1598
indices[precision] = pos;
1601
if (flags & FLAGS_BASE_PARAMETER)
1603
usedEntries[base] += 1;
1604
parameters[pos].type = FORMAT_PARAMETER;
1605
parameters[pos].flags = 0;
1606
indices[base] = pos;
1609
if (flags & FLAGS_VARSIZE_PARAMETER)
1611
usedEntries[varsize] += 1;
1612
parameters[pos].type = FORMAT_PARAMETER;
1613
parameters[pos].flags = 0;
1614
indices[varsize] = pos;
1618
indices[currentParam] = pos;
1620
switch (format[index++])
1622
#if defined(SPECIFIER_CHAR_UPPER)
1623
case SPECIFIER_CHAR_UPPER:
1624
flags |= FLAGS_WIDECHAR;
1627
case SPECIFIER_CHAR:
1628
if (flags & FLAGS_LONG)
1629
flags |= FLAGS_WIDECHAR;
1630
else if (flags & FLAGS_SHORT)
1631
flags &= ~FLAGS_WIDECHAR;
1632
parameters[pos].type = FORMAT_CHAR;
1635
#if defined(SPECIFIER_STRING_UPPER)
1636
case SPECIFIER_STRING_UPPER:
1637
flags |= FLAGS_WIDECHAR;
1640
case SPECIFIER_STRING:
1641
if (flags & FLAGS_LONG)
1642
flags |= FLAGS_WIDECHAR;
1643
else if (flags & FLAGS_SHORT)
1644
flags &= ~FLAGS_WIDECHAR;
1645
parameters[pos].type = FORMAT_STRING;
1648
case SPECIFIER_GROUP:
1649
if (TYPE_SCAN == type)
1652
parameters[pos].type = FORMAT_GROUP;
1653
if (format[index] == QUALIFIER_CIRCUMFLEX)
1655
if (format[index] == SPECIFIER_UNGROUP)
1657
if (format[index] == QUALIFIER_MINUS)
1659
/* Skip nested brackets */
1660
while (format[index] != NIL)
1662
if (format[index] == SPECIFIER_GROUP)
1666
else if (format[index] == SPECIFIER_UNGROUP)
1679
case SPECIFIER_INTEGER:
1680
parameters[pos].type = FORMAT_INT;
1683
case SPECIFIER_UNSIGNED:
1684
flags |= FLAGS_UNSIGNED;
1685
parameters[pos].type = FORMAT_INT;
1688
case SPECIFIER_DECIMAL:
1689
/* Disable base modifier */
1690
flags &= ~FLAGS_BASE_PARAMETER;
1691
base = BASE_DECIMAL;
1692
parameters[pos].type = FORMAT_INT;
1695
case SPECIFIER_OCTAL:
1696
flags |= FLAGS_UNSIGNED;
1697
flags &= ~FLAGS_BASE_PARAMETER;
1699
parameters[pos].type = FORMAT_INT;
1702
#if defined(SPECIFIER_BINARY)
1703
case SPECIFIER_BINARY_UPPER:
1704
flags |= FLAGS_UPPER;
1706
case SPECIFIER_BINARY:
1707
flags |= FLAGS_NILPADDING;
1708
flags &= ~FLAGS_BASE_PARAMETER;
1710
parameters[pos].type = FORMAT_INT;
1714
case SPECIFIER_HEX_UPPER:
1715
flags |= FLAGS_UPPER;
1718
flags |= FLAGS_UNSIGNED;
1719
flags &= ~FLAGS_BASE_PARAMETER;
1721
parameters[pos].type = FORMAT_INT;
1724
case SPECIFIER_FLOAT_E_UPPER:
1725
flags |= FLAGS_UPPER;
1727
case SPECIFIER_FLOAT_E:
1728
flags |= FLAGS_FLOAT_E;
1729
parameters[pos].type = FORMAT_DOUBLE;
1732
case SPECIFIER_FLOAT_G_UPPER:
1733
flags |= FLAGS_UPPER;
1735
case SPECIFIER_FLOAT_G:
1736
flags |= FLAGS_FLOAT_G;
1737
parameters[pos].type = FORMAT_DOUBLE;
1740
case SPECIFIER_FLOAT_F_UPPER:
1741
flags |= FLAGS_UPPER;
1743
case SPECIFIER_FLOAT_F:
1744
parameters[pos].type = FORMAT_DOUBLE;
1747
case SPECIFIER_POINTER:
1748
if (sizeof(trio_pointer_t) == sizeof(trio_ulonglong_t))
1749
flags |= FLAGS_QUAD;
1750
else if (sizeof(trio_pointer_t) == sizeof(long))
1751
flags |= FLAGS_LONG;
1752
parameters[pos].type = FORMAT_POINTER;
1755
case SPECIFIER_COUNT:
1756
parameters[pos].type = FORMAT_COUNT;
1759
#if defined(SPECIFIER_HEXFLOAT)
1760
# if defined(SPECIFIER_HEXFLOAT_UPPER)
1761
case SPECIFIER_HEXFLOAT_UPPER:
1762
flags |= FLAGS_UPPER;
1765
case SPECIFIER_HEXFLOAT:
1767
parameters[pos].type = FORMAT_DOUBLE;
1771
#if defined(FORMAT_ERRNO)
1772
case SPECIFIER_ERRNO:
1773
parameters[pos].type = FORMAT_ERRNO;
1777
#if defined(SPECIFIER_USER_DEFINED_BEGIN)
1778
case SPECIFIER_USER_DEFINED_BEGIN:
1781
int without_namespace = TRUE;
1783
parameters[pos].type = FORMAT_USER_DEFINED;
1784
parameters[pos].user_name[0] = NIL;
1785
tmpformat = (char *)&format[index];
1787
while ((ch = format[index]))
1790
if (ch == SPECIFIER_USER_DEFINED_END)
1792
if (without_namespace)
1794
/* We must get the handle first */
1795
parameters[pos].type = FORMAT_PARAMETER;
1796
parameters[pos].indexAfterSpecifier = index;
1797
parameters[pos].flags = FLAGS_USER_DEFINED;
1798
/* Adjust parameters for insertion of new one */
1800
usedEntries[currentParam] += 1;
1801
parameters[pos].type = FORMAT_USER_DEFINED;
1803
indices[currentParam] = pos;
1804
if (currentParam > maxParam)
1805
maxParam = currentParam;
1807
/* Copy the user data */
1808
max = (unsigned int)(&format[index] - tmpformat);
1809
if (max > MAX_USER_DATA)
1810
max = MAX_USER_DATA;
1811
trio_copy_max(parameters[pos].user_data,
1816
if (ch == SPECIFIER_USER_DEFINED_SEPARATOR)
1818
without_namespace = FALSE;
1819
/* Copy the namespace for later looking-up */
1820
max = (int)(&format[index] - tmpformat);
1821
if (max > MAX_USER_NAME)
1822
max = MAX_USER_NAME;
1823
trio_copy_max(parameters[pos].user_name,
1826
tmpformat = (char *)&format[index];
1829
if (ch != SPECIFIER_USER_DEFINED_END)
1830
return TRIO_ERROR_RETURN(TRIO_EINVAL, index);
1833
#endif /* defined(SPECIFIER_USER_DEFINED_BEGIN) */
1836
/* Bail out completely to make the error more obvious */
1837
return TRIO_ERROR_RETURN(TRIO_EINVAL, index);
1840
/* Count the number of times this entry has been used */
1841
usedEntries[currentParam] += 1;
1843
/* Find last sticky parameters */
1844
if (gotSticky && !(flags & FLAGS_STICKY))
1846
for (i = pos - 1; i >= 0; i--)
1848
if (parameters[i].type == FORMAT_PARAMETER)
1850
if ((parameters[i].flags & FLAGS_STICKY) &&
1851
(parameters[i].type == parameters[pos].type))
1853
/* Do not overwrite current qualifiers */
1854
flags |= (parameters[i].flags & (unsigned long)~FLAGS_STICKY);
1855
if (width == NO_WIDTH)
1856
width = parameters[i].width;
1857
if (precision == NO_PRECISION)
1858
precision = parameters[i].precision;
1859
if (base == NO_BASE)
1860
base = parameters[i].base;
1866
parameters[pos].indexAfterSpecifier = index;
1867
parameters[pos].flags = flags;
1868
parameters[pos].width = width;
1869
parameters[pos].precision = precision;
1870
parameters[pos].base = (base == NO_BASE) ? BASE_DECIMAL : base;
1871
parameters[pos].varsize = varsize;
1875
parameterPosition++;
1877
} /* if identifier */
2016
status = TrioParseQualifiers(type, format, offset, &workParameter);
2018
return status; /* Return qualifier syntax error */
2020
status = TrioParseSpecifier(type, format, workParameter.endOffset, &workParameter);
2022
return status; /* Return specifier syntax error */
2027
case CHAR_ALT_IDENTIFIER:
2029
status = TrioParseQualifiers(type, format, offset, &workParameter);
2031
continue; /* False alert, not a user defined specifier */
2033
status = TrioParseSpecifier(type, format, workParameter.endOffset, &workParameter);
2034
if ((status < 0) || (FORMAT_USER_DEFINED != workParameter.type))
2035
continue; /* False alert, not a user defined specifier */
2041
continue; /* while */
2044
/* now handle the parsed conversion specification */
2045
positional = (NO_POSITION != workParameter.position);
2048
* Parameters only need the type and value. The value is
2051
if (workParameter.flags & FLAGS_WIDTH_PARAMETER)
2053
if (workParameter.width == NO_WIDTH)
2055
workParameter.width = parameterPosition++;
2060
workParameter.position = workParameter.width + 1;
2063
usedEntries[workParameter.width] += 1;
2064
if (workParameter.width > maxParam)
2065
maxParam = workParameter.width;
2066
parameters[pos].type = FORMAT_PARAMETER;
2067
parameters[pos].flags = 0;
2068
indices[workParameter.width] = pos;
2069
workParameter.width = pos++;
2071
if (workParameter.flags & FLAGS_PRECISION_PARAMETER)
2073
if (workParameter.precision == NO_PRECISION)
2075
workParameter.precision = parameterPosition++;
2080
workParameter.position = workParameter.precision + 1;
2083
usedEntries[workParameter.precision] += 1;
2084
if (workParameter.precision > maxParam)
2085
maxParam = workParameter.precision;
2086
parameters[pos].type = FORMAT_PARAMETER;
2087
parameters[pos].flags = 0;
2088
indices[workParameter.precision] = pos;
2089
workParameter.precision = pos++;
2091
if (workParameter.flags & FLAGS_BASE_PARAMETER)
2093
if (workParameter.base == NO_BASE)
2095
workParameter.base = parameterPosition++;
2100
workParameter.position = workParameter.base + 1;
2103
usedEntries[workParameter.base] += 1;
2104
if (workParameter.base > maxParam)
2105
maxParam = workParameter.base;
2106
parameters[pos].type = FORMAT_PARAMETER;
2107
parameters[pos].flags = 0;
2108
indices[workParameter.base] = pos;
2109
workParameter.base = pos++;
2111
#if TRIO_FEATURE_VARSIZE
2112
if (workParameter.flags & FLAGS_VARSIZE_PARAMETER)
2114
workParameter.varsize = parameterPosition++;
2116
usedEntries[workParameter.varsize] += 1;
2117
if (workParameter.varsize > maxParam)
2118
maxParam = workParameter.varsize;
2119
parameters[pos].type = FORMAT_PARAMETER;
2120
parameters[pos].flags = 0;
2121
indices[workParameter.varsize] = pos;
2122
workParameter.varsize = pos++;
2125
#if TRIO_FEATURE_USER_DEFINED
2126
if (workParameter.flags & FLAGS_USER_DEFINED_PARAMETER)
2128
workParameter.user_defined.handler = parameterPosition++;
2130
usedEntries[workParameter.user_defined.handler] += 1;
2131
if (workParameter.user_defined.handler > maxParam)
2132
maxParam = workParameter.user_defined.handler;
2133
parameters[pos].type = FORMAT_PARAMETER;
2134
parameters[pos].flags = FLAGS_USER_DEFINED;
2135
indices[workParameter.user_defined.handler] = pos;
2136
workParameter.user_defined.handler = pos++;
2140
if (NO_POSITION == workParameter.position)
2142
workParameter.position = parameterPosition++;
2145
if (workParameter.position > maxParam)
2146
maxParam = workParameter.position;
2148
if (workParameter.position >= MAX_PARAMETERS)
2150
/* Bail out completely to make the error more obvious */
2151
return TRIO_ERROR_RETURN(TRIO_ETOOMANY, offset);
2154
indices[workParameter.position] = pos;
2156
/* Count the number of times this entry has been used */
2157
usedEntries[workParameter.position] += 1;
2159
/* Find last sticky parameters */
2160
#if TRIO_FEATURE_STICKY
2161
if (workParameter.flags & FLAGS_STICKY)
2167
for (i = pos - 1; i >= 0; i--)
2169
if (parameters[i].type == FORMAT_PARAMETER)
2171
if ((parameters[i].flags & FLAGS_STICKY) &&
2172
(parameters[i].type == workParameter.type))
2174
/* Do not overwrite current qualifiers */
2175
workParameter.flags |= (parameters[i].flags & (unsigned long)~FLAGS_STICKY);
2176
if (workParameter.width == NO_WIDTH)
2177
workParameter.width = parameters[i].width;
2178
if (workParameter.precision == NO_PRECISION)
2179
workParameter.precision = parameters[i].precision;
2180
if (workParameter.base == NO_BASE)
2181
workParameter.base = parameters[i].base;
2188
if (workParameter.base == NO_BASE)
2189
workParameter.base = BASE_DECIMAL;
2191
offset = workParameter.endOffset;
2193
TrioCopyParameter(¶meters[pos++], &workParameter);
1879
2194
} /* while format characters left */
2196
parameters[pos].type = FORMAT_SENTINEL; /* end parameter array with sentinel */
2197
parameters[pos].beginOffset = offset;
1881
2199
for (num = 0; num <= maxParam; num++)
1883
2201
if (usedEntries[num] != 1)
2763
exponent = (int)floorl(workNumber);
2764
number /= powl(dblBase, (trio_long_double_t)exponent);
3129
exponent = (int)trio_floor(workNumber);
3130
workNumber = number;
3132
* The expression A * 10^-B is equivalent to A / 10^B but the former
3133
* usually gives better accuracy.
3135
workNumber *= TrioPower(dblBase, (trio_long_double_t)-exponent);
3136
if (trio_isinf(workNumber)) {
3138
* Scaling is done it two steps to avoid problems with subnormal
3141
workNumber /= TrioPower(dblBase, (trio_long_double_t)(exponent / 2));
3142
workNumber /= TrioPower(dblBase, (trio_long_double_t)(exponent - (exponent / 2)));
3144
number = workNumber;
2765
3145
isExponentNegative = (exponent < 0);
2766
3146
uExponent = (isExponentNegative) ? -exponent : exponent;
2768
3148
uExponent *= 4; /* log16(2) */
3149
#if TRIO_FEATURE_QUOTE
2769
3150
/* No thousand separators */
2770
3151
flags &= ~FLAGS_QUOTE;
2774
integerNumber = floorl(number);
3156
integerNumber = trio_floor(number);
2775
3157
fractionNumber = number - integerNumber;
2778
3160
* Truncated number.
2780
* Precision is number of significant digits for FLOAT_G
2781
* and number of fractional digits for others.
3162
* Precision is number of significant digits for FLOAT_G and number of
3163
* fractional digits for others.
2783
integerDigits = (integerNumber > epsilon)
2784
? 1 + (int)TrioLogarithm(integerNumber, base)
2786
fractionDigits = ((flags & FLAGS_FLOAT_G) && (zeroes == 0))
2787
? precision - integerDigits
2788
: zeroes + precision;
3166
if (integerNumber > epsilon)
3168
integerDigits += (int)TrioLogarithm(integerNumber, base);
3171
fractionDigits = precision;
3172
if (flags & FLAGS_FLOAT_G)
3174
if (leadingFractionZeroes > 0)
3176
fractionDigits += leadingFractionZeroes;
3178
if ((integerNumber > epsilon) || (number <= epsilon))
3180
fractionDigits -= integerDigits;
2790
3184
dblFractionBase = TrioPower(base, fractionDigits);
2792
workNumber = number + 0.5 / dblFractionBase;
2793
if (floorl(number) != floorl(workNumber))
3186
if (integerNumber < 1.0)
3188
workNumber = number * dblFractionBase + TRIO_SUFFIX_LONG(0.5);
3189
if (trio_floor(number * dblFractionBase) != trio_floor(workNumber))
3191
adjustNumber = TRUE;
3192
/* Remove a leading fraction zero if fraction is rounded up */
3193
if ((int)TrioLogarithm(number * dblFractionBase, base) != (int)TrioLogarithm(workNumber, base))
3195
--leadingFractionZeroes;
3198
workNumber /= dblFractionBase;
3202
workNumber = number + TRIO_SUFFIX_LONG(0.5) / dblFractionBase;
3203
adjustNumber = (trio_floor(number) != trio_floor(workNumber));
3207
if ((flags & FLAGS_FLOAT_G) && !(flags & FLAGS_FLOAT_E))
3209
/* The adjustment may require a change to scientific notation */
3210
if ( (workNumber < TRIO_SUFFIX_LONG(1.0E-4)) ||
3211
(workNumber >= TrioPower(base, (trio_long_double_t)precision)) )
3213
/* Use scientific notation */
3214
flags |= FLAGS_FLOAT_E;
2795
3219
if (flags & FLAGS_FLOAT_E)
2797
/* Adjust if number was rounded up one digit (ie. 0.99 to 1.00) */
2799
isExponentNegative = (exponent < 0);
2800
uExponent = (isExponentNegative) ? -exponent : exponent;
2802
uExponent *= 4; /* log16(2) */
2803
workNumber = (number + 0.5 / dblFractionBase) / dblBase;
2804
integerNumber = floorl(workNumber);
2805
fractionNumber = workNumber - integerNumber;
3221
workDigits = 1 + TrioLogarithm(trio_floor(workNumber), base);
3222
if (integerDigits == workDigits)
3224
/* Adjust if the same number of digits are used */
3225
number += TRIO_SUFFIX_LONG(0.5) / dblFractionBase;
3226
integerNumber = trio_floor(number);
3227
fractionNumber = number - integerNumber;
3231
/* Adjust if number was rounded up one digit (ie. 0.99 to 1.00) */
3233
isExponentNegative = (exponent < 0);
3234
uExponent = (isExponentNegative) ? -exponent : exponent;
3236
uExponent *= 4; /* log16(2) */
3237
workNumber = (number + TRIO_SUFFIX_LONG(0.5) / dblFractionBase) / dblBase;
3238
integerNumber = trio_floor(workNumber);
3239
fractionNumber = workNumber - integerNumber;
2809
/* Adjust if number was rounded up one digit (ie. 99 to 100) */
2810
integerNumber = floorl(number + 0.5);
2811
fractionNumber = 0.0;
2812
integerDigits = (integerNumber > epsilon)
2813
? 1 + (int)TrioLogarithm(integerNumber, base)
3244
if (workNumber > 1.0)
3246
/* Adjust if number was rounded up one digit (ie. 99 to 100) */
3247
integerNumber = trio_floor(workNumber);
3248
fractionNumber = 0.0;
3249
integerDigits = (integerNumber > epsilon)
3250
? 1 + (int)TrioLogarithm(integerNumber, base)
3252
if (flags & FLAGS_FLOAT_G)
3254
if (flags & FLAGS_ALTERNATIVE)
3256
if ((integerNumber > epsilon) || (number <= epsilon))
3258
fractionDigits -= integerDigits;
3269
integerNumber = trio_floor(workNumber);
3270
fractionNumber = workNumber - integerNumber;
3271
if (flags & FLAGS_FLOAT_G)
3273
if (flags & FLAGS_ALTERNATIVE)
3275
fractionDigits = precision;
3276
if (leadingFractionZeroes > 0)
3278
fractionDigits += leadingFractionZeroes;
3280
if ((integerNumber > epsilon) || (number <= epsilon))
3282
fractionDigits -= integerDigits;
2818
3290
/* Estimate accuracy */
2819
integerAdjust = fractionAdjust = 0.5;
3291
integerAdjust = fractionAdjust = TRIO_SUFFIX_LONG(0.5);
3292
# if TRIO_FEATURE_ROUNDING
2820
3293
if (flags & FLAGS_ROUNDING)
2822
3295
if (integerDigits > baseDigits)
3055
3593
TRIO_CONST char *format,
3056
3594
trio_parameter_t *parameters)
3058
#if defined(TRIO_COMPILER_SUPPORTS_MULTIBYTE)
3597
#if TRIO_FEATURE_ERRNO
3062
3598
TRIO_CONST char *string;
3063
3600
trio_pointer_t pointer;
3064
3601
trio_flags_t flags;
3072
#if defined(TRIO_COMPILER_SUPPORTS_MULTIBYTE)
3073
(void)mblen(NULL, 0);
3076
while (format[index])
3078
#if defined(TRIO_COMPILER_SUPPORTS_MULTIBYTE)
3079
if (! isascii(format[index]))
3081
charlen = mblen(&format[index], MB_LEN_MAX);
3083
* Only valid multibyte characters are handled here. Invalid
3084
* multibyte characters (charlen == -1) are handled as normal
3089
while (charlen-- > 0)
3091
data->OutStream(data, format[index++]);
3093
continue; /* while characters left in formatting string */
3096
#endif /* TRIO_COMPILER_SUPPORTS_MULTIBYTE */
3097
if (CHAR_IDENTIFIER == format[index])
3099
if (CHAR_IDENTIFIER == format[index + 1])
3612
/* Skip the parameter entries */
3613
while (parameters[i].type == FORMAT_PARAMETER)
3616
/* Copy non conversion-specifier part of format string */
3617
while (offset < parameters[i].beginOffset)
3619
if (CHAR_IDENTIFIER == format[offset] && CHAR_IDENTIFIER == format[offset + 1])
3101
3621
data->OutStream(data, CHAR_IDENTIFIER);
3106
/* Skip the parameter entries */
3107
while (parameters[i].type == FORMAT_PARAMETER)
3110
flags = parameters[i].flags;
3113
width = parameters[i].width;
3114
if (flags & FLAGS_WIDTH_PARAMETER)
3116
/* Get width from parameter list */
3117
width = (int)parameters[width].data.number.as_signed;
3121
* A negative width is the same as the - flag and
3124
flags |= FLAGS_LEFTADJUST;
3125
flags &= ~FLAGS_NILPADDING;
3130
/* Find precision */
3131
if (flags & FLAGS_PRECISION)
3133
precision = parameters[i].precision;
3134
if (flags & FLAGS_PRECISION_PARAMETER)
3136
/* Get precision from parameter list */
3137
precision = (int)parameters[precision].data.number.as_signed;
3141
* A negative precision is the same as no
3144
precision = NO_PRECISION;
3626
data->OutStream(data, format[offset++]);
3630
/* Abort if we reached end of format string */
3631
if (parameters[i].type == FORMAT_SENTINEL)
3634
/* Ouput parameter */
3635
flags = parameters[i].flags;
3638
width = parameters[i].width;
3639
if (flags & FLAGS_WIDTH_PARAMETER)
3641
/* Get width from parameter list */
3642
width = (int)parameters[width].data.number.as_signed;
3646
* A negative width is the same as the - flag and
3649
flags |= FLAGS_LEFTADJUST;
3650
flags &= ~FLAGS_NILPADDING;
3655
/* Find precision */
3656
if (flags & FLAGS_PRECISION)
3658
precision = parameters[i].precision;
3659
if (flags & FLAGS_PRECISION_PARAMETER)
3661
/* Get precision from parameter list */
3662
precision = (int)parameters[precision].data.number.as_signed;
3666
* A negative precision is the same as no
3150
3669
precision = NO_PRECISION;
3154
base = parameters[i].base;
3155
if (flags & FLAGS_BASE_PARAMETER)
3157
/* Get base from parameter list */
3158
base = (int)parameters[base].data.number.as_signed;
3161
switch (parameters[i].type)
3164
if (flags & FLAGS_QUOTE)
3165
data->OutStream(data, CHAR_QUOTE);
3166
if (! (flags & FLAGS_LEFTADJUST))
3169
data->OutStream(data, CHAR_ADJUST);
3172
if (flags & FLAGS_WIDECHAR)
3174
TrioWriteWideStringCharacter(data,
3175
(trio_wchar_t)parameters[i].data.number.as_signed,
3182
TrioWriteStringCharacter(data,
3183
(int)parameters[i].data.number.as_signed,
3187
if (flags & FLAGS_LEFTADJUST)
3190
data->OutStream(data, CHAR_ADJUST);
3192
if (flags & FLAGS_QUOTE)
3193
data->OutStream(data, CHAR_QUOTE);
3195
break; /* FORMAT_CHAR */
3198
TrioWriteNumber(data,
3199
parameters[i].data.number.as_unsigned,
3205
break; /* FORMAT_INT */
3208
TrioWriteDouble(data,
3209
parameters[i].data.longdoubleNumber,
3214
break; /* FORMAT_DOUBLE */
3218
if (flags & FLAGS_WIDECHAR)
3220
TrioWriteWideString(data,
3221
parameters[i].data.wstring,
3229
TrioWriteString(data,
3230
parameters[i].data.string,
3235
break; /* FORMAT_STRING */
3237
case FORMAT_POINTER:
3239
trio_reference_t reference;
3241
reference.data = data;
3242
reference.parameter = ¶meters[i];
3243
trio_print_pointer(&reference, parameters[i].data.pointer);
3245
break; /* FORMAT_POINTER */
3248
pointer = parameters[i].data.pointer;
3249
if (NULL != pointer)
3252
* C99 paragraph 7.19.6.1.8 says "the number of
3253
* characters written to the output stream so far by
3254
* this call", which is data->committed
3256
#if defined(QUALIFIER_SIZE_T) || defined(QUALIFIER_SIZE_T_UPPER)
3257
if (flags & FLAGS_SIZE_T)
3258
*(size_t *)pointer = (size_t)data->committed;
3261
#if defined(QUALIFIER_PTRDIFF_T)
3262
if (flags & FLAGS_PTRDIFF_T)
3263
*(ptrdiff_t *)pointer = (ptrdiff_t)data->committed;
3266
#if defined(QUALIFIER_INTMAX_T)
3267
if (flags & FLAGS_INTMAX_T)
3268
*(trio_intmax_t *)pointer = (trio_intmax_t)data->committed;
3271
if (flags & FLAGS_QUAD)
3273
*(trio_ulonglong_t *)pointer = (trio_ulonglong_t)data->committed;
3275
else if (flags & FLAGS_LONG)
3277
*(long int *)pointer = (long int)data->committed;
3279
else if (flags & FLAGS_SHORT)
3281
*(short int *)pointer = (short int)data->committed;
3285
*(int *)pointer = (int)data->committed;
3288
break; /* FORMAT_COUNT */
3290
case FORMAT_PARAMETER:
3291
break; /* FORMAT_PARAMETER */
3293
#if defined(FORMAT_ERRNO)
3295
string = trio_error(parameters[i].data.errorNumber);
3298
TrioWriteString(data,
3306
data->OutStream(data, '#');
3307
TrioWriteNumber(data,
3308
(trio_uintmax_t)parameters[i].data.errorNumber,
3314
break; /* FORMAT_ERRNO */
3315
#endif /* defined(FORMAT_ERRNO) */
3317
#if defined(FORMAT_USER_DEFINED)
3318
case FORMAT_USER_DEFINED:
3320
trio_reference_t reference;
3321
trio_userdef_t *def = NULL;
3323
if (parameters[i].user_name[0] == NIL)
3327
(parameters[i - 1].type == FORMAT_PARAMETER))
3328
def = (trio_userdef_t *)parameters[i - 1].data.pointer;
3332
/* Look up namespace */
3333
def = TrioFindNamespace(parameters[i].user_name, NULL);
3336
reference.data = data;
3337
reference.parameter = ¶meters[i];
3338
def->callback(&reference);
3342
#endif /* defined(FORMAT_USER_DEFINED) */
3346
} /* switch parameter type */
3348
/* Prepare for next */
3349
index = parameters[i].indexAfterSpecifier;
3353
else /* not identifier */
3355
data->OutStream(data, format[index++]);
3675
precision = NO_PRECISION;
3679
if (NO_BASE != parameters[i].baseSpecifier)
3681
/* Base from specifier has priority */
3682
base = parameters[i].baseSpecifier;
3684
else if (flags & FLAGS_BASE_PARAMETER)
3686
/* Get base from parameter list */
3687
base = parameters[i].base;
3688
base = (int)parameters[base].data.number.as_signed;
3692
/* Use base from format string */
3693
base = parameters[i].base;
3696
switch (parameters[i].type)
3699
#if TRIO_FEATURE_QUOTE
3700
if (flags & FLAGS_QUOTE)
3701
data->OutStream(data, CHAR_QUOTE);
3703
if (! (flags & FLAGS_LEFTADJUST))
3706
data->OutStream(data, CHAR_ADJUST);
3708
#if TRIO_FEATURE_WIDECHAR
3709
if (flags & FLAGS_WIDECHAR)
3711
TrioWriteWideStringCharacter(data,
3712
(trio_wchar_t)parameters[i].data.number.as_signed,
3719
TrioWriteStringCharacter(data,
3720
(int)parameters[i].data.number.as_signed,
3724
if (flags & FLAGS_LEFTADJUST)
3727
data->OutStream(data, CHAR_ADJUST);
3729
#if TRIO_FEATURE_QUOTE
3730
if (flags & FLAGS_QUOTE)
3731
data->OutStream(data, CHAR_QUOTE);
3734
break; /* FORMAT_CHAR */
3737
TrioWriteNumber(data,
3738
parameters[i].data.number.as_unsigned,
3744
break; /* FORMAT_INT */
3746
#if TRIO_FEATURE_FLOAT
3748
TrioWriteDouble(data,
3749
parameters[i].data.longdoubleNumber,
3754
break; /* FORMAT_DOUBLE */
3758
#if TRIO_FEATURE_WIDECHAR
3759
if (flags & FLAGS_WIDECHAR)
3761
TrioWriteWideString(data,
3762
parameters[i].data.wstring,
3770
TrioWriteString(data,
3771
parameters[i].data.string,
3776
break; /* FORMAT_STRING */
3778
case FORMAT_POINTER:
3780
trio_reference_t reference;
3782
reference.data = data;
3783
reference.parameter = ¶meters[i];
3784
trio_print_pointer(&reference, parameters[i].data.pointer);
3786
break; /* FORMAT_POINTER */
3789
pointer = parameters[i].data.pointer;
3790
if (NULL != pointer)
3793
* C99 paragraph 7.19.6.1.8 says "the number of
3794
* characters written to the output stream so far by
3795
* this call", which is data->actually.committed
3797
#if TRIO_FEATURE_SIZE_T || TRIO_FEATURE_SIZE_T_UPPER
3798
if (flags & FLAGS_SIZE_T)
3799
*(size_t *)pointer = (size_t)data->actually.committed;
3802
#if TRIO_FEATURE_PTRDIFF_T
3803
if (flags & FLAGS_PTRDIFF_T)
3804
*(ptrdiff_t *)pointer = (ptrdiff_t)data->actually.committed;
3807
#if TRIO_FEATURE_INTMAX_T
3808
if (flags & FLAGS_INTMAX_T)
3809
*(trio_intmax_t *)pointer = (trio_intmax_t)data->actually.committed;
3812
if (flags & FLAGS_QUAD)
3814
*(trio_ulonglong_t *)pointer = (trio_ulonglong_t)data->actually.committed;
3816
else if (flags & FLAGS_LONG)
3818
*(long int *)pointer = (long int)data->actually.committed;
3820
else if (flags & FLAGS_SHORT)
3822
*(short int *)pointer = (short int)data->actually.committed;
3826
*(int *)pointer = (int)data->actually.committed;
3829
break; /* FORMAT_COUNT */
3831
case FORMAT_PARAMETER:
3832
break; /* FORMAT_PARAMETER */
3834
#if TRIO_FEATURE_ERRNO
3836
string = trio_error(parameters[i].data.errorNumber);
3839
TrioWriteString(data,
3847
data->OutStream(data, '#');
3848
TrioWriteNumber(data,
3849
(trio_uintmax_t)parameters[i].data.errorNumber,
3855
break; /* FORMAT_ERRNO */
3856
#endif /* TRIO_FEATURE_ERRNO */
3858
#if TRIO_FEATURE_USER_DEFINED
3859
case FORMAT_USER_DEFINED:
3861
trio_reference_t reference;
3862
trio_userdef_t *def = NULL;
3864
if (parameters[i].flags & FLAGS_USER_DEFINED_PARAMETER)
3868
(parameters[i - 1].type == FORMAT_PARAMETER))
3869
def = (trio_userdef_t *)parameters[i - 1].data.pointer;
3873
/* Look up namespace */
3874
def = TrioFindNamespace(parameters[i].user_defined.namespace, NULL);
3878
reference.data = data;
3879
reference.parameter = ¶meters[i];
3880
def->callback(&reference);
3884
#endif /* TRIO_FEATURE_USER_DEFINED */
3888
} /* switch parameter type */
3890
/* Prepare for next */
3891
offset = parameters[i].endOffset;
3358
3895
return data->processed;
3361
3898
/*************************************************************************
3362
3899
* TrioFormatRef
3364
3902
TRIO_PRIVATE int
3366
3904
TRIO_ARGS4((reference, format, arglist, argarray),
3367
3905
trio_reference_t *reference,
3368
3906
TRIO_CONST char *format,
3370
3908
trio_pointer_t *argarray)
6020
6714
TRIO_CONST char *format,
6021
6715
trio_parameter_t *parameters)
6023
#if defined(TRIO_COMPILER_SUPPORTS_MULTIBYTE)
6027
6718
int assignment;
6029
int index; /* Index of format string */
6030
int i; /* Index of current parameter */
6720
int offset; /* Offset of format string */
6721
int i; /* Offset of current parameter */
6031
6722
trio_flags_t flags;
6034
6725
trio_pointer_t pointer;
6727
/* Return on empty format string */
6728
if (format[0] == NIL)
6036
6732
assignment = 0;
6039
6735
data->InStream(data, &ch);
6041
#if defined(TRIO_COMPILER_SUPPORTS_MULTIBYTE)
6042
(void)mblen(NULL, 0);
6045
while (format[index])
6047
#if defined(TRIO_COMPILER_SUPPORTS_MULTIBYTE)
6048
if (! isascii(format[index]))
6050
charlen = mblen(&format[index], MB_LEN_MAX);
6053
/* Compare multibyte characters in format string */
6054
for (cnt = 0; cnt < charlen - 1; cnt++)
6056
if (ch != format[index + cnt])
6058
return TRIO_ERROR_RETURN(TRIO_EINVAL, index);
6060
data->InStream(data, &ch);
6062
continue; /* while characters left in formatting string */
6065
#endif /* TRIO_COMPILER_SUPPORTS_MULTIBYTE */
6067
if ((EOF == ch) && (parameters[i].type != FORMAT_COUNT))
6069
return (assignment > 0) ? assignment : EOF;
6072
if (CHAR_IDENTIFIER == format[index])
6074
if (CHAR_IDENTIFIER == format[index + 1])
6739
/* Skip the parameter entries */
6740
while (parameters[i].type == FORMAT_PARAMETER)
6742
assert(i <= MAX_PARAMETERS);
6746
/* Compare non conversion-specifier part of format string */
6747
while (offset < parameters[i].beginOffset)
6749
if ((CHAR_IDENTIFIER == format[offset]) &&
6750
(CHAR_IDENTIFIER == format[offset + 1]))
6076
6752
/* Two % in format matches one % in input stream */
6077
6753
if (CHAR_IDENTIFIER == ch)
6079
6755
data->InStream(data, &ch);
6081
6757
continue; /* while format chars left */
6084
return TRIO_ERROR_RETURN(TRIO_EINVAL, index);
6087
/* Skip the parameter entries */
6088
while (parameters[i].type == FORMAT_PARAMETER)
6091
flags = parameters[i].flags;
6093
width = parameters[i].width;
6094
if (flags & FLAGS_WIDTH_PARAMETER)
6096
/* Get width from parameter list */
6097
width = (int)parameters[width].data.number.as_signed;
6100
base = parameters[i].base;
6101
if (flags & FLAGS_BASE_PARAMETER)
6103
/* Get base from parameter list */
6104
base = (int)parameters[base].data.number.as_signed;
6107
switch (parameters[i].type)
6111
trio_uintmax_t number;
6114
base = BASE_DECIMAL;
6116
if (!TrioReadNumber(data,
6123
if (!(flags & FLAGS_IGNORE))
6127
pointer = parameters[i].data.pointer;
6128
#if defined(QUALIFIER_SIZE_T) || defined(QUALIFIER_SIZE_T_UPPER)
6129
if (flags & FLAGS_SIZE_T)
6130
*(size_t *)pointer = (size_t)number;
6133
#if defined(QUALIFIER_PTRDIFF_T)
6134
if (flags & FLAGS_PTRDIFF_T)
6135
*(ptrdiff_t *)pointer = (ptrdiff_t)number;
6138
#if defined(QUALIFIER_INTMAX_T)
6139
if (flags & FLAGS_INTMAX_T)
6140
*(trio_intmax_t *)pointer = (trio_intmax_t)number;
6143
if (flags & FLAGS_QUAD)
6144
*(trio_ulonglong_t *)pointer = (trio_ulonglong_t)number;
6145
else if (flags & FLAGS_LONG)
6146
*(long int *)pointer = (long int)number;
6147
else if (flags & FLAGS_SHORT)
6148
*(short int *)pointer = (short int)number;
6150
*(int *)pointer = (int)number;
6153
break; /* FORMAT_INT */
6157
if (flags & FLAGS_WIDECHAR)
6159
if (!TrioReadWideString(data,
6160
(flags & FLAGS_IGNORE)
6162
: parameters[i].data.wstring,
6761
status = TRIO_ERROR_RETURN(TRIO_EINVAL, offset);
6765
else /* Not an % identifier */
6767
if (isspace((int)format[offset]))
6769
/* Whitespaces may match any amount of whitespaces */
6770
ch = TrioSkipWhitespaces(data);
6772
else if (ch == format[offset])
6774
data->InStream(data, &ch);
6170
if (!TrioReadString(data,
6778
status = assignment;
6786
if (parameters[i].type == FORMAT_SENTINEL)
6789
if ((EOF == ch) && (parameters[i].type != FORMAT_COUNT))
6791
status = (assignment > 0) ? assignment : EOF;
6795
flags = parameters[i].flags;
6798
width = parameters[i].width;
6799
if (flags & FLAGS_WIDTH_PARAMETER)
6801
/* Get width from parameter list */
6802
width = (int)parameters[width].data.number.as_signed;
6806
if (NO_BASE != parameters[i].baseSpecifier)
6808
/* Base from specifier has priority */
6809
base = parameters[i].baseSpecifier;
6811
else if (flags & FLAGS_BASE_PARAMETER)
6813
/* Get base from parameter list */
6814
base = parameters[i].base;
6815
base = (int)parameters[base].data.number.as_signed;
6819
/* Use base from format string */
6820
base = parameters[i].base;
6823
switch (parameters[i].type)
6827
trio_uintmax_t number;
6830
base = BASE_DECIMAL;
6832
if (!TrioReadNumber(data,
6838
status = assignment;
6842
if (!(flags & FLAGS_IGNORE))
6846
pointer = parameters[i].data.pointer;
6847
#if TRIO_FEATURE_SIZE_T || TRIO_FEATURE_SIZE_T_UPPER
6848
if (flags & FLAGS_SIZE_T)
6849
*(size_t *)pointer = (size_t)number;
6852
#if TRIO_FEATURE_PTRDIFF_T
6853
if (flags & FLAGS_PTRDIFF_T)
6854
*(ptrdiff_t *)pointer = (ptrdiff_t)number;
6857
#if TRIO_FEATURE_INTMAX_T
6858
if (flags & FLAGS_INTMAX_T)
6859
*(trio_intmax_t *)pointer = (trio_intmax_t)number;
6862
if (flags & FLAGS_QUAD)
6863
*(trio_ulonglong_t *)pointer = (trio_ulonglong_t)number;
6864
else if (flags & FLAGS_LONG)
6865
*(long int *)pointer = (long int)number;
6866
else if (flags & FLAGS_SHORT)
6867
*(short int *)pointer = (short int)number;
6869
*(int *)pointer = (int)number;
6872
break; /* FORMAT_INT */
6875
#if TRIO_FEATURE_WIDECHAR
6876
if (flags & FLAGS_WIDECHAR)
6878
if (!TrioReadWideString(data,
6171
6879
(flags & FLAGS_IGNORE)
6173
: parameters[i].data.string,
6881
: parameters[i].data.wstring,
6178
if (!(flags & FLAGS_IGNORE))
6885
status = assignment;
6892
if (!TrioReadString(data,
6893
(flags & FLAGS_IGNORE)
6895
: parameters[i].data.string,
6899
status = assignment;
6903
if (!(flags & FLAGS_IGNORE))
6905
break; /* FORMAT_STRING */
6907
#if TRIO_FEATURE_FLOAT
6910
if (flags & FLAGS_IGNORE)
6916
pointer = (flags & FLAGS_LONGDOUBLE)
6917
? (trio_pointer_t)parameters[i].data.longdoublePointer
6918
: (trio_pointer_t)parameters[i].data.doublePointer;
6920
if (!TrioReadDouble(data, pointer, flags, width))
6922
status = assignment;
6925
if (!(flags & FLAGS_IGNORE))
6180
break; /* FORMAT_STRING */
6184
trio_pointer_t pointer;
6186
if (flags & FLAGS_IGNORE)
6192
pointer = (flags & FLAGS_LONGDOUBLE)
6193
? (trio_pointer_t)parameters[i].data.longdoublePointer
6194
: (trio_pointer_t)parameters[i].data.doublePointer;
6196
if (!TrioReadDouble(data, pointer, flags, width))
6200
if (!(flags & FLAGS_IGNORE))
6204
break; /* FORMAT_DOUBLE */
6208
int characterclass[MAX_CHARACTER_CLASS + 1];
6211
/* Skip over modifiers */
6212
while (format[index] != SPECIFIER_GROUP)
6216
/* Skip over group specifier */
6219
memset(characterclass, 0, sizeof(characterclass));
6220
rc = TrioGetCharacterClass(format,
6929
break; /* FORMAT_DOUBLE */
6935
int characterclass[MAX_CHARACTER_CLASS + 1];
6937
/* Skip over modifiers */
6938
while (format[offset] != SPECIFIER_GROUP)
6942
/* Skip over group specifier */
6945
memset(characterclass, 0, sizeof(characterclass));
6946
status = TrioGetCharacterClass(format,
6223
6949
characterclass);
6227
if (!TrioReadGroup(data,
6228
(flags & FLAGS_IGNORE)
6230
: parameters[i].data.string,
6233
parameters[i].width))
6235
if (!(flags & FLAGS_IGNORE))
6953
if (!TrioReadGroup(data,
6954
(flags & FLAGS_IGNORE)
6956
: parameters[i].data.string,
6959
parameters[i].width))
6961
status = assignment;
6238
break; /* FORMAT_GROUP */
6241
pointer = parameters[i].data.pointer;
6242
if (NULL != pointer)
6244
int count = data->committed;
6246
count--; /* a character is read, but is not consumed yet */
6247
#if defined(QUALIFIER_SIZE_T) || defined(QUALIFIER_SIZE_T_UPPER)
6248
if (flags & FLAGS_SIZE_T)
6249
*(size_t *)pointer = (size_t)count;
6252
#if defined(QUALIFIER_PTRDIFF_T)
6253
if (flags & FLAGS_PTRDIFF_T)
6254
*(ptrdiff_t *)pointer = (ptrdiff_t)count;
6257
#if defined(QUALIFIER_INTMAX_T)
6258
if (flags & FLAGS_INTMAX_T)
6259
*(trio_intmax_t *)pointer = (trio_intmax_t)count;
6262
if (flags & FLAGS_QUAD)
6264
*(trio_ulonglong_t *)pointer = (trio_ulonglong_t)count;
6266
else if (flags & FLAGS_LONG)
6268
*(long int *)pointer = (long int)count;
6270
else if (flags & FLAGS_SHORT)
6272
*(short int *)pointer = (short int)count;
6276
*(int *)pointer = (int)count;
6279
break; /* FORMAT_COUNT */
6283
if (flags & FLAGS_WIDECHAR)
6285
if (TrioReadWideChar(data,
6286
(flags & FLAGS_IGNORE)
6288
: parameters[i].data.wstring,
6290
(width == NO_WIDTH) ? 1 : width) == 0)
6296
if (TrioReadChar(data,
6964
if (!(flags & FLAGS_IGNORE))
6967
break; /* FORMAT_GROUP */
6970
pointer = parameters[i].data.pointer;
6971
if (NULL != pointer)
6973
int count = data->processed;
6975
count--; /* a character is read, but is not consumed yet */
6976
#if TRIO_FEATURE_SIZE_T || TRIO_FEATURE_SIZE_T_UPPER
6977
if (flags & FLAGS_SIZE_T)
6978
*(size_t *)pointer = (size_t)count;
6981
#if TRIO_FEATURE_PTRDIFF_T
6982
if (flags & FLAGS_PTRDIFF_T)
6983
*(ptrdiff_t *)pointer = (ptrdiff_t)count;
6986
#if TRIO_FEATURE_INTMAX_T
6987
if (flags & FLAGS_INTMAX_T)
6988
*(trio_intmax_t *)pointer = (trio_intmax_t)count;
6991
if (flags & FLAGS_QUAD)
6993
*(trio_ulonglong_t *)pointer = (trio_ulonglong_t)count;
6995
else if (flags & FLAGS_LONG)
6997
*(long int *)pointer = (long int)count;
6999
else if (flags & FLAGS_SHORT)
7001
*(short int *)pointer = (short int)count;
7005
*(int *)pointer = (int)count;
7008
break; /* FORMAT_COUNT */
7011
#if TRIO_FEATURE_WIDECHAR
7012
if (flags & FLAGS_WIDECHAR)
7014
if (TrioReadWideChar(data,
6297
7015
(flags & FLAGS_IGNORE)
6299
: parameters[i].data.string,
7017
: parameters[i].data.wstring,
6301
7019
(width == NO_WIDTH) ? 1 : width) == 0)
7021
status = assignment;
6304
if (!(flags & FLAGS_IGNORE))
6306
break; /* FORMAT_CHAR */
6308
case FORMAT_POINTER:
6309
if (!TrioReadPointer(data,
6310
(flags & FLAGS_IGNORE)
6312
: (trio_pointer_t *)parameters[i].data.pointer,
6315
if (!(flags & FLAGS_IGNORE))
6317
break; /* FORMAT_POINTER */
6319
case FORMAT_PARAMETER:
6320
break; /* FORMAT_PARAMETER */
6323
return TRIO_ERROR_RETURN(TRIO_EINVAL, index);
6326
index = parameters[i].indexAfterSpecifier;
6329
else /* Not an % identifier */
6331
if (isspace((int)format[index]))
6333
/* Whitespaces may match any amount of whitespaces */
6334
ch = TrioSkipWhitespaces(data);
6336
else if (ch == format[index])
6338
data->InStream(data, &ch);
7028
if (TrioReadChar(data,
7029
(flags & FLAGS_IGNORE)
7031
: parameters[i].data.string,
7033
(width == NO_WIDTH) ? 1 : width) == 0)
7035
status = assignment;
7039
if (!(flags & FLAGS_IGNORE))
7041
break; /* FORMAT_CHAR */
7043
case FORMAT_POINTER:
7044
if (!TrioReadPointer(data,
7045
(flags & FLAGS_IGNORE)
7047
: (trio_pointer_t *)parameters[i].data.pointer,
7050
status = assignment;
7053
if (!(flags & FLAGS_IGNORE))
7055
break; /* FORMAT_POINTER */
7057
case FORMAT_PARAMETER:
7058
break; /* FORMAT_PARAMETER */
7061
status = TRIO_ERROR_RETURN(TRIO_EINVAL, offset);
7066
offset = parameters[i].endOffset;
7070
status = assignment;
7072
if (data->UndoStream)
7073
data->UndoStream(data);
6349
7077
/*************************************************************************