sfhdr.h 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201
  1. /*************************************************************************
  2. * Copyright (c) 2011 AT&T Intellectual Property
  3. * All rights reserved. This program and the accompanying materials
  4. * are made available under the terms of the Eclipse Public License v1.0
  5. * which accompanies this distribution, and is available at
  6. * https://www.eclipse.org/legal/epl-v10.html
  7. *
  8. * Contributors: Details at https://graphviz.org
  9. *************************************************************************/
  10. #pragma once
  11. #ifdef __cplusplus
  12. extern "C" {
  13. #endif
  14. #include <inttypes.h>
  15. /* Internal definitions for sfio.
  16. ** Written by Kiem-Phong Vo
  17. */
  18. #include <sfio/sfio.h>
  19. #include "config.h"
  20. #include <limits.h>
  21. #include <stdlib.h>
  22. #include <string.h>
  23. #include <stdint.h>
  24. #include <stddef.h>
  25. #include <fcntl.h>
  26. #include <unistd.h>
  27. #include <errno.h>
  28. #include <ctype.h>
  29. /* short-hands */
  30. #ifndef uchar
  31. #define uchar unsigned char
  32. #endif
  33. #ifndef ulong
  34. #define ulong uint64_t
  35. #endif
  36. #ifndef ushort
  37. #define ushort unsigned short
  38. #endif
  39. /* function to get the decimal point for local environment */
  40. #include <locale.h>
  41. #define SFSETLOCALE(decimal,thousand) \
  42. { struct lconv* lv_; \
  43. if((decimal) == 0) \
  44. { (decimal) = '.'; \
  45. if((lv_ = localeconv())) \
  46. { if(lv_->decimal_point && lv_->decimal_point[0]) \
  47. (decimal) = lv_->decimal_point[0]; \
  48. if(lv_->thousands_sep && lv_->thousands_sep[0]) \
  49. (thousand) = lv_->thousands_sep[0]; \
  50. } \
  51. } \
  52. }
  53. /* extensions to sfvprintf/sfvscanf */
  54. #define FP_SET(fp,fn) (fp < 0 ? (fn += 1) : (fn = fp) )
  55. typedef union {
  56. int i, *ip;
  57. long l, *lp;
  58. short h, *hp;
  59. unsigned ui;
  60. ulong ul;
  61. ushort uh;
  62. long long ll, *llp;
  63. unsigned long long lu;
  64. long double ld;
  65. double d;
  66. float f;
  67. char c, *s, **sp;
  68. void *vp;
  69. Sffmt_t *ft;
  70. } Argv_t;
  71. #define LEFTP '('
  72. #define RIGHTP ')'
  73. #define QUOTE '\''
  74. #define FMTSET(ft, frm, fv, sz, flgs, wid,pr,bs, ts,ns) \
  75. ((ft->form = (char*)frm), \
  76. (ft->fmt = fv), (ft->size = sz), \
  77. (ft->flags = (flgs&SFFMT_SET)), \
  78. (ft->width = wid), (ft->precis = pr), (ft->base = bs), \
  79. (ft->t_str = ts), (ft->n_str = ns) )
  80. #define FMTGET(ft, frm, fv, sz, flgs, wid,pr,bs) \
  81. ((frm = ft->form), (fv = ft->fmt), (sz = ft->size), \
  82. (flgs = (flgs&~(SFFMT_SET))|(ft->flags&SFFMT_SET)), \
  83. (wid = ft->width), (pr = ft->precis), (bs = ft->base) )
  84. #define FMTCMP(sz, type, maxtype) \
  85. (sz == sizeof(type) || (sz == 0 && sizeof(type) == sizeof(maxtype)) || \
  86. (sz == 64 && sz == sizeof(type)*CHAR_BIT) )
  87. /* format flags&types, must coexist with those in sfio.h */
  88. #define SFFMT_EFORMAT 01000000000 /* sfcvt converting %e */
  89. #define SFFMT_MINUS 02000000000 /* minus sign */
  90. #define SFFMT_TYPES (SFFMT_SHORT|SFFMT_SSHORT | SFFMT_LONG|SFFMT_LLONG|\
  91. SFFMT_LDOUBLE | SFFMT_IFLAG|SFFMT_JFLAG| \
  92. SFFMT_TFLAG | SFFMT_ZFLAG )
  93. /* type of elements to be converted */
  94. #define SFFMT_INT 001 /* %d,%i */
  95. #define SFFMT_UINT 002 /* %u,o,x etc. */
  96. #define SFFMT_FLOAT 004 /* %f,e,g etc. */
  97. #define SFFMT_BYTE 010 /* %c */
  98. #define SFFMT_POINTER 020 /* %p, %n */
  99. #define SFFMT_CLASS 040 /* %[ */
  100. #define SF_RADIX 64 /* maximum integer conversion base */
  101. /* floating point to ascii conversion */
  102. #define SF_MAXEXP10 6
  103. #define SF_FDIGITS 256 /* max allowed fractional digits */
  104. #define SF_IDIGITS 1024 /* max number of digits in int part */
  105. #define SF_MAXDIGITS (((SF_FDIGITS+SF_IDIGITS)/sizeof(int) + 1)*sizeof(int))
  106. /* tables for numerical translation */
  107. #define _Sfpos10 (_Sftable.sf_pos10)
  108. #define _Sfneg10 (_Sftable.sf_neg10)
  109. #define _Sfdec (_Sftable.sf_dec)
  110. #define _Sfdigits (_Sftable.sf_digits)
  111. #define _Sfcvinit (_Sftable.sf_cvinit)
  112. #define _Sffmtintf (_Sftable.sf_fmtintf)
  113. #define _Sfcv36 (_Sftable.sf_cv36)
  114. #define _Sfcv64 (_Sftable.sf_cv64)
  115. #define _Sftype (_Sftable.sf_type)
  116. typedef struct _sftab_ {
  117. long double sf_pos10[SF_MAXEXP10]; ///< positive powers of 10
  118. long double sf_neg10[SF_MAXEXP10]; ///< negative powers of 10
  119. uchar sf_dec[200]; /* ascii reps of values < 100 */
  120. char *sf_digits; /* digits for general bases */
  121. int sf_cvinit; /* initialization state */
  122. char *(*sf_fmtintf) (const char *, int *);
  123. uchar sf_cv36[UCHAR_MAX + 1]; /* conversion for base [2-36] */
  124. uchar sf_cv64[UCHAR_MAX + 1]; /* conversion for base [37-64] */
  125. uchar sf_type[UCHAR_MAX + 1]; /* conversion formats&types */
  126. } Sftab_t;
  127. /* sfucvt() converts decimal integers to ASCII */
  128. #define SFDIGIT(v,scale,digit) \
  129. { if(v < 5*scale) \
  130. if(v < 2*scale) \
  131. if(v < 1*scale) \
  132. { digit = '0'; } \
  133. else { digit = '1'; v -= 1*scale; } \
  134. else if(v < 3*scale) \
  135. { digit = '2'; v -= 2*scale; } \
  136. else if(v < 4*scale) \
  137. { digit = '3'; v -= 3*scale; } \
  138. else { digit = '4'; v -= 4*scale; } \
  139. else if(v < 7*scale) \
  140. if(v < 6*scale) \
  141. { digit = '5'; v -= 5*scale; } \
  142. else { digit = '6'; v -= 6*scale; } \
  143. else if(v < 8*scale) \
  144. { digit = '7'; v -= 7*scale; } \
  145. else if(v < 9*scale) \
  146. { digit = '8'; v -= 8*scale; } \
  147. else { digit = '9'; v -= 9*scale; } \
  148. }
  149. #define sfucvt(v,s,n,list,type,utype) \
  150. { while((utype)v >= 10000) \
  151. { n = v; v = (type)(((utype)v)/10000); \
  152. n = (type)((utype)n - ((utype)v)*10000); \
  153. s -= 4; SFDIGIT(n,1000,s[0]); SFDIGIT(n,100,s[1]); \
  154. s[2] = *(list = (char*)_Sfdec + (n <<= 1)); s[3] = *(list+1); \
  155. } \
  156. if(v < 100) \
  157. { if(v < 10) \
  158. { s -= 1; s[0] = (char)('0'+v); \
  159. } else \
  160. { s -= 2; s[0] = *(list = (char*)_Sfdec + (v <<= 1)); s[1] = *(list+1); \
  161. } \
  162. } else \
  163. { if(v < 1000) \
  164. { s -= 3; SFDIGIT(v,100,s[0]); \
  165. s[1] = *(list = (char*)_Sfdec + (v <<= 1)); s[2] = *(list+1); \
  166. } else \
  167. { s -= 4; SFDIGIT(v,1000,s[0]); SFDIGIT(v,100,s[1]); \
  168. s[2] = *(list = (char*)_Sfdec + (v <<= 1)); s[3] = *(list+1); \
  169. } \
  170. } \
  171. }
  172. extern Sftab_t _Sftable;
  173. extern char *_sfcvt(void *, int, int *, int *, int);
  174. #ifdef __cplusplus
  175. }
  176. #endif