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.

477 lines
12 KiB

  1. /*++
  2. Copyright (c) 1992-2000 Microsoft Corporation
  3. Purpose:
  4. Formatting functions.
  5. --*/
  6. #include "precomp.hxx"
  7. #pragma hdrstop
  8. #define MAXNESTING (50)
  9. static TCHAR rgchOpenQuote[] = { _T('\"'), _T('\''), _T('('), _T('{'), _T('[') };
  10. static TCHAR rgchCloseQuote[] = { _T('\"'), _T('\''), _T(')'), _T('}'), _T(']') };
  11. #define MAXQUOTE (_tsizeof(rgchOpenQuote) / _tsizeof(rgchOpenQuote[0]))
  12. static TCHAR rgchDelim[] = { _T(' '), _T('\t'), _T(',') };
  13. #define MAXDELIM (_tsizeof(rgchDelim) / _tsizeof(rgchDelim[0]))
  14. //extern LPSHF Lpshf;
  15. int
  16. CPCopyString(
  17. PTSTR * lplps,
  18. PTSTR lpT,
  19. TCHAR chEscape,
  20. BOOL fQuote
  21. )
  22. /*++
  23. Routine Description:
  24. Scan and copy an optionally quoted C-style string. If the first character is
  25. a quote, a matching quote will terminate the string, otherwise the scanning will
  26. stop at the first whitespace encountered. The target string will be null
  27. terminated if any characters are copied.
  28. Arguments:
  29. lplps - Supplies a pointer to a pointer to the source string
  30. lpt - Supplies a pointer to the target string
  31. chEscape - Supplies the escape character (typically '\\')
  32. fQuote - Supplies a flag indicating whether the first character is a quote
  33. Return Value:
  34. The number of characters copied into lpt[]. If an error occurs, -1 is returned.
  35. --*/
  36. {
  37. PTSTR lps = *lplps;
  38. PTSTR lpt = lpT;
  39. int i;
  40. int n;
  41. int err = 0;
  42. TCHAR cQuote = _T('\0');
  43. if (fQuote) {
  44. if (*lps) {
  45. cQuote = *lps++;
  46. }
  47. }
  48. while (!err) {
  49. if (*lps == 0)
  50. {
  51. if (fQuote) {
  52. err = 1;
  53. } else {
  54. *lpt = _T('\0');
  55. }
  56. break;
  57. }
  58. else if (fQuote && *lps == cQuote)
  59. {
  60. *lpt = _T('\0');
  61. // eat the quote
  62. lps++;
  63. break;
  64. }
  65. else if (!fQuote && (!*lps || *lps == _T(' ') || *lps == _T('\t') || *lps == _T('\r') || *lps == _T('\n')))
  66. {
  67. *lpt = _T('\0');
  68. break;
  69. }
  70. else if (*lps != chEscape)
  71. {
  72. *lpt++ = *lps++;
  73. }
  74. else
  75. {
  76. switch (*++lps) {
  77. case 0:
  78. err = 1;
  79. --lps;
  80. break;
  81. default: // any char - usually escape or quote
  82. *lpt++ = *lps;
  83. break;
  84. case _T('b'): // backspace
  85. *lpt++ = _T('\b');
  86. break;
  87. case _T('f'): // formfeed
  88. *lpt++ = _T('\f');
  89. break;
  90. case _T('n'): // newline
  91. *lpt++ = _T('\n');
  92. break;
  93. case _T('r'): // return
  94. *lpt++ = _T('\r');
  95. break;
  96. case _T('s'): // space
  97. *lpt++ = _T(' ');
  98. break;
  99. case _T('t'): // tab
  100. *lpt++ = _T('\t');
  101. break;
  102. case _T('0'): // octal escape
  103. for (n = 0, i = 0; i < 3; i++) {
  104. ++lps;
  105. if (*lps < _T('0') || *lps > _T('7')) {
  106. --lps;
  107. break;
  108. }
  109. n = (n<<3) + *lps - _T('0');
  110. }
  111. *lpt++ = (UCHAR)(n & 0xff);
  112. break;
  113. }
  114. lps++; // skip char from switch
  115. }
  116. } // while
  117. if (err) {
  118. return -1;
  119. } else {
  120. *lplps = lps;
  121. return (int) (lpt - lpT);
  122. }
  123. }
  124. BOOL
  125. CPFormatMemory(
  126. LPCH lpchTarget,
  127. DWORD cchTarget,
  128. LPBYTE lpbSource,
  129. DWORD cBits,
  130. FMTTYPE fmtType,
  131. DWORD radix
  132. )
  133. /*++
  134. Routine Description:
  135. CPFormatMemory.
  136. formats a value by template
  137. Arguments:
  138. lpchTarget - Destination buffer.
  139. cchTarget - Size of destination buffer.
  140. lpbSource - Data to be formatted.
  141. cBits - Number of bits in the data.
  142. fmtType - Determines how the data will be treated?? UINT, float, real, ...
  143. radix - Radix to use when formatting.
  144. Return Value:
  145. TRUE - Success
  146. FALSE - Bad things happened
  147. --*/
  148. {
  149. LONG64 l;
  150. long cb;
  151. ULONG64 ul = 0;
  152. TCHAR rgch[512] = {0};
  153. Assert (radix == 8 || radix == 10 || radix == 16 ||
  154. (fmtType & fmtBasis) == fmtAscii ||
  155. (fmtType & fmtBasis) == fmtUnicode);
  156. Assert (cBits != 0);
  157. Assert (cchTarget <= _tsizeof(rgch));
  158. switch (fmtType & fmtBasis) {
  159. //
  160. // Format from memory bytes into an integer format number
  161. //
  162. case fmtInt:
  163. if (radix == 10) {
  164. switch( (cBits + 7)/8 ) {
  165. case 1:
  166. l = *(signed char *)lpbSource;
  167. if (fmtType & fmtZeroPad) {
  168. _stprintf(rgch, _T("%0*I64d"), cchTarget-1, l);
  169. } else if (fmtType & fmtSpacePad) {
  170. _stprintf(rgch, _T("% *I64d"), cchTarget-1, l);
  171. } else {
  172. _stprintf(rgch, _T("% I64d"), l);
  173. }
  174. break;
  175. case 2:
  176. l = *(short *)lpbSource;
  177. if (fmtType & fmtZeroPad) {
  178. _stprintf(rgch, _T("%0*I64d"), cchTarget-1, l);
  179. } else if (fmtType & fmtSpacePad) {
  180. _stprintf(rgch, _T("% *I64d"), cchTarget-1, l);
  181. } else {
  182. _stprintf(rgch, _T("% I64d"), l);
  183. }
  184. break;
  185. case 4:
  186. l = *(long *)lpbSource;
  187. if (fmtType & fmtZeroPad) {
  188. _stprintf(rgch, _T("%0*I64d"), cchTarget-1, l);
  189. } else if (fmtType & fmtSpacePad) {
  190. _stprintf(rgch, _T("% *I64d"), cchTarget-1, l);
  191. } else {
  192. _stprintf(rgch, _T("% I64d"), l);
  193. }
  194. break;
  195. case 8:
  196. l = *(LONG64 *)lpbSource;
  197. if (fmtType & fmtZeroPad) {
  198. _stprintf(rgch, _T("%0*I64d"), cchTarget-1, l);
  199. } else if (fmtType & fmtSpacePad) {
  200. _stprintf(rgch, _T("% *I64d"), cchTarget-1, l);
  201. } else {
  202. _stprintf(rgch, _T("% I64d"), l);
  203. }
  204. break;
  205. default:
  206. return FALSE; // Bad format
  207. }
  208. if (_tcslen(rgch) >= cchTarget) {
  209. return FALSE; // Overrun
  210. }
  211. _tcscpy(lpchTarget, rgch);
  212. break;
  213. }
  214. //
  215. // then we should handle this as UInt
  216. //
  217. case fmtUInt:
  218. cb = (cBits + 7)/8;
  219. switch( cb ) {
  220. case 1:
  221. ul = *(BYTE *) lpbSource;
  222. break;
  223. case 2:
  224. ul = *(USHORT *) lpbSource;
  225. break;
  226. case 4:
  227. ul = *(ULONG *) lpbSource;
  228. break;
  229. //
  230. // MBH - bugbug - CENTAUR bug;
  231. // putting contents of instead of address of structure
  232. // for return value in a0.
  233. //
  234. case 8:
  235. ul = *(ULONG64 *) lpbSource;
  236. break;
  237. default:
  238. if (radix != 16 || (fmtType & fmtZeroPad) == 0) {
  239. return FALSE; // Bad format
  240. }
  241. }
  242. if (fmtType & fmtZeroPad) {
  243. switch (radix) {
  244. case 8:
  245. _stprintf(rgch, _T("%0*.*I64o"), cchTarget-1, cchTarget-1, ul);
  246. break;
  247. case 10:
  248. _stprintf(rgch, _T("%0*.*I64u"), cchTarget-1, cchTarget-1, ul);
  249. break;
  250. case 16:
  251. if (cb <= 8) {
  252. _stprintf(rgch, _T("%0*.*I64x"), cchTarget-1, cchTarget-1, ul);
  253. } else {
  254. // handle any size:
  255. // NOTENOTE a-kentf this is dependent on byte order
  256. for (l = 0; l < cb; l++) {
  257. _stprintf(rgch+l+l, _T("%02.2x"), lpbSource[cb - l - 1]);
  258. }
  259. //_stprintf(rgch, _T("%0*.*x"), cchTarget-1, cchTarget-1, ul);
  260. }
  261. break;
  262. }
  263. } else if (fmtType & fmtSpacePad) {
  264. switch (radix) {
  265. case 8:
  266. _stprintf(rgch, _T("% *.*I64o"), cchTarget-1, cchTarget-1, ul);
  267. break;
  268. case 10:
  269. _stprintf(rgch, _T("% *.*I64u"), cchTarget-1, cchTarget-1, ul);
  270. break;
  271. case 16:
  272. if (cb <= 8) {
  273. _stprintf(rgch, _T("% *.*I64x"), cchTarget-1, cchTarget-1, ul);
  274. } else {
  275. // handle any size:
  276. // NOTENOTE a-kentf this is dependent on byte order
  277. /*for (l = 0; l < cb; l++) {
  278. _stprintf(rgch+l+l, _T("% 2.2x"), lpbSource[cb - l - 1]);
  279. }*/
  280. _stprintf(rgch, _T("% *.*I64x"), cchTarget-1, cchTarget-1, ul);
  281. }
  282. break;
  283. }
  284. } else {
  285. switch (radix) {
  286. case 8:
  287. _stprintf(rgch, _T("%I64o"), ul);
  288. break;
  289. case 10:
  290. _stprintf(rgch, _T("%I64u"), ul);
  291. break;
  292. case 16:
  293. _stprintf(rgch, _T("%I64x"), ul);
  294. break;
  295. }
  296. }
  297. if (_tcslen(rgch) >= cchTarget) {
  298. return FALSE; // Overrun
  299. }
  300. _tcscpy(lpchTarget, rgch);
  301. break;
  302. case fmtAscii:
  303. if ( cBits != 8 ) {
  304. return FALSE; // Bad format
  305. }
  306. lpchTarget[0] = *(BYTE *) lpbSource;
  307. if ((lpchTarget[0] < _T(' ')) || (lpchTarget[0] > 0x7e)) {
  308. lpchTarget[0] = _T('.');
  309. }
  310. lpchTarget[1] = 0;
  311. return TRUE; // success
  312. case fmtUnicode:
  313. if (cBits != 16) {
  314. return FALSE; // Bad format
  315. }
  316. Assert((DWORD)MB_CUR_MAX <= cchTarget);
  317. if ((wctomb(lpchTarget, *(LPWCH)lpbSource) == -1) ||
  318. (lpchTarget[0] < _T(' ')) ||
  319. (lpchTarget[0] > 0x7e)) {
  320. lpchTarget[0] = _T('.');
  321. }
  322. lpchTarget[1] = 0;
  323. return TRUE; // success
  324. case fmtFloat:
  325. switch ( cBits ) {
  326. case 4*8:
  327. _stprintf(rgch, _T("% 12.6e"),*((float *) lpbSource));
  328. break;
  329. case 8*8:
  330. // _stprintf(rgch, _T("% 17.11le"), *((double *) lpbSource));
  331. _stprintf(rgch, _T("% 21.14le"), *((double *) lpbSource));
  332. break;
  333. case 10*8:
  334. if (_uldtoa((_ULDOUBLE *)lpbSource, 25, rgch) == NULL) {
  335. return FALSE; // Bad format
  336. }
  337. break;
  338. case 16*8:
  339. // v-vadimp this is an IA64 float - may have to rethink the format here
  340. // what we are getting here is really FLOAT128
  341. if (_uldtoa((_ULDOUBLE *)(lpbSource), 30, rgch) == NULL) {
  342. return FALSE; // Bad format
  343. }
  344. break;
  345. default:
  346. return FALSE; // Bad format
  347. }
  348. if (_tcslen(rgch) >= cchTarget) {
  349. return FALSE; // Overrun
  350. }
  351. _tcsncpy(lpchTarget, rgch, cchTarget-1);
  352. lpchTarget[cchTarget-1] = 0;
  353. return TRUE; // success
  354. case fmtBit:
  355. {
  356. WORD i,j,shift=0; //shift will allow for a blank after each 8 bits
  357. for (i=0;i<cBits/8;i++) {
  358. for(j=0;j<8;j++) {
  359. if((lpbSource[i]>>j) & 0x1) {
  360. rgch[i*8+j+shift]=_T('1');
  361. } else {
  362. rgch[i*8+j+shift]=_T('0');
  363. }
  364. }
  365. rgch[(i+1)*8+shift]=_T(' ');
  366. shift++;
  367. }
  368. rgch[cBits+shift-1]=_T('\0');
  369. _tcscpy(lpchTarget,rgch);
  370. }
  371. return TRUE; // success
  372. default:
  373. return FALSE; // Bad format
  374. }
  375. return TRUE; // success
  376. } /* CPFormatMemory() */