PageRenderTime 66ms CodeModel.GetById 27ms RepoModel.GetById 0ms app.codeStats 1ms

/src/sdk/src/libc/src/trio/trio.c

https://gitlab.com/thomasphillips3/How-to-Make-a-Computer-Operating-System
C | 2002 lines | 1466 code | 170 blank | 366 comment | 256 complexity | 3d3a27631c7dc8e23875fefdff23f878 MD5 | raw file
  1. /*
  2. * TODO:
  3. * - Scan is probably too permissive about its modifiers.
  4. * - C escapes in %#[] ?
  5. * - Multibyte characters (done for format parsing, except scan groups)
  6. * - Complex numbers? (C99 _Complex)
  7. * - Boolean values? (C99 _Bool)
  8. * - C99 NaN(n-char-sequence) missing. The n-char-sequence can be used
  9. * to print the mantissa, e.g. NaN(0xc000000000000000)
  10. * - Should we support the GNU %a alloc modifier? GNU has an ugly hack
  11. * for %a, because C99 used %a for other purposes. If specified as
  12. * %as or %a[ it is interpreted as the alloc modifier, otherwise as
  13. * the C99 hex-float. This means that you cannot scan %as as a hex-float
  14. * immediately followed by an 's'.
  15. * - Scanning of collating symbols.
  16. */
  17. /*************************************************************************
  18. * Trio include files
  19. */
  20. #include "triodef.h"
  21. #include "trio.h"
  22. #include "triop.h"
  23. #if defined(TRIO_EMBED_NAN)
  24. # define TRIO_PUBLIC_NAN static
  25. # if TRIO_FEATURE_FLOAT
  26. # define TRIO_FUNC_NAN
  27. # define TRIO_FUNC_NINF
  28. # define TRIO_FUNC_PINF
  29. # define TRIO_FUNC_FPCLASSIFY_AND_SIGNBIT
  30. # define TRIO_FUNC_ISINF
  31. # endif
  32. #endif
  33. #include "trionan.h"
  34. #if defined(TRIO_EMBED_STRING)
  35. # define TRIO_PUBLIC_STRING static
  36. # define TRIO_FUNC_LENGTH
  37. # define TRIO_FUNC_LENGTH_MAX
  38. # define TRIO_FUNC_TO_LONG
  39. # if TRIO_FEATURE_LOCALE
  40. # define TRIO_FUNC_COPY_MAX
  41. # endif
  42. # if TRIO_FEATURE_DYNAMICSTRING
  43. # define TRIO_FUNC_XSTRING_DUPLICATE
  44. # endif
  45. # if TRIO_EXTENSION && TRIO_FEATURE_SCANF
  46. # define TRIO_FUNC_EQUAL_LOCALE
  47. # endif
  48. # if TRIO_FEATURE_ERRNO
  49. # define TRIO_FUNC_ERROR
  50. # endif
  51. # if TRIO_FEATURE_FLOAT && TRIO_FEATURE_SCANF
  52. # define TRIO_FUNC_TO_DOUBLE
  53. # endif
  54. # if TRIO_FEATURE_DYNAMICSTRING
  55. # define TRIO_FUNC_STRING_EXTRACT
  56. # endif
  57. # if TRIO_FEATURE_DYNAMICSTRING
  58. # define TRIO_FUNC_STRING_TERMINATE
  59. # endif
  60. # if TRIO_FEATURE_USER_DEFINED
  61. # define TRIO_FUNC_DUPLICATE
  62. # endif
  63. # if TRIO_FEATURE_DYNAMICSTRING
  64. # define TRIO_FUNC_STRING_DESTROY
  65. # endif
  66. # if TRIO_FEATURE_USER_DEFINED
  67. # define TRIO_FUNC_DESTROY
  68. # endif
  69. # if TRIO_FEATURE_USER_DEFINED || (TRIO_FEATURE_FLOAT && TRIO_FEATURE_SCANF)
  70. # define TRIO_FUNC_EQUAL
  71. # endif
  72. # if TRIO_FEATURE_USER_DEFINED || TRIO_FEATURE_SCANF
  73. # define TRIO_FUNC_EQUAL_CASE
  74. # endif
  75. # if (TRIO_EXTENSION && TRIO_FEATURE_SCANF)
  76. # define TRIO_FUNC_EQUAL_MAX
  77. # endif
  78. # if TRIO_FEATURE_SCANF
  79. # define TRIO_FUNC_TO_UPPER
  80. # endif
  81. # if TRIO_FEATURE_DYNAMICSTRING
  82. # define TRIO_FUNC_XSTRING_APPEND_CHAR
  83. # endif
  84. #endif
  85. #include "triostr.h"
  86. /**************************************************************************
  87. *
  88. * Definitions
  89. *
  90. *************************************************************************/
  91. #include <limits.h>
  92. #if TRIO_FEATURE_FLOAT
  93. # include <math.h>
  94. # include <float.h>
  95. #endif
  96. #if defined(__STDC_ISO_10646__) || defined(MB_LEN_MAX) || defined(USE_MULTIBYTE) || TRIO_FEATURE_WIDECHAR
  97. # if !defined(TRIO_PLATFORM_WINCE)
  98. //# define TRIO_COMPILER_SUPPORTS_MULTIBYTE
  99. # if !defined(MB_LEN_MAX)
  100. # define MB_LEN_MAX 6
  101. # endif
  102. # endif
  103. #endif
  104. #if (TRIO_COMPILER_VISUALC - 0 >= 1100) || defined(TRIO_COMPILER_BORLAND)
  105. # define TRIO_COMPILER_SUPPORTS_VISUALC_INT
  106. #endif
  107. #if TRIO_FEATURE_FLOAT
  108. # if defined(PREDEF_STANDARD_C99) \
  109. || defined(PREDEF_STANDARD_UNIX03)
  110. # if !defined(HAVE_FLOORL)
  111. # define HAVE_FLOORL
  112. # endif
  113. # if !defined(HAVE_CEILL)
  114. # define HAVE_CEILL
  115. # endif
  116. # if !defined(HAVE_POWL)
  117. # define HAVE_POWL
  118. # endif
  119. # if !defined(HAVE_FMODL)
  120. # define HAVE_FMODL
  121. # endif
  122. # if !defined(HAVE_LOG10L)
  123. # define HAVE_LOG10L
  124. # endif
  125. # endif
  126. # if defined(TRIO_COMPILER_VISUALC)
  127. # if defined(floorl)
  128. # define HAVE_FLOORL
  129. # endif
  130. # if defined(ceill)
  131. # define HAVE_CEILL
  132. # endif
  133. # if defined(powl)
  134. # define HAVE_POWL
  135. # endif
  136. # if defined(fmodl)
  137. # define HAVE_FMODL
  138. # endif
  139. # if defined(log10l)
  140. # define HAVE_LOG10L
  141. # endif
  142. # endif
  143. #endif
  144. /*************************************************************************
  145. * Generic definitions
  146. */
  147. #if !(defined(DEBUG) || defined(NDEBUG))
  148. # define NDEBUG
  149. #endif
  150. #include <assert.h>
  151. #include <ctype.h>
  152. #if defined(PREDEF_STANDARD_C99) && !defined(isascii)
  153. # define isascii(x) ((x) & 0x7F)
  154. #endif
  155. #if defined(TRIO_COMPILER_ANCIENT)
  156. # include <varargs.h>
  157. #else
  158. # include <stdarg.h>
  159. #endif
  160. #include <stddef.h>
  161. #if defined(TRIO_PLATFORM_WINCE)
  162. extern int errno;
  163. #else
  164. # include <errno.h>
  165. #endif
  166. #ifndef NULL
  167. # define NULL 0
  168. #endif
  169. #define NIL ((char)0)
  170. #ifndef FALSE
  171. # define FALSE (1 == 0)
  172. # define TRUE (! FALSE)
  173. #endif
  174. #define BOOLEAN_T int
  175. /* mincore() can be used for debugging purposes */
  176. #define VALID(x) (NULL != (x))
  177. #if TRIO_FEATURE_ERRORCODE
  178. /*
  179. * Encode the error code and the position. This is decoded
  180. * with TRIO_ERROR_CODE and TRIO_ERROR_POSITION.
  181. */
  182. # define TRIO_ERROR_RETURN(x,y) (- ((x) + ((y) << 8)))
  183. #else
  184. # define TRIO_ERROR_RETURN(x,y) (-1)
  185. #endif
  186. typedef unsigned long trio_flags_t;
  187. /*************************************************************************
  188. * Platform specific definitions
  189. */
  190. #if defined(TRIO_PLATFORM_UNIX)
  191. # include <unistd.h>
  192. # include <signal.h>
  193. # include <locale.h>
  194. # if !defined(TRIO_FEATURE_LOCALE)
  195. # define USE_LOCALE
  196. # endif
  197. #endif /* TRIO_PLATFORM_UNIX */
  198. #if defined(TRIO_PLATFORM_VMS)
  199. # include <unistd.h>
  200. #endif
  201. #if defined(TRIO_PLATFORM_WIN32)
  202. # if defined(TRIO_PLATFORM_WINCE)
  203. int read(int handle, char *buffer, unsigned int length);
  204. int write(int handle, const char *buffer, unsigned int length);
  205. # else
  206. # include <io.h>
  207. # define read _read
  208. # define write _write
  209. # endif
  210. #endif /* TRIO_PLATFORM_WIN32 */
  211. #if TRIO_FEATURE_WIDECHAR
  212. # if defined(PREDEF_STANDARD_C94)
  213. # include <wchar.h>
  214. # include <wctype.h>
  215. typedef wchar_t trio_wchar_t;
  216. typedef wint_t trio_wint_t;
  217. # else
  218. typedef char trio_wchar_t;
  219. typedef int trio_wint_t;
  220. # define WCONST(x) L ## x
  221. # define WEOF EOF
  222. # define iswalnum(x) isalnum(x)
  223. # define iswalpha(x) isalpha(x)
  224. # define iswcntrl(x) iscntrl(x)
  225. # define iswdigit(x) isdigit(x)
  226. # define iswgraph(x) isgraph(x)
  227. # define iswlower(x) islower(x)
  228. # define iswprint(x) isprint(x)
  229. # define iswpunct(x) ispunct(x)
  230. # define iswspace(x) isspace(x)
  231. # define iswupper(x) isupper(x)
  232. # define iswxdigit(x) isxdigit(x)
  233. # endif
  234. #endif
  235. /*************************************************************************
  236. * Compiler dependent definitions
  237. */
  238. /* Support for long long */
  239. #ifndef __cplusplus
  240. # if !defined(USE_LONGLONG)
  241. # if defined(TRIO_COMPILER_GCC) && !defined(__STRICT_ANSI__)
  242. # define USE_LONGLONG
  243. # else
  244. # if defined(TRIO_COMPILER_SUNPRO)
  245. # define USE_LONGLONG
  246. # else
  247. # if defined(TRIO_COMPILER_MSVC) && (_MSC_VER >= 1400)
  248. # define USE_LONGLONG
  249. # else
  250. # if defined(_LONG_LONG) || defined(_LONGLONG)
  251. # define USE_LONGLONG
  252. # endif
  253. # endif
  254. # endif
  255. # endif
  256. # endif
  257. #endif
  258. /* The extra long numbers */
  259. #if defined(USE_LONGLONG)
  260. typedef signed long long int trio_longlong_t;
  261. typedef unsigned long long int trio_ulonglong_t;
  262. #else
  263. # if defined(TRIO_COMPILER_SUPPORTS_VISUALC_INT)
  264. typedef signed __int64 trio_longlong_t;
  265. typedef unsigned __int64 trio_ulonglong_t;
  266. # else
  267. typedef TRIO_SIGNED long int trio_longlong_t;
  268. typedef unsigned long int trio_ulonglong_t;
  269. # endif
  270. #endif
  271. /* Maximal and fixed integer types */
  272. #if defined(PREDEF_STANDARD_C99)
  273. # include <stdint.h>
  274. typedef intmax_t trio_intmax_t;
  275. typedef uintmax_t trio_uintmax_t;
  276. typedef int8_t trio_int8_t;
  277. typedef int16_t trio_int16_t;
  278. typedef int32_t trio_int32_t;
  279. typedef int64_t trio_int64_t;
  280. #else
  281. # if defined(PREDEF_STANDARD_UNIX98)
  282. # include <inttypes.h>
  283. typedef intmax_t trio_intmax_t;
  284. typedef uintmax_t trio_uintmax_t;
  285. typedef int8_t trio_int8_t;
  286. typedef int16_t trio_int16_t;
  287. typedef int32_t trio_int32_t;
  288. typedef int64_t trio_int64_t;
  289. # else
  290. # if defined(TRIO_COMPILER_SUPPORTS_VISUALC_INT)
  291. typedef trio_longlong_t trio_intmax_t;
  292. typedef trio_ulonglong_t trio_uintmax_t;
  293. typedef __int8 trio_int8_t;
  294. typedef __int16 trio_int16_t;
  295. typedef __int32 trio_int32_t;
  296. typedef __int64 trio_int64_t;
  297. # else
  298. typedef trio_longlong_t trio_intmax_t;
  299. typedef trio_ulonglong_t trio_uintmax_t;
  300. # if defined(TRIO_INT8_T)
  301. typedef TRIO_INT8_T trio_int8_t;
  302. # else
  303. typedef TRIO_SIGNED char trio_int8_t;
  304. # endif
  305. # if defined(TRIO_INT16_T)
  306. typedef TRIO_INT16_T trio_int16_t;
  307. # else
  308. typedef TRIO_SIGNED short trio_int16_t;
  309. # endif
  310. # if defined(TRIO_INT32_T)
  311. typedef TRIO_INT32_T trio_int32_t;
  312. # else
  313. typedef TRIO_SIGNED int trio_int32_t;
  314. # endif
  315. # if defined(TRIO_INT64_T)
  316. typedef TRIO_INT64_T trio_int64_t;
  317. # else
  318. typedef trio_longlong_t trio_int64_t;
  319. # endif
  320. # endif
  321. # endif
  322. #endif
  323. #if defined(HAVE_FLOORL)
  324. # define trio_floor(x) floorl((x))
  325. #else
  326. # define trio_floor(x) floor((double)(x))
  327. #endif
  328. #if defined(HAVE_CEILL)
  329. # define trio_ceil(x) ceill((x))
  330. #else
  331. # define trio_ceil(x) ceil((double)(x))
  332. #endif
  333. #if defined(HAVE_FMODL)
  334. # define trio_fmod(x,y) fmodl((x),(y))
  335. #else
  336. # define trio_fmod(x,y) fmod((double)(x),(double)(y))
  337. #endif
  338. #if defined(HAVE_POWL)
  339. # define trio_pow(x,y) powl((x),(y))
  340. #else
  341. # define trio_pow(x,y) pow((double)(x),(double)(y))
  342. #endif
  343. #if defined(HAVE_LOG10L)
  344. # define trio_log10(x) log10l((x))
  345. #else
  346. # define trio_log10(x) log10((double)(x))
  347. #endif
  348. #if TRIO_FEATURE_FLOAT
  349. # define TRIO_FABS(x) (((x) < 0.0) ? -(x) : (x))
  350. #endif
  351. /*************************************************************************
  352. * Internal Definitions
  353. */
  354. #if TRIO_FEATURE_FLOAT
  355. # if !defined(DECIMAL_DIG)
  356. # define DECIMAL_DIG DBL_DIG
  357. # endif
  358. /* Long double sizes */
  359. # ifdef LDBL_DIG
  360. # define MAX_MANTISSA_DIGITS LDBL_DIG
  361. # define MAX_EXPONENT_DIGITS 4
  362. # define MAX_DOUBLE_DIGITS LDBL_MAX_10_EXP
  363. # else
  364. # define MAX_MANTISSA_DIGITS DECIMAL_DIG
  365. # define MAX_EXPONENT_DIGITS 3
  366. # define MAX_DOUBLE_DIGITS DBL_MAX_10_EXP
  367. # endif
  368. # if defined(TRIO_COMPILER_ANCIENT) || !defined(LDBL_DIG)
  369. # undef LDBL_DIG
  370. # undef LDBL_MANT_DIG
  371. # undef LDBL_EPSILON
  372. # define LDBL_DIG DBL_DIG
  373. # define LDBL_MANT_DIG DBL_MANT_DIG
  374. # define LDBL_EPSILON DBL_EPSILON
  375. # endif
  376. #endif /* TRIO_FEATURE_FLOAT */
  377. /* The maximal number of digits is for base 2 */
  378. #define MAX_CHARS_IN(x) (sizeof(x) * CHAR_BIT)
  379. /* The width of a pointer. The number of bits in a hex digit is 4 */
  380. #define POINTER_WIDTH ((sizeof("0x") - 1) + sizeof(trio_pointer_t) * CHAR_BIT / 4)
  381. #if TRIO_FEATURE_FLOAT
  382. /* Infinite and Not-A-Number for floating-point */
  383. # define INFINITE_LOWER "inf"
  384. # define INFINITE_UPPER "INF"
  385. # define LONG_INFINITE_LOWER "infinite"
  386. # define LONG_INFINITE_UPPER "INFINITE"
  387. # define NAN_LOWER "nan"
  388. # define NAN_UPPER "NAN"
  389. #endif
  390. /* Various constants */
  391. enum {
  392. TYPE_PRINT = 1,
  393. #if TRIO_FEATURE_SCANF
  394. TYPE_SCAN = 2,
  395. #endif
  396. /* Flags. FLAGS_LAST must be less than ULONG_MAX */
  397. FLAGS_NEW = 0,
  398. FLAGS_STICKY = 1,
  399. FLAGS_SPACE = 2 * FLAGS_STICKY,
  400. FLAGS_SHOWSIGN = 2 * FLAGS_SPACE,
  401. FLAGS_LEFTADJUST = 2 * FLAGS_SHOWSIGN,
  402. FLAGS_ALTERNATIVE = 2 * FLAGS_LEFTADJUST,
  403. FLAGS_SHORT = 2 * FLAGS_ALTERNATIVE,
  404. FLAGS_SHORTSHORT = 2 * FLAGS_SHORT,
  405. FLAGS_LONG = 2 * FLAGS_SHORTSHORT,
  406. FLAGS_QUAD = 2 * FLAGS_LONG,
  407. FLAGS_LONGDOUBLE = 2 * FLAGS_QUAD,
  408. FLAGS_SIZE_T = 2 * FLAGS_LONGDOUBLE,
  409. FLAGS_PTRDIFF_T = 2 * FLAGS_SIZE_T,
  410. FLAGS_INTMAX_T = 2 * FLAGS_PTRDIFF_T,
  411. FLAGS_NILPADDING = 2 * FLAGS_INTMAX_T,
  412. FLAGS_UNSIGNED = 2 * FLAGS_NILPADDING,
  413. FLAGS_UPPER = 2 * FLAGS_UNSIGNED,
  414. FLAGS_WIDTH = 2 * FLAGS_UPPER,
  415. FLAGS_WIDTH_PARAMETER = 2 * FLAGS_WIDTH,
  416. FLAGS_PRECISION = 2 * FLAGS_WIDTH_PARAMETER,
  417. FLAGS_PRECISION_PARAMETER = 2 * FLAGS_PRECISION,
  418. FLAGS_BASE = 2 * FLAGS_PRECISION_PARAMETER,
  419. FLAGS_BASE_PARAMETER = 2 * FLAGS_BASE,
  420. FLAGS_FLOAT_E = 2 * FLAGS_BASE_PARAMETER,
  421. FLAGS_FLOAT_G = 2 * FLAGS_FLOAT_E,
  422. FLAGS_QUOTE = 2 * FLAGS_FLOAT_G,
  423. FLAGS_WIDECHAR = 2 * FLAGS_QUOTE,
  424. FLAGS_IGNORE = 2 * FLAGS_WIDECHAR,
  425. FLAGS_IGNORE_PARAMETER = 2 * FLAGS_IGNORE,
  426. FLAGS_VARSIZE_PARAMETER = 2 * FLAGS_IGNORE_PARAMETER,
  427. FLAGS_FIXED_SIZE = 2 * FLAGS_VARSIZE_PARAMETER,
  428. FLAGS_LAST = FLAGS_FIXED_SIZE,
  429. /* Reused flags */
  430. FLAGS_EXCLUDE = FLAGS_SHORT,
  431. FLAGS_USER_DEFINED = FLAGS_IGNORE,
  432. FLAGS_USER_DEFINED_PARAMETER = FLAGS_IGNORE_PARAMETER,
  433. FLAGS_ROUNDING = FLAGS_INTMAX_T,
  434. /* Compounded flags */
  435. FLAGS_ALL_VARSIZES = FLAGS_LONG | FLAGS_QUAD | FLAGS_INTMAX_T | FLAGS_PTRDIFF_T | FLAGS_SIZE_T,
  436. FLAGS_ALL_SIZES = FLAGS_ALL_VARSIZES | FLAGS_SHORTSHORT | FLAGS_SHORT,
  437. NO_POSITION = -1,
  438. NO_WIDTH = 0,
  439. NO_PRECISION = -1,
  440. NO_SIZE = -1,
  441. /* Do not change these */
  442. NO_BASE = -1,
  443. MIN_BASE = 2,
  444. MAX_BASE = 36,
  445. BASE_BINARY = 2,
  446. BASE_OCTAL = 8,
  447. BASE_DECIMAL = 10,
  448. BASE_HEX = 16,
  449. /* Maximal number of allowed parameters */
  450. MAX_PARAMETERS = 64,
  451. /* Maximal number of characters in class */
  452. MAX_CHARACTER_CLASS = UCHAR_MAX + 1,
  453. #if TRIO_FEATURE_USER_DEFINED
  454. /* Maximal string lengths for user-defined specifiers */
  455. MAX_USER_NAME = 64,
  456. MAX_USER_DATA = 256,
  457. #endif
  458. /* Maximal length of locale separator strings */
  459. MAX_LOCALE_SEPARATOR_LENGTH = MB_LEN_MAX,
  460. /* Maximal number of integers in grouping */
  461. MAX_LOCALE_GROUPS = 64
  462. };
  463. #define NO_GROUPING ((int)CHAR_MAX)
  464. /* Fundamental formatting parameter types */
  465. #define FORMAT_SENTINEL -1 /* marks end of parameters array */
  466. #define FORMAT_UNKNOWN 0
  467. #define FORMAT_INT 1
  468. #define FORMAT_DOUBLE 2
  469. #define FORMAT_CHAR 3
  470. #define FORMAT_STRING 4
  471. #define FORMAT_POINTER 5
  472. #define FORMAT_COUNT 6
  473. #define FORMAT_PARAMETER 7
  474. #define FORMAT_GROUP 8
  475. #define FORMAT_ERRNO 9
  476. #define FORMAT_USER_DEFINED 10
  477. /* Character constants */
  478. #define CHAR_IDENTIFIER '%'
  479. #define CHAR_ALT_IDENTIFIER '$'
  480. #define CHAR_BACKSLASH '\\'
  481. #define CHAR_QUOTE '\"'
  482. #define CHAR_ADJUST ' '
  483. #if TRIO_EXTENSION
  484. /* Character class expressions */
  485. # define CLASS_ALNUM "[:alnum:]"
  486. # define CLASS_ALPHA "[:alpha:]"
  487. # define CLASS_BLANK "[:blank:]"
  488. # define CLASS_CNTRL "[:cntrl:]"
  489. # define CLASS_DIGIT "[:digit:]"
  490. # define CLASS_GRAPH "[:graph:]"
  491. # define CLASS_LOWER "[:lower:]"
  492. # define CLASS_PRINT "[:print:]"
  493. # define CLASS_PUNCT "[:punct:]"
  494. # define CLASS_SPACE "[:space:]"
  495. # define CLASS_UPPER "[:upper:]"
  496. # define CLASS_XDIGIT "[:xdigit:]"
  497. #endif
  498. /*
  499. * SPECIFIERS:
  500. *
  501. *
  502. * a Hex-float
  503. * A Hex-float
  504. * c Character
  505. * C Widechar character (wint_t)
  506. * d Decimal
  507. * e Float
  508. * E Float
  509. * F Float
  510. * F Float
  511. * g Float
  512. * G Float
  513. * i Integer
  514. * m Error message
  515. * n Count
  516. * o Octal
  517. * p Pointer
  518. * s String
  519. * S Widechar string (wchar_t *)
  520. * u Unsigned
  521. * x Hex
  522. * X Hex
  523. * [] Group
  524. * <> User-defined
  525. *
  526. * Reserved:
  527. *
  528. * D Binary Coded Decimal %D(length,precision) (OS/390)
  529. */
  530. #define SPECIFIER_CHAR 'c'
  531. #define SPECIFIER_STRING 's'
  532. #define SPECIFIER_DECIMAL 'd'
  533. #define SPECIFIER_INTEGER 'i'
  534. #define SPECIFIER_UNSIGNED 'u'
  535. #define SPECIFIER_OCTAL 'o'
  536. #define SPECIFIER_HEX 'x'
  537. #define SPECIFIER_HEX_UPPER 'X'
  538. #if TRIO_FEATURE_FLOAT
  539. # define SPECIFIER_FLOAT_E 'e'
  540. # define SPECIFIER_FLOAT_E_UPPER 'E'
  541. # define SPECIFIER_FLOAT_F 'f'
  542. # define SPECIFIER_FLOAT_F_UPPER 'F'
  543. # define SPECIFIER_FLOAT_G 'g'
  544. # define SPECIFIER_FLOAT_G_UPPER 'G'
  545. #endif
  546. #define SPECIFIER_POINTER 'p'
  547. #if TRIO_FEATURE_SCANF
  548. # define SPECIFIER_GROUP '['
  549. # define SPECIFIER_UNGROUP ']'
  550. #endif
  551. #define SPECIFIER_COUNT 'n'
  552. #if TRIO_UNIX98
  553. # define SPECIFIER_CHAR_UPPER 'C'
  554. # define SPECIFIER_STRING_UPPER 'S'
  555. #endif
  556. #define SPECIFIER_HEXFLOAT 'a'
  557. #define SPECIFIER_HEXFLOAT_UPPER 'A'
  558. #define SPECIFIER_ERRNO 'm'
  559. #if TRIO_FEATURE_BINARY
  560. # define SPECIFIER_BINARY 'b'
  561. # define SPECIFIER_BINARY_UPPER 'B'
  562. #endif
  563. #if TRIO_FEATURE_USER_DEFINED
  564. # define SPECIFIER_USER_DEFINED_BEGIN '<'
  565. # define SPECIFIER_USER_DEFINED_END '>'
  566. # define SPECIFIER_USER_DEFINED_SEPARATOR ':'
  567. # define SPECIFIER_USER_DEFINED_EXTRA '|'
  568. #endif
  569. /*
  570. * QUALIFIERS:
  571. *
  572. *
  573. * Numbers = d,i,o,u,x,X
  574. * Float = a,A,e,E,f,F,g,G
  575. * String = s
  576. * Char = c
  577. *
  578. *
  579. * 9$ Position
  580. * Use the 9th parameter. 9 can be any number between 1 and
  581. * the maximal argument
  582. *
  583. * 9 Width
  584. * Set width to 9. 9 can be any number, but must not be postfixed
  585. * by '$'
  586. *
  587. * h Short
  588. * Numbers:
  589. * (unsigned) short int
  590. *
  591. * hh Short short
  592. * Numbers:
  593. * (unsigned) char
  594. *
  595. * l Long
  596. * Numbers:
  597. * (unsigned) long int
  598. * String:
  599. * as the S specifier
  600. * Char:
  601. * as the C specifier
  602. *
  603. * ll Long Long
  604. * Numbers:
  605. * (unsigned) long long int
  606. *
  607. * L Long Double
  608. * Float
  609. * long double
  610. *
  611. * # Alternative
  612. * Float:
  613. * Decimal-point is always present
  614. * String:
  615. * non-printable characters are handled as \number
  616. *
  617. * Spacing
  618. *
  619. * + Sign
  620. *
  621. * - Alignment
  622. *
  623. * . Precision
  624. *
  625. * * Parameter
  626. * print: use parameter
  627. * scan: no parameter (ignore)
  628. *
  629. * q Quad
  630. *
  631. * Z size_t
  632. *
  633. * w Widechar
  634. *
  635. * ' Thousands/quote
  636. * Numbers:
  637. * Integer part grouped in thousands
  638. * Binary numbers:
  639. * Number grouped in nibbles (4 bits)
  640. * String:
  641. * Quoted string
  642. *
  643. * j intmax_t
  644. * t prtdiff_t
  645. * z size_t
  646. *
  647. * ! Sticky
  648. * @ Parameter (for both print and scan)
  649. *
  650. * I n-bit Integer
  651. * Numbers:
  652. * The following options exists
  653. * I8 = 8-bit integer
  654. * I16 = 16-bit integer
  655. * I32 = 32-bit integer
  656. * I64 = 64-bit integer
  657. */
  658. #define QUALIFIER_POSITION '$'
  659. #define QUALIFIER_SHORT 'h'
  660. #define QUALIFIER_LONG 'l'
  661. #define QUALIFIER_LONG_UPPER 'L'
  662. #define QUALIFIER_ALTERNATIVE '#'
  663. #define QUALIFIER_SPACE ' '
  664. #define QUALIFIER_PLUS '+'
  665. #define QUALIFIER_MINUS '-'
  666. #define QUALIFIER_DOT '.'
  667. #define QUALIFIER_STAR '*'
  668. #define QUALIFIER_CIRCUMFLEX '^' /* For scanlists */
  669. #define QUALIFIER_SIZE_T 'z'
  670. #define QUALIFIER_PTRDIFF_T 't'
  671. #define QUALIFIER_INTMAX_T 'j'
  672. #define QUALIFIER_QUAD 'q'
  673. #define QUALIFIER_SIZE_T_UPPER 'Z'
  674. #if TRIO_MISC
  675. # define QUALIFIER_WIDECHAR 'w'
  676. #endif
  677. #define QUALIFIER_FIXED_SIZE 'I'
  678. #define QUALIFIER_QUOTE '\''
  679. #define QUALIFIER_STICKY '!'
  680. #define QUALIFIER_VARSIZE '&' /* This should remain undocumented */
  681. #define QUALIFIER_ROUNDING_UPPER 'R'
  682. #if TRIO_EXTENSION
  683. # define QUALIFIER_PARAM '@' /* Experimental */
  684. # define QUALIFIER_COLON ':' /* For scanlists */
  685. # define QUALIFIER_EQUAL '=' /* For scanlists */
  686. #endif
  687. /*************************************************************************
  688. *
  689. * Internal Structures
  690. *
  691. *************************************************************************/
  692. /* Parameters */
  693. typedef struct {
  694. /* An indication of which entry in the data union is used */
  695. int type;
  696. /* The flags */
  697. trio_flags_t flags;
  698. /* The width qualifier */
  699. int width;
  700. /* The precision qualifier */
  701. int precision;
  702. /* The base qualifier */
  703. int base;
  704. /* Base from specifier */
  705. int baseSpecifier;
  706. /* The size for the variable size qualifier */
  707. int varsize;
  708. /* Offset of the first character of the specifier */
  709. int beginOffset;
  710. /* Offset of the first character after the specifier */
  711. int endOffset;
  712. /* Position in the argument list that this parameter refers to */
  713. int position;
  714. /* The data from the argument list */
  715. union {
  716. char *string;
  717. #if TRIO_FEATURE_WIDECHAR
  718. trio_wchar_t *wstring;
  719. #endif
  720. trio_pointer_t pointer;
  721. union {
  722. trio_intmax_t as_signed;
  723. trio_uintmax_t as_unsigned;
  724. } number;
  725. #if TRIO_FEATURE_FLOAT
  726. double doubleNumber;
  727. double *doublePointer;
  728. trio_long_double_t longdoubleNumber;
  729. trio_long_double_t *longdoublePointer;
  730. #endif
  731. int errorNumber;
  732. } data;
  733. #if TRIO_FEATURE_USER_DEFINED
  734. /* For the user-defined specifier */
  735. union {
  736. char namespace[MAX_USER_NAME];
  737. int handler; /* if flags & FLAGS_USER_DEFINED_PARAMETER */
  738. } user_defined;
  739. char user_data[MAX_USER_DATA];
  740. #endif
  741. } trio_parameter_t;
  742. /* Container for customized functions */
  743. typedef struct {
  744. union {
  745. trio_outstream_t out;
  746. trio_instream_t in;
  747. } stream;
  748. trio_pointer_t closure;
  749. } trio_custom_t;
  750. /* General trio "class" */
  751. typedef struct _trio_class_t {
  752. /*
  753. * The function to write characters to a stream.
  754. */
  755. void (*OutStream) TRIO_PROTO((struct _trio_class_t *, int));
  756. /*
  757. * The function to read characters from a stream.
  758. */
  759. void (*InStream) TRIO_PROTO((struct _trio_class_t *, int *));
  760. /*
  761. * The current location in the stream.
  762. */
  763. trio_pointer_t location;
  764. /*
  765. * The character currently being processed.
  766. */
  767. int current;
  768. /*
  769. * The number of characters that would have been written/read
  770. * if there had been sufficient space.
  771. */
  772. int processed;
  773. /*
  774. * The number of characters that are actually written/read.
  775. * Processed and committed will only differ for the *nprintf
  776. * and *nscanf functions.
  777. */
  778. int committed;
  779. /*
  780. * The upper limit of characters that may be written/read.
  781. */
  782. int max;
  783. /*
  784. * The last output error that was detected.
  785. */
  786. int error;
  787. } trio_class_t;
  788. /* References (for user-defined callbacks) */
  789. typedef struct _trio_reference_t {
  790. trio_class_t *data;
  791. trio_parameter_t *parameter;
  792. } trio_reference_t;
  793. #if TRIO_FEATURE_USER_DEFINED
  794. /* Registered entries (for user-defined callbacks) */
  795. typedef struct _trio_userdef_t {
  796. struct _trio_userdef_t *next;
  797. trio_callback_t callback;
  798. char *name;
  799. } trio_userdef_t;
  800. #endif
  801. /*************************************************************************
  802. *
  803. * Internal Variables
  804. *
  805. *************************************************************************/
  806. static TRIO_CONST char rcsid[] = "@(#)$Id: trio.c,v 1.112 2008/11/09 10:52:26 breese Exp $";
  807. #if TRIO_FEATURE_FLOAT
  808. /*
  809. * Need this to workaround a parser bug in HP C/iX compiler that fails
  810. * to resolves macro definitions that includes type 'long double',
  811. * e.g: va_arg(arg_ptr, long double)
  812. */
  813. # if defined(TRIO_PLATFORM_MPEIX)
  814. static TRIO_CONST trio_long_double_t ___dummy_long_double = 0;
  815. # endif
  816. #endif
  817. static TRIO_CONST char internalNullString[] = "(nil)";
  818. #if defined(USE_LOCALE)
  819. static struct lconv *internalLocaleValues = NULL;
  820. #endif
  821. /*
  822. * UNIX98 says "in a locale where the radix character is not defined,
  823. * the radix character defaults to a period (.)"
  824. */
  825. #if TRIO_FEATURE_FLOAT || TRIO_FEATURE_LOCALE || defined(USE_LOCALE)
  826. static int internalDecimalPointLength = 1;
  827. static char internalDecimalPoint = '.';
  828. static char internalDecimalPointString[MAX_LOCALE_SEPARATOR_LENGTH + 1] = ".";
  829. #endif
  830. #if TRIO_FEATURE_QUOTE || TRIO_FEATURE_LOCALE || TRIO_EXTENSION
  831. static int internalThousandSeparatorLength = 1;
  832. static char internalThousandSeparator[MAX_LOCALE_SEPARATOR_LENGTH + 1] = ",";
  833. static char internalGrouping[MAX_LOCALE_GROUPS] = { (char)NO_GROUPING };
  834. #endif
  835. static TRIO_CONST char internalDigitsLower[] = "0123456789abcdefghijklmnopqrstuvwxyz";
  836. static TRIO_CONST char internalDigitsUpper[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
  837. #if TRIO_FEATURE_SCANF
  838. static BOOLEAN_T internalDigitsUnconverted = TRUE;
  839. static int internalDigitArray[128];
  840. # if TRIO_EXTENSION
  841. static BOOLEAN_T internalCollationUnconverted = TRUE;
  842. static char internalCollationArray[MAX_CHARACTER_CLASS][MAX_CHARACTER_CLASS];
  843. # endif
  844. #endif
  845. #if TRIO_FEATURE_USER_DEFINED
  846. static TRIO_VOLATILE trio_callback_t internalEnterCriticalRegion = NULL;
  847. static TRIO_VOLATILE trio_callback_t internalLeaveCriticalRegion = NULL;
  848. static trio_userdef_t *internalUserDef = NULL;
  849. #endif
  850. /*************************************************************************
  851. *
  852. * Internal Functions
  853. *
  854. ************************************************************************/
  855. #if defined(TRIO_EMBED_NAN)
  856. # include "trionan.c"
  857. #endif
  858. #if defined(TRIO_EMBED_STRING)
  859. # include "triostr.c"
  860. #endif
  861. /*************************************************************************
  862. * TrioIsQualifier
  863. *
  864. * Description:
  865. * Remember to add all new qualifiers to this function.
  866. * QUALIFIER_POSITION must not be added.
  867. */
  868. TRIO_PRIVATE BOOLEAN_T
  869. TrioIsQualifier
  870. TRIO_ARGS1((character),
  871. TRIO_CONST char character)
  872. {
  873. /* QUALIFIER_POSITION is not included */
  874. switch (character)
  875. {
  876. case '0': case '1': case '2': case '3': case '4':
  877. case '5': case '6': case '7': case '8': case '9':
  878. case QUALIFIER_PLUS:
  879. case QUALIFIER_MINUS:
  880. case QUALIFIER_SPACE:
  881. case QUALIFIER_DOT:
  882. case QUALIFIER_STAR:
  883. case QUALIFIER_ALTERNATIVE:
  884. case QUALIFIER_SHORT:
  885. case QUALIFIER_LONG:
  886. case QUALIFIER_CIRCUMFLEX:
  887. case QUALIFIER_LONG_UPPER:
  888. case QUALIFIER_SIZE_T:
  889. case QUALIFIER_PTRDIFF_T:
  890. case QUALIFIER_INTMAX_T:
  891. case QUALIFIER_QUAD:
  892. case QUALIFIER_SIZE_T_UPPER:
  893. #if defined(QUALIFIER_WIDECHAR)
  894. case QUALIFIER_WIDECHAR:
  895. #endif
  896. case QUALIFIER_QUOTE:
  897. case QUALIFIER_STICKY:
  898. case QUALIFIER_VARSIZE:
  899. #if defined(QUALIFIER_PARAM)
  900. case QUALIFIER_PARAM:
  901. #endif
  902. case QUALIFIER_FIXED_SIZE:
  903. case QUALIFIER_ROUNDING_UPPER:
  904. return TRUE;
  905. default:
  906. return FALSE;
  907. }
  908. }
  909. /*************************************************************************
  910. * TrioSetLocale
  911. */
  912. #if defined(USE_LOCALE)
  913. TRIO_PRIVATE void
  914. TrioSetLocale(TRIO_NOARGS)
  915. {
  916. internalLocaleValues = (struct lconv *)localeconv();
  917. if (internalLocaleValues)
  918. {
  919. if ((internalLocaleValues->decimal_point) &&
  920. (internalLocaleValues->decimal_point[0] != NIL))
  921. {
  922. internalDecimalPointLength = trio_length(internalLocaleValues->decimal_point);
  923. if (internalDecimalPointLength == 1)
  924. {
  925. internalDecimalPoint = internalLocaleValues->decimal_point[0];
  926. }
  927. else
  928. {
  929. internalDecimalPoint = NIL;
  930. trio_copy_max(internalDecimalPointString,
  931. sizeof(internalDecimalPointString),
  932. internalLocaleValues->decimal_point);
  933. }
  934. }
  935. # if TRIO_EXTENSION
  936. if ((internalLocaleValues->thousands_sep) &&
  937. (internalLocaleValues->thousands_sep[0] != NIL))
  938. {
  939. trio_copy_max(internalThousandSeparator,
  940. sizeof(internalThousandSeparator),
  941. internalLocaleValues->thousands_sep);
  942. internalThousandSeparatorLength = trio_length(internalThousandSeparator);
  943. }
  944. # endif
  945. # if TRIO_EXTENSION
  946. if ((internalLocaleValues->grouping) &&
  947. (internalLocaleValues->grouping[0] != NIL))
  948. {
  949. trio_copy_max(internalGrouping,
  950. sizeof(internalGrouping),
  951. internalLocaleValues->grouping);
  952. }
  953. # endif
  954. }
  955. }
  956. #endif /* defined(USE_LOCALE) */
  957. #if TRIO_FEATURE_FLOAT && TRIO_FEATURE_QUOTE
  958. TRIO_PRIVATE int
  959. TrioCalcThousandSeparatorLength
  960. TRIO_ARGS1((digits),
  961. int digits)
  962. {
  963. int count = 0;
  964. int step = NO_GROUPING;
  965. char *groupingPointer = internalGrouping;
  966. while (digits > 0)
  967. {
  968. if (*groupingPointer == CHAR_MAX)
  969. {
  970. /* Disable grouping */
  971. break; /* while */
  972. }
  973. else if (*groupingPointer == 0)
  974. {
  975. /* Repeat last group */
  976. if (step == NO_GROUPING)
  977. {
  978. /* Error in locale */
  979. break; /* while */
  980. }
  981. }
  982. else
  983. {
  984. step = *groupingPointer++;
  985. }
  986. if (digits > step)
  987. count += internalThousandSeparatorLength;
  988. digits -= step;
  989. }
  990. return count;
  991. }
  992. #endif /* TRIO_FEATURE_FLOAT && TRIO_FEATURE_QUOTE */
  993. #if TRIO_FEATURE_QUOTE
  994. TRIO_PRIVATE BOOLEAN_T
  995. TrioFollowedBySeparator
  996. TRIO_ARGS1((position),
  997. int position)
  998. {
  999. int step = 0;
  1000. char *groupingPointer = internalGrouping;
  1001. position--;
  1002. if (position == 0)
  1003. return FALSE;
  1004. while (position > 0)
  1005. {
  1006. if (*groupingPointer == CHAR_MAX)
  1007. {
  1008. /* Disable grouping */
  1009. break; /* while */
  1010. }
  1011. else if (*groupingPointer != 0)
  1012. {
  1013. step = *groupingPointer++;
  1014. }
  1015. if (step == 0)
  1016. break;
  1017. position -= step;
  1018. }
  1019. return (position == 0);
  1020. }
  1021. #endif /* TRIO_FEATURE_QUOTE */
  1022. /*************************************************************************
  1023. * TrioGetPosition
  1024. *
  1025. * Get the %n$ position.
  1026. */
  1027. TRIO_PRIVATE int
  1028. TrioGetPosition
  1029. TRIO_ARGS2((format, offsetPointer),
  1030. TRIO_CONST char *format,
  1031. int *offsetPointer)
  1032. {
  1033. #if TRIO_FEATURE_POSITIONAL
  1034. char *tmpformat;
  1035. int number = 0;
  1036. int offset = *offsetPointer;
  1037. number = (int)trio_to_long(&format[offset], &tmpformat, BASE_DECIMAL);
  1038. offset = (int)(tmpformat - format);
  1039. if ((number != 0) && (QUALIFIER_POSITION == format[offset++]))
  1040. {
  1041. *offsetPointer = offset;
  1042. /*
  1043. * number is decreased by 1, because n$ starts from 1, whereas
  1044. * the array it is indexing starts from 0.
  1045. */
  1046. return number - 1;
  1047. }
  1048. #endif
  1049. return NO_POSITION;
  1050. }
  1051. /*************************************************************************
  1052. * TrioFindNamespace
  1053. *
  1054. * Find registered user-defined specifier.
  1055. * The prev argument is used for optimization only.
  1056. */
  1057. #if TRIO_FEATURE_USER_DEFINED
  1058. TRIO_PRIVATE trio_userdef_t *
  1059. TrioFindNamespace
  1060. TRIO_ARGS2((name, prev),
  1061. TRIO_CONST char *name,
  1062. trio_userdef_t **prev)
  1063. {
  1064. trio_userdef_t *def;
  1065. if (internalEnterCriticalRegion)
  1066. (void)internalEnterCriticalRegion(NULL);
  1067. for (def = internalUserDef; def; def = def->next)
  1068. {
  1069. /* Case-sensitive string comparison */
  1070. if (trio_equal_case(def->name, name))
  1071. break;
  1072. if (prev)
  1073. *prev = def;
  1074. }
  1075. if (internalLeaveCriticalRegion)
  1076. (void)internalLeaveCriticalRegion(NULL);
  1077. return def;
  1078. }
  1079. #endif
  1080. /*************************************************************************
  1081. * TrioPower
  1082. *
  1083. * Description:
  1084. * Calculate pow(base, exponent), where number and exponent are integers.
  1085. */
  1086. #if TRIO_FEATURE_FLOAT
  1087. TRIO_PRIVATE trio_long_double_t
  1088. TrioPower
  1089. TRIO_ARGS2((number, exponent),
  1090. int number,
  1091. int exponent)
  1092. {
  1093. trio_long_double_t result;
  1094. if (number == 10)
  1095. {
  1096. switch (exponent)
  1097. {
  1098. /* Speed up calculation of common cases */
  1099. case 0:
  1100. result = (trio_long_double_t)number * TRIO_SUFFIX_LONG(1E-1);
  1101. break;
  1102. case 1:
  1103. result = (trio_long_double_t)number * TRIO_SUFFIX_LONG(1E+0);
  1104. break;
  1105. case 2:
  1106. result = (trio_long_double_t)number * TRIO_SUFFIX_LONG(1E+1);
  1107. break;
  1108. case 3:
  1109. result = (trio_long_double_t)number * TRIO_SUFFIX_LONG(1E+2);
  1110. break;
  1111. case 4:
  1112. result = (trio_long_double_t)number * TRIO_SUFFIX_LONG(1E+3);
  1113. break;
  1114. case 5:
  1115. result = (trio_long_double_t)number * TRIO_SUFFIX_LONG(1E+4);
  1116. break;
  1117. case 6:
  1118. result = (trio_long_double_t)number * TRIO_SUFFIX_LONG(1E+5);
  1119. break;
  1120. case 7:
  1121. result = (trio_long_double_t)number * TRIO_SUFFIX_LONG(1E+6);
  1122. break;
  1123. case 8:
  1124. result = (trio_long_double_t)number * TRIO_SUFFIX_LONG(1E+7);
  1125. break;
  1126. case 9:
  1127. result = (trio_long_double_t)number * TRIO_SUFFIX_LONG(1E+8);
  1128. break;
  1129. default:
  1130. result = trio_pow((trio_long_double_t)number,
  1131. (trio_long_double_t)exponent);
  1132. break;
  1133. }
  1134. }
  1135. else
  1136. {
  1137. return trio_pow((trio_long_double_t)number,
  1138. (trio_long_double_t)exponent);
  1139. }
  1140. return result;
  1141. }
  1142. #endif /* TRIO_FEATURE_FLOAT */
  1143. /*************************************************************************
  1144. * TrioLogarithm
  1145. */
  1146. #if TRIO_FEATURE_FLOAT
  1147. TRIO_PRIVATE trio_long_double_t
  1148. TrioLogarithm
  1149. TRIO_ARGS2((number, base),
  1150. trio_long_double_t number,
  1151. int base)
  1152. {
  1153. trio_long_double_t result;
  1154. if (number <= 0.0)
  1155. {
  1156. /* xlC crashes on log(0) */
  1157. result = (number == 0.0) ? trio_ninf() : trio_nan();
  1158. }
  1159. else
  1160. {
  1161. if (base == 10)
  1162. {
  1163. result = trio_log10(number);
  1164. }
  1165. else
  1166. {
  1167. result = trio_log10(number) / trio_log10((double)base);
  1168. }
  1169. }
  1170. return result;
  1171. }
  1172. #endif /* TRIO_FEATURE_FLOAT */
  1173. /*************************************************************************
  1174. * TrioLogarithmBase
  1175. */
  1176. #if TRIO_FEATURE_FLOAT
  1177. TRIO_PRIVATE double
  1178. TrioLogarithmBase
  1179. TRIO_ARGS1((base),
  1180. int base)
  1181. {
  1182. switch (base)
  1183. {
  1184. case BASE_BINARY : return 1.0;
  1185. case BASE_OCTAL : return 3.0;
  1186. case BASE_DECIMAL: return 3.321928094887362345;
  1187. case BASE_HEX : return 4.0;
  1188. default : return TrioLogarithm((double)base, 2);
  1189. }
  1190. }
  1191. #endif /* TRIO_FEATURE_FLOAT */
  1192. /*************************************************************************
  1193. * TrioParseQualifiers
  1194. *
  1195. * Description:
  1196. * Parse the qualifiers of a potential conversion specifier
  1197. */
  1198. TRIO_PRIVATE int
  1199. TrioParseQualifiers
  1200. TRIO_ARGS4((type, format, offset, parameter),
  1201. int type,
  1202. TRIO_CONST char *format,
  1203. int offset,
  1204. trio_parameter_t *parameter)
  1205. {
  1206. char ch;
  1207. int dots = 0; /* Count number of dots in modifier part */
  1208. char *tmpformat;
  1209. parameter->beginOffset = offset - 1;
  1210. parameter->flags = FLAGS_NEW;
  1211. parameter->position = TrioGetPosition(format, &offset);
  1212. /* Default values */
  1213. parameter->width = NO_WIDTH;
  1214. parameter->precision = NO_PRECISION;
  1215. parameter->base = NO_BASE;
  1216. parameter->varsize = NO_SIZE;
  1217. while (TrioIsQualifier(format[offset]))
  1218. {
  1219. ch = format[offset++];
  1220. switch (ch)
  1221. {
  1222. case QUALIFIER_SPACE:
  1223. parameter->flags |= FLAGS_SPACE;
  1224. break;
  1225. case QUALIFIER_PLUS:
  1226. parameter->flags |= FLAGS_SHOWSIGN;
  1227. break;
  1228. case QUALIFIER_MINUS:
  1229. parameter->flags |= FLAGS_LEFTADJUST;
  1230. parameter->flags &= ~FLAGS_NILPADDING;
  1231. break;
  1232. case QUALIFIER_ALTERNATIVE:
  1233. parameter->flags |= FLAGS_ALTERNATIVE;
  1234. break;
  1235. case QUALIFIER_DOT:
  1236. if (dots == 0) /* Precision */
  1237. {
  1238. dots++;
  1239. /* Skip if no precision */
  1240. if (QUALIFIER_DOT == format[offset])
  1241. break;
  1242. /* After the first dot we have the precision */
  1243. parameter->flags |= FLAGS_PRECISION;
  1244. if ((QUALIFIER_STAR == format[offset])
  1245. #if defined(QUALIFIER_PARAM)
  1246. || (QUALIFIER_PARAM == format[offset])
  1247. #endif
  1248. )
  1249. {
  1250. offset++;
  1251. parameter->flags |= FLAGS_PRECISION_PARAMETER;
  1252. parameter->precision = TrioGetPosition(format, &offset);
  1253. }
  1254. else
  1255. {
  1256. parameter->precision = trio_to_long(&format[offset],
  1257. &tmpformat,
  1258. BASE_DECIMAL);
  1259. offset = (int)(tmpformat - format);
  1260. }
  1261. }
  1262. else if (dots == 1) /* Base */
  1263. {
  1264. dots++;
  1265. /* After the second dot we have the base */
  1266. parameter->flags |= FLAGS_BASE;
  1267. if ((QUALIFIER_STAR == format[offset])
  1268. #if defined(QUALIFIER_PARAM)
  1269. || (QUALIFIER_PARAM == format[offset])
  1270. #endif
  1271. )
  1272. {
  1273. offset++;
  1274. parameter->flags |= FLAGS_BASE_PARAMETER;
  1275. parameter->base = TrioGetPosition(format, &offset);
  1276. }
  1277. else
  1278. {
  1279. parameter->base = trio_to_long(&format[offset],
  1280. &tmpformat,
  1281. BASE_DECIMAL);
  1282. if (parameter->base > MAX_BASE)
  1283. return TRIO_ERROR_RETURN(TRIO_EINVAL, offset);
  1284. offset = (int)(tmpformat - format);
  1285. }
  1286. }
  1287. else
  1288. {
  1289. return TRIO_ERROR_RETURN(TRIO_EINVAL, offset);
  1290. }
  1291. break; /* QUALIFIER_DOT */
  1292. #if defined(QUALIFIER_PARAM)
  1293. case QUALIFIER_PARAM:
  1294. parameter->type = TYPE_PRINT;
  1295. /* FALLTHROUGH */
  1296. #endif
  1297. case QUALIFIER_STAR:
  1298. /* This has different meanings for print and scan */
  1299. if (TYPE_PRINT == type)
  1300. {
  1301. /* Read with from parameter */
  1302. parameter->flags |= (FLAGS_WIDTH | FLAGS_WIDTH_PARAMETER);
  1303. int width = TrioGetPosition(format, &offset);
  1304. if (NO_POSITION != width) parameter->width = width;
  1305. /* else keep parameter->width = NO_WIDTH which != NO_POSITION */
  1306. }
  1307. #if TRIO_FEATURE_SCANF
  1308. else
  1309. {
  1310. /* Scan, but do not store result */
  1311. parameter->flags |= FLAGS_IGNORE;
  1312. }
  1313. #endif
  1314. break; /* QUALIFIER_STAR */
  1315. case '0':
  1316. if (! (parameter->flags & FLAGS_LEFTADJUST))
  1317. parameter->flags |= FLAGS_NILPADDING;
  1318. /* FALLTHROUGH */
  1319. case '1': case '2': case '3': case '4':
  1320. case '5': case '6': case '7': case '8': case '9':
  1321. parameter->flags |= FLAGS_WIDTH;
  1322. /*
  1323. * &format[offset - 1] is used to "rewind" the read
  1324. * character from format
  1325. */
  1326. parameter->width = trio_to_long(&format[offset - 1],
  1327. &tmpformat,
  1328. BASE_DECIMAL);
  1329. offset = (int)(tmpformat - format);
  1330. break;
  1331. case QUALIFIER_SHORT:
  1332. if (parameter->flags & FLAGS_SHORTSHORT)
  1333. return TRIO_ERROR_RETURN(TRIO_EINVAL, offset);
  1334. else if (parameter->flags & FLAGS_SHORT)
  1335. parameter->flags |= FLAGS_SHORTSHORT;
  1336. else
  1337. parameter->flags |= FLAGS_SHORT;
  1338. break;
  1339. case QUALIFIER_LONG:
  1340. if (parameter->flags & FLAGS_QUAD)
  1341. return TRIO_ERROR_RETURN(TRIO_EINVAL, offset);
  1342. else if (parameter->flags & FLAGS_LONG)
  1343. parameter->flags |= FLAGS_QUAD;
  1344. else
  1345. parameter->flags |= FLAGS_LONG;
  1346. break;
  1347. #if TRIO_FEATURE_LONGDOUBLE
  1348. case QUALIFIER_LONG_UPPER:
  1349. parameter->flags |= FLAGS_LONGDOUBLE;
  1350. break;
  1351. #endif
  1352. #if TRIO_FEATURE_SIZE_T
  1353. case QUALIFIER_SIZE_T:
  1354. parameter->flags |= FLAGS_SIZE_T;
  1355. /* Modify flags for later truncation of number */
  1356. if (sizeof(size_t) == sizeof(trio_ulonglong_t))
  1357. parameter->flags |= FLAGS_QUAD;
  1358. else if (sizeof(size_t) == sizeof(long))
  1359. parameter->flags |= FLAGS_LONG;
  1360. break;
  1361. #endif
  1362. #if TRIO_FEATURE_PTRDIFF_T
  1363. case QUALIFIER_PTRDIFF_T:
  1364. parameter->flags |= FLAGS_PTRDIFF_T;
  1365. if (sizeof(ptrdiff_t) == sizeof(trio_ulonglong_t))
  1366. parameter->flags |= FLAGS_QUAD;
  1367. else if (sizeof(ptrdiff_t) == sizeof(long))
  1368. parameter->flags |= FLAGS_LONG;
  1369. break;
  1370. #endif
  1371. #if TRIO_FEATURE_INTMAX_T
  1372. case QUALIFIER_INTMAX_T:
  1373. parameter->flags |= FLAGS_INTMAX_T;
  1374. if (sizeof(trio_intmax_t) == sizeof(trio_ulonglong_t))
  1375. parameter->flags |= FLAGS_QUAD;
  1376. else if (sizeof(trio_intmax_t) == sizeof(long))
  1377. parameter->flags |= FLAGS_LONG;
  1378. break;
  1379. #endif
  1380. #if TRIO_FEATURE_QUAD
  1381. case QUALIFIER_QUAD:
  1382. parameter->flags |= FLAGS_QUAD;
  1383. break;
  1384. #endif
  1385. #if TRIO_FEATURE_FIXED_SIZE
  1386. case QUALIFIER_FIXED_SIZE:
  1387. if (parameter->flags & FLAGS_FIXED_SIZE)
  1388. return TRIO_ERROR_RETURN(TRIO_EINVAL, offset);
  1389. if (parameter->flags & (FLAGS_ALL_SIZES |
  1390. FLAGS_LONGDOUBLE |
  1391. FLAGS_WIDECHAR |
  1392. FLAGS_VARSIZE_PARAMETER))
  1393. return TRIO_ERROR_RETURN(TRIO_EINVAL, offset);
  1394. if ((format[offset] == '6') &&
  1395. (format[offset + 1] == '4'))
  1396. {
  1397. parameter->varsize = sizeof(trio_int64_t);
  1398. offset += 2;
  1399. }
  1400. else if ((format[offset] == '3') &&
  1401. (format[offset + 1] == '2'))
  1402. {
  1403. parameter->varsize = sizeof(trio_int32_t);
  1404. offset += 2;
  1405. }
  1406. else if ((format[offset] == '1') &&
  1407. (format[offset + 1] == '6'))
  1408. {
  1409. parameter->varsize = sizeof(trio_int16_t);
  1410. offset += 2;
  1411. }
  1412. else if (format[offset] == '8')
  1413. {
  1414. parameter->varsize = sizeof(trio_int8_t);
  1415. offset++;
  1416. }
  1417. else
  1418. return TRIO_ERROR_RETURN(TRIO_EINVAL, offset);
  1419. parameter->flags |= FLAGS_FIXED_SIZE;
  1420. break;
  1421. #endif /* TRIO_FEATURE_FIXED_SIZE */
  1422. #if defined(QUALIFIER_WIDECHAR)
  1423. case QUALIFIER_WIDECHAR:
  1424. parameter->flags |= FLAGS_WIDECHAR;
  1425. break;
  1426. #endif
  1427. #if TRIO_FEATURE_SIZE_T_UPPER
  1428. case QUALIFIER_SIZE_T_UPPER:
  1429. break;
  1430. #endif
  1431. #if TRIO_FEATURE_QUOTE
  1432. case QUALIFIER_QUOTE:
  1433. parameter->flags |= FLAGS_QUOTE;
  1434. break;
  1435. #endif
  1436. #if TRIO_FEATURE_STICKY
  1437. case QUALIFIER_STICKY:
  1438. parameter->flags |= FLAGS_STICKY;
  1439. break;
  1440. #endif
  1441. #if TRIO_FEATURE_VARSIZE
  1442. case QUALIFIER_VARSIZE:
  1443. parameter->flags |= FLAGS_VARSIZE_PARAMETER;
  1444. break;
  1445. #endif
  1446. #if TRIO_FEATURE_ROUNDING
  1447. case QUALIFIER_ROUNDING_UPPER:
  1448. parameter->flags |= FLAGS_ROUNDING;
  1449. break;
  1450. #endif
  1451. default:
  1452. /* Bail out completely to make the error more obvious */
  1453. return TRIO_ERROR_RETURN(TRIO_EINVAL, offset);
  1454. }
  1455. } /* while qualifier */
  1456. parameter->endOffset = offset;
  1457. return 0;
  1458. }
  1459. /*************************************************************************
  1460. * TrioParseSpecifier
  1461. *
  1462. * Description:
  1463. * Parse the specifier part of a potential conversion specifier
  1464. */
  1465. TRIO_PRIVATE int
  1466. TrioParseSpecifier
  1467. TRIO_ARGS4((type, format, offset, parameter),
  1468. int type,
  1469. TRIO_CONST char *format,
  1470. int offset,
  1471. trio_parameter_t *parameter)
  1472. {
  1473. parameter->baseSpecifier = NO_BASE;
  1474. switch (format[offset++])
  1475. {
  1476. #if defined(SPECIFIER_CHAR_UPPER)
  1477. case SPECIFIER_CHAR_UPPER:
  1478. parameter->flags |= FLAGS_WIDECHAR;
  1479. /* FALLTHROUGH */
  1480. #endif
  1481. case SPECIFIER_CHAR:
  1482. if (parameter->flags & FLAGS_LONG)
  1483. parameter->flags |= FLAGS_WIDECHAR;
  1484. else if (parameter->flags & FLAGS_SHORT)
  1485. parameter->flags &= ~FLAGS_WIDECHAR;
  1486. parameter->type = FORMAT_CHAR;
  1487. break;
  1488. #if defined(SPECIFIER_STRING_UPPER)
  1489. case SPECIFIER_STRING_UPPER:
  1490. parameter->flags |= FLAGS_WIDECHAR;
  1491. /* FALLTHROUGH */
  1492. #endif
  1493. case SPECIFIER_STRING:
  1494. if (parameter->flags & FLAGS_LONG)
  1495. parameter->flags |= FLAGS_WIDECHAR;
  1496. else if (parameter->flags & FLAGS_SHORT)
  1497. parameter->flags &= ~FLAGS_WIDECHAR;
  1498. parameter->type = FORMAT_STRING;
  1499. break;
  1500. #if defined(SPECIFIER_GROUP)
  1501. case SPECIFIER_GROUP:
  1502. if (TYPE_SCAN == type)
  1503. {
  1504. int depth = 1;
  1505. parameter->type = FORMAT_GROUP;
  1506. if (format[offset] == QUALIFIER_CIRCUMFLEX)
  1507. offset++;
  1508. if (format[offset] == SPECIFIER_UNGROUP)
  1509. offset++;
  1510. if (format[offset] == QUALIFIER_MINUS)
  1511. offset++;
  1512. /* Skip nested brackets */
  1513. while (format[offset] != NIL)
  1514. {
  1515. if (format[offset] == SPECIFIER_GROUP)
  1516. {
  1517. depth++;
  1518. }
  1519. else if (format[offset] == SPECIFIER_UNGROUP)
  1520. {
  1521. if (--depth <= 0)
  1522. {
  1523. offset++;
  1524. break;
  1525. }
  1526. }
  1527. offset++;
  1528. }
  1529. }
  1530. break;
  1531. #endif /* defined(SPECIFIER_GROUP) */
  1532. case SPECIFIER_INTEGER:
  1533. parameter->type = FORMAT_INT;
  1534. break;
  1535. case SPECIFIER_UNSIGNED:
  1536. parameter->flags |= FLAGS_UNSIGNED;
  1537. parameter->type = FORMAT_INT;
  1538. break;
  1539. case SPECIFIER_DECIMAL:
  1540. parameter->baseSpecifier = BASE_DECIMAL;
  1541. parameter->type = FORMAT_INT;
  1542. break;
  1543. case SPECIFIER_OCTAL:
  1544. parameter->flags |= FLAGS_UNSIGNED;
  1545. parameter->baseSpecifier = BASE_OCTAL;
  1546. parameter->type = FORMAT_INT;
  1547. break;
  1548. #if TRIO_FEATURE_BINARY
  1549. case SPECIFIER_BINARY_UPPER:
  1550. parameter->flags |= FLAGS_UPPER;
  1551. /* FALLTHROUGH */
  1552. case SPECIFIER_BINARY:
  1553. parameter->flags |= FLAGS_NILPADDING;
  1554. parameter->baseSpecifier = BASE_BINARY;
  1555. parameter->type = FORMAT_INT;
  1556. break;
  1557. #endif
  1558. case SPECIFIER_HEX_UPPER:
  1559. parameter->flags |= FLAGS_UPPER;
  1560. /* FALLTHROUGH */
  1561. case SPECIFIER_HEX:
  1562. parameter->flags |= FLAGS_UNSIGNED;
  1563. parameter->baseSpecifier = BASE_HEX;
  1564. parameter->type = FORMAT_INT;
  1565. break;
  1566. #if defined(SPECIFIER_FLOAT_E)
  1567. # if defined(SPECIFIER_FLOAT_E_UPPER)
  1568. case SPECIFIER_FLOAT_E_UPPER:
  1569. parameter->flags |= FLAGS_UPPER;
  1570. /* FALLTHROUGH */
  1571. # endif
  1572. case SPECIFIER_FLOAT_E:
  1573. parameter->flags |= FLAGS_FLOAT_E;
  1574. parameter->type = FORMAT_DOUBLE;
  1575. break;
  1576. #endif
  1577. #if defined(SPECIFIER_FLOAT_G)
  1578. # if defined(SPECIFIER_FLOAT_G_UPPER)
  1579. case SPECIFIER_FLOAT_G_UPPER:
  1580. parameter->flags |= FLAGS_UPPER;
  1581. /* FALLTHROUGH */
  1582. # endif
  1583. case SPECIFIER_FLOAT_G:
  1584. parameter->flags |= FLAGS_FLOAT_G;
  1585. parameter->type = FORMAT_DOUBLE;
  1586. break;
  1587. #endif
  1588. #if defined(SPECIFIER_FLOAT_F)
  1589. # if defined(SPECIFIER_FLOAT_F_UPPER)
  1590. case SPECIFIER_FLOAT_F_UPPER:
  1591. parameter->flags |= FLAGS_UPPER;
  1592. /* FALLTHROUGH */
  1593. # endif
  1594. case SPECIFIER_FLOAT_F:
  1595. parameter->type = FORMAT_DOUBLE;
  1596. break;
  1597. #endif
  1598. #if defined(TRIO_COMPILER_VISUALC)
  1599. # pragma warning( push )
  1600. # pragma warning( disable : 4127 ) /* Conditional expression is constant */
  1601. #endif
  1602. case SPECIFIER_POINTER:
  1603. if (sizeof(trio_pointer_t) == sizeof(trio_ulonglong_t))
  1604. parameter->flags |= FLAGS_QUAD;
  1605. else if (sizeof(trio_pointer_t) == sizeof(long))
  1606. parameter->flags |= FLAGS_LONG;
  1607. parameter->type = FORMAT_POINTER;
  1608. break;
  1609. #if defined(TRIO_COMPILER_VISUALC)
  1610. # pragma warning( pop )
  1611. #endif
  1612. case SPECIFIER_COUNT:
  1613. parameter->type = FORMAT_COUNT;
  1614. break;
  1615. #if TRIO_FEATURE_HEXFLOAT
  1616. case SPECIFIER_HEXFLOAT_UPPER:
  1617. parameter->flags |= FLAGS_UPPER;
  1618. /* FALLTHROUGH */
  1619. case SPECIFIER_HEXFLOAT:
  1620. parameter->baseSpecifier = BASE_HEX;
  1621. parameter->type = FORMAT_DOUBLE;
  1622. break;
  1623. #endif
  1624. #if TRIO_FEATURE_ERRNO
  1625. case SPECIFIER_ERRNO:
  1626. parameter->type = FORMAT_ERRNO;
  1627. break;
  1628. #endif
  1629. #if TRIO_FEATURE_USER_DEFINED
  1630. case SPECIFIER_USER_DEFINED_BEGIN:
  1631. {
  1632. unsigned int max;
  1633. int without_namespace = TRUE;
  1634. char* tmpformat = (char *)&format[offset];
  1635. int ch;
  1636. parameter->type = FORMAT_USER_DEFINED;
  1637. parameter->user_defined.namespace[0] = NIL;
  1638. while ((ch = format[offset]) != NIL)
  1639. {
  1640. offset++;
  1641. if ((ch == SPECIFIER_USER_DEFINED_END) || (ch == SPECIFIER_USER_DEFINED_EXTRA))
  1642. {
  1643. if (without_namespace)
  1644. /* No namespace, handler will be passed as an argument */
  1645. parameter->flags |= FLAGS_USER_DEFINED_PARAMETER;
  1646. /* Copy the user data */
  1647. max = (unsigned int)(&format[offset] - tmpformat);
  1648. if (max > MAX_USER_DATA)
  1649. max = MAX_USER_DATA;
  1650. trio_copy_max(parameter->user_data, max, tmpformat);
  1651. /* Skip extra data (which is only there to keep the compiler happy) */
  1652. while ((ch != NIL) && (ch != SPECIFIER_USER_DEFINED_END))
  1653. ch = format[offset++];
  1654. break; /* while */
  1655. }
  1656. if (ch == SPECIFIER_USER_DEFINED_SEPARATOR)
  1657. {
  1658. without_namespace = FALSE;
  1659. /* Copy the namespace for later looking-up */
  1660. max = (int)(&format[offset] - tmpformat);
  1661. if (max > MAX_USER_NAME)
  1662. max = MAX_USER_NAME;
  1663. trio_copy_max(parameter->user_defined.namespace, max, tmpformat);
  1664. tmpformat = (char *)&format[offset];
  1665. }
  1666. }
  1667. if (ch != SPECIFIER_USER_DEFINED_END)
  1668. return TRIO_ERROR_RETURN(TRIO_EINVAL, offset);
  1669. }
  1670. break;
  1671. #endif /* TRIO_FEATURE_USER_DEFINED */
  1672. default:
  1673. /* Bail out completely to make the error more obvious */
  1674. return TRIO_ERROR_RETURN(TRIO_EINVAL, offset);
  1675. }
  1676. parameter->endOffset = offset;
  1677. return 0;
  1678. }
  1679. /*************************************************************************
  1680. * TrioParse
  1681. *
  1682. * Description:
  1683. * Parse the format string
  1684. */
  1685. TRIO_PRIVATE int
  1686. TrioParse
  1687. TRIO_ARGS5((type, format, parameters, arglist, argarray),
  1688. int type,
  1689. TRIO_CONST char *format,
  1690. trio_parameter_t *parameters,
  1691. va_list arglist,
  1692. trio_pointer_t *argarray)
  1693. {
  1694. /* Count the number of times a parameter is referenced */
  1695. unsigned short usedEntries[MAX_PARAMETERS];
  1696. /* Parameter counters */
  1697. int parameterPosition;
  1698. int maxParam = -1;
  1699. /* Utility variables */
  1700. int offset; /* Offset into formatting string */
  1701. BOOLEAN_T positional; /* Does the specifier have a positional? */
  1702. #if TRIO_FEATURE_STICKY
  1703. BOOLEAN_T gotSticky = FALSE; /* Are there any sticky modifiers at all? */
  1704. #endif
  1705. /*
  1706. * indices specifies the order in which the parameters must be
  1707. * read from the va_args (this is necessary to handle positionals)
  1708. */
  1709. int indices[MAX_PARAMETERS];
  1710. int pos = 0;
  1711. /* Various variables */
  1712. #if defined(TRIO_COMPILER_SUPPORTS_MULTIBYTE)
  1713. int charlen;
  1714. #endif
  1715. int save_errno;
  1716. int i = -1;
  1717. int num;
  1718. /*
  1719. * The 'parameters' array is not initialized, but we need to
  1720. * know which entries we have used.
  1721. */
  1722. memset(usedEntries, 0, sizeof(usedEntries));
  1723. save_errno = errno;
  1724. offset = 0;
  1725. parameterPosition = 0;
  1726. #if defined(TRIO_COMPILER_SUPPORTS_MULTIBYTE)
  1727. (void)mblen(NULL, 0);
  1728. #endif
  1729. while (format[offset])
  1730. {
  1731. trio_parameter_t parameter = {};
  1732. int status;
  1733. #if defined(TRIO_COMPILER_SUPPORTS_MULTIBYTE)
  1734. if (! isascii(format[offset]))
  1735. {
  1736. /*
  1737. * Multibyte characters cannot be legal specifiers or
  1738. * modifiers, so we skip over them.
  1739. */
  1740. charlen = mblen(&format[offset], MB_LEN_MAX);
  1741. offset += (charlen > 0) ? charlen : 1;
  1742. continue; /* while */
  1743. }
  1744. #endif /* TRIO_COMPILER_SUPPORTS_MULTIBYTE */
  1745. switch(format[offset++]) {
  1746. case CHAR_IDENTIFIER:
  1747. {
  1748. if (CHAR_IDENTIFIER == format[offset])
  1749. {
  1750. /* skip double "%" */
  1751. offset++;
  1752. continue; /* while */
  1753. }
  1754. status = TrioParseQualifiers(type, format, offset, &parameter);
  1755. if (status < 0)
  1756. return status; /* Return qualifier syntax error */
  1757. status = TrioParseSpecifier(type, format, parameter.endOffset, &parameter);
  1758. if (status < 0)
  1759. return status; /* Return specifier syntax error */
  1760. }
  1761. break;
  1762. #if TRIO_EXTENSION
  1763. case CHAR_ALT_IDENTIFIER:
  1764. {
  1765. status = TrioParseQualifiers(type, format, offset, &parameter);
  1766. if (status < 0)
  1767. continue; /* False alert, not a user defined specifier */
  1768. status = TrioParseSpecifier(type, format, parameter.endOffset, &parameter);
  1769. if ((status < 0) || (FORMAT_USER_DEFINED != parameter.type))
  1770. continue; /* False alert, not a user defined specifier */
  1771. }
  1772. break;
  1773. #endif
  1774. default:
  1775. continue; /* while */
  1776. }
  1777. /* now handle the parsed conversion specification */
  1778. positional = (NO_POSITION != parameter.position);
  1779. /*
  1780. * Parameters only need the type and value. The value is
  1781. * read later.
  1782. */
  1783. if (parameter.flags & FLAGS_WIDTH_PARAMETER)
  1784. {
  1785. if (parameter.width == NO_WIDTH)
  1786. {
  1787. parameter.width = parameterPosition++;
  1788. }
  1789. else
  1790. {
  1791. if (! positional)
  1792. parameter.position = parameter.width + 1;
  1793. }
  1794. usedEntries[parameter.width] += 1;
  1795. if (parameter.width > maxParam) maxParam = parameter.width;
  1796. parameters[pos].type = FORMAT_PARAMETER;
  1797. parameters[pos].flags = 0;
  1798. indices[parameter.width] = pos;
  1799. parameter.width = pos++;
  1800. }
  1801. if (parameter.flags & FLAGS_PRECISION_PARAMETER)
  1802. {
  1803. if (parameter.precision == NO_PRECISION)
  1804. {
  1805. parameter.precision = parameterPosition++;
  1806. }
  1807. else
  1808. {
  1809. if (! positional)
  1810. parameter.position = parameter.precision + 1;
  1811. }
  1812. usedEntries[parameter.precision] += 1;
  1813. if (parameter.precision > maxParam) maxParam = parameter.precision;
  1814. parameters[pos].type = FORMAT_PARAMETER;
  1815. parameters[pos].flags = 0;
  1816. indices[parameter.precision] = pos;
  1817. parameter.precision = pos++;
  1818. }
  1819. if (parameter.flags & FLAGS_BASE_PARAMETER)
  1820. {
  1821. if (parameter.base == NO_BASE)
  1822. {
  1823. parameter.base = parameterPosition++;
  1824. }
  1825. else
  1826. {
  1827. if (! positional)
  1828. parameter.position = parameter.base + 1;
  1829. }
  1830. usedEntries[parameter.base] += 1;
  1831. if (parameter.base > maxParam) maxParam = parameter.base;
  1832. parameters[pos].type = FORMAT_PARAMETER;