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.
483 lines
13 KiB
483 lines
13 KiB
/*++
|
|
|
|
Copyright (c) 1992-2002 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 == 2 || 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
|
|
}
|
|
// This 2 should really be MB_CUR_MAX but that caused
|
|
// a compatibility problem with Win2K as its definition
|
|
// changed to a function.
|
|
Assert(2 <= 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+7)/8;i++) {
|
|
for(j=0;j<8;j++) {
|
|
if((lpbSource[i]>> (7-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');
|
|
if (_tcslen(rgch) >= cchTarget) {
|
|
return FALSE; // Overrun
|
|
}
|
|
_tcscpy(lpchTarget,rgch);
|
|
}
|
|
return TRUE; // success
|
|
|
|
default:
|
|
|
|
return FALSE; // Bad format
|
|
|
|
}
|
|
|
|
return TRUE; // success
|
|
} /* CPFormatMemory() */
|