Leaked source code of windows server 2003
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.

246 lines
6.8 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 WIN32
  23. * model). Also fixed copyright and indents.
  24. * 02-16-90 GJF Fixed copyright
  25. *
  26. *******************************************************************************/
  27. #include <windows.h>
  28. #include <wchar.h>
  29. #include <stdarg.h>
  30. #include <limits.h>
  31. #include "w4io.h"
  32. #ifdef _W4DPRINTF_
  33. #include "outfuncs.h"
  34. #endif
  35. #if defined(_W4PRINTF_)
  36. static HANDLE fh;
  37. # define _PRINTF_
  38. #elif defined(_W4DPRINTF_)
  39. # define _pwritechar _dwritechar
  40. # define _pflushbuf _dflushbuf
  41. # define w4printf w4dprintf
  42. # define w4vprintf w4vdprintf
  43. # define _PRINTF_
  44. #elif defined(_W4SPRINTF_)
  45. # define _pwritechar _swritechar
  46. # define w4printf w4sprintf
  47. # define w4vprintf w4vsprintf
  48. #elif defined(_W4WCSPRINTF_)
  49. # define _TCHAR_ wchar_t
  50. # define _PBUF_ pwcbuf
  51. # define _PSTART_ pwcstart
  52. # define w4printf w4wcsprintf
  53. # define w4vprintf w4vwcsprintf
  54. # define _pwritechar _wwritechar
  55. #else
  56. # error configuration problem
  57. #endif
  58. #ifndef _TCHAR_
  59. # define _TCHAR_ char
  60. # define _PBUF_ pchbuf
  61. # define _PSTART_ pchstart
  62. #endif
  63. #ifdef _PRINTF_
  64. # ifdef WIN32
  65. # undef OutputDebugString
  66. # define OutputDebugString OutputDebugStringA
  67. # else
  68. extern void _pascal OutputDebugString(char *);
  69. # endif
  70. int _cdecl _pflushbuf(struct w4io *f);
  71. # define SPR(a)
  72. # define MAXSTR 128
  73. #else
  74. # define SPR(a) a,
  75. # define MAXSTR INT_MAX
  76. #endif
  77. void _cdecl _pwritechar(int ch, int num, struct w4io *f, int *pcchwritten);
  78. int _cdecl w4vprintf(SPR(_TCHAR_ *string) const char *format, va_list arglist);
  79. /***
  80. *int w4printf(format, ...) - print formatted data
  81. *
  82. *Purpose:
  83. * Prints formatted data using the format string to
  84. * format data and getting as many arguments as called for
  85. * Sets up a w4io so file i/o operations can be used.
  86. * w4iooutput does the real work here
  87. *
  88. *Entry:
  89. * char *format - format string to control data format/number
  90. * of arguments followed by list of arguments, number and type
  91. * controlled by format string
  92. *
  93. *Exit:
  94. * returns number of characters written
  95. *
  96. *Exceptions:
  97. *
  98. *******************************************************************************/
  99. int _cdecl
  100. w4printf(SPR(_TCHAR_ *string) const char *format, ...)
  101. /*
  102. * 'PRINT', 'F'ormatted
  103. */
  104. {
  105. va_list arglist;
  106. va_start(arglist, format);
  107. return(w4vprintf(SPR(string) format, arglist));
  108. }
  109. /***
  110. *int w4vprintf(format, arglist) - print formatted data from arg ptr
  111. *
  112. *Purpose:
  113. * Prints formatted data, but gets data from an argument pointer.
  114. * Sets up a w4io so file i/o operations can be used, make string look
  115. * like a huge buffer to it, but _flsbuf will refuse to flush it if it
  116. * fills up. Appends '\0' to make it a true string.
  117. *
  118. * Multi-thread: (1) Since there is no stream, this routine must never try
  119. * to get the stream lock (i.e., there is no stream lock either). (2)
  120. * Also, since there is only one staticly allocated 'fake' iob, we must
  121. * lock/unlock to prevent collisions.
  122. *
  123. *Entry:
  124. * char *format - format string, describes format of data
  125. * va_list arglist - varargs argument pointer
  126. *
  127. *Exit:
  128. * returns number of characters written
  129. *
  130. *Exceptions:
  131. *
  132. *******************************************************************************/
  133. int _cdecl
  134. w4vprintf(SPR(_TCHAR_ *string) const char *format, va_list arglist)
  135. /*
  136. * 'V'ariable argument 'PRINT', 'F'ormatted
  137. */
  138. {
  139. struct w4io outfile;
  140. register int retval;
  141. #ifdef _PRINTF_
  142. char string[MAXSTR + 1]; // leave room for null termination
  143. #else
  144. int dummy = 0;
  145. #endif
  146. #ifdef _W4PRINTF_
  147. long ldummy;
  148. if (fh == 0 || fh == INVALID_HANDLE_VALUE)
  149. {
  150. ldummy = -11; // C7 bug workaround
  151. if ((fh = GetStdHandle(ldummy)) == 0 || fh == INVALID_HANDLE_VALUE)
  152. {
  153. OutputDebugString("GetStdHandle in " __FILE__ " failed\n");
  154. return(-1);
  155. }
  156. }
  157. #endif
  158. outfile._PBUF_ = outfile._PSTART_ = string;
  159. outfile.cchleft = MAXSTR;
  160. outfile.writechar = _pwritechar;
  161. retval = w4iooutput(&outfile, format, arglist);
  162. #ifdef _PRINTF_
  163. if (_pflushbuf(&outfile) == -1) {
  164. return(-1);
  165. }
  166. #else
  167. _pwritechar('\0', 1, &outfile, &dummy);
  168. #endif
  169. return(retval);
  170. }
  171. void _cdecl _pwritechar(int ch, int num, struct w4io *f, int *pcchwritten)
  172. {
  173. //printf(" char: ch=%c, cnt=%d, cch=%d\n", ch, num, *pcchwritten);
  174. while (num-- > 0) {
  175. #ifdef _PRINTF_
  176. if (f->cchleft < 2 && _pflushbuf(f) == -1) {
  177. *pcchwritten = -1;
  178. return;
  179. }
  180. #endif
  181. #ifdef _W4DPRINTF_
  182. # ifndef WIN32
  183. if (ch == '\n')
  184. {
  185. *f->_PBUF_++ = '\r';
  186. f->cchleft--;
  187. (*pcchwritten)++;
  188. }
  189. # endif
  190. #endif
  191. *f->_PBUF_++ = (char) ch;
  192. f->cchleft--;
  193. (*pcchwritten)++;
  194. }
  195. }
  196. #ifdef _PRINTF_
  197. int _cdecl _pflushbuf(struct w4io *f)
  198. {
  199. int cch;
  200. if (cch = (int)(f->pchbuf - f->pchstart))
  201. {
  202. #ifdef _W4DPRINTF_
  203. *f->pchbuf = '\0'; // null terminate
  204. CallOutputFunctions(f->pchstart); // funnel through outfuncs
  205. #else
  206. long cchret;
  207. //*f->pchbuf = '\0'; // null terminate
  208. //printf("%d chars: \"%s\"\n", cch, f->pchstart);
  209. WriteFile((HANDLE)fh, f->pchstart, cch, &cchret, 0);
  210. if (cch != cchret)
  211. {
  212. OutputDebugString("WriteFile in " __FILE__ " failed\n");
  213. return(-1);
  214. }
  215. #endif
  216. f->pchbuf -= cch; // reset pointer
  217. f->cchleft += cch; // reset count
  218. }
  219. return(0);
  220. }
  221. #endif // _PRINTF_
  222.