📄 parseext.cpp
字号:
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft shared
// source or premium shared source license agreement under which you licensed
// this source code. If you did not accept the terms of the license agreement,
// you are not authorized to use this source code. For the terms of the license,
// please see the license agreement between you and Microsoft or, if applicable,
// see the SOURCE.RTF on your install media or the root of your tools installation.
// THE SOURCE CODE IS PROVIDED "AS IS", WITH NO WARRANTIES.
//
/*--
Module Name: parseext.cpp
Abstract: Extended parsing functions that can be compomentalized away
This file has functionality to:
Preprocessing of directives <%@ ... %>
Include files.
--*/
#include "aspmain.h"
#define PREPROC_LANG "LANGUAGE"
#define PREPROC_LCID "LCID"
#define PREPROC_CDPG "CODEPAGE"
// for #include stuff
#define COMMENT_BEGIN "<!--"
#define COMMENT_END "-->"
#define INC_INCLUDE "#include"
#define INC_FILE "file"
#define INC_VIRTUAL "virtual"
const BOOL c_fUseExtendedParse = TRUE;
// Looks for <!-- #include file | virtual="file" -->, reads that data into pszFileData
// NOTE: No support for more than 1 level of #includes, 16 files max to include.
// IIS supports an arbitrary number of include files, and allows include files
// to include other include files, none of which is supported on WinCE ASP.
BOOL CASPState::ParseIncludes()
{
DEBUG_CODE_INIT;
BOOL ret = FALSE;
int nNewChars = 0; // extra space we'll need
int nFiles = 0;
int i;
DWORD dwMaxFileSize = 0; // largest file we've come across
// FindIncludeFiles determine amount of memory to add to buffer and gets the
// file handles loaded up.
if ( ! FindIncludeFiles(&nFiles,&nNewChars,&dwMaxFileSize))
myleave(60);
if (nFiles == 0) // no inc files, jump to the end
{
ret = TRUE;
myleave(0);
}
// ReadIncludeFiles uses file handles to suck include file info into script text
if ( ! ReadIncludeFiles(nFiles,nNewChars,dwMaxFileSize))
myleave(69);
ret = TRUE;
done:
DEBUGMSG_ERR(ZONE_ERROR,(L"ASP: ParseIncludes failed, err = %d\r\n",err));
// No call to ServerError, the called fcns will call it instead
for (i = 0; i < nFiles; i++)
{
MyCloseHandle(m_pIncludeInfo[i].m_hFile);
m_pIncludeInfo[i].m_hFile = INVALID_HANDLE_VALUE;
}
return ret;
}
// Runs through text, maps #include files to physical ones and gets a handle to them.
// This function does not modify the file text itself or read in any files -
// this is handled by ReadIncludeFiles
BOOL CASPState::FindIncludeFiles(int *pnFiles, int *pnNewChars, DWORD *pdwMaxFileSize)
{
DEBUG_CODE_INIT;
PSTR pszTrav = NULL;
BOOL ret = FALSE;
int nNewChars = 0; // extra space we'll need for scripting data after inc files are read
int nFiles = 0;
char szErr[MAX_PATH + 30];
WCHAR wszFileName[MAX_PATH+1];
PSTR pszSubEnd = NULL;
PSTR pszSubBegin = NULL;
PSTR pszTemp = NULL;
DWORD dwFileSize;
DWORD dwMaxFileSize = 0; // largest file we've come across
BOOL fFile; // Using file or virtual directory?
szErr[0] = '\0';
for(pszTrav=m_pszFileData; pszTrav=MyStrStr(pszTrav, COMMENT_BEGIN); ) // look for <!--
{
pszSubBegin = pszTrav; // keep original position
pszTrav += sizeof(COMMENT_BEGIN) - 1;
svsutil_SkipWhiteSpace(pszTrav);
// NOTE: The script engine right now executes code inside HTLM comments,
// IIS skips code inside HTLM comments.
// For example we'd execute the statement <!-- <% x = 5 %> -->
// The script writer can manually comment lines of code out
// at a time through the script language.
// continue past regular HTLM comment
if (0 != _memicmp(pszTrav,INC_INCLUDE,sizeof(INC_INCLUDE) - 1))
continue;
// Otherwise this is a <!-- #include ..., continue parsing.
// Note: If there are 2 or more #includes on the same line,our error reporting
// (matching the line #'s in the script to line #'s on the page) would
// get really messed up, so we don't allow it in 1st place.
if (nFiles && 1 == GetLineNumber(m_pIncludeInfo[nFiles-1].m_pszEnd, pszTrav))
{
m_aspErr = IDS_E_MULTIPLE_INC_LINE;
myleave(58);
}
// is this going to push us over the limit?
if (nFiles == MAX_INCLUDE_FILES)
{
m_aspErr = IDS_E_MAX_INCLUDE;
myleave(59);
}
m_aspErr = IDS_E_BAD_INCLUDE;
pszTrav += sizeof(INC_INCLUDE) - 1;
svsutil_SkipWhiteSpace(pszTrav);
// The next field tells us if it's a physical or virtual directory.
if ( 0 == _memicmp(pszTrav,INC_FILE,sizeof(INC_FILE) - 1))
{
pszTrav += sizeof(INC_FILE) - 1;
fFile = TRUE;
}
else if (0 == _memicmp(pszTrav,INC_VIRTUAL,sizeof(INC_VIRTUAL) - 1))
{
pszTrav += sizeof(INC_VIRTUAL) - 1;
fFile = FALSE;
}
else
myleave(60);
svsutil_SkipWhiteSpace(pszTrav);
if ( *pszTrav != '=')
myleave(63);
pszTrav++; // Skip =
svsutil_SkipWhiteSpace(pszTrav);
if ( (*pszTrav != '\"') && (*pszTrav != '\''))
myleave(61);
pszTrav++;
pszSubEnd = pszTrav;
while (*pszSubEnd) {
if ((*pszSubEnd == '\"') || (*pszSubEnd == '\''))
break;
pszSubEnd++;
}
if (! (*pszSubEnd))
myleave(62);
if (pszSubEnd - pszTrav > (MAX_PATH-1)) {
// filesys won't be able to handle this and would overflow our buffers if we try to copy.
m_aspErr = IDS_E_FILE_OPEN;
myleave(78);
}
// portion off a substring. We'll reset it later.
// pszTrav now has the file name, without the trailing quotes
*pszSubEnd = '\0';
// Map the file to physical path.
if(fFile ? !GetIncludeFilePath(pszTrav, wszFileName) : !GetVirtualIncludeFilePath(pszTrav, wszFileName) )
myleave(68);
// On the first include file we find, we must allocate the structure
// that helps us keep track of error line #'s.
if (0 == nFiles )
{
int i;
if (NULL == (m_pIncludeInfo = MyRgAllocZ(INCLUDE_INFO, MAX_INCLUDE_FILES)))
{
m_aspErr = IDS_E_NOMEM;
myleave(71);
}
// We set the # of lines in each file to 1 initially. This way should
// there be an error before we can get actual count (by sucking file in)
// then we'll use amount of space it takes up in the script.
for (i = 0; i < MAX_INCLUDE_FILES; i++)
m_pIncludeInfo[i].m_cLines = 1;
}
if(NULL == (m_pIncludeInfo[nFiles].m_pszFileName = MySzDupA(pszTrav,pszSubEnd - pszTrav)))
{
m_aspErr = IDS_E_NOMEM;
myleave(72);
}
if ( NTFAILED(m_pIncludeInfo[nFiles].m_hFile = MyOpenReadFile(wszFileName)) ||
NTFAILED((HANDLE)(dwFileSize = GetFileSize(m_pIncludeInfo[nFiles].m_hFile, NULL))))
{
WCHAR wszFormat[256];
CHAR szFormat[256];
MyLoadStringW2A(m_pACB->hInst,IDS_ERROR_CODE,wszFormat,szFormat);
sprintf(szErr,szFormat,pszTrav, GetLastError());
m_aspErr = IDS_E_FILE_OPEN;
myleave(69);
}
// Determine the largest file size, this will be used when it's time
// to read them in in ReadIncludeFiles()
if (dwFileSize > dwMaxFileSize)
dwMaxFileSize = dwFileSize;
// Put original char back in place
*pszSubEnd = '\"';
// Don't set this to pszTrav right away in case there's an error,
// GetLineNumber needs pszTrav to be non-NULL for this to work.
pszSubEnd = MyStrStr(pszTrav,COMMENT_END);
if (NULL == pszSubEnd)
{
m_aspErr = IDS_E_COMMENT_UNTERMINATED;
myleave(66);
}
pszTrav = pszSubEnd + sizeof(COMMENT_END) - 1;
// make sure there's no <% commands beginning on same line as #include file,
// if there are this might cause error reporting to be invalid.
if (NULL != (pszTemp = MyStrStr(pszTrav, BEGIN_COMMAND)) &&
1 == GetLineNumber(pszTrav, pszTemp))
{
m_aspErr = IDS_E_MULTIPLE_INC_LINE;
myleave(70);
}
m_pIncludeInfo[nFiles].m_pszStart = pszSubBegin;
m_pIncludeInfo[nFiles].m_pszEnd = pszTrav;
m_pIncludeInfo[nFiles].m_dwFileSize = dwFileSize;
nFiles++;
// The amount of extra memory needed is the size of the new file
// minus the size of the <!-- #include ... --> directive it will replace
nNewChars += (dwFileSize - ( pszTrav - pszSubBegin));
}
m_aspErr = IDS_E_DEFAULT; // set error back to default
ret = TRUE;
done:
if (FALSE == ret)
{
ServerError(szErr, GetLineNumber(m_pszFileData, pszTrav));
}
*pnFiles = nFiles;
*pnNewChars = nNewChars;
*pdwMaxFileSize = dwMaxFileSize;
return ret;
}
// This function sucks in the include files found in FindInclude files.
BOOL CASPState::ReadIncludeFiles(int nFiles, int nNewChars, DWORD dwMaxFileSize)
{
DEBUG_CODE_INIT;
PSTR pszNewFileData = NULL; // if we include stuff, shove it in here
PSTR pszRead = m_pszFileData;
PSTR pszWrite = NULL;
PSTR pszIncFile = NULL; // buffer, holds include file
DWORD dwRead;
int iErrLine = -1;
int i;
int nLines = 0;
BOOL ret = FALSE;
if( !(pszWrite = pszNewFileData = MyRgAllocZ(CHAR,m_cbFileData + nNewChars + 1)) ||
!(pszIncFile = MyRgAllocNZ(CHAR,dwMaxFileSize+1)) )
{
MyFree(pszNewFileData);
m_aspErr = IDS_E_NOMEM;
myleave(68);
}
pszNewFileData[m_cbFileData + nNewChars] = '\0';
pszIncFile[dwMaxFileSize] = '\0';
for (i = 0; i < nFiles ; i++)
{
// read between end of last inc file (or beginning of file) and the
// 1st # include
memcpy(pszWrite, pszRead, m_pIncludeInfo[i].m_pszStart - pszRead);
pszWrite += m_pIncludeInfo[i].m_pszStart - pszRead;
nLines += GetLineNumber(pszRead, m_pIncludeInfo[i].m_pszStart);
// Read the include file.
if (! ReadFile(m_pIncludeInfo[i].m_hFile, (LPVOID) pszIncFile,
m_pIncludeInfo[i].m_dwFileSize, &dwRead, 0))
{
DEBUGCHK(FALSE);
myleave(44);
}
m_pIncludeInfo[i].m_iStartLine = nLines;
m_pIncludeInfo[i].m_cLines = GetLineNumber(pszIncFile,
pszIncFile + m_pIncludeInfo[i].m_dwFileSize);
DEBUGMSG(ZONE_PARSER,(L"ASP: Inc file <<%a>> starts line %d, has %d lines\r\n",
m_pIncludeInfo[i].m_pszFileName, m_pIncludeInfo[i].m_iStartLine,
m_pIncludeInfo[i].m_cLines));
// To get nLines, add the # of lines in the file and subtract 2. Why 2??
// We subtract 1 line because the first line of the inc file is put onto the
// same line as the <! --- >, IE a 3 line include file really only
// spills over into 2 extra lines.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -