/santa/OpenCV/apps/Hawk/CVEiCL/EiC/module/stdClib/src/printf.c

https://github.com/siegleal/iSanta · C · 348 lines · 261 code · 38 blank · 49 comment · 104 complexity · 8c09b9d7aaba90fef1f90c4d78c5585d MD5 · raw file

  1. /* vprintf.c
  2. *
  3. * (C) Copyright Apr 15 1995, Edmond J. Breen.
  4. * ALL RIGHTS RESERVED.
  5. * This code may be copied for personal, non-profit use only.
  6. *
  7. */
  8. #include <stdio.h>
  9. #include <ctype.h>
  10. #include <string.h>
  11. #include <stdlib.h>
  12. #include <math.h>
  13. #include <stdarg.h>
  14. #include "stdliblocal.h"
  15. static int charin_(char **buf)
  16. {
  17. int ch;
  18. ch = **buf;
  19. *buf += 1;
  20. if(!ch)
  21. ch = EOF;
  22. return ch;
  23. }
  24. static int charback_(int ch, char **buf)
  25. {
  26. *buf -= 1;
  27. return ch;
  28. }
  29. static int charout_(int c, char **buf)
  30. {
  31. char *s;
  32. s = *buf;
  33. *s++ = c;
  34. *s = 0;
  35. *buf = s;
  36. return 1;
  37. }
  38. int _Uprintf(int (*output)(), void *arg, const char *fmt, va_list ap)
  39. {
  40. /*_UPRINTF
  41. * Orginally developed from James Hendrix's Small C tools.
  42. *
  43. * (c) Edmond J.Breen (March, 1995).
  44. * ALL RIGHTS RESERVED.
  45. *
  46. * Purpose: To perform formatted printing to a function.
  47. * It performs a superset of printf type
  48. * operations.
  49. *
  50. * _UPRINTF RECOGNISES:
  51. * FLAGS:
  52. * -, +, 0 and #.
  53. * plus ! and | (see below).
  54. *
  55. * CONVERSION CHARACTERS:
  56. * d, i, o, x, X, u, c, s,
  57. * f, e, E, g, G, p, n, %
  58. * plus b (see below).
  59. *
  60. * LENGTH MODIFIES:
  61. * l, L, and h.
  62. *
  63. * The WIDTH and or the PRECISION can be set indirectly
  64. * via * as specified by K&R.
  65. *
  66. * _UPRINTF EXTRA FEATURES.
  67. * NEW FLAGS:
  68. * FLAG WHAT IT SPECIFIES
  69. * | Centre justification.
  70. * ! Used with floating point numbers.
  71. * It specifies, if possible, that the
  72. * number will be centred with respect
  73. * to the decimal point.
  74. * If used with non floating point
  75. * numbers or the floating point number
  76. * does not contain a decimal point,
  77. * the ! flag is equivalent to |.
  78. * NEW CONVERSION CHARACTER:
  79. * CHARACTER WHAT IT SPECIFIES
  80. * b int, unsigned binary notation.
  81. */
  82. int v;
  83. static char str[128];
  84. char *sptr, lseen,Lseen;
  85. int left, right, centre, maxchr,
  86. pad, len, width, sign, dprec,
  87. mod, prec,dot,gotfloat;
  88. v = 0;
  89. while(*fmt) {
  90. if(*fmt != '%') {
  91. (*output)(*fmt,arg);
  92. ++fmt;++v;
  93. continue;
  94. } else if(*++fmt =='%') {
  95. (*output)(*fmt++,arg);
  96. ++v;
  97. continue;
  98. }
  99. pad = ' ';
  100. centre = len = right = left = 0;
  101. gotfloat = dot = sign = mod = 0;
  102. Lseen = lseen = dprec = 0;
  103. while(*fmt) { /* collect in any order */
  104. if(*fmt == '-') left = 1;
  105. else if(*fmt == '0') pad = '0';
  106. else if(*fmt == '+') sign = 1;
  107. else if(*fmt == '#') mod = 1;
  108. else if(*fmt == '|') centre = 1;
  109. else if(*fmt == '!') centre = 1, dot = 1;
  110. else
  111. break;
  112. ++fmt;
  113. }
  114. if(isdigit(*fmt)) {
  115. width = atoi(fmt);
  116. while(isdigit(*fmt)) ++fmt;
  117. } else if(*fmt == '*') {
  118. width = va_arg(ap,int);
  119. fmt++;
  120. } else
  121. width = -1;
  122. if(*fmt == '.') {
  123. if(*++fmt == '*') {
  124. maxchr = va_arg(ap,int);
  125. fmt++;
  126. } else {
  127. maxchr = atoi(fmt);
  128. while(isdigit(*fmt)) ++fmt;
  129. }
  130. } else
  131. maxchr = -1;
  132. switch(*fmt) { /* check for length modifier*/
  133. case 'h': fmt++;break;
  134. case 'l': lseen = 1; fmt++;break;
  135. case 'L': Lseen = 1; fmt++;break;
  136. }
  137. sptr = str;
  138. switch(*fmt++) {
  139. case 'c': sptr[0] = (char)va_arg(ap,int);
  140. sptr[1] = 0;
  141. break;
  142. case 'b':
  143. if(lseen) ultoa(va_arg(ap,long),sptr,2);
  144. else utoa(va_arg(ap,int),sptr,2);
  145. break;
  146. case 'i':
  147. case 'd': if(lseen) ltoa(va_arg(ap,long),sptr,10);
  148. else itoa(va_arg(ap,int),sptr,10);
  149. dprec=1;
  150. break;
  151. case 'u': if(lseen) ultoa(va_arg(ap,unsigned long),sptr,10);
  152. else utoa(va_arg(ap,unsigned),sptr,10);
  153. dprec=1;
  154. break;
  155. case 'o': if(mod) *sptr = '0';
  156. if(lseen)ltoa(va_arg(ap,long),&sptr[mod],8);
  157. else itoa(va_arg(ap,int),&sptr[mod],8);
  158. dprec = 1;
  159. break;
  160. case 's': sptr = va_arg(ap,char*); break;
  161. case 'x': case 'X':
  162. if(mod) {
  163. *sptr = '0', sptr[1] = *(fmt-1);
  164. mod++;
  165. }
  166. if(lseen)ultoa(va_arg(ap,long),&sptr[mod],16);
  167. else utoa(va_arg(ap,int),&sptr[mod],16);
  168. if(*(fmt-1) == 'X') {
  169. while(*sptr) {
  170. *sptr = toupper(*sptr);
  171. sptr++;
  172. }
  173. sptr = str;
  174. }
  175. dprec = 1;
  176. break;
  177. case 'e': case 'E': case 'g': case 'G':
  178. case 'f': {
  179. int trunc = 0;
  180. char type = *(fmt-1),c;
  181. double d;
  182. gotfloat = 1;
  183. if(maxchr < 0) prec = 6;
  184. else prec = maxchr,maxchr = -1;
  185. if(Lseen)
  186. d = va_arg(ap,double);
  187. else
  188. d = va_arg(ap,double);
  189. if(type == 'g' || type == 'G') {
  190. double ex;
  191. if(d !=0)
  192. ex = log10(d < 0? -d:d);
  193. else
  194. ex = 1;
  195. if(ex < -4 || ex >= prec)
  196. c = type - 2;
  197. else
  198. c = 'f';
  199. trunc = 1;
  200. } else
  201. c = type;
  202. if(mod) {
  203. if(!prec) prec = 1;
  204. trunc = 0;
  205. }
  206. sptr = fftoa(d,str, prec, c,trunc);
  207. }
  208. break;
  209. case 'n': *va_arg(ap,int*) = v; continue;
  210. case 'p':
  211. ultoa((long)va_arg(ap,long*),sptr,16);
  212. break;
  213. default: (*output)(*(fmt-1),arg);
  214. while(*fmt) {
  215. (*output)(*fmt++,arg);
  216. ++v;
  217. }
  218. return v;
  219. }
  220. if(!len && sptr) len = strlen(sptr);
  221. if(sign) len += (*sptr == '-' ? 0: 1);
  222. if(dprec && maxchr >=0) {
  223. dprec = maxchr;
  224. pad = '0';
  225. }else
  226. dprec = 0;
  227. if(maxchr > -1 && maxchr<len)
  228. len = maxchr;
  229. if(width>len)
  230. width = width -len;
  231. else if(dprec > len)
  232. width = dprec - len;
  233. else
  234. width = 0;
  235. if(centre) {
  236. left = (right = width >> 1) + (width%2);
  237. if(dot && gotfloat) {
  238. int d = 0,c;
  239. while(sptr[d] && sptr[d] != '.')
  240. d++;
  241. if(sptr[d] == '.') {
  242. c = (width + len)/2;
  243. if(sign && sptr[0] != '-')
  244. d++;
  245. if(c-d > 0) right = c-d;
  246. else right = 0;
  247. if(width - right > 0)
  248. left = width - right;
  249. else
  250. left = 0;
  251. }
  252. }
  253. } else
  254. if(!left)
  255. right = width;
  256. else
  257. left = width;
  258. if(sign && !left && pad == '0') {
  259. if(*sptr != '-') {
  260. (*output)('+',arg);
  261. ++v;len--;
  262. }
  263. sign = 0;
  264. }
  265. while(right--) {(*output)(pad,arg); ++v;}
  266. if(sign && *sptr != '-') {(*output)('+',arg);len--;++v;}
  267. while(len--) {(*output)(*sptr++,arg);++v;}
  268. while(left--) {(*output)(pad,arg);++v;}
  269. }
  270. return v;
  271. }
  272. int printf(const char *fmt,...)
  273. {
  274. int rtn;
  275. va_list ap;
  276. ap = va_start(ap,fmt);
  277. rtn = _Uprintf(fputc,stdout,fmt,ap);
  278. va_end(ap);
  279. return rtn;
  280. }
  281. int fprintf(FILE *fp, const char *fmt, ...)
  282. {
  283. int rtn;
  284. va_list ap;
  285. ap = va_start(ap,fmt);
  286. rtn = _Uprintf(fputc,fp,fmt,ap);
  287. va_end(ap);
  288. return rtn;
  289. }
  290. int sprintf(char *str, const char *fmt, ...)
  291. {
  292. int rtn;
  293. va_list ap;
  294. ap = va_start(ap,fmt);
  295. rtn = _Uprintf(charout_,&str,fmt,ap);
  296. va_end(ap);
  297. return rtn;
  298. }
  299. int vfprintf(FILE *fp, const char *fmt,va_list ap)
  300. {
  301. int rtn;
  302. rtn = _Uprintf(fputc,fp,fmt,ap);
  303. return rtn;
  304. }
  305. int vsprintf(char *str, const char *fmt,va_list ap)
  306. {
  307. int rtn;
  308. rtn = _Uprintf(charout_,&str,fmt,ap);
  309. return rtn;
  310. }