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.

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