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.

342 lines
9.3 KiB

  1. //+----------------------------------------------------------------------------
  2. //
  3. // Copyright (c) 1996 Microsoft Corporation
  4. //
  5. // File: ctprintf.cxx
  6. //
  7. // Synopsis: ct versions of the printf family
  8. //
  9. // History: 30-May-96 MikeW Created
  10. //
  11. // Notes: The ct version of the printf family adds two new format
  12. // specifiers: %os and %oc. These specifiers mean ole-string
  13. // and ole-character respectively.
  14. //
  15. // In the ANSI-version of this family these specifiers mean
  16. // "an octal digit followed by the letter s (or c)". Code that
  17. // uses octal should be careful when using these functions.
  18. //
  19. //-----------------------------------------------------------------------------
  20. #include <ctolerpc.h>
  21. #pragma hdrstop
  22. //
  23. // MAX_FORMAT_SPECIFIER_BUFFER is the maximum length of a (munged) format
  24. // specifier
  25. //
  26. const MAX_FORMAT_SPECIFIER_BUFFER = 1024;
  27. //
  28. // MAKE_UNICODE unconditionally makes a string or char constant Unicode
  29. //
  30. #define _MAKE_UNICODE(x) L##x
  31. #define MAKE_UNICODE(x) _MAKE_UNICODE(x)
  32. #ifndef UNICODE_ONLY
  33. //+----------------------------------------------------------------------------
  34. //
  35. // Function: MungeFormatSpecifiersA
  36. //
  37. // Synopsis: Convert the 'os' and 'oc' printf-format specifier to the right
  38. // thing to handle Ole strings and Ole chars.
  39. //
  40. // Parameters: [format] -- The format string to convert
  41. // [munged_format] -- Where to put the munged format
  42. //
  43. // Returns: void
  44. //
  45. // History: 30-May-96 MikeW Created
  46. //
  47. // Notes: In the regular printf family "%os" and "%oc" evaluate to
  48. // an octal number followed by a 's' or a 'c'. To get these
  49. // cases to work always put some character (such as a space)
  50. // after a %o specifier.
  51. //
  52. //-----------------------------------------------------------------------------
  53. void MungeFormatSpecifiersA(const char *format, char *munged_format)
  54. {
  55. const char *start_of_uncopied_data;
  56. *munged_format = '\0';
  57. start_of_uncopied_data = format;
  58. format = strchr(format, '%');
  59. while (NULL != format)
  60. {
  61. //
  62. // Find the type of the format specifier.
  63. // Watch out for "%%" and "%<null terminator>".
  64. //
  65. do
  66. {
  67. ++format;
  68. }
  69. while ('%' != *format && '\0' != *format && !isalpha(*format));
  70. strncat(
  71. munged_format,
  72. start_of_uncopied_data,
  73. format - start_of_uncopied_data);
  74. start_of_uncopied_data = format;
  75. //
  76. // Munge it to the right thing for %os or %oc
  77. //
  78. if ('o' == *format && 's' == *(format + 1))
  79. {
  80. strcat(munged_format, OLE_STRING_SPECIFIER);
  81. format += 1;
  82. start_of_uncopied_data += 2;
  83. }
  84. else if ('o' == *format && 'c' == *(format + 1))
  85. {
  86. strcat(munged_format, OLE_CHAR_SPECIFIER);
  87. format += 1;
  88. start_of_uncopied_data += 2;
  89. }
  90. format = strchr(format + 1, '%');
  91. }
  92. strcat(munged_format, start_of_uncopied_data);
  93. }
  94. //+----------------------------------------------------------------------------
  95. //
  96. // Functions: ctprintfA, ctsprintfA, ctsnprintfA, ctfprintfA
  97. // ctvprintfA, ctvsprintfA, ctvsnprintfA, ctvfprintfA
  98. //
  99. // Synopsis: ct versions of standard ANSI printf family
  100. //
  101. // History: 30-May-96 MikeW Created
  102. //
  103. //-----------------------------------------------------------------------------
  104. int ctprintfA(const char *format, ...)
  105. {
  106. va_list varargs;
  107. va_start(varargs, format);
  108. return ctvprintfA(format, varargs);
  109. }
  110. int ctsprintfA(char *buffer, const char *format, ...)
  111. {
  112. va_list varargs;
  113. va_start(varargs, format);
  114. return ctvsprintfA(buffer, format, varargs);
  115. }
  116. int ctsnprintfA(char *buffer, size_t count, const char *format, ...)
  117. {
  118. va_list varargs;
  119. va_start(varargs, format);
  120. return ctvsnprintfA(buffer, count, format, varargs);
  121. }
  122. int ctfprintfA(FILE *stream, const char *format, ...)
  123. {
  124. va_list varargs;
  125. va_start(varargs, format);
  126. return ctvfprintfA(stream, format, varargs);
  127. }
  128. int ctvprintfA(const char *format, va_list varargs)
  129. {
  130. char munged_format[MAX_FORMAT_SPECIFIER_BUFFER];
  131. MungeFormatSpecifiersA(format, munged_format);
  132. return vprintf(munged_format, varargs);
  133. }
  134. int ctvsprintfA(char *buffer, const char *format, va_list varargs)
  135. {
  136. char munged_format[MAX_FORMAT_SPECIFIER_BUFFER];
  137. MungeFormatSpecifiersA(format, munged_format);
  138. return vsprintf(buffer, munged_format, varargs);
  139. }
  140. int ctvsnprintfA(
  141. char *buffer,
  142. size_t count,
  143. const char *format,
  144. va_list varargs)
  145. {
  146. char munged_format[MAX_FORMAT_SPECIFIER_BUFFER];
  147. MungeFormatSpecifiersA(format, munged_format);
  148. return _vsnprintf(buffer, count, munged_format, varargs);
  149. }
  150. int ctvfprintfA(FILE *stream, const char *format, va_list varargs)
  151. {
  152. char munged_format[MAX_FORMAT_SPECIFIER_BUFFER];
  153. MungeFormatSpecifiersA(format, munged_format);
  154. return vfprintf(stream, munged_format, varargs);
  155. }
  156. #endif // !UNICODE_ONLY
  157. #ifndef ANSI_ONLY
  158. //+----------------------------------------------------------------------------
  159. //
  160. // Function: MungeFormatSpecifiersW
  161. //
  162. // Synopsis: Convert the 'os' and 'oc' printf-format specifier to the right
  163. // thing to handle Ole strings and Ole chars.
  164. //
  165. // Parameters: [format] -- The format string to convert
  166. // [munged_format] -- Where to put the munged format
  167. //
  168. // Returns: void
  169. //
  170. // History: 30-May-96 MikeW Created
  171. //
  172. // Notes: In the regular printf family "%os" and "%oc" evaluate to
  173. // an octal number followed by a 's' or a 'c'. To get these
  174. // cases to work always put some character (such as a space)
  175. // after a %o specifier.
  176. //
  177. //-----------------------------------------------------------------------------
  178. void MungeFormatSpecifiersW(const wchar_t *format, wchar_t *munged_format)
  179. {
  180. const wchar_t *start_of_uncopied_data;
  181. *munged_format = L'\0';
  182. start_of_uncopied_data = format;
  183. format = wcschr(format, L'%');
  184. while (NULL != format)
  185. {
  186. //
  187. // Find the type of the format specifier.
  188. // Watch out for "%%" and "%<null terminator>".
  189. //
  190. do
  191. {
  192. ++format;
  193. }
  194. while (L'%' != *format && L'\0' != *format && !iswalpha(*format));
  195. wcsncat(
  196. munged_format,
  197. start_of_uncopied_data,
  198. format - start_of_uncopied_data);
  199. start_of_uncopied_data = format;
  200. //
  201. // Munge it to the right thing for %os or %oc
  202. //
  203. if (L'o' == *format && L's' == *(format + 1))
  204. {
  205. wcscat(munged_format, MAKE_UNICODE(OLE_STRING_SPECIFIER));
  206. format += 1;
  207. start_of_uncopied_data += 2;
  208. }
  209. else if (L'o' == *format && L'c' == *(format + 1))
  210. {
  211. wcscat(munged_format, MAKE_UNICODE(OLE_CHAR_SPECIFIER));
  212. format += 1;
  213. start_of_uncopied_data += 2;
  214. }
  215. format = wcschr(format + 1, '%');
  216. }
  217. wcscat(munged_format, start_of_uncopied_data);
  218. }
  219. //+----------------------------------------------------------------------------
  220. //
  221. // Functions: ctprintfW, ctsprintfW, ctsnprintfW, ctfprintfW
  222. // ctvprintfW, ctvsprintfW, ctvsnprintfW, ctvfprintfW
  223. //
  224. // Synopsis: ct versions of standard Unicode printf family
  225. //
  226. // History: 30-May-96 MikeW Created
  227. //
  228. //-----------------------------------------------------------------------------
  229. int ctprintfW(const wchar_t *format, ...)
  230. {
  231. va_list varargs;
  232. va_start(varargs, format);
  233. return ctvprintfW(format, varargs);
  234. }
  235. int ctsprintfW(wchar_t *buffer, const wchar_t *format, ...)
  236. {
  237. va_list varargs;
  238. va_start(varargs, format);
  239. return ctvsprintfW(buffer, format, varargs);
  240. }
  241. int ctsnprintfW(wchar_t *buffer, size_t count, const wchar_t *format, ...)
  242. {
  243. va_list varargs;
  244. va_start(varargs, format);
  245. return ctvsnprintfW(buffer, count, format, varargs);
  246. }
  247. int ctfprintfW(FILE *stream, const wchar_t *format, ...)
  248. {
  249. va_list varargs;
  250. va_start(varargs, format);
  251. return ctvfprintfW(stream, format, varargs);
  252. }
  253. int ctvprintfW(const wchar_t *format, va_list varargs)
  254. {
  255. wchar_t munged_format[MAX_FORMAT_SPECIFIER_BUFFER];
  256. MungeFormatSpecifiersW(format, munged_format);
  257. return vwprintf(munged_format, varargs);
  258. }
  259. int ctvsprintfW(wchar_t *buffer, const wchar_t *format, va_list varargs)
  260. {
  261. wchar_t munged_format[MAX_FORMAT_SPECIFIER_BUFFER];
  262. MungeFormatSpecifiersW(format, munged_format);
  263. return vswprintf(buffer, munged_format, varargs);
  264. }
  265. int ctvsnprintfW(
  266. wchar_t *buffer,
  267. size_t count,
  268. const wchar_t *format,
  269. va_list varargs)
  270. {
  271. wchar_t munged_format[MAX_FORMAT_SPECIFIER_BUFFER];
  272. MungeFormatSpecifiersW(format, munged_format);
  273. return _vsnwprintf(buffer, count, munged_format, varargs);
  274. }
  275. int ctvfprintfW(FILE *stream, const wchar_t *format, va_list varargs)
  276. {
  277. wchar_t munged_format[MAX_FORMAT_SPECIFIER_BUFFER];
  278. MungeFormatSpecifiersW(format, munged_format);
  279. return vfwprintf(stream, munged_format, varargs);
  280. }
  281. #endif // !ANSI_ONLY