📄 si_misc.c
字号:
break;
case esc_unicode:
if ((val = GetHexValueFromChar(aChar)) != -1)
{
theResultChar = theResultChar << 4;
theResultChar += val;
(*strPos)++;
nbrOfChars++;
if (nbrOfChars == 4)
{
done = TRUE;
}
}
else
{
done = TRUE;
error = TRUE;
}
break;
}
}
if (done && (!error))
{
result = NEWSTRUCT( structEscapeSeq );
result->startPos = startPos;
result->endPos = *strPos;
result->theChar = theResultChar;
result->next = NULL;
}
return result;
}
VOID EscSeq_Delete( pstructEscapeSeq *list )
{
pstructEscapeSeq el = NULL;
pstructEscapeSeq nextEl = NULL;
el = *list;
while (el != NULL)
{
nextEl = el->next;
DEALLOC( &el );
el = nextEl;
}
*list = NULL;
}
/**/
typedef enum
{
formatTypeNone = 1,
formatTypeInt,
formatTypeFloat,
formatTypeString
} enumFormatType;
WCHAR* parseFormatSpecifier( WCHAR *formatStr, UINT32 strLen, UINT32 *pStrPos,
pstructVar value, BOOL *pWentOk )
{
WCHAR *result = NULL;
WCHAR aChar = 0;
BOOL done = FALSE;
UINT8 charsUsed = 0;
INT32 number = 0;
BOOL overflow = FALSE;
UINT32 i;
UINT32 j;
INT32 width = 0;
INT32 precision = -1;
enumFormatType theFormatType = formatTypeNone;
BOOL aNegativeNumber = FALSE;
BOOL widthParsed = FALSE;
BOOL precisionParsed = FALSE;
BOOL typeParsed = FALSE;
BYTE* pchFloatAsString = NULL;
*pWentOk = TRUE;
while ((*pStrPos < strLen) && (!done))
{
aChar = formatStr[ *pStrPos ];
/*
if (IsWhitespaceChar(aChar))
{
(*pStrPos)++;
}
else
*/
if (((aChar >= '0') && (aChar <= '9')) && (! widthParsed))
{
if (String2Int( formatStr + *pStrPos, &charsUsed, &number, &overflow ) &&
((*pStrPos + charsUsed) < strLen))
{
*pStrPos += charsUsed;
width = number;
}
else
{
done = TRUE;
*pWentOk = FALSE;
}
}
else if ((aChar == '.') && (! precisionParsed))
{
precisionParsed = TRUE;
(*pStrPos)++;
if (*pStrPos < strLen)
{
aChar = formatStr[ *pStrPos ];
if ((aChar >= '0') && (aChar <= '9'))
{
if (String2Int( formatStr + *pStrPos, &charsUsed, &number, &overflow ) &&
((*pStrPos + charsUsed) < strLen))
{
*pStrPos += charsUsed;
precision = number;
}
else
{
done = TRUE;
*pWentOk = FALSE;
}
}
}
else
{
done = TRUE;
*pWentOk = FALSE;
}
}
else if ((aChar == 'd') && (! typeParsed))
{
(*pStrPos)++;
theFormatType = formatTypeInt;
done = TRUE;
}
else if ((aChar == 'f') && (! typeParsed))
{
(*pStrPos)++;
theFormatType = formatTypeFloat;
done = TRUE;
}
else if ((aChar == 's') && (! typeParsed))
{
(*pStrPos)++;
theFormatType = formatTypeString;
done = TRUE;
}
else
{
done = TRUE;
*pWentOk = FALSE;
}
}
if (*pWentOk)
{
/* now format the value variable as specified */
switch (theFormatType)
{
case formatTypeInt:
#ifdef HAS_FLOAT
/*
000808 (KHN) WAP 1.2.1 update:
CR WMLSL-IBM-20000315-FormatConversion
If doing a %d but the value is float then do Float.int() conversion first.
*/
if (value->type == typeFloat)
{
if ((value->val.theFloat >= FLOAT32_INTMAX_AS_FLOAT) || (value->val.theFloat < INT32_MIN) )
{
Var_AssignInvalid( value ); /*the float is bigger/smaller than an int can be*/
}
else
{
Var_AssignInt( value, (INT32) value->val.theFloat );
}
}
#endif
*pWentOk = (VCR_OK == Var_Convert( value, typeInteger ));
break;
#ifdef HAS_FLOAT
case formatTypeFloat:
*pWentOk = (VCR_OK == Var_Convert( value, typeFloat ));
break;
#else
case formatTypeFloat:
*pWentOk = FALSE;
break;
#endif
case formatTypeString:
*pWentOk = (VCR_OK == Var_Convert( value, typeString ));
break;
default:
*pWentOk = FALSE;
break;
}
if (*pWentOk)
{
/* now convert to string while applying the width and precision variables */
switch (value->type)
{
case typeInteger:
aNegativeNumber = value->val.theInt < 0;
if ((precision == 0) && (value->val.theInt == 0))
{ /* the result is an empty string */
*pWentOk = TRUE;
/* totally done! The result will be NULL */
}
else if ( (*pWentOk = (VCR_OK == Var_Convert( value, typeString ))) )
{
if (precision == -1)
{ /* no precision specified */
precision = MAX( (INT32)value->theStringLen, precision );
}
else
{
if (! aNegativeNumber)
{
precision = MAX( (INT32)value->theStringLen, precision );
}
else
{ /* if the number is negative the prcecision 3 will make "-xx" to become "-0xx"
thus the stringlength will be increased by one. To reflect this we
add one to precision in this case. The precision is now the length of the number
subject to the precision field. */
precision = MAX( (INT32)value->theStringLen, precision + 1 );
}
}
width = MAX( precision, width );
if (width == (INT32)value->theStringLen)
{ /* the result is the integer without adjustment */
result = NEWARRAY( WCHAR, value->theStringLen + 1 );
result[value->theStringLen] = 0;
COPYSTRINGN( result, value->val.theString, value->theStringLen );
/* done! */
*pWentOk = TRUE;
}
else
{ /* the string must be altered in some way */
result = NEWARRAY( WCHAR, width + 1 );
result[width] = 0;
for (i=0; i < (UINT32)(width - precision); i++)
{
result[i] = CHAR_SPACE;
}
if (aNegativeNumber)
{
/* transfer the minus ('-') sign first before padding the number according to the precision */
result[i] = value->val.theString[0];
i++;
}
j = 0;
while (j < ((UINT32)(precision - value->theStringLen)))
{ /* pad with zeroes */
result[i] = WC('0'); /* a zero */
i++;
j++;
}
if (aNegativeNumber)
{
COPYSTRINGN( result + i, value->val.theString + 1, value->theStringLen - 1 );
}
else
{
COPYSTRINGN( result + i, value->val.theString, value->theStringLen );
}
/* done! */
}
}
break;
#ifdef HAS_FLOAT
case typeFloat:
if (precision == -1)
{
if (precisionParsed)
{ /* only a dot but no number means precision 0 */
precision = 0;
}
else
{ /* no precision given and the default is 6 */
precision = 6;
}
}
pchFloatAsString = NEWARRAY( BYTE, MAX( 41 + precision, width ) +1 );
sprintf (pchFloatAsString, "%*.*f", (int)width, (int)precision, (double)(value->val.theFloat) );
result = wip_byte2wchar( pchFloatAsString );
DEALLOC( &pchFloatAsString );
break;
#endif
case typeString:
if (precision == -1)
{
precision = (INT32)value->theStringLen;
width = MAX( precision, width );
}
else
{
precision = MIN( (INT32)value->theStringLen, precision );
width = precision;
/* When the width is larger than precision,
the width should be ignored. Also, the width never trucates a value
which means that it can never be less than precision. So if
a precision is given, the width value is not important. */
}
result = NEWARRAY( WCHAR, width + 1 );
result[width] = 0;
for (i=0; i < (UINT32)(width - precision); i++)
{
result[i] = CHAR_SPACE;
}
COPYSTRINGN( result + i, value->val.theString, precision );
break;
default:
*pWentOk = FALSE;
break;
}
}
}
return result;
}
#ifdef HAS_FLOAT
BOOL IsLegalFloatVal( FLOAT32 a )
{
UINT32 aAsHex = (* (UINT32*)((void*)&a) );
if ( ((aAsHex) == 0xFF800000) || /* -INF */
((aAsHex) == 0x7F800000) || /* +INF */
( (((aAsHex) & 0x7F800000)== 0x7F800000) && ((aAsHex) & 0x007FFFFF) ) ) /* NaN */
{
return FALSE;
}
else
{
return TRUE;
}
}
BOOL IsUnderflow( FLOAT32 a )
{
if ((a > 0.0) && (a < FLOAT32_MIN))
{
/* underflow */
return TRUE;
}
else if ((a < 0.0) && (a > -FLOAT32_MIN))
{
/* underflow */
return TRUE;
}
else
{
return FALSE;
}
}
BOOL FloatIsZero( FLOAT32 a )
{
UINT32 aAsHex = (* (UINT32*)((void*)&a) );
if ((aAsHex & 0x7FFFFFFF) == 0)
{
return TRUE;
}
else
{
return FALSE;
}
}
#endif
/* ifdef HAS_FLOAT */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -