NT4/private/sdktools/vctools/mc/mcutil.c
2020-09-30 17:12:29 +02:00

302 lines
5.7 KiB
C

/*++
Copyright (c) 1991 Microsoft Corporation
Module Name:
mcutil.c
Abstract:
This file contains utility functions for the Win32 Message Compiler (MC)
Author:
Steve Wood (stevewo) 22-Aug-1991
Revision History:
--*/
#include "mc.h"
typedef BOOL (*PISTEXTUNICODE_ROUTINE)(
CONST LPVOID lpBuffer,
int cb,
LPINT lpi
);
PISTEXTUNICODE_ROUTINE OptionalIsTextUnicode = NULL;
BOOL
DefaultIsTextUnicode(
CONST LPVOID lpBuffer,
int cb,
LPINT lpi
)
{
return FALSE;
}
PNAME_INFO
McAddName(
PNAME_INFO *NameListHead,
WCHAR *Name,
ULONG Id,
PVOID Value
)
{
PNAME_INFO p;
int n;
while (p = *NameListHead) {
if (!(n = _wcsicmp( p->Name, Name ))) {
if (p->Id != Id) {
McInputErrorW( L"Redefining value of %s", FALSE, Name );
}
p->Id = Id;
p->Value = Value;
p->Used = FALSE;
return( p );
} else if (n < 0) {
break;
}
NameListHead = &p->Next;
}
p = malloc( sizeof( *p ) + ( wcslen( Name ) + 1 ) * sizeof( WCHAR ) );
p->LastId = 0;
p->Id = Id;
p->Value = Value;
p->Used = FALSE;
p->CodePage = GetOEMCP();
wcscpy( p->Name, Name );
p->Next = *NameListHead;
*NameListHead = p;
return( p );
}
PNAME_INFO
McFindName(
PNAME_INFO NameListHead,
WCHAR *Name
)
{
PNAME_INFO p;
p = NameListHead;
while (p) {
if (!_wcsicmp( p->Name, Name )) {
p->Used = TRUE;
break;
}
p = p->Next;
}
return( p );
}
BOOLEAN
McCharToInteger(
WCHAR *String,
int Base,
PULONG Value
)
{
WCHAR c;
ULONG Result, Digit, Shift;
c = *String++;
if (!Base) {
Base = 10;
Shift = 0;
if (c == L'0') {
c = *String++;
if (c == L'x') {
Base = 16;
Shift = 4;
} else if (c == L'o') {
Base = 8;
Shift = 3;
} else if (c == L'b') {
Base = 2;
Shift = 1;
} else {
String--;
}
c = *String++;
}
} else {
switch( Base ) {
case 16: Shift = 4; break;
case 8: Shift = 3; break;
case 2: Shift = 1; break;
case 10: Shift = 0; break;
default: return( FALSE );
}
}
Result = 0;
while (c) {
if (c >= L'0' && c <= L'9') {
Digit = c - L'0';
}
else if (c >= L'A' && c <= L'F') {
Digit = c - L'A' + 10;
}
else if (c >= L'a' && c <= L'f') {
Digit = c - L'a' + 10;
} else {
break;
}
if ((int)Digit >= Base) {
break;
}
if (Shift == 0) {
Result = (Base * Result) + Digit;
} else {
Result = (Result << Shift) | Digit;
}
c = *String++;
}
*Value = Result;
return( TRUE );
}
WCHAR *
McMakeString(
WCHAR *String
)
{
WCHAR *s;
s = malloc( ( wcslen( String ) + 1 ) * sizeof( WCHAR ) );
wcscpy( s, String );
return( s );
}
BOOLEAN
IsFileUnicode (char * fName)
{
#define CCH_READ_MAX 200
WORD cbRead;
INT value = 0xFFFFFFFF;
FILE *fp;
LPVOID lpBuf;
BOOLEAN result;
if (OptionalIsTextUnicode == NULL) {
OptionalIsTextUnicode = (PISTEXTUNICODE_ROUTINE)GetProcAddress( LoadLibrary( "ADVAPI32.DLL" ), "IsTextUnicode" );
if (OptionalIsTextUnicode == NULL) {
OptionalIsTextUnicode = DefaultIsTextUnicode;
}
}
if ( ( fp = fopen( fName, "rb" ) ) == NULL )
return (FALSE);
lpBuf = malloc( CCH_READ_MAX + 10 );
if (!lpBuf) {
fclose( fp );
return( FALSE );
}
cbRead = fread( lpBuf, 1, CCH_READ_MAX, fp );
result = (BOOLEAN) (*OptionalIsTextUnicode)( lpBuf, cbRead, &value );
fclose( fp );
free( lpBuf );
return( result );
}
BOOLEAN
MyIsDBCSLeadByte(UCHAR c)
{
int i;
CPINFO* PCPInfo = &CPInfo;
if (PCPInfo == NULL) {
return FALSE;
}
if (!PCPInfo->MaxCharSize) {
return(IsDBCSLeadByte(c));
}
if (PCPInfo->MaxCharSize == 1) {
return FALSE;
}
for (i=0 ; i<MAX_LEADBYTES ; i+=2) {
if (PCPInfo->LeadByte[i] == 0 && PCPInfo->LeadByte[i+1] == 0)
return FALSE;
if (c >= PCPInfo->LeadByte[i] && c <= PCPInfo->LeadByte[i+1])
return TRUE;
}
return FALSE;
}
WCHAR *
fgetsW (WCHAR * string, long count, FILE * fp)
{
UCHAR ch[2];
WCHAR *pch = string;
DWORD nBytesRead;
assert (string != NULL);
assert (fp != NULL);
if (count <= 0)
return (NULL);
while (--count) {
if (UnicodeInput) {
nBytesRead = fread (ch, 1, sizeof(WCHAR), fp);
} else {
nBytesRead = fread (ch, 1, 1, fp);
ch[1] = '\0';
}
//
// if there are no more characters, end the line
//
if (feof (fp)) {
if (pch == string)
return (NULL);
break;
}
if (ch[0] < 128 || UnicodeInput) {
*pch = *(WCHAR*)&ch[0];
} else if (MyIsDBCSLeadByte(ch[0])) {
nBytesRead = fread (&ch[1], 1, 1, fp);
MultiByteToWideChar(CurrentLanguageName->CodePage, 0, ch, 2, pch, 1);
} else {
MultiByteToWideChar(CurrentLanguageName->CodePage, 0, ch, 1, pch, 1);
}
pch++;
if (*(pch-1) == L'\n') {
break;
}
}
*pch = L'\0';
return (string);
}