478 lines
12 KiB
C++
478 lines
12 KiB
C++
/*++
|
||
|
||
Copyright (c) 1992-2000 Microsoft Corporation
|
||
|
||
Purpose:
|
||
|
||
Formatting functions.
|
||
|
||
--*/
|
||
|
||
|
||
#include "precomp.hxx"
|
||
#pragma hdrstop
|
||
|
||
|
||
|
||
#define MAXNESTING (50)
|
||
|
||
static TCHAR rgchOpenQuote[] = { _T('\"'), _T('\''), _T('('), _T('{'), _T('[') };
|
||
static TCHAR rgchCloseQuote[] = { _T('\"'), _T('\''), _T(')'), _T('}'), _T(']') };
|
||
#define MAXQUOTE (_tsizeof(rgchOpenQuote) / _tsizeof(rgchOpenQuote[0]))
|
||
|
||
static TCHAR rgchDelim[] = { _T(' '), _T('\t'), _T(',') };
|
||
#define MAXDELIM (_tsizeof(rgchDelim) / _tsizeof(rgchDelim[0]))
|
||
|
||
//extern LPSHF Lpshf;
|
||
|
||
|
||
|
||
|
||
|
||
int
|
||
CPCopyString(
|
||
PTSTR * lplps,
|
||
PTSTR lpT,
|
||
TCHAR chEscape,
|
||
BOOL fQuote
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Scan and copy an optionally quoted C-style string. If the first character is
|
||
a quote, a matching quote will terminate the string, otherwise the scanning will
|
||
stop at the first whitespace encountered. The target string will be null
|
||
terminated if any characters are copied.
|
||
|
||
Arguments:
|
||
|
||
lplps - Supplies a pointer to a pointer to the source string
|
||
|
||
lpt - Supplies a pointer to the target string
|
||
|
||
chEscape - Supplies the escape character (typically '\\')
|
||
|
||
fQuote - Supplies a flag indicating whether the first character is a quote
|
||
|
||
Return Value:
|
||
|
||
The number of characters copied into lpt[]. If an error occurs, -1 is returned.
|
||
|
||
--*/
|
||
{
|
||
PTSTR lps = *lplps;
|
||
PTSTR lpt = lpT;
|
||
int i;
|
||
int n;
|
||
int err = 0;
|
||
TCHAR cQuote = _T('\0');
|
||
|
||
if (fQuote) {
|
||
if (*lps) {
|
||
cQuote = *lps++;
|
||
}
|
||
}
|
||
|
||
while (!err) {
|
||
|
||
if (*lps == 0)
|
||
{
|
||
if (fQuote) {
|
||
err = 1;
|
||
} else {
|
||
*lpt = _T('\0');
|
||
}
|
||
break;
|
||
}
|
||
else if (fQuote && *lps == cQuote)
|
||
{
|
||
*lpt = _T('\0');
|
||
// eat the quote
|
||
lps++;
|
||
break;
|
||
}
|
||
else if (!fQuote && (!*lps || *lps == _T(' ') || *lps == _T('\t') || *lps == _T('\r') || *lps == _T('\n')))
|
||
{
|
||
*lpt = _T('\0');
|
||
break;
|
||
}
|
||
|
||
else if (*lps != chEscape)
|
||
{
|
||
*lpt++ = *lps++;
|
||
}
|
||
else
|
||
{
|
||
switch (*++lps) {
|
||
case 0:
|
||
err = 1;
|
||
--lps;
|
||
break;
|
||
|
||
default: // any char - usually escape or quote
|
||
*lpt++ = *lps;
|
||
break;
|
||
|
||
case _T('b'): // backspace
|
||
*lpt++ = _T('\b');
|
||
break;
|
||
|
||
case _T('f'): // formfeed
|
||
*lpt++ = _T('\f');
|
||
break;
|
||
|
||
case _T('n'): // newline
|
||
*lpt++ = _T('\n');
|
||
break;
|
||
|
||
case _T('r'): // return
|
||
*lpt++ = _T('\r');
|
||
break;
|
||
|
||
case _T('s'): // space
|
||
*lpt++ = _T(' ');
|
||
break;
|
||
|
||
case _T('t'): // tab
|
||
*lpt++ = _T('\t');
|
||
break;
|
||
|
||
case _T('0'): // octal escape
|
||
for (n = 0, i = 0; i < 3; i++) {
|
||
++lps;
|
||
if (*lps < _T('0') || *lps > _T('7')) {
|
||
--lps;
|
||
break;
|
||
}
|
||
n = (n<<3) + *lps - _T('0');
|
||
}
|
||
*lpt++ = (UCHAR)(n & 0xff);
|
||
break;
|
||
}
|
||
lps++; // skip char from switch
|
||
}
|
||
|
||
} // while
|
||
|
||
if (err) {
|
||
return -1;
|
||
} else {
|
||
*lplps = lps;
|
||
return (int) (lpt - lpT);
|
||
}
|
||
}
|
||
|
||
|
||
|
||
BOOL
|
||
CPFormatMemory(
|
||
LPCH lpchTarget,
|
||
DWORD cchTarget,
|
||
LPBYTE lpbSource,
|
||
DWORD cBits,
|
||
FMTTYPE fmtType,
|
||
DWORD radix
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
CPFormatMemory.
|
||
|
||
formats a value by template
|
||
|
||
Arguments:
|
||
|
||
lpchTarget - Destination buffer.
|
||
|
||
cchTarget - Size of destination buffer.
|
||
|
||
lpbSource - Data to be formatted.
|
||
|
||
cBits - Number of bits in the data.
|
||
|
||
fmtType - Determines how the data will be treated?? UINT, float, real, ...
|
||
|
||
radix - Radix to use when formatting.
|
||
|
||
Return Value:
|
||
|
||
TRUE - Success
|
||
|
||
FALSE - Bad things happened
|
||
|
||
--*/
|
||
{
|
||
LONG64 l;
|
||
long cb;
|
||
ULONG64 ul = 0;
|
||
TCHAR rgch[512] = {0};
|
||
|
||
|
||
Assert (radix == 8 || radix == 10 || radix == 16 ||
|
||
(fmtType & fmtBasis) == fmtAscii ||
|
||
(fmtType & fmtBasis) == fmtUnicode);
|
||
Assert (cBits != 0);
|
||
Assert (cchTarget <= _tsizeof(rgch));
|
||
|
||
switch (fmtType & fmtBasis) {
|
||
//
|
||
// Format from memory bytes into an integer format number
|
||
//
|
||
case fmtInt:
|
||
|
||
if (radix == 10) {
|
||
|
||
switch( (cBits + 7)/8 ) {
|
||
case 1:
|
||
l = *(signed char *)lpbSource;
|
||
if (fmtType & fmtZeroPad) {
|
||
_stprintf(rgch, _T("%0*I64d"), cchTarget-1, l);
|
||
} else if (fmtType & fmtSpacePad) {
|
||
_stprintf(rgch, _T("% *I64d"), cchTarget-1, l);
|
||
} else {
|
||
_stprintf(rgch, _T("% I64d"), l);
|
||
}
|
||
break;
|
||
|
||
case 2:
|
||
l = *(short *)lpbSource;
|
||
if (fmtType & fmtZeroPad) {
|
||
_stprintf(rgch, _T("%0*I64d"), cchTarget-1, l);
|
||
} else if (fmtType & fmtSpacePad) {
|
||
_stprintf(rgch, _T("% *I64d"), cchTarget-1, l);
|
||
} else {
|
||
_stprintf(rgch, _T("% I64d"), l);
|
||
}
|
||
break;
|
||
|
||
case 4:
|
||
l = *(long *)lpbSource;
|
||
if (fmtType & fmtZeroPad) {
|
||
_stprintf(rgch, _T("%0*I64d"), cchTarget-1, l);
|
||
} else if (fmtType & fmtSpacePad) {
|
||
_stprintf(rgch, _T("% *I64d"), cchTarget-1, l);
|
||
} else {
|
||
_stprintf(rgch, _T("% I64d"), l);
|
||
}
|
||
break;
|
||
|
||
case 8:
|
||
l = *(LONG64 *)lpbSource;
|
||
if (fmtType & fmtZeroPad) {
|
||
_stprintf(rgch, _T("%0*I64d"), cchTarget-1, l);
|
||
} else if (fmtType & fmtSpacePad) {
|
||
_stprintf(rgch, _T("% *I64d"), cchTarget-1, l);
|
||
} else {
|
||
_stprintf(rgch, _T("% I64d"), l);
|
||
}
|
||
break;
|
||
|
||
default:
|
||
return FALSE; // Bad format
|
||
}
|
||
|
||
|
||
if (_tcslen(rgch) >= cchTarget) {
|
||
return FALSE; // Overrun
|
||
}
|
||
|
||
_tcscpy(lpchTarget, rgch);
|
||
|
||
break;
|
||
}
|
||
//
|
||
// then we should handle this as UInt
|
||
//
|
||
|
||
case fmtUInt:
|
||
|
||
cb = (cBits + 7)/8;
|
||
switch( cb ) {
|
||
case 1:
|
||
ul = *(BYTE *) lpbSource;
|
||
break;
|
||
|
||
case 2:
|
||
ul = *(USHORT *) lpbSource;
|
||
break;
|
||
|
||
case 4:
|
||
ul = *(ULONG *) lpbSource;
|
||
break;
|
||
|
||
//
|
||
// MBH - bugbug - CENTAUR bug;
|
||
// putting contents of instead of address of structure
|
||
// for return value in a0.
|
||
//
|
||
|
||
case 8:
|
||
ul = *(ULONG64 *) lpbSource;
|
||
break;
|
||
|
||
|
||
default:
|
||
if (radix != 16 || (fmtType & fmtZeroPad) == 0) {
|
||
return FALSE; // Bad format
|
||
}
|
||
}
|
||
|
||
if (fmtType & fmtZeroPad) {
|
||
switch (radix) {
|
||
case 8:
|
||
_stprintf(rgch, _T("%0*.*I64o"), cchTarget-1, cchTarget-1, ul);
|
||
break;
|
||
case 10:
|
||
_stprintf(rgch, _T("%0*.*I64u"), cchTarget-1, cchTarget-1, ul);
|
||
break;
|
||
case 16:
|
||
if (cb <= 8) {
|
||
_stprintf(rgch, _T("%0*.*I64x"), cchTarget-1, cchTarget-1, ul);
|
||
} else {
|
||
// handle any size:
|
||
// NOTENOTE a-kentf this is dependent on byte order
|
||
for (l = 0; l < cb; l++) {
|
||
_stprintf(rgch+l+l, _T("%02.2x"), lpbSource[cb - l - 1]);
|
||
}
|
||
//_stprintf(rgch, _T("%0*.*x"), cchTarget-1, cchTarget-1, ul);
|
||
}
|
||
break;
|
||
}
|
||
} else if (fmtType & fmtSpacePad) {
|
||
switch (radix) {
|
||
case 8:
|
||
_stprintf(rgch, _T("% *.*I64o"), cchTarget-1, cchTarget-1, ul);
|
||
break;
|
||
case 10:
|
||
_stprintf(rgch, _T("% *.*I64u"), cchTarget-1, cchTarget-1, ul);
|
||
break;
|
||
case 16:
|
||
if (cb <= 8) {
|
||
_stprintf(rgch, _T("% *.*I64x"), cchTarget-1, cchTarget-1, ul);
|
||
} else {
|
||
// handle any size:
|
||
// NOTENOTE a-kentf this is dependent on byte order
|
||
/*for (l = 0; l < cb; l++) {
|
||
_stprintf(rgch+l+l, _T("% 2.2x"), lpbSource[cb - l - 1]);
|
||
}*/
|
||
_stprintf(rgch, _T("% *.*I64x"), cchTarget-1, cchTarget-1, ul);
|
||
}
|
||
break;
|
||
}
|
||
} else {
|
||
switch (radix) {
|
||
case 8:
|
||
_stprintf(rgch, _T("%I64o"), ul);
|
||
break;
|
||
case 10:
|
||
_stprintf(rgch, _T("%I64u"), ul);
|
||
break;
|
||
case 16:
|
||
_stprintf(rgch, _T("%I64x"), ul);
|
||
break;
|
||
}
|
||
}
|
||
|
||
|
||
if (_tcslen(rgch) >= cchTarget) {
|
||
return FALSE; // Overrun
|
||
}
|
||
|
||
_tcscpy(lpchTarget, rgch);
|
||
|
||
break;
|
||
|
||
|
||
case fmtAscii:
|
||
if ( cBits != 8 ) {
|
||
return FALSE; // Bad format
|
||
}
|
||
lpchTarget[0] = *(BYTE *) lpbSource;
|
||
if ((lpchTarget[0] < _T(' ')) || (lpchTarget[0] > 0x7e)) {
|
||
lpchTarget[0] = _T('.');
|
||
}
|
||
lpchTarget[1] = 0;
|
||
return TRUE; // success
|
||
|
||
case fmtUnicode:
|
||
if (cBits != 16) {
|
||
return FALSE; // Bad format
|
||
}
|
||
Assert((DWORD)MB_CUR_MAX <= cchTarget);
|
||
if ((wctomb(lpchTarget, *(LPWCH)lpbSource) == -1) ||
|
||
(lpchTarget[0] < _T(' ')) ||
|
||
(lpchTarget[0] > 0x7e)) {
|
||
lpchTarget[0] = _T('.');
|
||
}
|
||
lpchTarget[1] = 0;
|
||
return TRUE; // success
|
||
|
||
case fmtFloat:
|
||
switch ( cBits ) {
|
||
case 4*8:
|
||
_stprintf(rgch, _T("% 12.6e"),*((float *) lpbSource));
|
||
break;
|
||
|
||
case 8*8:
|
||
// _stprintf(rgch, _T("% 17.11le"), *((double *) lpbSource));
|
||
_stprintf(rgch, _T("% 21.14le"), *((double *) lpbSource));
|
||
break;
|
||
|
||
case 10*8:
|
||
if (_uldtoa((_ULDOUBLE *)lpbSource, 25, rgch) == NULL) {
|
||
return FALSE; // Bad format
|
||
}
|
||
break;
|
||
|
||
case 16*8:
|
||
// v-vadimp this is an IA64 float - may have to rethink the format here
|
||
// what we are getting here is really FLOAT128
|
||
if (_uldtoa((_ULDOUBLE *)(lpbSource), 30, rgch) == NULL) {
|
||
return FALSE; // Bad format
|
||
}
|
||
break;
|
||
|
||
default:
|
||
return FALSE; // Bad format
|
||
|
||
}
|
||
|
||
if (_tcslen(rgch) >= cchTarget) {
|
||
return FALSE; // Overrun
|
||
}
|
||
|
||
_tcsncpy(lpchTarget, rgch, cchTarget-1);
|
||
lpchTarget[cchTarget-1] = 0;
|
||
return TRUE; // success
|
||
|
||
case fmtBit:
|
||
{
|
||
WORD i,j,shift=0; //shift will allow for a blank after each 8 bits
|
||
for (i=0;i<cBits/8;i++) {
|
||
for(j=0;j<8;j++) {
|
||
if((lpbSource[i]>>j) & 0x1) {
|
||
rgch[i*8+j+shift]=_T('1');
|
||
} else {
|
||
rgch[i*8+j+shift]=_T('0');
|
||
}
|
||
}
|
||
rgch[(i+1)*8+shift]=_T(' ');
|
||
shift++;
|
||
}
|
||
rgch[cBits+shift-1]=_T('\0');
|
||
_tcscpy(lpchTarget,rgch);
|
||
}
|
||
return TRUE; // success
|
||
|
||
default:
|
||
|
||
return FALSE; // Bad format
|
||
|
||
}
|
||
|
||
return TRUE; // success
|
||
} /* CPFormatMemory() */
|