|
|
/****************************************************************************/ /* */ /* rcutil.C - */ /* */ /* Windows 3.0 Resource Compiler - Utility Functions */ /* */ /* */ /****************************************************************************/
#include "rc.h"
/*---------------------------------------------------------------------------*/ /* */ /* MyAlloc() - */ /* */ /*---------------------------------------------------------------------------*/
// HACK Alert. Allocate an extra longlong and return past it (to allow for PREVCH()
// to store a byte before the allocation block and to maintain 8 byte alignment).
VOID * MyAlloc( UINT nbytes ) { PVOID s;
if ((s = HeapAlloc(hHeap, HEAP_NO_SERIALIZE|HEAP_ZERO_MEMORY, nbytes+8)) != NULL) { return(((PCHAR)s)+8); } else { SET_MSG(Msg_Text, sizeof(Msg_Text), GET_MSG(1120), nbytes); quit(Msg_Text); } return NULL; }
/*---------------------------------------------------------------------------*/ /* */ /* MyFree() - */ /* */ /*---------------------------------------------------------------------------*/
VOID * MyFree( VOID *p ) { if (p) { HeapFree(hHeap, HEAP_NO_SERIALIZE, ((PCHAR)p)-8); }
return(NULL); }
/*---------------------------------------------------------------------------*/ /* */ /* MyMakeStr() - */ /* */ /*---------------------------------------------------------------------------*/
WCHAR * MyMakeStr( WCHAR *s ) { WCHAR * s1;
if (s) { s1 = (WCHAR *) MyAlloc((wcslen(s) + 1) * sizeof(WCHAR)); /* allocate buffer */ wcscpy(s1, s); /* copy string */ } else { s1 = s; }
return(s1); }
/*---------------------------------------------------------------------------*/ /* */ /* MyRead() - */ /* */ /*---------------------------------------------------------------------------*/
UINT MyRead( FILE *fh, VOID *p, UINT n ) { UINT n1;
n1 = fread(p, 1, (size_t)n, fh); if (ferror (fh)) { quit(GET_MSG(1121)); return 0; } else { return(n1); } }
/*---------------------------------------------------------------------------*/ /* */ /* MyWrite() - */ /* */ /*---------------------------------------------------------------------------*/
UINT MyWrite( FILE *fh, VOID *p, UINT n ) { UINT n1;
if ((n1 = fwrite(p, 1, n, fh)) != n) { quit("RC : fatal error RW1022: I/O error writing file."); return (0); } else { return(n1); } }
/*---------------------------------------------------------------------------*/ /* */ /* MyAlign() - */ /* */ /*---------------------------------------------------------------------------*/
UINT MyAlign( PFILE fh ) { DWORD t0 = 0; DWORD ib;
/* align file to dword */ ib = MySeek(fh, 0L, SEEK_CUR); if (ib % 4) { ib = 4 - ib % 4; MyWrite(fh, (PVOID)&t0, (UINT)ib); return(ib); } return(0); }
/*---------------------------------------------------------------------------*/ /* */ /* MySeek() - */ /* */ /*---------------------------------------------------------------------------*/
LONG MySeek( FILE *fh, LONG pos, int cmd ) { if (fseek(fh, pos, cmd)) quit("RC : fatal error RW1023: I/O error seeking in file"); if ((pos = ftell (fh)) == -1L) quit("RC : fatal error RW1023: I/O error seeking in file"); return(pos); }
/*---------------------------------------------------------------------------*/ /* */ /* MyCopy() - */ /* */ /*---------------------------------------------------------------------------*/
int MyCopy( FILE *srcfh, PFILE dstfh, ULONG nbytes ) { PCHAR buffer = (PCHAR) MyAlloc(BUFSIZE);
UINT n;
while (nbytes) { if (nbytes <= BUFSIZE) n = (UINT)nbytes; else n = BUFSIZE; nbytes -= n;
MyRead(srcfh, buffer, n); MyWrite( dstfh, buffer, n); }
MyFree(buffer);
return(n); }
/*---------------------------------------------------------------------------*/ /* */ /* MyCopyAll() - */ /* */ /*---------------------------------------------------------------------------*/
int MyCopyAll( FILE *srcfh, PFILE dstfh ) { PCHAR buffer = (PCHAR) MyAlloc(BUFSIZE);
UINT n;
while ((n = fread(buffer, 1, BUFSIZE, srcfh)) != 0) MyWrite(dstfh, buffer, n);
MyFree(buffer);
return TRUE; }
/*---------------------------------------------------------------------------*/ /* */ /* strpre() - */ /* */ /*---------------------------------------------------------------------------*/
/* strpre: return -1 if pch1 is a prefix of pch2, 0 otherwise.
* compare is case insensitive. */
int strpre( PWCHAR pch1, PWCHAR pch2 ) { while (*pch1) { if (!*pch2) return 0; else if (towupper(*pch1) == towupper(*pch2)) pch1++, pch2++; else return 0; } return - 1; }
/*---------------------------------------------------------------------------*/ /* */ /* iswhite() - */ /* */ /*---------------------------------------------------------------------------*/
int iswhite ( WCHAR c ) { /* returns true for whitespace and linebreak characters */ switch (c) { case L' ': case L'\t': case L'\r': case L'\n': case EOF: return(-1); break; default: return(0); break; } }
/*---------------------------------------------------------------------------*/ /* */ /* IsSwitchChar() - */ /* */ /*---------------------------------------------------------------------------*/
BOOL IsSwitchChar( CHAR c ) { /* true for switch characters */ return (c == '/' || c == '-'); }
/*---------------------------------------------------------------------------*/ /* */ /* searchenv() - */ /* */ /*---------------------------------------------------------------------------*/
/* the _searchenv() function in the C5.0 RTL doesn't work. In particular,
* it fails to check for \ characters and can end up returning paths like * D:\\FILE.EXT. szActual is assumed to be at least MAX_PATH and will * always get walked all over */
VOID searchenv( PCHAR szFile, PCHAR szVar, PCHAR szActual ) { PCHAR pchVar; PCHAR pch; int ich; PFILE fhTemp;
if (!strcmp(szVar, "INCLUDE")) pchVar = pchInclude; else pchVar = getenv(szVar);
if (!pchVar) return;
/* we don't do absolute paths */ if (szFile[0] == '\\' || szFile[0] == '/' || szFile[1] == ':') { for (ich = 0; szActual[ich] = szFile[ich]; ich++) ; return; }
do { /* copy the next environment string... */ for (ich = 0; (szActual[ich] = pchVar[ich]) != '\000'; ich++) if (pchVar[ich] == ';') break; szActual[ich] = '\000'; pchVar += ich; if (*pchVar) pchVar++;
/* HARD LOOP -- find end of path string */ for (pch = szActual; *pch; pch++) ;
/* check first! this is what _searchenv() messed up! */ if (pch[-1] != '\\' && pch[-1] != '/') *pch++ = '\\';
/* HARD LOOP -- we already know szFile does start with a drive or abs. dir */ for (ich = 0; pch[ich] = szFile[ich]; ich++) ;
/* is the file here? szActual already contains name */ if ((fhTemp = fopen(szActual, "rb")) != NULL) { fclose (fhTemp); return; } } while (szActual[0] && *pchVar);
/* if we reach here, we know szActual is empty */ return;
}
/*---------------------------------------------------------------------------*/ /* */ /* ExtractFileName(szFullName, szFileName) - */ /* */ /* This routine is used to extract just the file name from a string */ /* that may or may not contain a full or partial path name. */ /* */ /*---------------------------------------------------------------------------*/
VOID ExtractFileName( PWCHAR szFullName, PWCHAR szFileName ) { int iLen; PWCHAR pCh;
iLen = wcslen(szFullName);
/* Goto the last character of the full name; */ pCh = (PWCHAR)(szFullName + iLen); pCh--;
/* Look for '/', '\\' or ':' character */ while (iLen--) { if ((*pCh == L'\\') || (*pCh == L'/') || (*pCh == L':')) break; pCh--; }
wcscpy(szFileName, ++pCh); }
DWORD wcsatoi( WCHAR *s ) { DWORD t = 0;
while (*s) { t = 10 * t + (DWORD)((CHAR)*s - '0'); s++; } return t; }
WCHAR * wcsitow( LONG v, WCHAR *s, DWORD r ) { DWORD cb = 0; DWORD t; DWORD tt = v;
while (tt) { t = tt % r; cb++; tt /= r; }
s += cb; *s-- = 0; while (v) { t = v % r; *s-- = (WCHAR)((CHAR)t + '0'); v /= r; } return ++s; }
// ----------------------------------------------------------------------------
//
// PreBeginParse
//
// ----------------------------------------------------------------------------
VOID PreBeginParse( PRESINFO pRes, int id ) { while (token.type != BEGIN) { switch (token.type) { case TKLANGUAGE: pRes->language = GetLanguage(); break;
case TKVERSION: GetToken(FALSE); if (token.type != NUMLIT) ParseError1(2139); pRes->version = token.longval; break;
case TKCHARACTERISTICS: GetToken(FALSE); if (token.type != NUMLIT) ParseError1(2140); pRes->characteristics = token.longval; break;
default: ParseError1(id); break; } GetToken(FALSE); }
if (token.type != BEGIN) ParseError1(id);
GetToken(TRUE); }
|