677 lines
22 KiB
C
677 lines
22 KiB
C
|
/************************************************************************/
|
||
|
/* */
|
||
|
/* RCPP - Resource Compiler Pre-Processor for NT system */
|
||
|
/* */
|
||
|
/* P0IO.C - Input/Output for Preprocessor */
|
||
|
/* */
|
||
|
/* 27-Nov-90 w-BrianM Update for NT from PM SDK RCPP */
|
||
|
/* */
|
||
|
/************************************************************************/
|
||
|
|
||
|
#include "rc.h"
|
||
|
|
||
|
|
||
|
/************************************************************************/
|
||
|
/* Local Function Prototypes */
|
||
|
/************************************************************************/
|
||
|
PWCHAR esc_sequence(PWCHAR, PWCHAR);
|
||
|
|
||
|
|
||
|
#define TEXT_TYPE ptext_t
|
||
|
|
||
|
/*** ASSUME : the trailing marker byte is only 1 character. ***/
|
||
|
|
||
|
#define PUSHBACK_BYTES 1
|
||
|
|
||
|
#define TRAILING_BYTES 1
|
||
|
|
||
|
#define EXTRA_BYTES (PUSHBACK_BYTES + TRAILING_BYTES)
|
||
|
/*
|
||
|
** here are some defines for the new handling of io buffers.
|
||
|
** the buffer itself is 6k plus some extra bytes.
|
||
|
** the main source file uses all 6k.
|
||
|
** the first level of include files will use 4k starting 2k from the beginning.
|
||
|
** the 2nd level - n level will use 2k starting 4k from the beginning.
|
||
|
** this implies that some special handling may be necessary when we get
|
||
|
** overlapping buffers. (unless the source file itself is < 2k
|
||
|
** all the include files are < 2k and they do not nest more than 2 deep.)
|
||
|
** first, the source file is read into the buffer (6k at a time).
|
||
|
** at the first include file, (if the source from the parent file
|
||
|
** is more than 2k chars) . . .
|
||
|
** if the Current_char ptr is not pointing above the 2k boundary
|
||
|
** (which is the beginning of the buffer for the include file)
|
||
|
** then we pretend we've read in only 2k into the buffer and
|
||
|
** place the terminator at the end of the parents 2k buffer.
|
||
|
** else we pretend we've used up all chars in the parents buffer
|
||
|
** so the next read for the parent will be the terminator, and
|
||
|
** the buffer will get filled in the usual manner.
|
||
|
** (if we're in a macro, the picture is slightly different in that we have
|
||
|
** to update the 'real' source file pointer in the macro structure.)
|
||
|
**
|
||
|
** the first nested include file is handled in a similar manner. (except
|
||
|
** it starts up 4k away from the start.)
|
||
|
**
|
||
|
** any further nesting will keep overlaying the upper 2k part.
|
||
|
*/
|
||
|
#define IO_BLOCK (4 * 1024 + EXTRA_BYTES)
|
||
|
|
||
|
int vfCurrFileType = DFT_FILE_IS_UNKNOWN; //- Added for 16-bit file support.
|
||
|
|
||
|
extern expansion_t Macro_expansion[];
|
||
|
|
||
|
typedef struct s_filelist filelist_t;
|
||
|
static struct s_filelist { /* list of input files (nested) */
|
||
|
int fl_bufsiz; /* characters to read into the buffer */
|
||
|
FILE * fl_file; /* FILE id */
|
||
|
long fl_lineno; /* line number when file was pushed */
|
||
|
PWCHAR fl_name; /* previous file text name */
|
||
|
ptext_t fl_currc; /* ptr into our buffer for current c */
|
||
|
TEXT_TYPE fl_buffer; /* type of buffer */
|
||
|
int fl_numread; /* # of characters read from the file */
|
||
|
int fl_fFileType; //- Added for 16-bit file support.
|
||
|
//- return from DetermineFileType.
|
||
|
long fl_seek; //- Added for restart - contains seek
|
||
|
// address of last read.
|
||
|
} Fstack[LIMIT_NESTED_INCLUDES];
|
||
|
|
||
|
static FILE *Fp = NULL;
|
||
|
int Findex = -1;
|
||
|
|
||
|
|
||
|
/************************************************************************
|
||
|
* NEWINPUT - A new input file is to be opened, saving the old.
|
||
|
*
|
||
|
* ARGUMENTS
|
||
|
* WCHAR *newname - the name of the file
|
||
|
*
|
||
|
* RETURNS - none
|
||
|
*
|
||
|
* SIDE EFFECTS
|
||
|
* - causes input stream to be switched
|
||
|
* - Linenumber is reset to 1
|
||
|
* - storage is allocated for the newname
|
||
|
* - Filename is set to the new name
|
||
|
*
|
||
|
* DESCRIPTION
|
||
|
* The file is opened, and if successful, the current input stream is saved
|
||
|
* and the stream is switched to the new file. If the newname is NULL,
|
||
|
* then stdin is taken as the new input.
|
||
|
*
|
||
|
* AUTHOR - Ralph Ryan, Sept. 9, 1982
|
||
|
*
|
||
|
* MODIFICATIONS - none
|
||
|
*
|
||
|
************************************************************************/
|
||
|
int
|
||
|
newinput (
|
||
|
WCHAR *newname,
|
||
|
int m_open
|
||
|
)
|
||
|
{
|
||
|
filelist_t *pF;
|
||
|
WCHAR *p;
|
||
|
|
||
|
if( newname == NULL ) {
|
||
|
Fp = stdin;
|
||
|
}
|
||
|
else {
|
||
|
// Note: Always use the Ansi codepage here. uiCodePage may have been
|
||
|
// modified by a codepage pragma in the source file.
|
||
|
|
||
|
WideCharToMultiByte (GetACP(), 0, newname, -1, chBuf, sizeof(chBuf), NULL, NULL);
|
||
|
if((Fp = fopen(chBuf, "rb")) == NULL) {
|
||
|
if(m_open == MUST_OPEN) {
|
||
|
Msg_Temp = GET_MSG (1005);
|
||
|
SET_MSG (Msg_Text, sizeof(Msg_Text), Msg_Temp, chBuf);
|
||
|
fatal(1005);
|
||
|
}
|
||
|
return(FALSE);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/* now push it onto the file stack */
|
||
|
++Findex;
|
||
|
if(Findex >= LIMIT_NESTED_INCLUDES) {
|
||
|
Msg_Temp = GET_MSG (1014);
|
||
|
SET_MSG (Msg_Text, sizeof(Msg_Text), Msg_Temp, LIMIT_NESTED_INCLUDES);
|
||
|
fatal(1014);
|
||
|
}
|
||
|
pF = &Fstack[Findex];
|
||
|
p = (WCHAR *) MyAlloc((IO_BLOCK + PUSHBACK_BYTES) * sizeof(WCHAR));
|
||
|
if (!p) {
|
||
|
strcpy (Msg_Text, GET_MSG (1002));
|
||
|
fatal(1002); /* no memory */
|
||
|
return 0;
|
||
|
}
|
||
|
pF->fl_bufsiz = IO_BLOCK;
|
||
|
|
||
|
pF->fl_currc = Current_char; /* previous file's current char */
|
||
|
pF->fl_lineno = Linenumber; /* previous file's line number */
|
||
|
pF->fl_file = Fp; /* the new file descriptor */
|
||
|
pF->fl_buffer = p;
|
||
|
pF->fl_numread = 0;
|
||
|
pF->fl_seek = 0;
|
||
|
|
||
|
pF->fl_fFileType = DetermineFileType (Fp);
|
||
|
|
||
|
if (pF->fl_fFileType == DFT_FILE_IS_UNKNOWN) {
|
||
|
Msg_Temp = GET_MSG (4413);
|
||
|
SET_MSG (Msg_Text, sizeof(Msg_Text), Msg_Temp, newname);
|
||
|
warning (4413);
|
||
|
pF->fl_fFileType = DFT_FILE_IS_8_BIT;
|
||
|
}
|
||
|
|
||
|
vfCurrFileType = pF->fl_fFileType;
|
||
|
|
||
|
Current_char = p;
|
||
|
io_eob(); /* fill the buffer */
|
||
|
/*
|
||
|
* Note that include filenames will live the entire compiland. This
|
||
|
* puts the burden on the user with MANY include files. Any other
|
||
|
* scheme takes space out of static data.
|
||
|
* Notice also, that we save the previous filename in the new file's
|
||
|
* fl_name.
|
||
|
*/
|
||
|
pF->fl_name = pstrdup(Filename);
|
||
|
wcsncpy(Filebuff, newname, sizeof(Filebuff) / sizeof(WCHAR));
|
||
|
Linenumber = 0; /* do_newline() will increment to the first line */
|
||
|
if(Eflag) {
|
||
|
emit_line();
|
||
|
// must manually write '\r' with '\n' when writing 16-bit strings
|
||
|
myfwrite(L"\r\n", 2 * sizeof(WCHAR), 1, OUTPUTFILE); /* this line is inserted */
|
||
|
}
|
||
|
|
||
|
{
|
||
|
defn_t d;
|
||
|
int old_line = Linenumber;
|
||
|
Linenumber = Findex;
|
||
|
|
||
|
DEFN_IDENT(&d) = L"!";
|
||
|
DEFN_TEXT(&d) = Reuse_Include;
|
||
|
DEFN_NEXT(&d) = NULL;
|
||
|
DEFN_NFORMALS(&d) = 0;
|
||
|
DEFN_EXPANDING(&d) = FALSE;
|
||
|
AfxOutputMacroDefn(&d);
|
||
|
|
||
|
if (Findex > 0) {
|
||
|
DEFN_IDENT(&d) = L"$";
|
||
|
DEFN_TEXT(&d) = Filename;
|
||
|
DEFN_NEXT(&d) = NULL;
|
||
|
DEFN_NFORMALS(&d) = 0;
|
||
|
DEFN_EXPANDING(&d) = FALSE;
|
||
|
AfxOutputMacroDefn(&d);
|
||
|
}
|
||
|
|
||
|
Linenumber = old_line;
|
||
|
}
|
||
|
|
||
|
do_newline(); /* a new file may have preproc cmd as first line */
|
||
|
return(TRUE);
|
||
|
}
|
||
|
|
||
|
|
||
|
/************************************************************************
|
||
|
* FPOP - pop to a previous level of input stream
|
||
|
*
|
||
|
* ARGUMENTS - none
|
||
|
*
|
||
|
* RETURNS
|
||
|
* TRUE if successful, FALSE if the stack is empty
|
||
|
*
|
||
|
* SIDE EFFECTS
|
||
|
* - Linenumber is restored to the old files line number
|
||
|
* - Filename is reset to the old filename
|
||
|
* - frees storage allocated for filename
|
||
|
*
|
||
|
* DESCRIPTION
|
||
|
* Pop the top of the file stack, restoring the previous input stream.
|
||
|
*
|
||
|
* AUTHOR - Ralph Ryan, Sept. 9, 1982
|
||
|
*
|
||
|
* MODIFICATIONS - none
|
||
|
*
|
||
|
************************************************************************/
|
||
|
WCHAR
|
||
|
fpop(
|
||
|
void
|
||
|
)
|
||
|
{
|
||
|
int OldLine;
|
||
|
defn_t DefType;
|
||
|
|
||
|
if(Findex == -1) { /* no files left */
|
||
|
return(FALSE);
|
||
|
}
|
||
|
|
||
|
if (Fp)
|
||
|
fclose(Fp);
|
||
|
|
||
|
OldLine = Linenumber;
|
||
|
|
||
|
--Findex;
|
||
|
Linenumber = Findex;
|
||
|
|
||
|
DEFN_IDENT(&DefType) = L"!";
|
||
|
DEFN_TEXT(&DefType) = L"";
|
||
|
DEFN_NEXT(&DefType) = NULL;
|
||
|
DEFN_NFORMALS(&DefType) = 0;
|
||
|
DEFN_EXPANDING(&DefType) = FALSE;
|
||
|
AfxOutputMacroDefn(&DefType);
|
||
|
Findex++;
|
||
|
Linenumber = OldLine;
|
||
|
|
||
|
strappend(Filebuff,Fstack[Findex].fl_name);
|
||
|
OldLine = Linenumber;
|
||
|
Linenumber = (int)Fstack[Findex].fl_lineno;
|
||
|
Current_char = Fstack[Findex].fl_currc;
|
||
|
MyFree(Fstack[Findex].fl_buffer);
|
||
|
if(--Findex < 0) { /* popped the last file */
|
||
|
Linenumber = OldLine;
|
||
|
return(FALSE);
|
||
|
}
|
||
|
Fp = Fstack[Findex].fl_file;
|
||
|
vfCurrFileType = Fstack[Findex].fl_fFileType;
|
||
|
if(Eflag) {
|
||
|
// If the last file didn't end in a \r\n, the #line from emit_line could
|
||
|
// end up in whatever data structure it ended in... Emit a dummy newline
|
||
|
// just in case.
|
||
|
myfwrite(L"\r\n", 2 * sizeof(WCHAR), 1, OUTPUTFILE); /* this line is inserted */
|
||
|
emit_line();
|
||
|
}
|
||
|
return(TRUE);
|
||
|
}
|
||
|
|
||
|
|
||
|
/************************************************************************
|
||
|
** nested_include : searches the parentage list of the currently
|
||
|
** open files on the stack when a new include file is found.
|
||
|
** Input : ptr to include file name.
|
||
|
** Output : TRUE if the file was found, FALSE if not.
|
||
|
*************************************************************************/
|
||
|
int
|
||
|
nested_include(
|
||
|
void
|
||
|
)
|
||
|
{
|
||
|
PWCHAR p_tmp1;
|
||
|
PWCHAR p_file;
|
||
|
PWCHAR p_slash;
|
||
|
int tos;
|
||
|
|
||
|
tos = Findex;
|
||
|
p_file = Filename; /* always start with the current file */
|
||
|
for(;;) {
|
||
|
p_tmp1 = p_file;
|
||
|
p_slash = NULL;
|
||
|
while(*p_tmp1) { /* pt to end of filename, find trailing slash */
|
||
|
if(wcschr(Path_chars, *p_tmp1)) {
|
||
|
p_slash = p_tmp1;
|
||
|
}
|
||
|
p_tmp1++;
|
||
|
}
|
||
|
if(p_slash) {
|
||
|
p_tmp1 = Reuse_W;
|
||
|
while(p_file <= p_slash) { /* we want the trailing '/' */
|
||
|
*p_tmp1++ = *p_file++; /* copy the parent directory */
|
||
|
}
|
||
|
p_file = yylval.yy_string.str_ptr;
|
||
|
while((*p_tmp1++ = *p_file++)!=0) { /*append include file name */
|
||
|
; /* NULL */
|
||
|
}
|
||
|
} else {
|
||
|
wcscpy(Reuse_W, yylval.yy_string.str_ptr);
|
||
|
}
|
||
|
if(newinput(Reuse_W,MAY_OPEN)) {
|
||
|
return(TRUE);
|
||
|
}
|
||
|
if(tos <= 0) {
|
||
|
break;
|
||
|
}
|
||
|
p_file = Fstack[tos--].fl_name;
|
||
|
}
|
||
|
return(FALSE);
|
||
|
}
|
||
|
|
||
|
|
||
|
/************************************************************************/
|
||
|
/* esc_sequence() */
|
||
|
/************************************************************************/
|
||
|
PWCHAR
|
||
|
esc_sequence(
|
||
|
PWCHAR dest,
|
||
|
PWCHAR name
|
||
|
)
|
||
|
{
|
||
|
*dest = L'"';
|
||
|
while((*++dest = *name) != 0) {
|
||
|
if (CHARMAP(*name) == LX_EOS) {
|
||
|
*++dest = L'\\';
|
||
|
}
|
||
|
name++;
|
||
|
}
|
||
|
*dest++ = L'"'; /* overwrite null */
|
||
|
return( dest );
|
||
|
}
|
||
|
|
||
|
|
||
|
/************************************************************************/
|
||
|
/* emit_line() */
|
||
|
/************************************************************************/
|
||
|
void
|
||
|
emit_line(
|
||
|
void
|
||
|
)
|
||
|
{
|
||
|
PWCHAR p;
|
||
|
|
||
|
swprintf(Reuse_W, L"#line %d ", Linenumber+1);
|
||
|
myfwrite(Reuse_W, wcslen(Reuse_W) * sizeof(WCHAR), 1, OUTPUTFILE);
|
||
|
|
||
|
p = esc_sequence(Reuse_W, Filename);
|
||
|
myfwrite(Reuse_W, (size_t)(p - Reuse_W) * sizeof(WCHAR), 1, OUTPUTFILE);
|
||
|
}
|
||
|
|
||
|
/************************************************************************
|
||
|
** io_eob : handle getting the next block from a file.
|
||
|
** return TRUE if this is the real end of the buffer, FALSE if we have
|
||
|
** more to do.
|
||
|
************************************************************************/
|
||
|
int
|
||
|
io_eob(
|
||
|
void
|
||
|
)
|
||
|
{
|
||
|
int n;
|
||
|
TEXT_TYPE p;
|
||
|
|
||
|
static int dc;
|
||
|
|
||
|
p = Fstack[Findex].fl_buffer;
|
||
|
if((Current_char - (ptext_t)p) < Fstack[Findex].fl_numread) {
|
||
|
/*
|
||
|
** haven't used all the chars from the buffer yet.
|
||
|
** (some clown has a null/cntl z embedded in his source file.)
|
||
|
*/
|
||
|
if(PREVCH() == CONTROL_Z) { /* imbedded control z, real eof */
|
||
|
UNGETCH();
|
||
|
return(TRUE);
|
||
|
}
|
||
|
return(FALSE);
|
||
|
}
|
||
|
Current_char = p;
|
||
|
|
||
|
//-
|
||
|
//- The following section was added to support 16-bit resource files.
|
||
|
//- It will just convert them to 8-bit files that the Resource Compiler
|
||
|
//- can read. Here is the basic strategy used. An 8-bit file is
|
||
|
//- read into the normal buffer and should be processed the old way.
|
||
|
//- A 16-bit file is read into a wide character buffer identical to the
|
||
|
//- normal 8-bit one. The entire contents are then copied to the 8-bit
|
||
|
//- buffer and processed normally. The one exception to this is when
|
||
|
//- a string literal is encountered. We then return to the 16-bit buffer
|
||
|
//- to read the characters. These characters are written as backslashed
|
||
|
//- escape characters inside an 8-bit string. (ex. "\x004c\x523f").
|
||
|
//- I'll be the first person to admit that this is an ugly solution, but
|
||
|
//- hey, we're Microsoft :-). 8-2-91 David Marsyla.
|
||
|
//-
|
||
|
if (Fstack[Findex].fl_fFileType == DFT_FILE_IS_8_BIT) {
|
||
|
REG int i;
|
||
|
REG PUCHAR lpb;
|
||
|
PUCHAR Buf;
|
||
|
|
||
|
Buf = (PUCHAR) MyAlloc(Fstack[Findex].fl_bufsiz + 1);
|
||
|
if (Buf == NULL) {
|
||
|
strcpy (Msg_Text, GET_MSG (1002));
|
||
|
fatal(1002); /* no memory */
|
||
|
}
|
||
|
Fstack[Findex].fl_seek = fseek(Fp, 0, SEEK_CUR);
|
||
|
n = fread (Buf, sizeof(char), Fstack[Findex].fl_bufsiz, Fp);
|
||
|
|
||
|
//-
|
||
|
//- Determine if the last byte is a DBCS lead byte
|
||
|
//- if YES (i will be greater than n), backup one byte
|
||
|
//-
|
||
|
for (i = 0, lpb = Buf; i < n; i++, lpb++) {
|
||
|
if (IsDBCSLeadByteEx(uiCodePage, *lpb)) {
|
||
|
i++;
|
||
|
lpb++;
|
||
|
}
|
||
|
}
|
||
|
if (i > n) {
|
||
|
fseek (Fp, -1, SEEK_CUR);
|
||
|
n--;
|
||
|
*(Buf + n) = 0;
|
||
|
}
|
||
|
|
||
|
//-
|
||
|
//- Convert the 8-bit buffer to the 16-bit buffer.
|
||
|
//-
|
||
|
Fstack[Findex].fl_numread = MultiByteToWideChar (uiCodePage, MB_PRECOMPOSED,
|
||
|
(LPCSTR) Buf, n, p, Fstack[Findex].fl_bufsiz);
|
||
|
MyFree (Buf);
|
||
|
} else {
|
||
|
|
||
|
Fstack[Findex].fl_numread = n =
|
||
|
fread (p, sizeof(WCHAR), Fstack[Findex].fl_bufsiz, Fp);
|
||
|
|
||
|
//-
|
||
|
//- If the file is in reversed format, swap the bytes.
|
||
|
//-
|
||
|
if (Fstack[Findex].fl_fFileType == DFT_FILE_IS_16_BIT_REV && n > 0) {
|
||
|
WCHAR *pT = p;
|
||
|
BYTE jLowNibble;
|
||
|
BYTE jHighNibble;
|
||
|
INT cNumWords = n;
|
||
|
|
||
|
while (cNumWords--) {
|
||
|
jLowNibble = (BYTE)(*pT & 0xFF);
|
||
|
jHighNibble = (BYTE)((*pT >> 8) & 0xFF);
|
||
|
|
||
|
*pT++ = (WCHAR)(jHighNibble | (jLowNibble << 8));
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
** the total read counts the total read *and* used.
|
||
|
*/
|
||
|
|
||
|
if (n != 0) { /* we read something */
|
||
|
*(p + Fstack[Findex].fl_numread) = EOS_CHAR; /* sentinal at the end */
|
||
|
return(FALSE); /* more to do */
|
||
|
}
|
||
|
*p = EOS_CHAR; /* read no chars */
|
||
|
return(TRUE); /* real end of buffer */
|
||
|
}
|
||
|
|
||
|
|
||
|
/************************************************************************
|
||
|
** io_restart : restarts the current file with a new codepage
|
||
|
** Method: figure out where the current character came from
|
||
|
** using WideCharToMultiByte(...cch up to current char...)
|
||
|
** Note that this assumes that roundtrip conversion to/from
|
||
|
** Unicode results in the same # of characters out as in.
|
||
|
** fseek to the right place, then read a new buffer
|
||
|
**
|
||
|
** Note that uiCodePage controls the seek, so it must
|
||
|
** remain set to the value used to do the translation
|
||
|
** from multi-byte to Unicode until after io_restart returns.
|
||
|
**
|
||
|
************************************************************************/
|
||
|
int
|
||
|
io_restart(
|
||
|
unsigned long cp
|
||
|
)
|
||
|
{
|
||
|
int n;
|
||
|
TEXT_TYPE p;
|
||
|
|
||
|
// If it's a Unicode file, nothing to do, so just return.
|
||
|
if (Fstack[Findex].fl_fFileType != DFT_FILE_IS_8_BIT)
|
||
|
return TRUE;
|
||
|
|
||
|
p = Fstack[Findex].fl_buffer;
|
||
|
n = Fstack[Findex].fl_numread - (int)(Current_char - p);
|
||
|
|
||
|
if (n != 0) {
|
||
|
if (Fstack[Findex].fl_fFileType == DFT_FILE_IS_8_BIT) {
|
||
|
n = WideCharToMultiByte(uiCodePage, 0, Current_char, n, NULL, 0, NULL, NULL);
|
||
|
if (n == 0)
|
||
|
return TRUE;
|
||
|
} else
|
||
|
n *= sizeof(WCHAR);
|
||
|
|
||
|
fseek(Fp, -n, SEEK_CUR);
|
||
|
}
|
||
|
Fstack[Findex].fl_numread = 0;
|
||
|
// io_eob will return true if we're at the end of the file.
|
||
|
// this is an error for restart (it means there's nothing more
|
||
|
// to do here (ie: #pragma codepage is the last line in the file).
|
||
|
return !io_eob();
|
||
|
}
|
||
|
|
||
|
|
||
|
/************************************************************************
|
||
|
** p0_init : inits for prepocessing.
|
||
|
** Input : ptr to file name to use as input.
|
||
|
** ptr to LIST containing predefined values.
|
||
|
** ( -D's from cmd line )
|
||
|
**
|
||
|
** Note : if "newinput" cannot open the file,
|
||
|
** it gives a fatal msg and exits.
|
||
|
**
|
||
|
************************************************************************/
|
||
|
void
|
||
|
p0_init(
|
||
|
WCHAR *p_fname,
|
||
|
WCHAR *p_outname,
|
||
|
LIST *p_defns,
|
||
|
LIST *p_undefns
|
||
|
)
|
||
|
{
|
||
|
REG WCHAR *p_dstr;
|
||
|
REG WCHAR *p_eq;
|
||
|
int ntop;
|
||
|
|
||
|
SETCHARMAP(LX_FORMALMARK, LX_MACFORMAL);
|
||
|
SETCHARMAP(LX_FORMALSTR, LX_STRFORMAL);
|
||
|
SETCHARMAP(LX_FORMALCHAR, LX_CHARFORMAL);
|
||
|
SETCHARMAP(LX_NOEXPANDMARK, LX_NOEXPAND);
|
||
|
if(EXTENSION) {
|
||
|
/*
|
||
|
** '$' is an identifier character under extensions.
|
||
|
*/
|
||
|
SETCHARMAP(L'$', LX_ID);
|
||
|
SETCONTMAP(L'$', LXC_ID);
|
||
|
}
|
||
|
|
||
|
for(ntop = p_defns->li_top; ntop < MAXLIST; ++ntop) {
|
||
|
p_dstr = p_defns->li_defns[ntop];
|
||
|
p_eq = Reuse_W;
|
||
|
while ((*p_eq = *p_dstr++) != 0) { /* copy the name to Reuse_W */
|
||
|
if(*p_eq == L'=') { /* we're told what the value is */
|
||
|
break;
|
||
|
}
|
||
|
p_eq++;
|
||
|
}
|
||
|
if(*p_eq == L'=') {
|
||
|
WCHAR *p_tmp;
|
||
|
WCHAR *last_space = NULL;
|
||
|
|
||
|
*p_eq = L'\0'; /* null the = */
|
||
|
for(p_tmp = p_dstr; *p_tmp; p_tmp++) { /* find the end of it */
|
||
|
if(iswspace(*p_tmp)) {
|
||
|
if(last_space == NULL) {
|
||
|
last_space = p_tmp;
|
||
|
}
|
||
|
} else {
|
||
|
last_space = NULL;
|
||
|
}
|
||
|
}
|
||
|
if(last_space != NULL) {
|
||
|
*last_space = L'\0';
|
||
|
}
|
||
|
Reuse_W_hash = local_c_hash(Reuse_W);
|
||
|
Reuse_W_length = wcslen(Reuse_W) + 1;
|
||
|
if( *p_dstr ) { /* non-empty string */
|
||
|
definstall(p_dstr, (wcslen(p_dstr) + 2), FROM_COMMAND);
|
||
|
} else {
|
||
|
definstall((WCHAR *)0, 0, 0);
|
||
|
}
|
||
|
} else {
|
||
|
Reuse_W_hash = local_c_hash(Reuse_W);
|
||
|
Reuse_W_length = wcslen(Reuse_W) + 1;
|
||
|
definstall(L"1\000", 3, FROM_COMMAND); /* value of string is 1 */
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/* undefine */
|
||
|
for(ntop = p_undefns->li_top; ntop < MAXLIST; ++ntop) {
|
||
|
p_dstr = p_undefns->li_defns[ntop];
|
||
|
p_eq = Reuse_W;
|
||
|
while ((*p_eq = *p_dstr++) != 0) { /* copy the name to Reuse_W */
|
||
|
if(*p_eq == L'=') { /* we're told what the value is */
|
||
|
break;
|
||
|
}
|
||
|
p_eq++;
|
||
|
}
|
||
|
if(*p_eq == L'=') {
|
||
|
WCHAR *p_tmp;
|
||
|
WCHAR *last_space = NULL;
|
||
|
|
||
|
*p_eq = L'\0'; /* null the = */
|
||
|
for(p_tmp = p_dstr; *p_tmp; p_tmp++) { /* find the end of it */
|
||
|
if(iswspace(*p_tmp)) {
|
||
|
if(last_space == NULL) {
|
||
|
last_space = p_tmp;
|
||
|
}
|
||
|
} else {
|
||
|
last_space = NULL;
|
||
|
}
|
||
|
}
|
||
|
if(last_space != NULL) {
|
||
|
*last_space = L'\0';
|
||
|
}
|
||
|
Reuse_W_hash = local_c_hash(Reuse_W);
|
||
|
Reuse_W_length = wcslen(Reuse_W) + 1;
|
||
|
if( *p_dstr ) { /* non-empty string */
|
||
|
undefine();
|
||
|
} else {
|
||
|
undefine();
|
||
|
}
|
||
|
} else {
|
||
|
Reuse_W_hash = local_c_hash(Reuse_W);
|
||
|
Reuse_W_length = wcslen(Reuse_W) + 1;
|
||
|
undefine(); /* value of string is 1 */
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Note: Always use the Ansi codepage here. uiCodePage may have been
|
||
|
// modified by a codepage pragma in the source file.
|
||
|
|
||
|
WideCharToMultiByte (GetACP(), 0, p_outname, -1, chBuf, sizeof(chBuf), NULL, NULL);
|
||
|
if ((OUTPUTFILE = fopen (chBuf, "w+b")) == NULL) {
|
||
|
Msg_Temp = GET_MSG (1023);
|
||
|
SET_MSG (Msg_Text, sizeof(Msg_Text), Msg_Temp, chBuf);
|
||
|
fatal (1023);
|
||
|
}
|
||
|
|
||
|
newinput(p_fname,MUST_OPEN);
|
||
|
}
|
||
|
|
||
|
/************************************************************************
|
||
|
** p0_terminate : terminates prepocessing.
|
||
|
**
|
||
|
**
|
||
|
************************************************************************/
|
||
|
void
|
||
|
p0_terminate(
|
||
|
void
|
||
|
)
|
||
|
{
|
||
|
for ( ;fpop(); )
|
||
|
;
|
||
|
if (OUTPUTFILE)
|
||
|
fclose(OUTPUTFILE);
|
||
|
}
|