Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

268 lines
7.1 KiB

  1. /**
  2. *printf.h - print formatted
  3. *
  4. * Copyright (c) 1985-1991, Microsoft Corporation. All rights reserved.
  5. *
  6. *Purpose:
  7. * defines w4*printf() - print formatted data
  8. * defines w4v*printf() - print formatted output, get data from an
  9. * argument ptr instead of explicit args.
  10. *
  11. *Revision History:
  12. * 09-02-83 RN original sprintf
  13. * 06-17-85 TC rewrote to use new varargs macros, and to be vsprintf
  14. * 04-13-87 JCR added const to declaration
  15. * 11-07-87 JCR Multi-thread support
  16. * 12-11-87 JCR Added "_LOAD_DS" to declaration
  17. * 05-27-88 PHG Merged DLL and normal versions
  18. * 06-13-88 JCR Fake _iob entry is now static so that other routines
  19. * can assume _iob entries are in DGROUP.
  20. * 08-25-88 GJF Define MAXSTR to be INT_MAX (from LIMITS.H).
  21. * 06-06-89 JCR 386 mthread support
  22. * 08-18-89 GJF Clean up, now specific to OS/2 2.0 (i.e., 386 flat
  23. * model). Also fixed copyright and indents.
  24. * 02-16-90 GJF Fixed copyright
  25. * 14-Mar-94 DonCl stolen from common project for use with Forms so
  26. * we can build on Daytona without linking to commnot.
  27. *
  28. *******************************************************************************/
  29. #include <wchar.h>
  30. #include <stdarg.h>
  31. #include <limits.h>
  32. #include <sys\types.h>
  33. #define _W4DPRINTF_
  34. #include <w4io.h>
  35. #define pwcbuf buf.wc._pwcbuf
  36. #define pwcstart buf.wc._pwcstart
  37. #define pchbuf buf.ch._pchbuf
  38. #define pchstart buf.ch._pchstart
  39. #define REG1 register
  40. #define REG2 register
  41. /* prototypes */
  42. #ifdef __cplusplus
  43. extern "C" {
  44. #endif
  45. int _cdecl w4iooutput(struct w4io *stream, const char *format, va_list argptr);
  46. #ifdef __cplusplus
  47. }
  48. #endif
  49. #if defined(_W4PRINTF_)
  50. static long fh;
  51. // extern long GetStdHandle(long);
  52. // extern void WriteFile(long fh, char *s, long cch, long * pcchret, long);
  53. # define _PRINTF_
  54. #elif defined(_W4DPRINTF_)
  55. # define _pwritechar _dwritechar
  56. # define _pflushbuf _dflushbuf
  57. # define w4printf w4dprintf
  58. # define w4vprintf w4vdprintf
  59. # define _PRINTF_
  60. #elif defined(_W4SPRINTF_)
  61. # define _pwritechar _swritechar
  62. # define w4printf w4sprintf
  63. # define w4vprintf w4vsprintf
  64. #elif defined(_W4WCSPRINTF_)
  65. # define _TCHAR_ wchar_t
  66. # define _PBUF_ pwcbuf
  67. # define _PSTART_ pwcstart
  68. # define w4printf w4wcsprintf
  69. # define w4vprintf w4vwcsprintf
  70. # define _pwritechar _wwritechar
  71. #else
  72. # error configuration problem
  73. #endif
  74. #ifndef _TCHAR_
  75. # define _TCHAR_ char
  76. # define _PBUF_ pchbuf
  77. # define _PSTART_ pchstart
  78. #endif
  79. #ifdef _PRINTF_
  80. # ifdef WIN32
  81. # undef OutputDebugString
  82. # define OutputDebugString OutputDebugStringA
  83. # else
  84. extern void _pascal OutputDebugString(char *);
  85. # endif
  86. int _cdecl _pflushbuf(struct w4io *f);
  87. # define SPR(a)
  88. # define MAXSTR 128
  89. #else
  90. # define SPR(a) a,
  91. # define MAXSTR INT_MAX
  92. #endif
  93. void _cdecl _pwritechar(int ch, int num, struct w4io *f, int *pcchwritten);
  94. int _cdecl w4vprintf(SPR(_TCHAR_ *string) const char *format, va_list arglist);
  95. /***
  96. *int w4printf(format, ...) - print formatted data
  97. *
  98. *Purpose:
  99. * Prints formatted data using the format string to
  100. * format data and getting as many arguments as called for
  101. * Sets up a w4io so file i/o operations can be used.
  102. * w4iooutput does the real work here
  103. *
  104. *Entry:
  105. * char *format - format string to control data format/number
  106. * of arguments followed by list of arguments, number and type
  107. * controlled by format string
  108. *
  109. *Exit:
  110. * returns number of characters written
  111. *
  112. *Exceptions:
  113. *
  114. *******************************************************************************/
  115. int _cdecl
  116. w4printf(SPR(_TCHAR_ *string) const char *format, ...)
  117. /*
  118. * 'PRINT', 'F'ormatted
  119. */
  120. {
  121. va_list arglist;
  122. va_start(arglist, format);
  123. return(w4vprintf(SPR(string) format, arglist));
  124. }
  125. /***
  126. *int w4vprintf(format, arglist) - print formatted data from arg ptr
  127. *
  128. *Purpose:
  129. * Prints formatted data, but gets data from an argument pointer.
  130. * Sets up a w4io so file i/o operations can be used, make string look
  131. * like a huge buffer to it, but _flsbuf will refuse to flush it if it
  132. * fills up. Appends '\0' to make it a true string.
  133. *
  134. * Multi-thread: (1) Since there is no stream, this routine must never try
  135. * to get the stream lock (i.e., there is no stream lock either). (2)
  136. * Also, since there is only one staticly allocated 'fake' iob, we must
  137. * lock/unlock to prevent collisions.
  138. *
  139. *Entry:
  140. * char *format - format string, describes format of data
  141. * va_list arglist - varargs argument pointer
  142. *
  143. *Exit:
  144. * returns number of characters written
  145. *
  146. *Exceptions:
  147. *
  148. *******************************************************************************/
  149. int _cdecl
  150. w4vprintf(SPR(_TCHAR_ *string) const char *format, va_list arglist)
  151. /*
  152. * 'V'ariable argument 'PRINT', 'F'ormatted
  153. */
  154. {
  155. struct w4io outfile;
  156. register int retval;
  157. #ifdef _PRINTF_
  158. char string[MAXSTR + 1]; // leave room for null termination
  159. #else
  160. int dummy;
  161. #endif
  162. #ifdef _W4PRINTF_
  163. long ldummy;
  164. if (fh == 0 || fh == -1)
  165. {
  166. ldummy = -11; // C7 bug workaround
  167. if ((fh = (long)GetStdHandle(ldummy)) == 0 || fh == -1)
  168. {
  169. OutputDebugString("GetStdHandle in " __FILE__ " failed\n");
  170. return(-1);
  171. }
  172. }
  173. #endif
  174. outfile._PBUF_ = outfile._PSTART_ = string;
  175. outfile.cchleft = MAXSTR;
  176. outfile.writechar = _pwritechar;
  177. retval = w4iooutput(&outfile, format, arglist);
  178. #ifdef _PRINTF_
  179. if (_pflushbuf(&outfile) == -1) {
  180. return(-1);
  181. }
  182. #else
  183. _pwritechar('\0', 1, &outfile, &dummy);
  184. #endif
  185. return(retval);
  186. }
  187. void _cdecl _pwritechar(int ch, int num, struct w4io *f, int *pcchwritten)
  188. {
  189. //printf(" char: ch=%c, cnt=%d, cch=%d\n", ch, num, *pcchwritten);
  190. while (num-- > 0) {
  191. #ifdef _PRINTF_
  192. if (f->cchleft < 2 && _pflushbuf(f) == -1) {
  193. *pcchwritten = -1;
  194. return;
  195. }
  196. #endif
  197. #ifdef _W4DPRINTF_
  198. # ifndef FLAT
  199. if (ch == '\n')
  200. {
  201. *f->_PBUF_++ = '\r';
  202. f->cchleft--;
  203. (*pcchwritten)++;
  204. }
  205. # endif
  206. #endif
  207. *f->_PBUF_++ = (char) ch;
  208. f->cchleft--;
  209. (*pcchwritten)++;
  210. }
  211. }
  212. #ifdef _PRINTF_
  213. int _cdecl _pflushbuf(struct w4io *f)
  214. {
  215. int cch;
  216. if ((cch = (int)(f->pchbuf - f->pchstart)))
  217. {
  218. #ifdef _W4DPRINTF_
  219. *f->pchbuf = '\0'; // null terminate
  220. OutputDebugString(f->pchstart);
  221. #else
  222. long cchret;
  223. //*f->pchbuf = '\0'; // null terminate
  224. //printf("%d chars: \"%s\"\n", cch, f->pchstart);
  225. WriteFile((HANDLE)fh, f->pchstart, cch, &cchret, 0);
  226. if (cch != cchret)
  227. {
  228. OutputDebugString("WriteFile in " __FILE__ " failed\n");
  229. return(-1);
  230. }
  231. #endif
  232. f->pchbuf -= cch; // reset pointer
  233. f->cchleft += cch; // reset count
  234. }
  235. return(0);
  236. }
  237. #endif // _PRINTF_