fork download
  1. /*
  2.  
  3. ax_printf - public domain
  4. Last update: 2015-02-27 Aaron Miller
  5.  
  6.  
  7. TODO
  8.  
  9. - Add proper %g and %e support.
  10. - Test %f more, and add support for #INF, #NAN, etc.
  11.  
  12.  
  13. See: http://w...content-available-to-author-only...s.com/reference/cstdio/printf/
  14. See: http://w...content-available-to-author-only...x.com/man-page/FreeBSD/9/printf/
  15. See: http://w...content-available-to-author-only...x.com/man-page/freebsd/3/syslog/
  16.  
  17.  
  18. LICENSE
  19.  
  20. This software is in the public domain. Where that dedication is not
  21. recognized, you are granted a perpetual, irrevocable license to copy
  22. and modify this file as you see fit.
  23.  
  24. */
  25.  
  26. #ifndef INCGUARD_AX_PRINTF_H_
  27. #define INCGUARD_AX_PRINTF_H_
  28.  
  29. #ifdef AXPRINTF_IMPLEMENTATION
  30. # define AXPF_IMPLEMENT 1
  31. #else
  32. # define AXPF_IMPLEMENT 0
  33. #endif
  34.  
  35. #ifndef AXPF_CXX_ENABLED
  36. # define AXPF_CXX_ENABLED 1
  37. #endif
  38.  
  39. #ifndef AXPF_CXX_OVERLOADS_ENABLED
  40. # define AXPF_CXX_OVERLOADS_ENABLED 1
  41. #endif
  42.  
  43. /* function declaration specifier */
  44. #ifndef AXPF_FUNC
  45. # ifndef AXPRINTF_IMPLEMENTATION
  46. # define AXPF_FUNC extern
  47. # else
  48. # define AXPF_FUNC
  49. # endif
  50. #endif
  51.  
  52. /* function calling convention */
  53. #ifndef AXPF_CALL
  54. # define AXPF_CALL
  55. #endif
  56.  
  57. #include <stdio.h> /* Needed for FILE ;; TODO: Make inclusion optional */
  58. #include <stdarg.h>
  59. #if AXPF_IMPLEMENT
  60. # include <errno.h>
  61. # include <string.h> /* TODO: Don't rely on this */
  62. #endif
  63.  
  64. #ifndef __cplusplus
  65. # undef AXPF_CXX_ENABLED
  66. # define AXPF_CXX_ENABLED 0
  67. #endif
  68.  
  69. #if !AXPF_CXX_ENABLED
  70. # undef AXPF_CXX_OVERLOADS_ENABLED
  71. # define AXPF_CXX_OVERLOADS_ENABLED 0
  72. #endif
  73.  
  74. #ifdef AX_TYPES_DEFINED
  75. typedef ax_s8_t axpf_s8_t;
  76. typedef ax_s16_t axpf_s16_t;
  77. typedef ax_s32_t axpf_s32_t;
  78. typedef ax_s64_t axpf_s64_t;
  79. typedef ax_u8_t axpf_u8_t;
  80. typedef ax_u16_t axpf_u16_t;
  81. typedef ax_u32_t axpf_u32_t;
  82. typedef ax_u64_t axpf_u64_t;
  83. typedef ax_sptr_t axpf_sptr_t;
  84. typedef ax_uptr_t axpf_uptr_t;
  85. typedef ax_smax_t axpf_smax_t;
  86. typedef ax_umax_t axpf_umax_t;
  87. #elif defined( _MSC_VER )
  88. # include <stddef.h>
  89. typedef signed __int8 axpf_s8_t;
  90. typedef signed __int16 axpf_s16_t;
  91. typedef signed __int32 axpf_s32_t;
  92. typedef signed __int64 axpf_s64_t;
  93. typedef unsigned __int8 axpf_u8_t;
  94. typedef unsigned __int16 axpf_u16_t;
  95. typedef unsigned __int32 axpf_u32_t;
  96. typedef unsigned __int64 axpf_u64_t;
  97. typedef ptrdiff_t axpf_sptr_t;
  98. typedef size_t axpf_uptr_t;
  99. typedef ax_s64_t axpf_smax_t;
  100. typedef ax_u64_t axpf_umax_t;
  101. #else
  102. # include <stdint.h>
  103. # include <stddef.h>
  104. typedef int8_t axpf_s8_t;
  105. typedef int16_t axpf_s16_t;
  106. typedef int32_t axpf_s32_t;
  107. typedef int64_t axpf_s64_t;
  108. typedef uint8_t axpf_u8_t;
  109. typedef uint16_t axpf_u16_t;
  110. typedef uint32_t axpf_u32_t;
  111. typedef uint64_t axpf_u64_t;
  112. typedef ptrdiff_t axpf_sptr_t;
  113. typedef size_t axpf_uptr_t;
  114. typedef intmax_t axpf_smax_t;
  115. typedef uintmax_t axpf_umax_t;
  116. #endif
  117. typedef axpf_sptr_t axpf_ptrdiff_t;
  118. typedef axpf_uptr_t axpf_size_t;
  119.  
  120. #ifdef _MSC_VER
  121. typedef axpf_s64_t axpf_longlong_t;
  122. typedef axpf_u64_t axpf_ulonglong_t;
  123. #else
  124. typedef signed long long int axpf_longlong_t;
  125. typedef unsigned long long int axpf_ulonglong_t;
  126. #endif
  127.  
  128. typedef axpf_ptrdiff_t( AXPF_CALL *axpf_write_fn_t )( void *, const char *,
  129. const char * );
  130.  
  131. struct axpf__state_;
  132.  
  133. struct axpf__write_mem_data_
  134. {
  135. char *p;
  136. axpf_size_t i;
  137. axpf_size_t n;
  138. };
  139.  
  140. AXPF_FUNC axpf_ptrdiff_t
  141. AXPF_CALL axpf__write_mem_f
  142. (
  143. void *data,
  144. const char *s,
  145. const char *e
  146. )
  147. #if AXPF_IMPLEMENT
  148. {
  149. struct axpf__write_mem_data_ *md;
  150. axpf_size_t n;
  151.  
  152. md = ( struct axpf__write_mem_data_ * )data;
  153.  
  154. n = ( axpf_size_t )( e - s );
  155. if( !n ) {
  156. return 0;
  157. }
  158.  
  159. if( md->i + n > md->n ) {
  160. n = md->n - md->i;
  161. }
  162.  
  163. memcpy( ( void * )&md->p[ md->i ], ( const void * )s, n );
  164. md->i += n;
  165. md->p[ md->i ] = '\0';
  166.  
  167. return n;
  168. }
  169. #else
  170. ;
  171. #endif
  172. AXPF_FUNC axpf_ptrdiff_t
  173. AXPF_CALL axpf__write_memdup_f
  174. (
  175. void *data,
  176. const char *s,
  177. const char *e
  178. )
  179. #if AXPF_IMPLEMENT
  180. {
  181. struct axpf__write_mem_data_ *md;
  182. axpf_size_t n;
  183. char *p;
  184.  
  185. md = ( struct axpf__write_mem_data_ * )data;
  186.  
  187. n = ( axpf_size_t )( e - s );
  188. if( !n ) {
  189. return 0;
  190. }
  191.  
  192. if( md->i + n > md->n ) {
  193. axpf_size_t capacity;
  194.  
  195. capacity = md->i + n + 1;
  196. capacity += ( capacity - capacity%32 ) + 32;
  197.  
  198. p = ( char * )( !md->p ? malloc( capacity ) : realloc( ( void * )md->p,
  199. capacity ) );
  200. if( !p ) {
  201. return ( axpf_ptrdiff_t )-1;
  202. }
  203.  
  204. md->p = p;
  205. md->n = capacity;
  206. }
  207.  
  208. memcpy( ( void * )&md->p[ md->i ], ( const void * )s, n );
  209. md->i += n;
  210. md->p[ md->i ] = '\0';
  211.  
  212. return n;
  213. }
  214. #else
  215. ;
  216. #endif
  217. AXPF_FUNC axpf_ptrdiff_t
  218. AXPF_CALL axpf__write_fp_f
  219. (
  220. void *data,
  221. const char *s,
  222. const char *e
  223. )
  224. #if AXPF_IMPLEMENT
  225. {
  226. if( !fwrite( ( const void * )s, ( axpf_size_t )( e - s ), 1,
  227. ( FILE * )data ) ) {
  228. return ( axpf_ptrdiff_t )-1;
  229. }
  230.  
  231. return ( axpf_ptrdiff_t )( e - s );
  232. }
  233. #else
  234. ;
  235. #endif
  236.  
  237. #if AXPF_IMPLEMENT
  238.  
  239. enum
  240. {
  241. /* "-" Left-justify within the given field width */
  242. kAxPF_Left = 1<<0,
  243. /* "+" Result will be preceeded by either a - or + */
  244. kAxPF_Sign = 1<<1,
  245. /* " " Result will be preceeded by either a - or a space */
  246. kAxPF_Space = 1<<2,
  247. /* "#" Insert an appropriate radix (0, 0x, 0X) */
  248. kAxPF_Radix = 1<<3,
  249. /* "0" Left-pad the number with zeroes instead of spaces */
  250. kAxPF_Zero = 1<<4,
  251. /* "'" Use a digit separator */
  252. kAxPF_Group = 1<<5,
  253.  
  254. /* [Internal] Printing an array */
  255. kAxPF_Array = 1<<11,
  256. /* [Internal] Uppercase */
  257. kAxPF_Upper = 1<<12,
  258. /* [Internal] Width directive was specified */
  259. kAxPF_Width = 1<<13,
  260. /* [Internal] Precision directive was specified */
  261. kAxPF_Precision = 1<<14,
  262. /* [Internal] Use a lower-case radix (for pointer printing) */
  263. kAxPF_Pointer = 1<<15
  264. };
  265. typedef enum
  266. {
  267. kAxLS_None,
  268. kAxLS_hh,
  269. kAxLS_h,
  270. kAxLS_l,
  271. kAxLS_ll,
  272. kAxLS_j,
  273. kAxLS_z,
  274. kAxLS_t,
  275. kAxLS_L,
  276.  
  277. kAxLS_I,
  278. kAxLS_I32,
  279. kAxLS_I64
  280. } axpf__lengthSpecifier_t;
  281.  
  282. #define AXPF__MAX_ARRAY_PRINT 4
  283. struct axpf__state_
  284. {
  285. axpf_write_fn_t pfn_write;
  286. void *write_data;
  287. axpf_size_t num_written;
  288. int diderror;
  289.  
  290. unsigned repeats;
  291. axpf_size_t arraysize;
  292. char arrayprint[ AXPF__MAX_ARRAY_PRINT ];
  293. unsigned flags;
  294. int width;
  295. int precision;
  296. axpf__lengthSpecifier_t lenspec;
  297. unsigned radix;
  298. va_list args;
  299. const char *s;
  300. const char *e;
  301. const char *p;
  302. };
  303.  
  304. static char axpf__read( struct axpf__state_ *s )
  305. {
  306. return s->p < s->e ? *s->p++ : '\0';
  307. }
  308. static char axpf__look( struct axpf__state_ *s )
  309. {
  310. return s->p < s->e ? *s->p : '\0';
  311. }
  312. static void axpf__skip( struct axpf__state_ *s )
  313. {
  314. if( s->p < s->e ) {
  315. s->p++;
  316. }
  317. }
  318.  
  319. static int axpf__check( struct axpf__state_ *s, int ch )
  320. {
  321. if( s->p < s->e && *s->p == ch ) {
  322. ++s->p;
  323. return 1;
  324. }
  325.  
  326. return 0;
  327. }
  328. static int axpf__checks( struct axpf__state_ *s, const char *p )
  329. {
  330. if( s->p < s->e && *s->p == *p ) {
  331. const char *q;
  332.  
  333. q = s->p + 1;
  334. while( *q++ == *++p ) {
  335. if( !*p ) {
  336. break;
  337. }
  338. }
  339. if( !*p ) {
  340. s->p = q;
  341. return 1;
  342. }
  343. }
  344.  
  345. return 0;
  346. }
  347.  
  348. static int axpf__write( struct axpf__state_ *s, const char *p, const char *e )
  349. {
  350. axpf_ptrdiff_t r;
  351.  
  352. r = s->pfn_write( s->write_data, p, e );
  353. if( r == -1 ) {
  354. s->diderror = 1;
  355. return 0;
  356. }
  357.  
  358. if( s->num_written + ( axpf_size_t )r >= s->num_written ) {
  359. s->num_written += ( axpf_size_t )r;
  360. } else {
  361. s->num_written = ( ~( axpf_size_t )0 ) - 1;
  362. }
  363.  
  364. return 1;
  365. }
  366. static int axpf__writech( struct axpf__state_ *s, char ch )
  367. {
  368. char txt[ 2 ];
  369.  
  370. txt[ 0 ] = ch;
  371. txt[ 1 ] = '\0';
  372.  
  373. return axpf__write( s, &txt[ 0 ], &txt[ 1 ] );
  374. }
  375.  
  376. static char *axpf__utoa( char *end, axpf_umax_t i, unsigned radix, int flags )
  377. {
  378. static const char *lower = "0123456789abcdefghijklmnopqrstuvwxyz";
  379. static const char *upper = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
  380.  
  381. const char *digits;
  382. unsigned groupingdist, groupingbase;
  383. char groupingchar;
  384. char *p;
  385.  
  386. if( radix < 2 ) { radix = 2; }
  387. if( radix > 36 ) { radix = 36; }
  388.  
  389. digits = ( flags & 1 ) ? upper : lower;
  390.  
  391. /* TODO: Grab information from locale */
  392. groupingbase = ( flags & 4 ) ? 3 : 9999;
  393. groupingdist = groupingbase + 1;
  394. groupingchar = ',';
  395.  
  396. p = end - 1;
  397.  
  398. *p = '\0';
  399.  
  400. while( i > 0 ) {
  401. if( !--groupingdist ) {
  402. groupingdist = groupingbase;
  403. *--p = groupingchar;
  404. }
  405. *--p = digits[ i%radix ];
  406. i /= radix;
  407. }
  408. if( *p == '\0' && ( ~flags & 2 ) ) {
  409. *--p = '0';
  410. }
  411.  
  412. return p;
  413. }
  414. static int axpf__dtoax( char *buf, char *outsign, double f, int usescinot,
  415. unsigned maxdigits, unsigned radix )
  416. {
  417. /*
  418. ORIGINAL: http://w...content-available-to-author-only...d.com/thread5585.html (by cb30)
  419. */
  420. union {
  421. axpf_s64_t i;
  422. double f;
  423. } x;
  424. axpf_s64_t mantissa, whole, fract;
  425. axpf_s16_t exp2;
  426.  
  427. ( void )usescinot;
  428.  
  429. if( !f ) {
  430. *buf++ = '0';
  431. *buf++ = '.';
  432. *buf++ = '0';
  433. *buf = '\0';
  434.  
  435. return 0;
  436. }
  437.  
  438. x.f = f;
  439. if( x.i < 0 ) {
  440. x.i &= ~( 1ULL<<63 );
  441. *outsign = '-';
  442. } else {
  443. *outsign = '+';
  444. }
  445.  
  446. exp2 = ( ( axpf_s16_t )( ( x.i>>52 ) & 0x7FF ) ) - 1023;
  447. mantissa = ( x.i & 0x1FFFFFFFFFFFFF ) | 0x10000000000000;
  448. whole = 0;
  449. fract = 0;
  450.  
  451. if( exp2 >= 63 ) {
  452. *buf = '\0';
  453. return 1;
  454. }
  455.  
  456. if( exp2 < -52 ) {
  457. *buf = '\0';
  458. return -1;
  459. }
  460.  
  461. if( exp2 >= 52 ) {
  462. whole = mantissa << ( exp2 - 52 );
  463. } else if( exp2 >= 0 ) {
  464. whole = mantissa >> ( 52 - exp2 );
  465. fract = ( mantissa << ( exp2 + 1 ) ) & 0x1FFFFFFFFFFFFF;
  466. } else {
  467. fract = ( mantissa & 0x1FFFFFFFFFFFFF ) >> -( exp2 + 1 );
  468. }
  469.  
  470. if( !whole ) {
  471. *buf++ = '0';
  472. } else {
  473. char tmp[ 32 ];
  474. char *p;
  475.  
  476. p = axpf__utoa( &tmp[ sizeof( tmp ) - 1 ], whole, radix, 0 );
  477. while( *p != '\0' ) {
  478. *buf++ = *p++;
  479. }
  480. }
  481.  
  482. *buf++ = '.';
  483.  
  484. if( !fract ) {
  485. *buf++ = '0';
  486. } else {
  487. unsigned numdigits = 0;
  488.  
  489. if( maxdigits > 32 ) {
  490. maxdigits = 32;
  491. }
  492.  
  493. for( numdigits = 0; numdigits < maxdigits; ++numdigits ) {
  494. fract *= 10;
  495. *buf++ = ( fract >> 53 ) + '0';
  496. fract &= 0x1FFFFFFFFFFFFF;
  497. }
  498. }
  499.  
  500. *buf = '\0';
  501. return 0;
  502. }
  503.  
  504. static int axpf__pad( struct axpf__state_ *s, unsigned num, char ch )
  505. {
  506. static const char spaces[] = " ";
  507. static const char zeroes[] = "0000000000000000";
  508. const char *p;
  509.  
  510. p = ( ch == ' ' ? &spaces[0] : ( ch == '0' ? &zeroes[0] : NULL ) );
  511.  
  512. if( !p ) {
  513. while( num-- > 0 ) {
  514. if( !axpf__writech( s, ch ) ) {
  515. return 0;
  516. }
  517. }
  518.  
  519. return 1;
  520. }
  521.  
  522. while( num > 0 ) {
  523. unsigned n = num;
  524.  
  525. if( n > sizeof( spaces ) - 1 ) {
  526. n = sizeof( spaces ) - 1;
  527. }
  528.  
  529. if( !axpf__write( s, p, p + n ) ) {
  530. return 0;
  531. }
  532.  
  533. num -= n;
  534. }
  535.  
  536. return 1;
  537. }
  538. static int axpf__write_uintx( struct axpf__state_ *s, axpf_umax_t i, char sign )
  539. {
  540. const char *prefix;
  541. unsigned prefixlen;
  542. unsigned numberlen, numbersignlen;
  543. unsigned numpadzeroes;
  544. unsigned numpadspaces;
  545. unsigned padinfringe;
  546. char buf[ 128 ];
  547. char *p;
  548. int f;
  549.  
  550. f = 0;
  551. if( s->flags & kAxPF_Upper ) { f |= 1; }
  552. if( ( s->flags & kAxPF_Precision ) && s->precision == 0 ) { f |= 2; }
  553. if( s->flags & kAxPF_Group ) { f |= 4; }
  554.  
  555. p = axpf__utoa( &buf[ sizeof( buf ) ], i, s->radix, f );
  556.  
  557. prefix = NULL;
  558. prefixlen = 0;
  559. if( s->flags & ( kAxPF_Radix | kAxPF_Pointer ) ) {
  560. int useupper;
  561.  
  562. if( ( s->flags & kAxPF_Pointer ) || ( ~s->flags & kAxPF_Upper ) ) {
  563. useupper = 0;
  564. } else {
  565. useupper = 1;
  566. }
  567.  
  568. switch( s->radix ) {
  569. case 2:
  570. prefixlen = 2;
  571. prefix = useupper ? "0B" : "0b";
  572. break;
  573. case 8:
  574. prefixlen = 1;
  575. prefix = "0";
  576. break;
  577. case 16:
  578. prefixlen = 2;
  579. prefix = useupper ? "0X" : "0x";
  580. break;
  581. default:
  582. break;
  583. }
  584. }
  585. numberlen = ( unsigned )( axpf_size_t )( &buf[ sizeof( buf ) - 1 ] - p );
  586.  
  587. if( !sign ) {
  588. if( s->flags & kAxPF_Sign ) {
  589. sign = '+';
  590. } else if( s->flags & kAxPF_Space ) {
  591. sign = ' ';
  592. }
  593. }
  594. numbersignlen = numberlen + +( sign != '\0' );
  595.  
  596. numpadzeroes = 0;
  597. if( ( s->flags & kAxPF_Precision ) &&
  598. ( unsigned )s->precision > numbersignlen ) {
  599. numpadzeroes = s->precision - numbersignlen;
  600. }
  601.  
  602. numpadspaces = 0;
  603. padinfringe = numbersignlen + prefixlen + numpadzeroes;
  604. if( ( s->flags & kAxPF_Width ) && ( unsigned )s->width > padinfringe ) {
  605. if( s->flags & kAxPF_Zero ) {
  606. numpadzeroes += s->width - padinfringe;
  607. } else {
  608. numpadspaces += s->width - padinfringe;
  609. }
  610. }
  611.  
  612. if( ~s->flags & kAxPF_Left ) {
  613. if( !axpf__pad( s, numpadspaces, ' ' ) ) {
  614. return 0;
  615. }
  616. }
  617.  
  618. if( sign ) {
  619. if( !axpf__writech( s, sign ) ) {
  620. return 0;
  621. }
  622. }
  623.  
  624. if( prefix != NULL && prefixlen > 0 ) {
  625. if( !axpf__write( s, prefix, prefix + prefixlen ) ) {
  626. return 0;
  627. }
  628. }
  629. axpf__pad( s, numpadzeroes, '0' );
  630.  
  631. if( !axpf__write( s, p, &buf[ sizeof( buf ) - 1 ] ) ) {
  632. return 0;
  633. }
  634.  
  635. if( s->flags & kAxPF_Left ) {
  636. if( !axpf__pad( s, numpadspaces, ' ' ) ) {
  637. return 0;
  638. }
  639. }
  640.  
  641. return 1;
  642. }
  643. static int axpf__write_int( struct axpf__state_ *s, axpf_smax_t i )
  644. {
  645. while( s->repeats-- > 0 ) {
  646. if( i < 0 ) {
  647. if( !axpf__write_uintx( s, ( axpf_umax_t )-i, '-' ) ) {
  648. return 0;
  649. }
  650. } else if( !axpf__write_uintx( s, ( axpf_umax_t )i, '\0' ) ) {
  651. return 0;
  652. }
  653. }
  654.  
  655. return 1;
  656. }
  657. static int axpf__write_uint( struct axpf__state_ *s, axpf_umax_t i )
  658. {
  659. while( s->repeats-- > 0 ) {
  660. if( !axpf__write_uintx( s, i, '\0' ) ) {
  661. return 0;
  662. }
  663. }
  664.  
  665. return 1;
  666. }
  667.  
  668. static int axpf__write_floatd( struct axpf__state_ *s, double f, char spec )
  669. {
  670. unsigned maxdigits;
  671. char buf[ 128 ], *p, *end, *dec;
  672. char sign;
  673. int r;
  674.  
  675. maxdigits = ( s->flags & kAxPF_Precision ) ? s->precision : 6;
  676. sign = '\0';
  677. p = &buf[ sizeof( buf )/2 ];
  678. r = axpf__dtoax( p, &sign, ( double )f, 0, maxdigits, s->radix );
  679. if( r < 0 ) {
  680. buf[ 0 ] = '#'; buf[ 1 ] = 'S'; buf[ 2 ] = '\0';
  681. p = &buf[ 0 ];
  682. } else if( r > 0 ) {
  683. buf[ 0 ] = '#'; buf[ 1 ] = 'L'; buf[ 2 ] = '\0';
  684. p = &buf[ 0 ];
  685. }
  686.  
  687. if( sign != '-' && ( ~s->flags & kAxPF_Sign ) ) {
  688. sign = '\0';
  689. }
  690.  
  691. end = strchr( p, '\0' );
  692.  
  693. if( spec == 'g' ) {
  694. while( end > &buf[ 0 ] && *( end - 1 ) == '0' ) {
  695. *--end = '\0';
  696. }
  697.  
  698. if( end > &buf[ 0 ] && *( end - 1 ) == '.' ) {
  699. *--end = '\0';
  700. }
  701. }
  702.  
  703. dec = strchr( p, '.' );
  704. if( !dec ) {
  705. dec = end;
  706. }
  707.  
  708. if( ( s->flags & kAxPF_Precision ) && s->precision > 0 && r == 0 ) {
  709. unsigned numdigits;
  710.  
  711. if( *dec != '.' ) {
  712. dec[ 0 ] = '.';
  713. dec[ 1 ] = '\0';
  714. end = &dec[ 1 ];
  715. }
  716.  
  717. numdigits = ( unsigned )( axpf_size_t )( end - dec ) - 1;
  718. while( ( int )numdigits < s->precision && numdigits < 32 ) {
  719. *end++ = '0';
  720. }
  721.  
  722. *end = '\0';
  723. }
  724.  
  725. if( ( s->flags & kAxPF_Width ) && s->width > 0 && r == 0 ) {
  726. unsigned numwidth;
  727. char ch;
  728.  
  729. ch = ( s->flags & kAxPF_Zero ) ? '0' : ' ';
  730.  
  731. numwidth = ( unsigned )( axpf_size_t )( dec - p );
  732. if( ch != '0' && sign != '\0' ) {
  733. *--p = sign;
  734. sign = '\0';
  735. ++numwidth;
  736. }
  737.  
  738. while( ( int )numwidth < s->width && numwidth < 32 ) {
  739. *--p = ch;
  740. ++numwidth;
  741. }
  742. }
  743.  
  744. if( sign != '\0' ) {
  745. *--p = sign;
  746. }
  747.  
  748. while( s->repeats-- > 0 ) {
  749. if( !axpf__write( s, p, end ) ) {
  750. return 0;
  751. }
  752. }
  753.  
  754. return 1;
  755. }
  756.  
  757. static int axpf__write_char( struct axpf__state_ *s, int ch )
  758. {
  759. while( s->repeats-- > 0 ) {
  760. if( !axpf__writech( s, ch ) ) {
  761. return 0;
  762. }
  763. }
  764.  
  765. return 1;
  766. }
  767. static int axpf__writewch( struct axpf__state_ *s, wchar_t ch )
  768. {
  769. ( void )s;
  770. ( void )ch;
  771.  
  772. return 0;
  773. }
  774. static int axpf__write_wchar( struct axpf__state_ *s, wchar_t ch )
  775. {
  776. while( s->repeats-- > 0 ) {
  777. if( !axpf__writewch( s, ch ) ) {
  778. return 0;
  779. }
  780. }
  781.  
  782. return 1;
  783. }
  784.  
  785. static int axpf__write_str( struct axpf__state_ *s, const char *p )
  786. {
  787. const char *e;
  788.  
  789. if( !p ) {
  790. p = "(null)";
  791. e = p + 6;
  792. } else if( s->flags & kAxPF_Precision ) {
  793. e = &p[ s->precision ];
  794. } else {
  795. e = strchr( p, '\0' );
  796. }
  797.  
  798. while( s->repeats-- > 0 ) {
  799. if( !axpf__write( s, p, e ) ) {
  800. return 0;
  801. }
  802. }
  803.  
  804. return 1;
  805. }
  806. static int axpf__write_wstr( struct axpf__state_ *s, const wchar_t *p )
  807. {
  808. const wchar_t *e;
  809.  
  810. if( !p ) {
  811. p = L"(null)";
  812. e = p + 6;
  813. } else if( s->flags & kAxPF_Precision ) {
  814. e = &p[ s->precision ];
  815. } else {
  816. e = wcschr( p, L'\0' );
  817. }
  818.  
  819. while( s->repeats-- > 0 ) {
  820. while( p < e ) {
  821. if( !axpf__writewch( s, *p++ ) ) {
  822. return 0;
  823. }
  824. }
  825. }
  826.  
  827. return 1;
  828. }
  829.  
  830. static int axpf__write_syserr( struct axpf__state_ *s, int err )
  831. {
  832. char errbuf[ 128 ];
  833.  
  834. #if defined( _MSC_VER ) && defined( __STDC_WANT_SECURE_LIB__ )
  835. if( strerror_s( errbuf, sizeof( errbuf ), err ) != 0 ) {
  836. errbuf[ 0 ] = '('; errbuf[ 1 ] = 'n'; errbuf[ 2 ] = 'u';
  837. errbuf[ 3 ] = 'l'; errbuf[ 4 ] = 'l'; errbuf[ 5 ] = ')';
  838. errbuf[ 6 ] = '\0';
  839. }
  840. #else
  841. strncpy( errbuf, strerror( err ), sizeof( errbuf ) - 1 );
  842. #endif
  843. errbuf[ sizeof( errbuf ) - 1 ] = '\0';
  844.  
  845. while( s->repeats-- > 0 ) {
  846. if( !axpf__write( s, errbuf, strchr( errbuf, '\0' ) ) ) {
  847. return 0;
  848. }
  849. }
  850.  
  851. return 1;
  852. }
  853. static int axpf__write_bitfield( struct axpf__state_ *s, int bits,
  854. const char *names )
  855. {
  856. int needcomma;
  857.  
  858. if( !names || !*names ) {
  859. return 0;
  860. }
  861.  
  862. if( !s->repeats ) {
  863. return 1;
  864. }
  865.  
  866. s->radix = *( const unsigned char * )names;
  867. if( s->radix == 1 ) {
  868. s->radix = 10;
  869. }
  870.  
  871. ++names;
  872.  
  873. if( !axpf__write_uint( s, ( unsigned )bits ) ) {
  874. return 0;
  875. }
  876.  
  877. if( !axpf__writech( s, ' ' ) || !axpf__writech( s, '<' ) ) {
  878. return 0;
  879. }
  880.  
  881. needcomma = 0;
  882. while( *names && bits ) {
  883. unsigned bit;
  884.  
  885. bit = ( ( unsigned )*names++ ) - 1;
  886. if( bits & ( 1<<bit ) ) {
  887. const char *p;
  888.  
  889. bits &= ~( 1<<bit );
  890.  
  891. if( needcomma ) {
  892. axpf__writech( s, ',' );
  893. }
  894.  
  895. p = names;
  896. while( *names > ' ' ) {
  897. ++names;
  898. }
  899.  
  900. if( !axpf__write( s, p, names ) ) {
  901. return 0;
  902. }
  903.  
  904. needcomma = 1;
  905. }
  906. }
  907.  
  908. if( !axpf__writech( s, '>' ) ) {
  909. return 0;
  910. }
  911.  
  912. return 1;
  913. }
  914. static int axpf__write_hex_dump( struct axpf__state_ *s, const unsigned char *p,
  915. const char *delimiter )
  916. {
  917. const char *delimend;
  918. unsigned count = 16;
  919. unsigned n;
  920. unsigned i;
  921.  
  922. if( !s->repeats ) {
  923. return 1;
  924. }
  925.  
  926. if( !delimiter || !*delimiter ) {
  927. delimiter = " ";
  928. }
  929.  
  930. delimend = strchr( delimiter, '\0' );
  931. n = ( unsigned )( axpf_size_t )( delimend - delimiter );
  932.  
  933. s->radix = 16;
  934.  
  935. if( ( s->flags & kAxPF_Width ) && s->width > 0 ) {
  936. count = s->width;
  937. }
  938.  
  939. s->flags = kAxPF_Precision;
  940. s->precision = 2;
  941. for( i = 0; i < count; ++i ) {
  942. if( i > 0 && !axpf__writech( s, delimiter[ ( i - 1 )%n ] ) ) {
  943. return 0;
  944. }
  945.  
  946. if( !axpf__write_uintx( s, p[ i ], '\0' ) ) {
  947. return 0;
  948. }
  949. }
  950.  
  951. return 1;
  952. }
  953.  
  954. static int axpf__find( struct axpf__state_ *s, int ch, int doflush )
  955. {
  956. const char *p;
  957. axpf_size_t n;
  958.  
  959. n = ( axpf_size_t )( s->e - s->p );
  960. if( !n ) {
  961. return 0;
  962. }
  963.  
  964. p = ( const char * )memchr( ( const void * )s->p, ch, n );
  965. if( !p ) {
  966. return 0;
  967. }
  968.  
  969. if( doflush && s->p != p ) {
  970. if( !axpf__write( s, s->p, p ) ) {
  971. return 0;
  972. }
  973. }
  974.  
  975. s->p = p;
  976. return 1;
  977. }
  978.  
  979. static int axpf__getdigit( int ch, unsigned radix )
  980. {
  981. unsigned rlo, rhi;
  982. unsigned c;
  983.  
  984. rlo = radix < 10 ? radix : 10;
  985. rhi = radix > 10 ? radix - 10 : 0;
  986.  
  987. c = ( unsigned )ch;
  988. if( c >= '0' && c < '0' + rlo ) {
  989. return ch - '0';
  990. }
  991.  
  992. if( c >= 'a' && c < 'a' + rhi ) {
  993. return ch - 'a' + 10;
  994. }
  995. if( c >= 'A' && c < 'A' + rhi ) {
  996. return ch - 'A' + 10;
  997. }
  998.  
  999. return -1;
  1000. }
  1001.  
  1002. static unsigned axpf__step_uint( struct axpf__state_ *s )
  1003. {
  1004. unsigned r = 0;
  1005.  
  1006. for(;;) {
  1007. int n;
  1008.  
  1009. n = axpf__getdigit( axpf__look( s ), 10 );
  1010. if( n < 0 ) {
  1011. break;
  1012. }
  1013.  
  1014. if( r < ( 1L<<( sizeof( int )*8 - 2 ) ) ) {
  1015. r *= 10;
  1016. r += n;
  1017. }
  1018. axpf__skip( s );
  1019. }
  1020.  
  1021. return r;
  1022. }
  1023. static int axpf__step_int( struct axpf__state_ *s )
  1024. {
  1025. int m = 1;
  1026.  
  1027. if( axpf__check( s, '-' ) ) {
  1028. m = -1;
  1029. }
  1030.  
  1031. return m*( int )axpf__step_uint( s );
  1032. }
  1033. static int axpf__step( struct axpf__state_ *s )
  1034. {
  1035. char spec;
  1036.  
  1037. if( !axpf__find( s, '%', 1 ) ) {
  1038. axpf__write( s, s->p, s->e );
  1039. return 0;
  1040. }
  1041.  
  1042. axpf__skip( s );
  1043.  
  1044. if( axpf__check( s, '%' ) ) {
  1045. axpf__writech( s, '%' );
  1046. return 1;
  1047. }
  1048.  
  1049. s->repeats = 1;
  1050. s->arraysize = 0;
  1051. s->arrayprint[ 0 ] = '{';
  1052. s->arrayprint[ 1 ] = ',';
  1053. s->arrayprint[ 2 ] = ' ';
  1054. s->arrayprint[ 3 ] = '}';
  1055. s->flags = 0;
  1056. s->width = 0;
  1057. s->precision = 0;
  1058. s->lenspec = kAxLS_None;
  1059. s->radix = 10;
  1060.  
  1061. /* repeats */
  1062. if( axpf__check( s, '{' ) ) {
  1063. if( axpf__check( s, '*' ) ) {
  1064. s->repeats = va_arg( s->args, unsigned );
  1065. } else {
  1066. s->repeats = axpf__step_uint( s );
  1067. }
  1068.  
  1069. ( void )axpf__check( s, '}' );
  1070. }
  1071.  
  1072. /* array */
  1073. if( axpf__check( s, '[' ) ) {
  1074. unsigned n = 0;
  1075.  
  1076. if( axpf__check( s, '*' ) ) {
  1077. s->arraysize = va_arg( s->args, axpf_size_t );
  1078. } else {
  1079. s->arraysize = axpf__step_uint( s );
  1080. }
  1081. s->flags |= kAxPF_Array;
  1082.  
  1083. while( n < AXPF__MAX_ARRAY_PRINT ) {
  1084. if( axpf__check( s, ']' ) ) {
  1085. break;
  1086. }
  1087.  
  1088. s->arrayprint[ n++ ] = axpf__read( s );
  1089. }
  1090.  
  1091. if( n == AXPF__MAX_ARRAY_PRINT ) {
  1092. ( void )axpf__check( s, ']' );
  1093. } else if( n > 0 ) {
  1094. /* the last character specified is the closing value */
  1095. s->arrayprint[ AXPF__MAX_ARRAY_PRINT - 1 ] = s->arrayprint[ n - 1 ];
  1096.  
  1097. /* if a space was omitted then don't space elements out */
  1098. if( n < 4 ) {
  1099. s->arrayprint[ 2 ] = '\0';
  1100. }
  1101.  
  1102. /* if a delimiter was omitted then assume a comma */
  1103. if( n < 3 ) {
  1104. s->arrayprint[ 1 ] = ',';
  1105. }
  1106. }
  1107. }
  1108.  
  1109. /* flags */
  1110. unsigned fcount;
  1111. do {
  1112. fcount = 0;
  1113.  
  1114. if( axpf__check( s, '-' ) ) {
  1115. s->flags |= kAxPF_Left;
  1116. ++fcount;
  1117. }
  1118. if( axpf__check( s, '+' ) ) {
  1119. s->flags |= kAxPF_Sign;
  1120. ++fcount;
  1121. }
  1122. if( axpf__check( s, ' ' ) ) {
  1123. s->flags |= kAxPF_Space;
  1124. ++fcount;
  1125. }
  1126. if( axpf__check( s, '#' ) ) {
  1127. s->flags |= kAxPF_Radix;
  1128. ++fcount;
  1129. }
  1130. if( axpf__check( s, '0' ) ) {
  1131. s->flags |= kAxPF_Zero;
  1132. ++fcount;
  1133. }
  1134. if( axpf__check( s, '\'' ) ) {
  1135. s->flags |= kAxPF_Group;
  1136. ++fcount;
  1137. }
  1138. } while( fcount > 0 );
  1139.  
  1140. /* width */
  1141. if( axpf__check( s, '*' ) ) {
  1142. s->width = va_arg( s->args, int );
  1143. s->flags |= kAxPF_Width;
  1144. } else if( axpf__getdigit( axpf__look( s ), 10 ) >= 0 ) {
  1145. s->width = axpf__step_int( s );
  1146. s->flags |= kAxPF_Width;
  1147. }
  1148.  
  1149. /* precision */
  1150. if( axpf__check( s, '.' ) ) {
  1151. if( axpf__check( s, '*' ) ) {
  1152. s->precision = va_arg( s->args, int );
  1153. s->flags |= kAxPF_Precision;
  1154. } else if( axpf__getdigit( axpf__look( s ), 10 ) >= 0 ) {
  1155. s->precision = axpf__step_int( s );
  1156. s->flags |= kAxPF_Precision;
  1157. }
  1158. }
  1159.  
  1160. /* length specifier */
  1161. if( axpf__check( s, 'h' ) ) {
  1162. if( axpf__check( s, 'h' ) ) {
  1163. s->lenspec = kAxLS_hh;
  1164. } else {
  1165. s->lenspec = kAxLS_h;
  1166. }
  1167. } else if( axpf__check( s, 'l' ) ) {
  1168. if( axpf__check( s, 'l' ) ) {
  1169. s->lenspec = kAxLS_ll;
  1170. } else {
  1171. s->lenspec = kAxLS_l;
  1172. }
  1173. } else if( axpf__check( s, 'j' ) ) {
  1174. s->lenspec = kAxLS_j;
  1175. } else if( axpf__check( s, 'z' ) ) {
  1176. s->lenspec = kAxLS_z;
  1177. } else if( axpf__check( s, 't' ) ) {
  1178. s->lenspec = kAxLS_t;
  1179. } else if( axpf__check( s, 'L' ) ) {
  1180. s->lenspec = kAxLS_L;
  1181. } else if( axpf__check( s, 'q' ) ) {
  1182. s->lenspec = kAxLS_I64;
  1183. } else if( axpf__check( s, 'w' ) ) {
  1184. s->lenspec = kAxLS_l;
  1185. } else if( axpf__check( s, 'I' ) ) {
  1186. if( axpf__checks( s, "32" ) ) {
  1187. s->lenspec = kAxLS_I32;
  1188. } else if( axpf__checks( s, "64" ) ) {
  1189. s->lenspec = kAxLS_I64;
  1190. } else {
  1191. s->lenspec = kAxLS_I;
  1192. }
  1193. }
  1194.  
  1195. spec = axpf__read( s );
  1196. if( spec >= 'A' && spec <= 'Z' && spec!='C' && spec!='D' && spec!='S' ) {
  1197. s->flags |= kAxPF_Upper;
  1198. spec = spec - 'A' + 'a';
  1199. }
  1200.  
  1201. /* arrays require special handling */
  1202. if( s->flags & kAxPF_Array ) {
  1203. const void *ptrbase;
  1204. unsigned repeats;
  1205.  
  1206. if( spec == 'r' ) {
  1207. s->radix = va_arg( s->args, unsigned int );
  1208. }
  1209. ptrbase = va_arg( s->args, const void * );
  1210.  
  1211. if( spec == 'a' ) {
  1212. spec = 'f';
  1213. s->radix = 16;
  1214. }
  1215.  
  1216. repeats = s->repeats;
  1217. while( repeats-- > 0 ) {
  1218. union {
  1219. const void *p;
  1220. const int *i; const unsigned int *u;
  1221. const signed char *sc; const unsigned char *usc;
  1222. const short int *si; const unsigned short int *usi;
  1223. const long int *li; const unsigned long int *uli;
  1224. #ifdef _MSC_VER
  1225. const __int64 *lli; const unsigned __int64 *ulli;
  1226. #else
  1227. const long long int *lli; const unsigned long long int *ulli;
  1228. #endif
  1229. const axpf_smax_t *im; const axpf_umax_t *uim;
  1230. const axpf_size_t *sz;
  1231. const axpf_ptrdiff_t *pd;
  1232. const axpf_s32_t *i32; const axpf_u32_t *ui32;
  1233. const axpf_s64_t *i64; const axpf_u64_t *ui64;
  1234. const float *f;
  1235. const double *d;
  1236. const long double *ld;
  1237. const char *c;
  1238. const wchar_t *wc;
  1239. const char *const *s;
  1240. const wchar_t *const *ws;
  1241. } x;
  1242. axpf_size_t i;
  1243.  
  1244. if( !ptrbase ) {
  1245. const char buf[] = "(null)";
  1246. axpf__write( s, buf, buf + sizeof(buf) - 1 );
  1247. continue;
  1248. }
  1249.  
  1250. axpf__writech( s, s->arrayprint[ 0 ] );
  1251.  
  1252. x.p = ptrbase;
  1253. for( i = 0; i < s->arraysize; ++i ) {
  1254. if( i > 0 ) {
  1255. axpf__writech( s, s->arrayprint[ 1 ] );
  1256. }
  1257. if( s->arrayprint[ 2 ] == ' ' ) {
  1258. axpf__writech( s, ' ' );
  1259. }
  1260.  
  1261. s->repeats = 1;
  1262. switch( spec ) {
  1263. case 'd':
  1264. case 'i':
  1265. switch( s->lenspec ) {
  1266. #define P_(F_) axpf__write_int( s, x.F_[i] ); break
  1267. case kAxLS_None: P_( i );
  1268. case kAxLS_hh: P_( sc );
  1269. case kAxLS_h: P_( si );
  1270. case kAxLS_l:
  1271. case kAxLS_L: P_( li );
  1272. case kAxLS_ll: P_( lli );
  1273. case kAxLS_j: P_( im );
  1274. case kAxLS_z: P_( sz );
  1275. case kAxLS_I:
  1276. case kAxLS_t: P_( pd );
  1277. case kAxLS_I32: P_( i32 );
  1278. case kAxLS_I64: P_( i64 );
  1279. #undef P_
  1280. }
  1281. break;
  1282.  
  1283. case 'u':
  1284. case 'o':
  1285. case 'x':
  1286. case 'r':
  1287. if( spec == 'o' ) {
  1288. s->radix = 8;
  1289. } else if( spec == 'x' ) {
  1290. s->radix = 16;
  1291. } else if( spec == 'r' ) {
  1292. s->radix = va_arg( s->args, unsigned int );
  1293. }
  1294.  
  1295. switch( s->lenspec ) {
  1296. #define P_(F_) axpf__write_uint( s, x.F_[i] ); break
  1297. case kAxLS_None: P_( u );
  1298. case kAxLS_hh: P_( usc );
  1299. case kAxLS_h: P_( usi );
  1300. case kAxLS_l:
  1301. case kAxLS_L: P_( uli );
  1302. case kAxLS_ll: P_( ulli );
  1303. case kAxLS_j: P_( uim );
  1304. case kAxLS_I:
  1305. case kAxLS_z: P_( sz );
  1306. case kAxLS_t: P_( pd );
  1307. case kAxLS_I32: P_( ui32 );
  1308. case kAxLS_I64: P_( ui64 );
  1309. #undef P_
  1310. }
  1311. break;
  1312.  
  1313. case 'f':
  1314. case 'e':
  1315. case 'g':
  1316. if( s->lenspec == kAxLS_None ) {
  1317. axpf__write_floatd( s, ( double )x.f[ i ], spec );
  1318. } else if( s->lenspec == kAxLS_l ) {
  1319. axpf__write_floatd( s, x.d[ i ], spec );
  1320. } else if( s->lenspec == kAxLS_L ) {
  1321. axpf__write_floatd( s, ( double )x.ld[ i ], spec );
  1322. }
  1323. break;
  1324.  
  1325. case 'c':
  1326. case 'C':
  1327. if( s->lenspec == kAxLS_None && spec != 'C' ) {
  1328. axpf__write_char( s, x.c[ i ] );
  1329. } else if( s->lenspec == kAxLS_l || spec == 'C' ) {
  1330. axpf__write_wchar( s, x.wc[ i ] );
  1331. }
  1332. break;
  1333.  
  1334. case 's':
  1335. case 'S':
  1336. if( s->lenspec == kAxLS_None && spec != 'S' ) {
  1337. axpf__write_str( s, x.s[ i ] );
  1338. } else if( s->lenspec == kAxLS_l || spec == 'S' ) {
  1339. axpf__write_wstr( s, x.ws[ i ] );
  1340. }
  1341. break;
  1342.  
  1343. case 'p':
  1344. s->radix = 16;
  1345. s->flags |= kAxPF_Radix | kAxPF_Pointer | kAxPF_Precision;
  1346. s->precision = sizeof( void * )*2;
  1347. axpf__write_uint( s, x.sz[ i ] );
  1348. break;
  1349. }
  1350. }
  1351.  
  1352. if( s->arrayprint[ 2 ] == ' ' ) {
  1353. axpf__writech( s, ' ' );
  1354. }
  1355.  
  1356. axpf__writech( s, s->arrayprint[ 3 ] );
  1357. }
  1358.  
  1359. return !s->diderror;
  1360. }
  1361.  
  1362. /* check the specifier */
  1363. switch( spec ) {
  1364. case 'd':
  1365. case 'i':
  1366. if( s->lenspec == kAxLS_l ) {
  1367. axpf__write_int( s, va_arg( s->args, long int ) );
  1368. } else if( s->lenspec == kAxLS_ll || s->lenspec == kAxLS_L ) {
  1369. axpf__write_int( s, va_arg( s->args, axpf_longlong_t ) );
  1370. } else if( s->lenspec == kAxLS_t || s->lenspec == kAxLS_I ) {
  1371. axpf__write_int( s, va_arg( s->args, axpf_ptrdiff_t ) );
  1372. } else if( s->lenspec == kAxLS_z ) {
  1373. axpf__write_int( s, va_arg( s->args, axpf_size_t ) );
  1374. } else if( s->lenspec == kAxLS_j ) {
  1375. axpf__write_int( s, va_arg( s->args, axpf_smax_t ) );
  1376. } else if( s->lenspec == kAxLS_I32 ) {
  1377. axpf__write_int( s, va_arg( s->args, axpf_s32_t ) );
  1378. } else if( s->lenspec == kAxLS_I64 ) {
  1379. axpf__write_int( s, va_arg( s->args, axpf_s64_t ) );
  1380. } else {
  1381. axpf__write_int( s, va_arg( s->args, int ) );
  1382. }
  1383. break;
  1384.  
  1385. case 'u':
  1386. case 'o':
  1387. case 'x':
  1388. case 'r':
  1389. if( spec == 'o' ) {
  1390. s->radix = 8;
  1391. } else if( spec == 'x' ) {
  1392. s->radix = 16;
  1393. } else if( spec == 'r' ) {
  1394. s->radix = va_arg( s->args, unsigned int );
  1395. }
  1396.  
  1397. if( s->lenspec == kAxLS_l ) {
  1398. axpf__write_uint( s, va_arg( s->args, unsigned long int ) );
  1399. } else if( s->lenspec == kAxLS_ll || s->lenspec == kAxLS_L ) {
  1400. axpf__write_uint( s, va_arg( s->args, axpf_ulonglong_t ) );
  1401. } else if( s->lenspec == kAxLS_t ) {
  1402. axpf__write_uint( s, va_arg( s->args, axpf_ptrdiff_t ) );
  1403. } else if( s->lenspec == kAxLS_z || s->lenspec == kAxLS_I ) {
  1404. axpf__write_uint( s, va_arg( s->args, axpf_size_t ) );
  1405. } else if( s->lenspec == kAxLS_j ) {
  1406. axpf__write_uint( s, va_arg( s->args, axpf_umax_t ) );
  1407. } else if( s->lenspec == kAxLS_I32 ) {
  1408. axpf__write_uint( s, va_arg( s->args, axpf_u32_t ) );
  1409. } else if( s->lenspec == kAxLS_I64 ) {
  1410. axpf__write_uint( s, va_arg( s->args, axpf_u64_t ) );
  1411. } else {
  1412. axpf__write_uint( s, va_arg( s->args, unsigned int ) );
  1413. }
  1414. break;
  1415.  
  1416. case 'f':
  1417. case 'e':
  1418. case 'g':
  1419. case 'a':
  1420. if( spec == 'a' ) {
  1421. spec = 'f';
  1422. s->radix = 16;
  1423. }
  1424.  
  1425. if( s->lenspec == kAxLS_None ) {
  1426. axpf__write_floatd( s, va_arg( s->args, double ), spec );
  1427. } else if( s->lenspec == kAxLS_l || s->lenspec == kAxLS_L ) {
  1428. axpf__write_floatd( s, ( double )va_arg( s->args, long double ),
  1429. spec );
  1430. }
  1431. break;
  1432.  
  1433. case 'c':
  1434. case 'C':
  1435. if( s->lenspec == kAxLS_None && spec != 'C' ) {
  1436. axpf__write_char( s, va_arg( s->args, int ) );
  1437. } else if( s->lenspec == kAxLS_l || spec == 'C' ) {
  1438. axpf__write_wchar( s, va_arg( s->args, int/*wint_t*/ ) );
  1439. }
  1440. break;
  1441.  
  1442. case 's':
  1443. case 'S':
  1444. if( s->lenspec == kAxLS_None && spec != 'S' ) {
  1445. axpf__write_str( s, va_arg( s->args, const char * ) );
  1446. } else if( s->lenspec == kAxLS_l || spec == 'S' ) {
  1447. axpf__write_wstr( s, va_arg( s->args, const wchar_t * ) );
  1448. }
  1449. break;
  1450.  
  1451. case 'p':
  1452. s->radix = 16;
  1453. s->flags |= kAxPF_Radix | kAxPF_Pointer | kAxPF_Precision;
  1454. s->precision = sizeof( void * )*2;
  1455. axpf__write_uint( s, va_arg( s->args, axpf_size_t ) );
  1456. break;
  1457.  
  1458. case 'n':
  1459. switch( s->lenspec ) {
  1460. #define P_(Ty_) *va_arg( s->args, Ty_ * ) = ( Ty_ )s->num_written; break
  1461. case kAxLS_None: P_( int );
  1462. case kAxLS_hh: P_( signed char );
  1463. case kAxLS_h: P_( short int );
  1464. case kAxLS_l:
  1465. case kAxLS_L: P_( long int );
  1466. #ifdef _MSC_VER
  1467. case kAxLS_ll: P_( __int64 );
  1468. #else
  1469. case kAxLS_ll: P_( long long int );
  1470. #endif
  1471. case kAxLS_j: P_( axpf_smax_t );
  1472. case kAxLS_z: P_( axpf_size_t );
  1473. case kAxLS_I:
  1474. case kAxLS_t: P_( axpf_ptrdiff_t );
  1475. case kAxLS_I32: P_( axpf_s32_t );
  1476. case kAxLS_I64: P_( axpf_s64_t );
  1477. #undef P_
  1478. }
  1479. break;
  1480.  
  1481. case 'm':
  1482. axpf__write_syserr( s, s->width != 0 ? s->width : ( int )errno );
  1483. break;
  1484.  
  1485. case 'b':
  1486. {
  1487. int bits;
  1488. const char *names;
  1489.  
  1490. bits = va_arg( s->args, int );
  1491. names = va_arg( s->args, const char * );
  1492.  
  1493. axpf__write_bitfield( s, bits, names );
  1494. }
  1495. break;
  1496. case 'D':
  1497. {
  1498. const unsigned char *data;
  1499. const char *delm;
  1500.  
  1501. data = va_arg( s->args, const unsigned char * );
  1502. delm = va_arg( s->args, const char * );
  1503.  
  1504. axpf__write_hex_dump( s, data, delm );
  1505. }
  1506. break;
  1507. }
  1508.  
  1509. return !s->diderror;
  1510. }
  1511.  
  1512. #endif /* AXPF_IMPLEMENT */
  1513.  
  1514. AXPF_FUNC axpf_ptrdiff_t
  1515. AXPF_CALL axpf__main
  1516. (
  1517. struct axpf__state_ *s,
  1518. const char *fmt,
  1519. const char *fmte,
  1520. va_list args
  1521. )
  1522. #if AXPF_IMPLEMENT
  1523. {
  1524. s->s = fmt;
  1525. s->p = fmt;
  1526. s->e = !fmte ? strchr( fmt, '\0' ) : fmte;
  1527.  
  1528. s->num_written = 0;
  1529. s->args = args;
  1530.  
  1531. s->diderror = 0;
  1532.  
  1533. while( axpf__step( s ) ) {
  1534. }
  1535.  
  1536. if( s->diderror ) {
  1537. return -1;
  1538. }
  1539.  
  1540. return ( axpf_ptrdiff_t )s->num_written;
  1541. }
  1542. #else
  1543. ;
  1544. #endif
  1545.  
  1546. AXPF_FUNC axpf_ptrdiff_t
  1547. AXPF_CALL axfpfev
  1548. (
  1549. FILE *fp,
  1550. const char *fmt,
  1551. const char *fmte,
  1552. va_list args
  1553. )
  1554. #if AXPF_IMPLEMENT
  1555. {
  1556. struct axpf__state_ s;
  1557.  
  1558. s.pfn_write = &axpf__write_fp_f;
  1559. s.write_data = ( void * )fp;
  1560.  
  1561. return axpf__main( &s, fmt, fmte, args );
  1562. }
  1563. #else
  1564. ;
  1565. #endif
  1566. AXPF_FUNC axpf_ptrdiff_t
  1567. AXPF_CALL axfpfv
  1568. (
  1569. FILE *fp,
  1570. const char *fmt,
  1571. va_list args
  1572. )
  1573. #if AXPF_IMPLEMENT
  1574. {
  1575. struct axpf__state_ s;
  1576.  
  1577. s.pfn_write = &axpf__write_fp_f;
  1578. s.write_data = ( void * )fp;
  1579.  
  1580. return axpf__main( &s, fmt, ( const char * )0, args );
  1581. }
  1582. #else
  1583. ;
  1584. #endif
  1585. AXPF_FUNC axpf_ptrdiff_t
  1586. AXPF_CALL axfpfe
  1587. (
  1588. FILE *fp,
  1589. const char *fmt,
  1590. const char *fmte,
  1591. ...
  1592. )
  1593. #if AXPF_IMPLEMENT
  1594. {
  1595. struct axpf__state_ s;
  1596. axpf_ptrdiff_t r;
  1597. va_list args;
  1598.  
  1599. s.pfn_write = &axpf__write_fp_f;
  1600. s.write_data = ( void * )fp;
  1601.  
  1602. va_start( args, fmte );
  1603. r = axpf__main( &s, fmt, fmte, args );
  1604. va_end( args );
  1605.  
  1606. return r;
  1607. }
  1608. #else
  1609. ;
  1610. #endif
  1611. AXPF_FUNC axpf_ptrdiff_t
  1612. AXPF_CALL axfpf
  1613. (
  1614. FILE *fp,
  1615. const char *fmt,
  1616. ...
  1617. )
  1618. #if AXPF_IMPLEMENT
  1619. {
  1620. struct axpf__state_ s;
  1621. axpf_ptrdiff_t r;
  1622. va_list args;
  1623.  
  1624. s.pfn_write = &axpf__write_fp_f;
  1625. s.write_data = ( void * )fp;
  1626.  
  1627. va_start( args, fmt );
  1628. r = axpf__main( &s, fmt, ( const char * )0, args );
  1629. va_end( args );
  1630.  
  1631. return r;
  1632. }
  1633. #else
  1634. ;
  1635. #endif
  1636.  
  1637. AXPF_FUNC axpf_ptrdiff_t
  1638. AXPF_CALL axerrfev
  1639. (
  1640. const char *fmt,
  1641. const char *fmte,
  1642. va_list args
  1643. )
  1644. #if AXPF_IMPLEMENT
  1645. {
  1646. struct axpf__state_ s;
  1647.  
  1648. s.pfn_write = &axpf__write_fp_f;
  1649. s.write_data = ( void * )stderr;
  1650.  
  1651. return axpf__main( &s, fmt, fmte, args );
  1652. }
  1653. #else
  1654. ;
  1655. #endif
  1656. AXPF_FUNC axpf_ptrdiff_t
  1657. AXPF_CALL axerrfv
  1658. (
  1659. const char *fmt,
  1660. va_list args
  1661. )
  1662. #if AXPF_IMPLEMENT
  1663. {
  1664. struct axpf__state_ s;
  1665.  
  1666. s.pfn_write = &axpf__write_fp_f;
  1667. s.write_data = ( void * )stderr;
  1668.  
  1669. return axpf__main( &s, fmt, ( const char * )0, args );
  1670. }
  1671. #else
  1672. ;
  1673. #endif
  1674. AXPF_FUNC axpf_ptrdiff_t
  1675. AXPF_CALL axerrfe
  1676. (
  1677. const char *fmt,
  1678. const char *fmte,
  1679. ...
  1680. )
  1681. #if AXPF_IMPLEMENT
  1682. {
  1683. struct axpf__state_ s;
  1684. axpf_ptrdiff_t r;
  1685. va_list args;
  1686.  
  1687. s.pfn_write = &axpf__write_fp_f;
  1688. s.write_data = ( void * )stderr;
  1689.  
  1690. va_start( args, fmte );
  1691. r = axpf__main( &s, fmt, fmte, args );
  1692. va_end( args );
  1693.  
  1694. return r;
  1695. }
  1696. #else
  1697. ;
  1698. #endif
  1699. AXPF_FUNC axpf_ptrdiff_t
  1700. AXPF_CALL axerrf
  1701. (
  1702. const char *fmt,
  1703. ...
  1704. )
  1705. #if AXPF_IMPLEMENT
  1706. {
  1707. struct axpf__state_ s;
  1708. axpf_ptrdiff_t r;
  1709. va_list args;
  1710.  
  1711. s.pfn_write = &axpf__write_fp_f;
  1712. s.write_data = ( void * )stderr;
  1713.  
  1714. va_start( args, fmt );
  1715. r = axpf__main( &s, fmt, ( const char * )0, args );
  1716. va_end( args );
  1717.  
  1718. return r;
  1719. }
  1720. #else
  1721. ;
  1722. #endif
  1723.  
  1724. AXPF_FUNC axpf_ptrdiff_t
  1725. AXPF_CALL axpfev
  1726. (
  1727. const char *fmt,
  1728. const char *fmte,
  1729. va_list args
  1730. )
  1731. #if AXPF_IMPLEMENT
  1732. {
  1733. struct axpf__state_ s;
  1734.  
  1735. s.pfn_write = &axpf__write_fp_f;
  1736. s.write_data = ( void * )stdout;
  1737.  
  1738. return axpf__main( &s, fmt, fmte, args );
  1739. }
  1740. #else
  1741. ;
  1742. #endif
  1743. AXPF_FUNC axpf_ptrdiff_t
  1744. AXPF_CALL axpfv
  1745. (
  1746. const char *fmt,
  1747. va_list args
  1748. )
  1749. #if AXPF_IMPLEMENT
  1750. {
  1751. struct axpf__state_ s;
  1752.  
  1753. s.pfn_write = &axpf__write_fp_f;
  1754. s.write_data = ( void * )stdout;
  1755.  
  1756. return axpf__main( &s, fmt, ( const char * )0, args );
  1757. }
  1758. #else
  1759. ;
  1760. #endif
  1761. AXPF_FUNC axpf_ptrdiff_t
  1762. AXPF_CALL axpfe
  1763. (
  1764. const char *fmt,
  1765. const char *fmte,
  1766. ...
  1767. )
  1768. #if AXPF_IMPLEMENT
  1769. {
  1770. struct axpf__state_ s;
  1771. axpf_ptrdiff_t r;
  1772. va_list args;
  1773.  
  1774. s.pfn_write = &axpf__write_fp_f;
  1775. s.write_data = ( void * )stdout;
  1776.  
  1777. va_start( args, fmte );
  1778. r = axpf__main( &s, fmt, fmte, args );
  1779. va_end( args );
  1780.  
  1781. return r;
  1782. }
  1783. #else
  1784. ;
  1785. #endif
  1786. AXPF_FUNC axpf_ptrdiff_t
  1787. AXPF_CALL axpf
  1788. (
  1789. const char *fmt,
  1790. ...
  1791. )
  1792. #if AXPF_IMPLEMENT
  1793. {
  1794. struct axpf__state_ s;
  1795. axpf_ptrdiff_t r;
  1796. va_list args;
  1797.  
  1798. s.pfn_write = &axpf__write_fp_f;
  1799. s.write_data = ( void * )stdout;
  1800.  
  1801. va_start( args, fmt );
  1802. r = axpf__main( &s, fmt, ( const char * )0, args );
  1803. va_end( args );
  1804.  
  1805. return r;
  1806. }
  1807. #else
  1808. ;
  1809. #endif
  1810.  
  1811. AXPF_FUNC axpf_ptrdiff_t
  1812. AXPF_CALL axspfev
  1813. (
  1814. char *buf,
  1815. axpf_size_t nbuf,
  1816. const char *fmt,
  1817. const char *fmte,
  1818. va_list args
  1819. )
  1820. #if AXPF_IMPLEMENT
  1821. {
  1822. struct axpf__write_mem_data_ m;
  1823. struct axpf__state_ s;
  1824. axpf_ptrdiff_t r;
  1825.  
  1826. m.p = buf;
  1827. m.i = 0;
  1828. m.n = nbuf;
  1829.  
  1830. s.pfn_write = &axpf__write_mem_f;
  1831. s.write_data = ( void * )&m;
  1832.  
  1833. r = axpf__main( &s, fmt, fmte, args );
  1834. if( m.n > 0 ) {
  1835. m.p[ m.i < m.n ? m.i : m.n - 1 ] = '\0';
  1836. }
  1837.  
  1838. return r;
  1839. }
  1840. #else
  1841. ;
  1842. #endif
  1843. AXPF_FUNC axpf_ptrdiff_t
  1844. AXPF_CALL axspfv
  1845. (
  1846. char *buf,
  1847. axpf_size_t nbuf,
  1848. const char *fmt,
  1849. va_list args
  1850. )
  1851. #if AXPF_IMPLEMENT
  1852. {
  1853. return axspfev( buf, nbuf, fmt, ( const char * )0, args );
  1854. }
  1855. #else
  1856. ;
  1857. #endif
  1858. AXPF_FUNC axpf_ptrdiff_t
  1859. AXPF_CALL axspfe
  1860. (
  1861. char *buf,
  1862. axpf_size_t nbuf,
  1863. const char *fmt,
  1864. const char *fmte,
  1865. ...
  1866. )
  1867. #if AXPF_IMPLEMENT
  1868. {
  1869. axpf_ptrdiff_t r;
  1870. va_list args;
  1871.  
  1872. va_start( args, fmte );
  1873. r = axspfev( buf, nbuf, fmt, fmte, args );
  1874. va_end( args );
  1875.  
  1876. return r;
  1877. }
  1878. #else
  1879. ;
  1880. #endif
  1881. AXPF_FUNC axpf_ptrdiff_t
  1882. AXPF_CALL axspf
  1883. (
  1884. char *buf,
  1885. axpf_size_t nbuf,
  1886. const char *fmt,
  1887. ...
  1888. )
  1889. #if AXPF_IMPLEMENT
  1890. {
  1891. axpf_ptrdiff_t r;
  1892. va_list args;
  1893.  
  1894. va_start( args, fmt );
  1895. r = axspfev( buf, nbuf, fmt, ( const char * )0, args );
  1896. va_end( args );
  1897.  
  1898. return r;
  1899. }
  1900. #else
  1901. ;
  1902. #endif
  1903.  
  1904. AXPF_FUNC char *
  1905. AXPF_CALL axdupfev
  1906. (
  1907. const char *fmt,
  1908. const char *fmte,
  1909. va_list args
  1910. )
  1911. #if AXPF_IMPLEMENT
  1912. {
  1913. struct axpf__write_mem_data_ m;
  1914. struct axpf__state_ s;
  1915. axpf_ptrdiff_t r;
  1916.  
  1917. m.p = ( char * )0;
  1918. m.i = 0;
  1919. m.n = 0;
  1920.  
  1921. s.pfn_write = &axpf__write_memdup_f;
  1922. s.write_data = ( void * )&m;
  1923.  
  1924. r = axpf__main( &s, fmt, fmte, args );
  1925. if( r < 0 ) {
  1926. free( ( void * )m.p );
  1927. return ( char * )0;
  1928. }
  1929.  
  1930. return m.p;
  1931. }
  1932. #else
  1933. ;
  1934. #endif
  1935. AXPF_FUNC char *
  1936. AXPF_CALL axdupfe
  1937. (
  1938. const char *fmt,
  1939. const char *fmte,
  1940. ...
  1941. )
  1942. #if AXPF_IMPLEMENT
  1943. {
  1944. va_list args;
  1945. char *p;
  1946.  
  1947. va_start( args, fmte );
  1948. p = axdupfev( fmt, fmte, args );
  1949. va_end( args );
  1950.  
  1951. return p;
  1952. }
  1953. #else
  1954. ;
  1955. #endif
  1956. AXPF_FUNC char *
  1957. AXPF_CALL axdupfv
  1958. (
  1959. const char *fmt,
  1960. va_list args
  1961. )
  1962. #if AXPF_IMPLEMENT
  1963. {
  1964. return axdupfev( fmt, ( const char * )0, args );
  1965. }
  1966. #else
  1967. ;
  1968. #endif
  1969. AXPF_FUNC char *
  1970. AXPF_CALL axdupf
  1971. (
  1972. const char *fmt,
  1973. ...
  1974. )
  1975. #if AXPF_IMPLEMENT
  1976. {
  1977. va_list args;
  1978. char *p;
  1979.  
  1980. va_start( args, fmt );
  1981. p = axdupfev( fmt, ( const char * )0, args );
  1982. va_end( args );
  1983.  
  1984. return p;
  1985. }
  1986. #else
  1987. ;
  1988. #endif
  1989.  
  1990. AXPF_FUNC const char *
  1991. AXPF_CALL axfev
  1992. (
  1993. const char *fmt,
  1994. const char *fmte,
  1995. va_list args
  1996. )
  1997. #if AXPF_IMPLEMENT
  1998. {
  1999. static axpf_size_t bufi = 0;
  2000. static char buf[ 0x10000 ];
  2001.  
  2002. struct axpf__write_mem_data_ m;
  2003. struct axpf__state_ s;
  2004. axpf_ptrdiff_t r;
  2005.  
  2006. m.p = &buf[ bufi ];
  2007. m.i = 0;
  2008. m.n = sizeof( buf ) - bufi;
  2009.  
  2010. s.pfn_write = &axpf__write_mem_f;
  2011. s.write_data = ( void * )&m;
  2012.  
  2013. r = axpf__main( &s, fmt, fmte, args );
  2014. if( r < 0 ) {
  2015. return ( char * )0;
  2016. }
  2017.  
  2018. bufi += ( axpf_size_t )r;
  2019. if( bufi + 0x200 >= sizeof( buf ) ) {
  2020. bufi = 0;
  2021. }
  2022.  
  2023. return m.p;
  2024. }
  2025. #else
  2026. ;
  2027. #endif
  2028. AXPF_FUNC const char *
  2029. AXPF_CALL axfe
  2030. (
  2031. const char *fmt,
  2032. const char *fmte,
  2033. ...
  2034. )
  2035. #if AXPF_IMPLEMENT
  2036. {
  2037. va_list args;
  2038. const char *p;
  2039.  
  2040. va_start( args, fmte );
  2041. p = axfev( fmt, fmte, args );
  2042. va_end( args );
  2043.  
  2044. return p;
  2045. }
  2046. #else
  2047. ;
  2048. #endif
  2049. AXPF_FUNC const char *
  2050. AXPF_CALL axfv
  2051. (
  2052. const char *fmt,
  2053. va_list args
  2054. )
  2055. #if AXPF_IMPLEMENT
  2056. {
  2057. return axfev( fmt, ( const char * )0, args );
  2058. }
  2059. #else
  2060. ;
  2061. #endif
  2062. AXPF_FUNC const char *
  2063. AXPF_CALL axf
  2064. (
  2065. const char *fmt,
  2066. ...
  2067. )
  2068. #if AXPF_IMPLEMENT
  2069. {
  2070. const char *p;
  2071. va_list args;
  2072.  
  2073. va_start( args, fmt );
  2074. p = axfev( fmt, ( const char * )0, args );
  2075. va_end( args );
  2076.  
  2077. return p;
  2078. }
  2079. #else
  2080. ;
  2081. #endif
  2082.  
  2083. #if AXPF_CXX_OVERLOADS_ENABLED
  2084. template< axpf_size_t tMaxBuf >
  2085. inline axpf_ptrdiff_t axspfev( char( &buf )[ tMaxBuf ], const char *fmt,
  2086. const char *fmte, va_list args )
  2087. {
  2088. return axspfev( buf, tMaxBuf, fmt, fmte, args );
  2089. }
  2090. template< axpf_size_t tMaxBuf >
  2091. inline axpf_ptrdiff_t axspfv( char( &buf )[ tMaxBuf ], const char *fmt,
  2092. va_list args )
  2093. {
  2094. return axspfev( buf, tMaxBuf, fmt, ( const char * )0, args );
  2095. }
  2096. template< axpf_size_t tMaxBuf >
  2097. inline axpf_ptrdiff_t axspfe( char( &buf )[ tMaxBuf ], const char *fmt,
  2098. const char *fmte, ... )
  2099. {
  2100. axpf_ptrdiff_t r;
  2101. va_list args;
  2102.  
  2103. va_start( args, fmte );
  2104. r = axspfev( buf, tMaxBuf, fmt, fmte, args );
  2105. va_end( args );
  2106.  
  2107. return r;
  2108. }
  2109. template< axpf_size_t tMaxBuf >
  2110. inline axpf_ptrdiff_t axspf( char( &buf )[ tMaxBuf ], const char *fmt, ... )
  2111. {
  2112. axpf_ptrdiff_t r;
  2113. va_list args;
  2114.  
  2115. va_start( args, fmt );
  2116. r = axspfev( buf, tMaxBuf, fmt, ( const char * )0, args );
  2117. va_end( args );
  2118.  
  2119. return r;
  2120. }
  2121. #endif /*AXPF_CXX_OVERLOADS_ENABLED*/
  2122.  
  2123. #endif
  2124.  
Compilation error #stdin compilation error #stdout 0s 0KB
stdin
Standard input is empty
compilation info
/usr/lib/gcc/i586-linux-gnu/4.9/../../../i386-linux-gnu/crt1.o: In function `_start':
(.text+0x18): undefined reference to `main'
collect2: error: ld returned 1 exit status
stdout
Standard output is empty