/* Copyright (C) Microsoft Corporation, 1998. All rights reserved. */ #include "precomp.h" #include "getsym.h" #include "utils.h" CInput:: CInput ( BOOL *pfRetCode, LPSTR pszPathName, UINT cbBufSize ) : m_cbBufSize(cbBufSize), m_cbValidData(0), m_nCurrOffset(0), m_chCurr(INVALID_CHAR), m_fEndOfFile(TRUE) { m_pszPathName = ::My_strdup(pszPathName); m_pbDataBuf = new BYTE[m_cbBufSize]; m_hFile = ::CreateFile(pszPathName, GENERIC_READ, FILE_SHARE_READ, NULL, // default security OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_ATTRIBUTE_READONLY, NULL); // no template m_cbFileSize = (NULL != m_hFile) ? ::GetFileSize(m_hFile, NULL) : 0; *pfRetCode = (NULL != m_pszPathName) && (NULL != m_pbDataBuf) && (NULL != m_hFile); if (*pfRetCode) { if (CheckBuffer(1)) { m_chCurr = m_pbDataBuf[0]; m_fEndOfFile = FALSE; } } } CInput:: ~CInput ( void ) { delete m_pszPathName; delete m_pbDataBuf; if (NULL != m_hFile) { ::CloseHandle(m_hFile); } } void CInput:: NextChar ( void ) { if (INVALID_CHAR != m_chCurr) { // set up the next new char if (CheckBuffer(1)) { m_chCurr = m_pbDataBuf[++m_nCurrOffset]; } else { m_chCurr = INVALID_CHAR; m_fEndOfFile = TRUE; } } } void CInput:: PeekChars ( UINT cChars, LPSTR pszChars ) { if (CheckBuffer(cChars - 1)) { ::CopyMemory(pszChars, &m_pbDataBuf[m_nCurrOffset], cChars); } else { ::ZeroMemory(pszChars, cChars); } } void CInput:: SkipChars ( UINT cChars ) { for (UINT i = 0; i < cChars; i++) { NextChar(); } } BOOL CInput:: CheckBuffer ( UINT cChars ) { if (m_nCurrOffset + cChars >= m_cbValidData) { ASSERT(m_cbValidData >= m_nCurrOffset); UINT cbCurrValid = m_cbValidData - m_nCurrOffset; UINT cbToRead = m_cbBufSize - cbCurrValid; if (cbCurrValid > 0) { // Move the data to the front of the buffer. ::CopyMemory(&m_pbDataBuf[0], &m_pbDataBuf[m_nCurrOffset], cbCurrValid); m_nCurrOffset = 0; } ULONG cbRead = 0; if (::ReadFile(m_hFile, &m_pbDataBuf[cbCurrValid], cbToRead, &cbRead, NULL)) { ASSERT(cbRead <= cbToRead); m_cbValidData = cbCurrValid + cbRead; m_nCurrOffset = 0; if (cbRead < cbToRead) { m_fEndOfFile = TRUE; } } else { m_fEndOfFile = TRUE; } return (m_nCurrOffset + cChars < m_cbValidData); } return TRUE; } BOOL CInput:: Rewind ( void ) { if ((DWORD) -1 != ::SetFilePointer(m_hFile, 0, NULL, FILE_BEGIN)) { // clean up members m_cbValidData = 0; m_nCurrOffset = 0; m_chCurr = INVALID_CHAR; // set up the buffer if (CheckBuffer(1)) { m_chCurr = m_pbDataBuf[0]; m_fEndOfFile = FALSE; } else { m_fEndOfFile = TRUE; } return TRUE; } return FALSE; } CSymbol:: CSymbol ( CInput *pInput ) : m_pInput(pInput), m_eSymbolID(SYMBOL_UNKNOWN), m_cchSymbolStr(0) { m_szSymbolStr[0] = '\0'; } BOOL CSymbol:: NextSymbol ( void ) { if (SYMBOL_EOF == m_eSymbolID) { return FALSE; } char ch = m_pInput->GetChar(); m_szSymbolStr[0] = ch; m_cchSymbolStr = 1; m_pInput->NextChar(); if (::isdigit(ch)) { // numbers while (INVALID_CHAR != (ch = m_pInput->GetChar())) { if (::isdigit(ch)) { m_szSymbolStr[m_cchSymbolStr++] = ch; m_pInput->NextChar(); } else { break; } } m_eSymbolID = SYMBOL_NUMBER; } else if (::isalpha(ch)) { // alphanumeric while (INVALID_CHAR != (ch = m_pInput->GetChar())) { if (::isalnum(ch) || '_' == ch || '-' == ch) { m_szSymbolStr[m_cchSymbolStr++] = ch; m_pInput->NextChar(); } else { m_szSymbolStr[m_cchSymbolStr] = '\0'; break; } } m_eSymbolID = ::IsKeyword(&m_szSymbolStr[0]) ? SYMBOL_KEYWORD : SYMBOL_IDENTIFIER; } else if ('\n' == ch) { m_szSymbolStr[m_cchSymbolStr++] = '\n'; m_eSymbolID = SYMBOL_SPACE_EOL; } else if (::isspace(ch)) { // space m_eSymbolID = SYMBOL_SPACE; while (INVALID_CHAR != (ch = m_pInput->GetChar())) { if (::isspace(ch)) { m_szSymbolStr[m_cchSymbolStr++] = ch; m_pInput->NextChar(); if ('\n' == ch) { m_eSymbolID = SYMBOL_SPACE_EOL; } } else { break; } } } else if ('&' == ch) { m_eSymbolID = SYMBOL_FIELD; // alphanumeric while (INVALID_CHAR != (ch = m_pInput->GetChar())) { if (::isalnum(ch) || '_' == ch) { m_szSymbolStr[m_cchSymbolStr++] = ch; m_pInput->NextChar(); } else { m_szSymbolStr[m_cchSymbolStr] = '\0'; break; } } } else { char szTemp[4]; m_eSymbolID = SYMBOL_SPECIAL; if (':' == ch) { m_pInput->PeekChars(2, &szTemp[0]); if (':' == szTemp[0] && '=' == szTemp[1]) { m_pInput->SkipChars(2); m_szSymbolStr[m_cchSymbolStr++] = ':'; m_szSymbolStr[m_cchSymbolStr++] = '='; m_eSymbolID = SYMBOL_DEFINITION; } } else if ('-' == ch) { m_pInput->PeekChars(1, &szTemp[0]); if ('-' == szTemp[0]) { m_pInput->SkipChars(1); m_szSymbolStr[m_cchSymbolStr++] = '-'; m_eSymbolID = SYMBOL_COMMENT; } } else if ('.' == ch) { m_pInput->PeekChars(2, &szTemp[0]); if ('.' == szTemp[0] && '.' == szTemp[1]) { m_pInput->SkipChars(2); m_szSymbolStr[m_cchSymbolStr++] = '.'; m_szSymbolStr[m_cchSymbolStr++] = '.'; m_eSymbolID = SYMBOL_DOTDOTDOT; } } } // null terminate the string m_szSymbolStr[m_cchSymbolStr] = '\0'; if (INVALID_CHAR != m_szSymbolStr[0]) { return TRUE; } m_eSymbolID = SYMBOL_EOF; return FALSE; } BOOL CSymbol:: NextUsefulSymbol ( void ) { BOOL fInsideComment = FALSE; while (NextSymbol()) { if (SYMBOL_SPACE_EOL == m_eSymbolID) { fInsideComment = FALSE; } else if (SYMBOL_COMMENT == m_eSymbolID) { fInsideComment = ! fInsideComment; } else if (! fInsideComment) { if (SYMBOL_SPACE != m_eSymbolID) { return TRUE; } } } return FALSE; } COutput:: COutput ( BOOL *pfRetCode, LPSTR pszPathName, UINT cbBufSize ) : m_cbBufSize(cbBufSize), m_cbValidData(0) { m_pszPathName = ::My_strdup(pszPathName); m_pbDataBuf = new BYTE[m_cbBufSize]; m_hFile = ::CreateFile(pszPathName, GENERIC_WRITE, FILE_SHARE_READ, NULL, // default security CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); // no template *pfRetCode = (NULL != m_pszPathName) && (NULL != m_pbDataBuf) && (NULL != m_hFile); } COutput:: ~COutput ( void ) { delete m_pszPathName; delete m_pbDataBuf; if (NULL != m_hFile) { Flush(); ::CloseHandle(m_hFile); } } BOOL COutput:: Write ( LPBYTE pbDataBuf, UINT cbToWrite ) { ULONG cbWritten; while (0 != cbToWrite) { if (::WriteFile(m_hFile, pbDataBuf, cbToWrite, &cbWritten, NULL)) { pbDataBuf += cbWritten; cbToWrite -= cbWritten; } else { return FALSE; } } return TRUE; } BOOL COutput:: Writeln ( LPBYTE pbDataBuf, UINT cbToWrite ) { return Write(pbDataBuf, cbToWrite) && Write("\n", 1); }