Windows-Server-2003/sdktools/rcdll/rc.c

1069 lines
28 KiB
C

/***********************************************************************
* Microsoft (R) Windows (R) Resource Compiler
*
* Copyright (c) Microsoft Corporation. All rights reserved.
*
* File Comments:
*
*
***********************************************************************/
#include "rc.h"
#include <setjmp.h>
#include <ddeml.h>
#define READ_MAX (MAXSTR+80)
#define MAX_CMD 256
#define cDefineMax 100
wchar_t resname[_MAX_PATH];
wchar_t *szRCPP[MAX_CMD];
BOOL fRcppAlloc[MAX_CMD];
/************************************************************************/
/* Define Global Variables */
/************************************************************************/
int __cdecl rcpp_main(int, wchar_t *[]);
SHORT ResCount; /* number of resources */
PTYPEINFO pTypInfo;
SHORT nFontsRead;
FONTDIR *pFontList;
FONTDIR *pFontLast;
TOKEN token;
int errorCount;
WCHAR tokenbuf[ MAXSTR + 1 ];
wchar_t exename[ _MAX_PATH ];
wchar_t fullname[ _MAX_PATH ];
wchar_t curFile[ _MAX_PATH ];
HANDLE hHeap = NULL;
PDLGHDR pLocDlg;
UINT mnEndFlagLoc; /* patch location for end of a menu. */
/* we set the high order bit there */
/* BOOL fLeaveFontDir; */
BOOL fVerbose; /* verbose mode (-v) */
BOOL fAFXSymbols;
BOOL fMacRsrcs;
BOOL fAppendNull;
BOOL fWarnInvalidCodePage;
BOOL fSkipDuplicateCtlIdWarning;
long lOffIndex;
WORD idBase;
BOOL fPreprocessOnly;
wchar_t szBuf[_MAX_PATH * 2];
wchar_t szPreProcessName[_MAX_PATH];
/* File global variables */
wchar_t inname[_MAX_PATH];
wchar_t *szTempFileName;
wchar_t *szTempFileName2;
PFILE fhBin;
PFILE fhInput;
/* array for include path stuff, initially empty */
wchar_t *pchInclude;
/* Substitute font name */
int nBogusFontNames;
WCHAR *pszBogusFontNames[16];
WCHAR szSubstituteFontName[MAXTOKSTR];
static jmp_buf jb;
extern ULONG lCPPTotalLinenumber;
/* Function prototypes for local functions */
HANDLE RCInit(void);
void RC_PreProcess(const wchar_t *);
void CleanUpFiles(void);
/*---------------------------------------------------------------------------*/
/* */
/* rc_main() - */
/* */
/*---------------------------------------------------------------------------*/
int __cdecl
rc_main(
int argc,
wchar_t *argv[],
char *argvA[]
)
{
wchar_t *r;
wchar_t *x;
wchar_t *s1;
wchar_t *s2;
wchar_t *s3;
int n;
wchar_t *pchIncludeT;
ULONG cchIncludeMax;
int fInclude = TRUE; /* by default, search INCLUDE */
int fIncludeCurrentFirst = TRUE; /* by default, add current dir to start of includes */
int cDefine = 0;
int cUnDefine = 0;
wchar_t *pszDefine[cDefineMax];
wchar_t *pszUnDefine[cDefineMax];
wchar_t szDrive[_MAX_DRIVE];
wchar_t szDir[_MAX_DIR];
wchar_t szFName[_MAX_FNAME];
wchar_t szExt[_MAX_EXT];
wchar_t szFullPath[_MAX_PATH];
wchar_t szIncPath[_MAX_PATH];
wchar_t buf[10];
wchar_t *szRC;
wchar_t **ppargv;
BOOL *pfRcppAlloc;
int rcpp_argc;
/* Set up for this run of RC */
if (_setjmp(jb)) {
return Nerrors;
}
hHeap = RCInit();
if (hHeap == NULL) {
fatal(1120, 0x01000000);
}
if (argvA != NULL) {
argv = UnicodeCommandLine(argc, argvA);
}
pchInclude = pchIncludeT = (wchar_t *) MyAlloc(_MAX_PATH * 2 * sizeof(wchar_t));
cchIncludeMax = _MAX_PATH*2;
szRC = argv[0];
/* process the command line switches */
while ((argc > 1) && (IsSwitchChar(*argv[1]))) {
switch (towupper(argv[1][1])) {
case L'?':
case L'H':
// Print out help, and quit
SendWarning(L"\n");
SET_MSG(10001, LVER_PRODUCTVERSION_STR);
SendWarning(Msg_Text);
SET_MSG(10002);
SendWarning(Msg_Text);
SET_MSG(20001);
SendWarning(Msg_Text);
return 0; /* can just return - nothing to cleanup, yet. */
case L'B':
if (towupper(argv[1][2]) == L'R') { /* base resource id */
unsigned long id;
if (isdigit(argv[1][3]))
argv[1] += 3;
else if (argv[1][3] == L':')
argv[1] += 4;
else {
argc--;
argv++;
if (argc <= 1)
goto BadId;
}
if (*(argv[1]) == 0)
goto BadId;
id = _wtoi(argv[1]);
if (id < 1 || id > 32767)
fatal(1210);
idBase = (WORD)id;
break;
BadId:
fatal(1209);
}
break;
case L'C':
/* Check for the existence of CodePage Number */
if (argv[1][2])
argv[1] += 2;
else {
argc--;
argv++;
}
/* Now argv point to first digit of CodePage */
if (!argv[1])
fatal(1204);
uiCodePage = _wtoi(argv[1]);
if (uiCodePage == 0)
fatal(1205);
/* Check if uiCodePage exist in registry. */
if (!IsValidCodePage (uiCodePage))
fatal(1206);
break;
case L'D':
/* if not attached to switch, skip to next */
if (argv[1][2])
argv[1] += 2;
else {
argc--;
argv++;
}
/* remember pointer to string */
pszDefine[cDefine++] = argv[1];
if (cDefine > cDefineMax) {
fatal(1105, argv[1]);
}
break;
case L'F':
switch (towupper(argv[1][2])) {
case L'O':
if (argv[1][3])
argv[1] += 3;
else {
argc--;
argv++;
}
if (argc > 1)
wcscpy(resname, argv[1]);
else
fatal(1101);
break;
default:
fatal(1103, argv[1]);
}
break;
case L'I':
/* add string to directories to search */
/* note: format is <path>\0<path>\0\0 */
/* if not attached to switch, skip to next */
if (argv[1][2])
argv[1] += 2;
else {
argc--;
argv++;
}
if (!argv[1])
fatal(1201);
if ((wcslen(argv[1]) + 1 + wcslen(pchInclude)) >= cchIncludeMax) {
cchIncludeMax = wcslen(pchInclude) + wcslen(argv[1]) + _MAX_PATH*2;
pchIncludeT = (wchar_t *) MyAlloc(cchIncludeMax * sizeof(wchar_t));
wcscpy(pchIncludeT, pchInclude);
MyFree(pchInclude);
pchInclude = pchIncludeT;
pchIncludeT = pchInclude + wcslen(pchIncludeT) + 1;
}
/* if not first switch, write over terminator with semicolon */
if (pchInclude != pchIncludeT)
pchIncludeT[-1] = L';';
/* copy the path */
while ((*pchIncludeT++ = *argv[1]++) != 0)
;
break;
case L'L':
/* if not attached to switch, skip to next */
if (argv[1][2])
argv[1] += 2;
else {
argc--;
argv++;
}
if (!argv[1])
fatal(1202);
if (swscanf(argv[1], L"%x", &language) != 1)
fatal(1203);
while (*argv[1]++ != 0)
;
break;
case L'M':
fMacRsrcs = TRUE;
goto MaybeMore;
case L'N':
fAppendNull = TRUE;
goto MaybeMore;
case L'P':
fPreprocessOnly = TRUE;
break;
case L'R':
goto MaybeMore;
case L'S':
// find out from BRAD what -S does
fAFXSymbols = TRUE;
break;
case L'U':
/* if not attached to switch, skip to next */
if (argv[1][2])
argv[1] += 2;
else {
argc--;
argv++;
}
/* remember pointer to string */
pszUnDefine[cUnDefine++] = argv[1];
if (cUnDefine > cDefineMax) {
fatal(1104, argv[1]);
}
break;
case L'V':
fVerbose = TRUE; // AFX doesn't set this
goto MaybeMore;
case L'W':
fWarnInvalidCodePage = TRUE; // Invalid Codepage is a warning, not an error.
goto MaybeMore;
case L'Y':
fSkipDuplicateCtlIdWarning = TRUE;
goto MaybeMore;
case L'X':
/* remember not to add INCLUDE path */
fInclude = FALSE;
// VC seems to feel the current dir s/b added first no matter what...
// If -X! is specified, don't do that.
if (argv[1][2] == L'!') {
fIncludeCurrentFirst = FALSE;
argv[1]++;
}
MaybeMore: /* check to see if multiple switches, like -xrv */
if (argv[1][2]) {
argv[1][1] = L'-';
argv[1]++;
continue;
}
break;
case L'Z':
/* if not attached to switch, skip to next */
if (argv[1][2])
argv[1] += 2;
else {
argc--;
argv++;
}
if (!argv[1])
fatal(1211);
s3 = wcschr(argv[1], L'/');
if (s3 == NULL)
fatal(1212);
*s3 = L'\0';
wcscpy(szSubstituteFontName, s3+1);
s1 = argv[1];
do {
s2 = wcschr(s1, L',');
if (s2 != NULL)
*s2 = L'\0';
if (wcslen(s1)) {
if (nBogusFontNames >= 16)
fatal(1213);
pszBogusFontNames[nBogusFontNames] = (WCHAR *) MyAlloc((wcslen(s1)+1) * sizeof(WCHAR));
wcscpy(pszBogusFontNames[nBogusFontNames], s1);
nBogusFontNames += 1;
}
if (s2 != NULL)
*s2++ = L',';
}
while (s1 = s2);
*s3 = L'/';
while (*argv[1]++ != 0)
;
break;
default:
fatal(1106, argv[1]);
}
/* get next argument or switch */
argc--;
argv++;
}
/* make sure we have at least one file name to work with */
if (argc != 2 || *argv[1] == L'\0')
fatal(1107);
if (fVerbose) {
SET_MSG(10001, LVER_PRODUCTVERSION_STR);
SendWarning(Msg_Text);
SET_MSG(10002);
SendWarning(Msg_Text);
SendWarning(L"\n");
}
// Support Multi Code Page
// If user did NOT indicate code in command line, we have to set Default
// for NLS Conversion
if (uiCodePage == 0) {
CHAR *pchCodePageString;
/* At first, search ENVIRONMENT VALUE */
if ((pchCodePageString = getenv("RCCODEPAGE")) != NULL) {
uiCodePage = atoi(pchCodePageString);
if (uiCodePage == 0 || !IsValidCodePage(uiCodePage)) {
fatal(1207);
}
} else {
// We use System ANSI Code page (ACP)
uiCodePage = GetACP();
}
}
uiDefaultCodePage = uiCodePage;
if (fVerbose) {
wprintf(L"Using codepage %d as default\n", uiDefaultCodePage);
}
/* If we have no extension, assumer .rc */
/* If .res extension, make sure we have -fo set, or error */
/* Otherwise, just assume file is .rc and output .res (or resname) */
_wsplitpath(argv[1], szDrive, szDir, szFName, szExt);
if (!(*szDir || *szDrive)) {
wcscpy(szIncPath, L".;");
} else {
wcscpy(szIncPath, szDrive);
wcscat(szIncPath, szDir);
wcscat(szIncPath, L";.;");
}
if ((wcslen(szIncPath) + 1 + wcslen(pchInclude)) >= cchIncludeMax) {
cchIncludeMax = wcslen(pchInclude) + wcslen(szIncPath) + _MAX_PATH*2;
pchIncludeT = (wchar_t *) MyAlloc(cchIncludeMax * sizeof(wchar_t));
wcscpy(pchIncludeT, pchInclude);
MyFree(pchInclude);
pchInclude = pchIncludeT;
pchIncludeT = pchInclude + wcslen(pchIncludeT) + 1;
}
pchIncludeT = (wchar_t *) MyAlloc(cchIncludeMax * sizeof(wchar_t));
if (fIncludeCurrentFirst) {
wcscpy(pchIncludeT, szIncPath);
wcscat(pchIncludeT, pchInclude);
} else {
wcscpy(pchIncludeT, pchInclude);
wcscat(pchIncludeT, L";");
wcscat(pchIncludeT, szIncPath);
}
MyFree(pchInclude);
pchInclude = pchIncludeT;
pchIncludeT = pchInclude + wcslen(pchIncludeT) + 1;
if (!szExt[0]) {
wcscpy(szExt, L".RC");
} else if (wcscmp(szExt, L".RES") == 0) {
fatal(1208);
}
_wmakepath(inname, szDrive, szDir, szFName, szExt);
if (fPreprocessOnly) {
_wmakepath(szPreProcessName, NULL, NULL, szFName, L".rcpp");
}
/* Create the name of the .RES file */
if (resname[0] == 0) {
// if building a Mac resource file, we use .rsc to match mrc's output
_wmakepath(resname, szDrive, szDir, szFName, fMacRsrcs ? L".RSC" : L".RES");
}
/* create the temporary file names */
szTempFileName = (wchar_t *) MyAlloc(_MAX_PATH * sizeof(wchar_t));
_wfullpath(szFullPath, resname, _MAX_PATH);
_wsplitpath(szFullPath, szDrive, szDir, NULL, NULL);
_wmakepath(szTempFileName, szDrive, szDir, L"RCXXXXXX", NULL);
_wmktemp (szTempFileName);
szTempFileName2 = (wchar_t *) MyAlloc(_MAX_PATH * sizeof(wchar_t));
_wmakepath(szTempFileName2, szDrive, szDir, L"RDXXXXXX", NULL);
_wmktemp(szTempFileName2);
ppargv = szRCPP;
pfRcppAlloc = fRcppAlloc;
*ppargv++ = L"RCPP";
*pfRcppAlloc++ = FALSE;
rcpp_argc = 1;
/* Open the .RES file (deleting any old versions which exist). */
if ((fhBin = _wfopen(resname, L"w+b")) == NULL) {
fatal(1109, resname);
}
if (fMacRsrcs)
MySeek(fhBin, MACDATAOFFSET, 0);
if (fVerbose) {
SET_MSG(10102, resname);
SendWarning(Msg_Text);
}
/* Set up for RCPP. This constructs the command line for it. */
*ppargv++ = _wcsdup(L"-CP");
*pfRcppAlloc++ = TRUE;
rcpp_argc++;
_itow(uiCodePage, buf, 10);
*ppargv++ = buf;
*pfRcppAlloc++ = FALSE;
rcpp_argc++;
*ppargv++ = _wcsdup(L"-f");
*pfRcppAlloc++ = TRUE;
rcpp_argc++;
*ppargv++ = _wcsdup(szTempFileName);
*pfRcppAlloc++ = TRUE;
rcpp_argc++;
*ppargv++ = _wcsdup(L"-g");
*pfRcppAlloc++ = TRUE;
rcpp_argc++;
if (fPreprocessOnly) {
*ppargv++ = _wcsdup(szPreProcessName);
} else {
*ppargv++ = _wcsdup(szTempFileName2);
}
*pfRcppAlloc++ = TRUE;
rcpp_argc++;
*ppargv++ = _wcsdup(L"-DRC_INVOKED");
*pfRcppAlloc++ = TRUE;
rcpp_argc++;
if (fAFXSymbols) {
*ppargv++ = _wcsdup(L"-DAPSTUDIO_INVOKED");
*pfRcppAlloc++ = TRUE;
rcpp_argc++;
}
if (fMacRsrcs) {
*ppargv++ = _wcsdup(L"-D_MAC");
*pfRcppAlloc++ = TRUE;
rcpp_argc++;
}
*ppargv++ = _wcsdup(L"-D_WIN32"); /* to be compatible with C9/VC++ */
*pfRcppAlloc++ = TRUE;
rcpp_argc++;
*ppargv++ = _wcsdup(L"-pc\\:/");
*pfRcppAlloc++ = TRUE;
rcpp_argc++;
*ppargv++ = _wcsdup(L"-E");
*pfRcppAlloc++ = TRUE;
rcpp_argc++;
/* Parse the INCLUDE environment variable */
if (fInclude) {
*ppargv++ = _wcsdup(L"-I.");
*pfRcppAlloc++ = TRUE;
rcpp_argc++;
/* add seperator if any -I switches */
if (pchInclude != pchIncludeT)
pchIncludeT[-1] = L';';
/* read 'em */
x = _wgetenv(L"INCLUDE");
if (x == NULL) {
*pchIncludeT = L'\0';
} else {
if (wcslen(pchInclude) + wcslen(x) + 1 >= cchIncludeMax) {
cchIncludeMax = wcslen(pchInclude) + wcslen(x) + _MAX_PATH*2;
pchIncludeT = (wchar_t *) MyAlloc(cchIncludeMax * sizeof(wchar_t));
wcscpy(pchIncludeT, pchInclude);
MyFree(pchInclude);
pchInclude = pchIncludeT;
}
wcscat(pchInclude, x);
pchIncludeT = pchInclude + wcslen(pchInclude);
}
}
/* now put includes on the RCPP command line */
for (x = pchInclude ; *x ; ) {
r = x;
while (*x && *x != L';')
x = CharNextW(x);
/* mark if semicolon */
if (*x)
*x-- = 0;
if (*r != L'\0' && /* empty include path? */
*r != L'%' /* check for un-expanded stuff */
// && wcschr(r, L' ') == NULL /* check for whitespace */
) {
/* add switch */
*ppargv++ = _wcsdup(L"-I");
*pfRcppAlloc++ = TRUE;
rcpp_argc++;
*ppargv++ = _wcsdup(r);
*pfRcppAlloc++ = TRUE;
rcpp_argc++;
}
/* was semicolon, need to fix for searchenv() */
if (*x) {
*++x = L';';
x++;
}
}
/* include defines */
for (n = 0; n < cDefine; n++) {
*ppargv++ = _wcsdup(L"-D");
*pfRcppAlloc++ = TRUE;
rcpp_argc++;
*ppargv++ = pszDefine[n];
*pfRcppAlloc++ = FALSE;
rcpp_argc++;
}
/* include undefine */
for (n = 0; n < cUnDefine; n++) {
*ppargv++ = _wcsdup(L"-U");
*pfRcppAlloc++ = TRUE;
rcpp_argc++;
*ppargv++ = pszUnDefine[n];
*pfRcppAlloc++ = FALSE;
rcpp_argc++;
}
if (rcpp_argc > MAX_CMD) {
fatal(1102);
}
if (fVerbose) {
/* echo the preprocessor command */
wprintf(L"RC:");
for (n = 0 ; n < rcpp_argc ; n++) {
wprintf(L" %s", szRCPP[n]);
}
wprintf(L"\n");
}
/* Add .rc with rcincludes into szTempFileName */
RC_PreProcess(inname);
/* Run the Preprocessor. */
if (rcpp_main(rcpp_argc, szRCPP) != 0)
fatal(1116);
// All done. Now free up the argv array.
for (n = 0 ; n < rcpp_argc ; n++) {
if (fRcppAlloc[n] == TRUE) {
free(szRCPP[n]);
}
}
if (fPreprocessOnly) {
swprintf(szBuf, L"Preprocessed file created in: %s\n", szPreProcessName);
quit(szBuf);
}
if (fVerbose)
wprintf(L"\n%s", inname);
if ((fhInput = _wfopen(szTempFileName2, L"rb")) == NULL_FILE)
fatal(2180);
if (!InitSymbolInfo())
fatal(22103);
LexInit (fhInput);
uiCodePage = uiDefaultCodePage;
ReadRF(); /* create .RES from .RC */
if (!TermSymbolInfo(fhBin))
fatal(22204);
if (!fMacRsrcs)
MyAlign(fhBin); // Pad end of file so that we can concatenate files
CleanUpFiles();
HeapDestroy(hHeap);
return Nerrors; // return success, not quitting.
}
/* RCInit
* Initializes this run of RC.
*/
HANDLE
RCInit(
void
)
{
Nerrors = 0;
uiCodePage = 0;
nFontsRead = 0;
szTempFileName = NULL;
szTempFileName2 = NULL;
lOffIndex = 0;
idBase = 128;
pTypInfo = NULL;
fVerbose = FALSE;
fMacRsrcs = FALSE;
// Clear the filenames
exename[0] = L'\0';
resname[0] = L'\0';
/* create growable local heap of 16MB minimum size */
return HeapCreate(HEAP_NO_SERIALIZE, 0, 0);
}
/*---------------------------------------------------------------------------*/
/* */
/* skipblanks() - */
/* */
/*---------------------------------------------------------------------------*/
wchar_t *
skipblanks(
wchar_t *pstr,
int fTerminate
)
{
/* search forward for first non-white character and save its address */
while (*pstr && iswspace(*pstr))
pstr++;
if (fTerminate) {
wchar_t *retval = pstr;
/* search forward for first white character and zero to extract word */
while (*pstr && !iswspace(*pstr))
pstr++;
*pstr = 0;
return retval;
} else {
return pstr;
}
}
/*---------------------------------------------------------------------------*/
/* */
/* RC_PreProcess() - */
/* */
/*---------------------------------------------------------------------------*/
void
RC_PreProcess(
const wchar_t *szname
)
{
PFILE fhout; /* fhout: is temp file with rcincluded stuff */
PFILE fhin;
wchar_t *wch_buf;
wchar_t *pwch;
wchar_t *pfilename;
wchar_t *szT;
UINT iLine = 0;
int fBlanks = TRUE;
INT fFileType;
wch_buf = (wchar_t *)MyAlloc(sizeof(wchar_t) * READ_MAX);
szT = (wchar_t *)MyAlloc(sizeof(wchar_t) * MAXSTR);
/* Open the .RC source file. */
wcscpy(Filename, szname);
fhin = _wfopen(szname, L"rb");
if (!fhin) {
fatal(1110, szname);
}
/* Open the temporary output file. */
fhout = _wfopen(szTempFileName, L"w+b");
if (!fhout) {
fatal(2180);
}
/* output the current filename for RCPP messages */
for (pwch=wch_buf ; *szname ; szname++) {
*pwch++ = *szname;
/* Hack to fix bug #8786: makes '\' to "\\" */
if (*szname == L'\\')
*pwch++ = L'\\';
}
*pwch++ = L'\0';
/* Output the current filename for RCPP messages */
MyWrite(fhout, L"#line 1\"", 8 * sizeof(wchar_t));
MyWrite(fhout, wch_buf, wcslen(wch_buf) * sizeof(wchar_t));
MyWrite(fhout, L"\"\r\n", 3 * sizeof(wchar_t));
/* Determine if the input file is Unicode */
fFileType = DetermineFileType (fhin);
/* Process each line of the input file. */
while (fgetl(wch_buf, READ_MAX, fFileType == DFT_FILE_IS_16_BIT, fhin)) {
/* keep track of the number of lines read */
Linenumber = iLine++;
if ((iLine & RC_PREPROCESS_UPDATE) == 0)
UpdateStatus(1, iLine);
/* Skip the Byte Order Mark and the leading bytes. */
pwch = wch_buf;
while (*pwch && (iswspace(*pwch) || *pwch == 0xFEFF))
pwch++;
/* if the line is a rcinclude line... */
if (strpre(L"rcinclude", pwch)) {
/* Get the name of the rcincluded file. */
pfilename = skipblanks(pwch + 9, TRUE);
MyWrite(fhout, L"#include \"", 10 * sizeof(WCHAR));
MyWrite(fhout, pfilename, wcslen(pfilename) * sizeof(WCHAR));
MyWrite(fhout, L"\"\r\n", 3 * sizeof(WCHAR));
} else if (strpre(L"#pragma", pwch)) {
WCHAR cSave;
pfilename = skipblanks(pwch + 7, FALSE);
if (strpre(L"code_page", pfilename)) {
pfilename = skipblanks(pfilename + 9, FALSE);
if (*pfilename == L'(') {
ULONG cp = 0;
pfilename = skipblanks(pfilename + 1, FALSE);
// really should allow hex/octal, but ...
if (iswdigit(*pfilename)) {
while (iswdigit(*pfilename)) {
cp = cp * 10 + (*pfilename++ - L'0');
}
pfilename = skipblanks(pfilename, FALSE);
} else if (strpre(L"default", pfilename)) {
cp = uiDefaultCodePage;
pfilename = skipblanks(pfilename + 7, FALSE);
}
if (cp == 0) {
error(4212, pfilename);
} else if (*pfilename != L')') {
error(4211);
} else if (cp == CP_WINUNICODE) {
if (fWarnInvalidCodePage) {
warning(4213);
} else {
fatal(4213);
}
} else if (!IsValidCodePage(cp)) {
if (fWarnInvalidCodePage) {
warning(4214);
} else {
fatal(4214);
}
} else {
uiCodePage = cp;
/* Copy the #pragma line to the temp file. */
MyWrite(fhout, pwch, wcslen(pwch) * sizeof(WCHAR));
MyWrite(fhout, L"\r\n", 2 * sizeof(WCHAR));
}
} else {
error(4210);
}
}
} else if (!*pwch) {
fBlanks = TRUE;
} else {
if (fBlanks) {
swprintf(szT, L"#line %d\r\n", iLine);
MyWrite(fhout, szT, wcslen(szT) * sizeof(WCHAR));
fBlanks = FALSE;
}
/* Copy the .RC line to the temp file. */
MyWrite(fhout, pwch, wcslen(pwch) * sizeof(WCHAR));
MyWrite(fhout, L"\r\n", 2 * sizeof(WCHAR));
}
}
lCPPTotalLinenumber = iLine;
Linenumber = 0;
uiCodePage = uiDefaultCodePage;
MyFree(wch_buf);
MyFree(szT);
fclose(fhout);
fclose(fhin);
}
/*---------------------------------------------------------------------------*/
/* */
/* quit() */
/* */
/*---------------------------------------------------------------------------*/
void quit(const wchar_t *wsz)
{
/* print out the error message */
if (wsz != NULL) {
SendWarning(L"\n");
SendError(wsz);
SendWarning(L"\n");
}
CleanUpFiles();
/* delete output file */
if (resname) {
_wremove(resname);
}
if (hHeap) {
HeapDestroy(hHeap);
}
Nerrors++;
longjmp(jb, Nerrors);
}
extern "C"
BOOL WINAPI Handler(DWORD fdwCtrlType)
{
if (fdwCtrlType == CTRL_C_EVENT) {
SendWarning(L"\n");
SET_MSG(20101);
SendWarning(Msg_Text);
CleanUpFiles();
HeapDestroy(hHeap);
/* Delete output file */
if (resname) {
_wremove(resname);
}
return(FALSE);
}
return(FALSE);
}
VOID
CleanUpFiles(
void
)
{
TermSymbolInfo(NULL_FILE);
// Close ALL files.
if (fhBin != NULL) {
fclose(fhBin);
}
if (fhInput != NULL) {
fclose(fhInput);
}
if (fhCode != NULL) {
fclose(fhCode);
}
p0_terminate();
// Clean up after font directory temp file
if (nFontsRead) {
_wremove(L"rc$x.fdr");
}
// Delete the temporary files
if (szTempFileName) {
_wremove(szTempFileName);
}
if (szTempFileName2) {
_wremove(szTempFileName2);
}
if (Nerrors > 0) {
_wremove(resname);
}
}