RWINC.C
资源名称:MSDN_VC98.zip [点击查看]
上传用户:bangxh
上传日期:2007-01-31
资源大小:42235k
文件大小:35k
源码类别:
Windows编程
开发平台:
Visual C++
- /******************************************************************************
- * This is a part of the Microsoft Source Code Samples.
- * Copyright (C) 1993-1997 Microsoft Corporation.
- * All rights reserved.
- * This source code is only intended as a supplement to
- * Microsoft Development Tools and/or WinHelp documentation.
- * See these sources for detailed information regarding the
- * Microsoft samples programs.
- ******************************************************************************/
- /****************************** Module Header *******************************
- * Module Name: rwinc.c
- *
- * Does the include file reading and writing.
- *
- * Functions:
- *
- * OpenIncludeFile()
- * FreeInclude()
- * WriteInc()
- * LoadIncludeFile()
- * GetChar()
- * ReadChar()
- * GetLabel()
- * GetValue()
- * GetWord()
- * FindDefine()
- * GetNextInc()
- * RWToOffset()
- * WriteIncChar()
- * WriteIncFlush()
- * WriteChangedInc()
- * WriteDeletedInc()
- * WriteAddedInc()
- * WriteSymbol()
- * WriteIDInc()
- *
- * Comments:
- *
- ****************************************************************************/
- #include "dlgedit.h"
- #include "dlgfuncs.h"
- #include "dlgextrn.h"
- #include <ctype.h>
- /*
- * Field width that the symbol is printed within. This indirectly
- * determines where the id value starts, because blanks are added
- * after the symbol is printed up to this width value.
- */
- #define CCHSYMFIELDWIDTH 27
- /*
- * Return codes from the file reading functions.
- */
- #define READ_OK 1
- #define READ_EOF 2
- #define READ_BAD 3
- #define READ_WRONG 4
- #define BAD_POINTER ((VOID *)0xFFFF)
- /*
- * Return codes from the GetNextInc function.
- */
- #define GNI_DONE 0
- #define GNI_NOCHANGE 1
- #define GNI_CHANGED 2
- #define GNI_DELETED 3
- #define GNI_ADDED 4
- static BYTE abBuffer[CCHFILEBUFFER]; /* Buffer for read file data. */
- static TCHAR achBuffer[CCHFILEBUFFER]; /* Unicode buffer for data. */
- static INT cbBuf; /* Pointer into achBuffer. */
- static DWORD cchFile; /* Count of characters read. */
- static DWORD cchFileMax; /* Max characters in file. */
- static DWORD fposLastDefine; /* Saves location of "#define". */
- static DWORD fposWordStart; /* Saves start of id value. */
- static BOOL fAtNewLine; /* At start or r or n. */
- static HANDLE hfInclude; /* The current include file. */
- STATICFN BOOL LoadIncludeFile(VOID);
- STATICFN LPTSTR GetChar(VOID);
- STATICFN LPTSTR ReadChar(VOID);
- STATICFN INT GetLabel(BOOL *pfDups);
- STATICFN INT GetValue(PINT pnValue);
- STATICFN INT GetWord(LPTSTR pch);
- STATICFN INT FindDefine(VOID);
- STATICFN INT GetNextInc(NPLABEL *pplReturn, BOOL fFirst);
- STATICFN BOOL RWToOffset(HANDLE hfWrite, DWORD lOffset);
- STATICFN BOOL WriteIncChar(HANDLE hfWrite, TCHAR ch);
- STATICFN BOOL WriteIncFlush(HANDLE hfWrite);
- STATICFN BOOL WriteChangedInc(HANDLE hfWrite, NPLABEL plInc);
- STATICFN BOOL WriteDeletedInc(HANDLE hfWrite, NPLABEL plInc);
- STATICFN BOOL WriteAddedInc(HANDLE hfWrite, NPLABEL plInc);
- STATICFN BOOL WriteSymbol(HANDLE hfWrite, LPTSTR pszSymbol);
- STATICFN BOOL WriteIDInc(HANDLE hfWrite, INT id);
- /****************************************************************************
- * OpenIncludeFile
- *
- * This function attempts to open and load the include file with name
- * pointed to by pszOpenInclude. If pszOpenInclude is just a file name, and
- * not a path, then the path is taken from szFullLoadFile. Otherwise
- * pszOpenInclude itself is used. The full pathname is put in
- * szFullIncludeFile and pszIncludeFile is set to point to just the file
- * name in it.
- *
- * If fDoOpen is TRUE, the file is opened. If it is FALSE, it is assumed
- * that hfInc contains the file handle to the opened include file and this
- * handle is used. In addition, the caller is responsible for closing
- * any passed in file handle if an error occurs.
- *
- * Any existing includes are freed, szFullIncludeFile is set to the full
- * include path, pszIncludeFile is set to the filename portion of this full
- * path and hfInclude will contain the file handle to the include file.
- *
- * Arguments:
- * LPTSTR pszOpenInclude - name of the include file to open.
- *
- * Returns:
- * If the load is successful, TRUE is returned. Otherwise,
- * FALSE is returned.
- *
- ****************************************************************************/
- BOOL OpenIncludeFile(
- LPTSTR pszOpenInclude)
- {
- TCHAR szFullIncludeFileTemp[CCHMAXPATH];
- HCURSOR hcurSave;
- BOOL fSuccess = FALSE;
- hcurSave = SetCursor(hcurWait);
- if (FileInPath(pszOpenInclude) == pszOpenInclude) {
- lstrcpy(szFullIncludeFileTemp, szFullResFile);
- lstrcpy(FileInPath(szFullIncludeFileTemp), pszOpenInclude);
- }
- else {
- lstrcpy(szFullIncludeFileTemp, pszOpenInclude);
- }
- /*
- * Close any existing include file and free memory.
- */
- FreeInclude();
- if ((hfInclude = CreateFile(szFullIncludeFileTemp, GENERIC_READ,
- FILE_SHARE_READ, NULL, OPEN_EXISTING,
- FILE_FLAG_SEQUENTIAL_SCAN, NULL)) != (HANDLE)-1) {
- if (LoadIncludeFile()) {
- lstrcpy(szFullIncludeFile, szFullIncludeFileTemp);
- pszIncludeFile = FileInPath(szFullIncludeFile);
- fSuccess = TRUE;
- }
- CloseHandle(hfInclude);
- }
- /*
- * Update the status windows symbol combo box. Update other fields
- * also, in case the currently selected control's symbol was affected
- * by the reading of the new include file.
- */
- StatusFillSymbolList(plInclude);
- StatusUpdate();
- ShowFileStatus(TRUE);
- SetCursor(hcurSave);
- return fSuccess;
- }
- /************************************************************************
- * LoadIncludeFile
- *
- * This function creates or adds to plInclude with all the #define
- * statements in the file with handle hfInclude.
- *
- * Returns:
- * TRUE - Load succeeded.
- * FALSE - Load failed (a read error).
- *
- ************************************************************************/
- STATICFN BOOL LoadIncludeFile(VOID)
- {
- INT RetCode;
- BOOL fDups = FALSE;
- /*
- * Set char count, get file cb.
- */
- cchFile = 0L;
- cchFileMax = GetFileSize((HANDLE)hfInclude, NULL);
- cbBuf = CCHFILEBUFFER;
- fAtNewLine = TRUE;
- /*
- * Loop through and extract all id definitions.
- */
- while ((RetCode = FindDefine()) != READ_EOF) {
- if (RetCode == READ_BAD || (RetCode = GetLabel(&fDups)) == READ_BAD) {
- Message(MSG_INTERNAL);
- return FALSE;
- }
- }
- /*
- * Warn the user if there were duplicate symbols,
- * or symbols with duplicate ids.
- */
- if (fDups)
- Message(MSG_IDUPIDS);
- return TRUE;
- }
- /****************************************************************************
- * FindDefine
- *
- * This function looks for ^#define[st], that "#define" at the start
- * of a line and followed by a space or a tab.
- *
- * Returns:
- * READ_OK -> All OK & #define found.
- * READ_EOF -> All OK, but EOF found before #define.
- * READ_BAD = Failure on read.
- *
- ****************************************************************************/
- STATICFN INT FindDefine(VOID)
- {
- LPTSTR pchIn;
- LPTSTR pchCmp;
- BOOL fLastAtNewLine;
- tryagain:
- /*
- * Skip blank lines looking for a newline followed by a '#'.
- */
- while (TRUE) {
- fLastAtNewLine = fAtNewLine;
- pchIn = GetChar();
- if (pchIn == NULL)
- return READ_EOF;
- else if (pchIn == BAD_POINTER)
- return READ_BAD;
- else if (fLastAtNewLine && *pchIn == CHAR_POUND)
- break;
- else if (IsDBCSLeadByte((BYTE)*pchIn))
- pchIn = GetChar();
- }
- /*
- * At this point a newline followed by a '#' has been found.
- * Begin checking for "define". Save away the file offset,
- * in case we have really found one.
- */
- fposLastDefine = cchFile - 1;
- pchCmp = ids(IDS_DEFINE);
- do {
- pchIn = GetChar();
- if (pchIn == BAD_POINTER)
- return READ_BAD;
- else if (pchIn == NULL || *pchIn != *pchCmp++)
- goto tryagain;
- } while (*pchCmp);
- /*
- * Finally, look for the trailing space or tab after the "#define".
- */
- pchIn = GetChar();
- if (pchIn == BAD_POINTER)
- return READ_BAD;
- else if (pchIn == NULL || (*pchIn != CHAR_SPACE && *pchIn != CHAR_TAB))
- goto tryagain;
- return READ_OK;
- }
- /************************************************************************
- * GetLabel
- *
- * This function gets the next two words from the file hfInclude and treats
- * them as a label and id, respectively. It allocates another LABEL
- * and string to hold this information.
- *
- * Arguments:
- * BOOL *pfDups = Points to a BOOL that will be set to TRUE if AddLabel
- * finds a duplicate symbol or id.
- *
- * Returns:
- * READ_OK -> All OK.
- * READ_BAD = Failure on read.
- *
- ************************************************************************/
- STATICFN INT GetLabel(
- BOOL *pfDups)
- {
- INT id;
- INT RetCode;
- TCHAR szLabel[CCHTEXTMAX];
- /*
- * Get string and ID at current position
- */
- switch (RetCode = GetWord(szLabel)) {
- case READ_OK:
- if ((RetCode = GetValue(&id)) == READ_OK) {
- AddLabel(szLabel, id, fposLastDefine,
- (INT)(fposWordStart - fposLastDefine),
- &plInclude, &plDelInclude, NULL, pfDups);
- }
- break;
- default:
- break;
- }
- return RetCode;
- }
- /************************************************************************
- * GetWord
- *
- * This function uses GetChar to get the next word from the include
- * file. First it removes tabs and spaces, then it collects everything
- * to the next white space. Finally it null terminates the word.
- *
- * Arguments:
- * LPTSTR pch - Where to put the word.
- *
- * Returns:
- * READ_OK - a word was found.
- * READ_EOF - EOF was found.
- * READ_BAD - Error on Read.
- * READ_WRONG - Found other than ' ' or 't' followed by a letter,
- * number or _, +, -.
- *
- ************************************************************************/
- STATICFN INT GetWord(
- LPTSTR pch)
- {
- TCHAR ch;
- LPTSTR pchIn;
- /*
- * Skip spaces.
- */
- while ((pchIn = GetChar()) != NULL && pchIn != BAD_POINTER &&
- ((ch = *pchIn) == CHAR_SPACE || ch == CHAR_TAB))
- ;
- /*
- * Errors or EOF?
- */
- if (pchIn == NULL)
- return READ_EOF;
- else if (pchIn == BAD_POINTER)
- return READ_BAD;
- if (!iscsym(ch) && ch != CHAR_MINUS && ch != CHAR_PLUS)
- return READ_WRONG;
- /*
- * Save starting location of the word in the file.
- */
- fposWordStart = cchFile - 1;
- /*
- * Pick out the current word.
- */
- do {
- *pch++ = ch;
- } while ((pchIn = GetChar()) != NULL && pchIn != BAD_POINTER &&
- (ch = *pchIn) != CHAR_SPACE && ch != CHAR_TAB &&
- ch != CHAR_NEWLINE && ch != CHAR_RETURN);
- /*
- * Errors or EOF?
- */
- if (pchIn == NULL)
- return READ_WRONG;
- else if (pchIn == BAD_POINTER)
- return READ_BAD;
- /*
- * Null terminate the word.
- */
- *pch = (TCHAR)0;
- return READ_OK;
- }
- /************************************************************************
- * GetChar
- *
- * This function returns a pointer to the next character in the
- * stream hfInclude. It calls ReadChar to do the actual work.
- *
- * As it is reading the stream, it will compress a comment sequence to
- * a single space. This means that from a slash+asterisk to the next
- * asterisk+slash and from a pair of slashes to the end of the line all
- * that will be returned is a single space character.
- *
- * Returns:
- * A pointer to next character in the stream hfInclude.
- * NULL => End of file.
- * BAD_POINTER => Problems reading file.
- *
- ************************************************************************/
- STATICFN LPTSTR GetChar(VOID)
- {
- register LPTSTR pch;
- /*
- * Read the next character.
- */
- pch = ReadChar();
- if (pch == NULL || pch == BAD_POINTER)
- return pch;
- /*
- * Possibly starting a comment?
- */
- if (*pch == CHAR_SLASH) {
- /*
- * Starting a traditional comment?
- */
- if (*(pch + 1) == CHAR_ASTERISK) {
- /*
- * Read the '*'.
- */
- pch = ReadChar();
- if (pch == NULL || pch == BAD_POINTER)
- return pch;
- /*
- * Read until the next asterisk+slash is found.
- */
- do {
- pch = ReadChar();
- if (pch == NULL || pch == BAD_POINTER)
- return pch;
- } while (*pch != CHAR_ASTERISK || *(pch + 1) != CHAR_SLASH);
- /*
- * Read the final '/'.
- */
- pch = ReadChar();
- if (pch == NULL || pch == BAD_POINTER)
- return pch;
- /*
- * Change it to a space.
- */
- *pch = CHAR_SPACE;
- }
- /*
- * Starting a single line comment?
- */
- else if (*(pch + 1) == CHAR_SLASH) {
- /*
- * Read up to the end of line.
- */
- do {
- pch = ReadChar();
- if (pch == NULL || pch == BAD_POINTER)
- return pch;
- } while (*(pch + 1) != CHAR_RETURN && *(pch + 1) != CHAR_NEWLINE);
- /*
- * Convert the last character before the newline into a space.
- */
- *pch = CHAR_SPACE;
- }
- }
- return pch;
- }
- /************************************************************************
- * ReadChar
- *
- * This function returns a pointer to the next character in the
- * stream hfInclude, but does it in a buffered fashion. That is, abBuffer
- * is filled from hfInclude and pointers are returned to there.
- * Note that after ReadChar is called, all previous pointers
- * returned are meaningless.
- *
- * Returns:
- * A pointer to next character in the stream hfInclude.
- * NULL => End of file.
- * BAD_POINTER => Problems reading file.
- *
- * Comments:
- * May cause abBuffer to be filled from file with handle hfInclude.
- * cbBuf is changed.
- * cchFile is changed.
- * Sets fAtNewLine = TRUE if char returned is 'n' or 'r', or FALSE
- * otherwise. Not changed unless a character is returned.
- *
- ************************************************************************/
- STATICFN LPTSTR ReadChar(VOID)
- {
- register LPTSTR pch;
- INT cbRead;
- if (cchFile >= cchFileMax)
- return NULL;
- if (cbBuf >= CCHFILEBUFFER) {
- if ((cbRead = _lread((HFILE)hfInclude, abBuffer, CCHFILEBUFFER)) == -1)
- return BAD_POINTER;
- MultiByteToWideChar(CP_ACP, 0, abBuffer, cbRead, achBuffer,
- CCHFILEBUFFER);
- cbBuf = 0;
- }
- pch = achBuffer + cbBuf;
- cbBuf++;
- cchFile++;
- if (*pch == CHAR_DOSEOF) {
- cchFile = cchFileMax;
- return NULL;
- }
- fAtNewLine = (*pch == CHAR_RETURN || *pch == CHAR_NEWLINE) ? TRUE : FALSE;
- return pch;
- }
- /************************************************************************
- * GetValue
- *
- * This function reads the next word in the file hfInclude with GetWord
- * and converts that word to a number.
- *
- * If the second character of the word is an 'x' or 'X', the word is
- * assumed to be a hex number and it is converted appropriately.
- *
- * Arguments:
- * npsValue - Where to put the value of the next word in file.
- *
- * Returns:
- * READ_OK - success.
- * READ_BAD - am error occured.
- * READ_WRONG - Something other than a number was found.
- *
- ************************************************************************/
- STATICFN INT GetValue(
- PINT pnValue)
- {
- TCHAR achValue[CCHTEXTMAX];
- LPTSTR pch;
- INT RetValue;
- *pnValue = 0;
- if ((RetValue = GetWord(achValue)) != READ_OK)
- return RetValue;
- /*
- * Verify we have only a number.
- */
- pch = achValue;
- if (pch[1] == CHAR_CAP_X || pch[1] == CHAR_X) {
- if (*pch != CHAR_0) {
- RetValue = READ_WRONG;
- }
- else {
- for (pch += 2; *pch; pch++) {
- if (!iswxdigit(*pch)) {
- RetValue = READ_WRONG;
- break;
- }
- }
- if (RetValue == READ_OK)
- *pnValue = axtoi(&achValue[2]);
- }
- }
- else {
- if (!iswdigit(*pch) && *pch != CHAR_MINUS && *pch != CHAR_PLUS) {
- RetValue = READ_WRONG;
- }
- else {
- for (pch++; *pch; pch++) {
- if (!iswdigit(*pch)) {
- RetValue = READ_WRONG;
- break;
- }
- }
- if (RetValue == READ_OK)
- *pnValue = awtoi(achValue);
- }
- }
- return RetValue;
- }
- /************************************************************************
- * FreeInclude
- *
- * This function frees the memory associated with an include file,
- * sets global variables to match, and closes the currently open
- * include file. It frees plInclude, plDelInclude and all the LABELs in them.
- * It sets gfIncChged to FALSE, sets pszIncludeFile to NULL, and
- * closes any open include file.
- *
- ************************************************************************/
- VOID FreeInclude(VOID)
- {
- FreeLabels(&plInclude);
- FreeLabels(&plDelInclude);
- gfIncChged = FALSE;
- pszIncludeFile = NULL;
- }
- /************************************************************************
- * WriteInc
- *
- * This function writes the labels in plInclude to an include file.
- *
- * Arguments:
- * HANDLE hfWrite - handle to the file to write to.
- *
- * Returns:
- * TRUE if successful, FALSE if not.
- *
- ************************************************************************/
- BOOL WriteInc(
- HANDLE hfWrite)
- {
- INT nGNIRet;
- NPLABEL plInc;
- BOOL fEOF;
- /*
- * Is there an include file already specified? If so,
- * open it. If not, we are effectively at EOF now.
- */
- if (pszIncludeFile) {
- if ((hfInclude = CreateFile(szFullIncludeFile, GENERIC_READ,
- FILE_SHARE_READ, NULL, OPEN_EXISTING,
- FILE_FLAG_SEQUENTIAL_SCAN, NULL)) == (HANDLE)-1) {
- //if the include file is missing or locked...
- return FALSE;
- }
- fEOF = FALSE;
- }
- else {
- fEOF = TRUE;
- }
- cchFile = 0;
- cbWritePos = 0;
- cbBuf = CCHFILEBUFFER;
- fAtNewLine = TRUE;
- /*
- * Loop through all the includes.
- */
- nGNIRet = GetNextInc(&plInc, TRUE);
- while (nGNIRet != GNI_DONE) {
- switch (nGNIRet) {
- case GNI_NOCHANGE:
- break;
- case GNI_CHANGED:
- if (!WriteChangedInc(hfWrite, plInc))
- return FALSE;
- break;
- case GNI_DELETED:
- if (!WriteDeletedInc(hfWrite, plInc))
- return FALSE;
- break;
- case GNI_ADDED:
- /*
- * The first time we reach an added label, we know that
- * there are no more changed or deleted ones to handle
- * so we read/write up to the end of the old include file.
- * This only has to be done once.
- */
- if (!fEOF) {
- if (!RWToOffset(hfWrite, FPOS_MAX))
- return FALSE;
- fEOF = TRUE;
- /*
- * In the unlikely case that the read include file
- * does not end with a carriage return and/or
- * linefeed character, add them before beginning
- * to write added labels. This ensures that the
- * first label added always starts on a new line.
- */
- if (!fAtNewLine) {
- if (!WriteIncChar(hfWrite, CHAR_RETURN))
- return FALSE;
- if (!WriteIncChar(hfWrite, CHAR_NEWLINE))
- return FALSE;
- }
- }
- if (!WriteAddedInc(hfWrite, plInc))
- return FALSE;
- break;
- }
- nGNIRet = GetNextInc(&plInc, FALSE);
- }
- /*
- * Write the rest of the file, if there is any left.
- */
- if (!fEOF)
- if (!RWToOffset(hfWrite, FPOS_MAX))
- return FALSE;
- /*
- * Flush any remaining characters in the write buffer.
- */
- if (!WriteIncFlush(hfWrite))
- return FALSE;
- /*
- * If we just opened the old include file, close it.
- */
- if (pszIncludeFile)
- CloseHandle(hfInclude);
- return TRUE;
- }
- /************************************************************************
- * GetNextInc
- *
- * This routine will return the next label in the plInclude and plDelInclude
- * linked lists, as well as the status of the returned label.
- *
- * The labels will be returned in order based upon their location in the
- * lists, which is their order found in the include file if their fpos
- * field is not FPOS_MAX. This routine looks at the next label in both the
- * plInclude and plDelInclude lists and returns the one with the lowest
- * fpos. Labels are returned from plInclude and plDelInclude in order of
- * their fpos until all have been returned with a valid fpos. After this,
- * all new includes are returned from plInclude.
- *
- * Call it with fFirst equal to TRUE to initialize it.
- *
- * Arguments:
- * NPLABEL *pplReturn - label to return.
- * BOOL fFirst - TRUE if initializing.
- *
- * Returns:
- * GNI_DONE - No more labels exist.
- * GNI_NOCHANGE - An existing label is being returned.
- * GNI_CHANGED - An existing label with a changed id is being returned.
- * GNI_DELETED - A deleted label is being returned.
- * GNI_ADDED - An added label is being returned.
- *
- ************************************************************************/
- STATICFN INT GetNextInc(
- NPLABEL *pplReturn,
- BOOL fFirst)
- {
- static NPLABEL plCur;
- static NPLABEL plDelCur;
- /*
- * Initialize if this is the first time.
- */
- if (fFirst) {
- plCur = plInclude;
- plDelCur = plDelInclude;
- }
- /*
- * Are we out of valid includes?
- */
- if (!plCur) {
- /*
- * If there are deleted ones left, return the next one.
- * Otherwise we are done.
- */
- if (plDelCur) {
- *pplReturn = plDelCur;
- plDelCur = plDelCur->npNext;
- return GNI_DELETED;
- }
- else {
- return GNI_DONE;
- }
- }
- /*
- * Have we reached the added includes (fpos == FPOS_MAX)?
- */
- else if (plCur->fpos == FPOS_MAX) {
- /*
- * If there are deleted ones remaining, return them first.
- * Otherwise, return the next added one.
- */
- if (plDelCur) {
- *pplReturn = plDelCur;
- plDelCur = plDelCur->npNext;
- return GNI_DELETED;
- }
- else {
- *pplReturn = plCur;
- plCur = plCur->npNext;
- return GNI_ADDED;
- }
- }
- else {
- /*
- * Return either the next label or the next deleted label,
- * based on whether there are any deleted labels and who
- * has the lowest file position (fpos).
- */
- if (plDelCur && plDelCur->fpos < plCur->fpos) {
- *pplReturn = plDelCur;
- plDelCur = plDelCur->npNext;
- return GNI_DELETED;
- }
- else {
- *pplReturn = plCur;
- plCur = plCur->npNext;
- /*
- * Return either GNI_CHANGE or GNI_NOCHANGE based on
- * whether the original id value has been changed.
- */
- return ((*pplReturn)->id == (*pplReturn)->idOrig) ?
- GNI_NOCHANGE : GNI_CHANGED;
- }
- }
- }
- /************************************************************************
- * RWToOffset
- *
- * This routine reads from the current include file and writes to the
- * hfWrite file up to the lOffset position in the file. If lOffset is
- * set to FPOS_MAX, reads/writes are performed up to the end of the
- * read file.
- *
- * Arguments:
- * HANDLE hfWrite - handle to the file to write to.
- * DWORD lOffset - where to write up to.
- *
- * Returns:
- * TRUE if successful, FALSE if not.
- *
- * Comments:
- * This routine relies on cchFile and cchFileMax to be properly updated
- * by the reading and writing routines.
- *
- ************************************************************************/
- STATICFN BOOL RWToOffset(
- HANDLE hfWrite,
- DWORD lOffset)
- {
- LPTSTR pchIn;
- DWORD cbWrite;
- if (lOffset == FPOS_MAX)
- lOffset = cchFileMax;
- for (cbWrite = lOffset - cchFile; cbWrite; cbWrite--) {
- /*
- * NULL can be returned if there is an EOF character found in
- * the file. This is not an error, and we will stop reading
- * and writing at this point.
- */
- if ((pchIn = ReadChar()) == NULL)
- return TRUE;
- /*
- * If BAD_POINTER is returned, there was an error reading the
- * include file.
- */
- if (pchIn == BAD_POINTER)
- return FALSE;
- /*
- * Write out the character.
- */
- if (!WriteIncChar(hfWrite, *pchIn))
- return FALSE;
- }
- return TRUE;
- }
- /************************************************************************
- * WriteIncChar
- *
- * This routine writes a character (ch) to the hfWrite file, doing it in a
- * buffered fashion. Because it is buffered, before closing the file
- * any remaining characters in the buffer must be "flushed" to disk.
- *
- * Arguments:
- * HANDLE hfWrite - handle to the file to write to.
- * TCHAR ch - character to write.
- *
- * Returns:
- * TRUE if successful, FALSE if not.
- *
- * Comments:
- * The globals gachWriteBuffer and cbWritePos are updated by this routine.
- *
- ************************************************************************/
- STATICFN BOOL WriteIncChar(
- HANDLE hfWrite,
- TCHAR ch)
- {
- INT cbWritten;
- gachWriteBuffer[cbWritePos++] = ch;
- /*
- * Is the buffer full?
- */
- if (cbWritePos == CCHFILEBUFFER) {
- CHAR abWriteBuffer[CCHFILEBUFFER];
- BOOL fDefCharUsed;
- WideCharToMultiByte(CP_ACP, 0, gachWriteBuffer, CCHFILEBUFFER,
- abWriteBuffer, CCHFILEBUFFER, NULL, &fDefCharUsed);
- cbWritten = (INT)_lwrite((HFILE)hfWrite, abWriteBuffer, cbWritePos);
- if (cbWritten != cbWritePos)
- return FALSE;
- cbWritePos = 0;
- }
- return TRUE;
- }
- /************************************************************************
- * WriteIncFlush
- *
- * This routine flushes the write buffer. This must be done before
- * the file is closed or data can be lost.
- *
- * Arguments:
- * HANDLE hfWrite - handle to the file to write to.
- *
- * Returns:
- * TRUE if successful, FALSE if not.
- *
- * Comments:
- * The global cbWritePos is updated by this routine.
- *
- ************************************************************************/
- STATICFN BOOL WriteIncFlush(
- HANDLE hfWrite)
- {
- INT cbWritten;
- /*
- * Are any bytes remaining in the buffer?
- */
- if (cbWritePos) {
- CHAR abWriteBuffer[CCHFILEBUFFER];
- BOOL fDefCharUsed;
- WideCharToMultiByte(CP_ACP, 0, gachWriteBuffer, cbWritePos,
- abWriteBuffer, CCHFILEBUFFER, NULL, &fDefCharUsed);
- cbWritten = (INT)_lwrite((HFILE)hfWrite, abWriteBuffer, cbWritePos);
- if (cbWritten != cbWritePos)
- return FALSE;
- cbWritePos = 0;
- }
- return TRUE;
- }
- /************************************************************************
- * WriteChangedInc
- *
- * This routine writes out a label that has had its id changed since the
- * include file was last read.
- *
- * Arguments:
- * HANDLE hfWrite - File to write to.
- * NPLABEL plInc - Label to write.
- *
- * Returns:
- * TRUE if successful, FALSE if not.
- *
- * History:
- * 03/13/90 Byron Dazey - Created.
- ************************************************************************/
- STATICFN BOOL WriteChangedInc(
- HANDLE hfWrite,
- NPLABEL plInc)
- {
- TCHAR ch;
- LPTSTR pchIn;
- if (!RWToOffset(hfWrite, plInc->fpos + plInc->nValueOffset))
- return FALSE;
- /*
- * Consume the old id value (up to the next space, tab,
- * beginning of a comment, newline or return).
- */
- while ((pchIn = ReadChar()) != NULL && pchIn != BAD_POINTER &&
- (ch = *pchIn) != CHAR_SPACE && ch != CHAR_TAB &&
- ch != CHAR_SLASH && ch != CHAR_NEWLINE && ch != CHAR_RETURN)
- ;
- /*
- * It is an error if ReadChar returns BAD_POINTER. Note that it
- * is NOT an error if it reaches EOF (and returns NULL).
- */
- if (pchIn == BAD_POINTER)
- return FALSE;
- /*
- * Write the new one.
- */
- if (!WriteIDInc(hfWrite, plInc->id))
- return FALSE;
- /*
- * Remember to write the last character read after the old value.
- */
- if (pchIn != NULL)
- if (!WriteIncChar(hfWrite, *pchIn))
- return FALSE;
- return TRUE;
- }
- /************************************************************************
- * WriteDeletedInc
- *
- * This routine deletes a label in the include file, closing up the
- * space. The entire line will be deleted, unless a comment is found
- * after the id value. If so, the comment and following characters will
- * be left.
- *
- * Arguments:
- * HANDLE hfWrite - File to write to.
- * NPLABEL plInc - Label to delete.
- *
- * Returns:
- * TRUE if successful, FALSE if not.
- *
- * History:
- * 03/13/90 Byron Dazey - Created.
- ************************************************************************/
- STATICFN BOOL WriteDeletedInc(
- HANDLE hfWrite,
- NPLABEL plInc)
- {
- register INT i;
- TCHAR ch;
- LPTSTR pchIn;
- /*
- * Read and write up to the #define to be deleted.
- */
- if (!RWToOffset(hfWrite, plInc->fpos))
- return FALSE;
- /*
- * Consume up to the id value.
- */
- for (i = plInc->nValueOffset; i; i--)
- if ((pchIn = ReadChar()) == NULL || pchIn == BAD_POINTER)
- return FALSE;
- /*
- * Consume the id value and following characters up to the end of
- * the line or the beginning of a comment.
- */
- while ((pchIn = ReadChar()) != NULL && pchIn != BAD_POINTER &&
- (ch = *pchIn) != CHAR_NEWLINE && ch != CHAR_RETURN &&
- ch != CHAR_SLASH)
- ;
- if (pchIn == BAD_POINTER)
- return FALSE;
- /*
- * We are done if we have reached EOF.
- */
- if (pchIn == NULL)
- return TRUE;
- /*
- * If the beginning of a comment was found, be sure to write the
- * character back out and leave the rest of the comment.
- */
- if (ch == CHAR_SLASH) {
- if (!WriteIncChar(hfWrite, ch))
- return FALSE;
- }
- else {
- /*
- * At this point either a newline or a return was found
- * and we are going to consume it. We also want to check
- * for a return following the newline, or a newline
- * following the return and consume it also.
- */
- if ((ch == CHAR_NEWLINE && *(pchIn + 1) == CHAR_RETURN) ||
- (ch == CHAR_RETURN && *(pchIn + 1) == CHAR_NEWLINE))
- if (ReadChar() == BAD_POINTER)
- return FALSE;
- }
- return TRUE;
- }
- /************************************************************************
- * WriteAddedInc
- *
- * Adds a label to the new include file.
- *
- * Arguments:
- * HANDLE hfWrite - File to write to.
- * NPLABEL plInc - Label to add.
- *
- * Returns:
- * TRUE if successful, FALSE if not.
- *
- * History:
- * 03/13/90 Byron Dazey - Created.
- ************************************************************************/
- STATICFN BOOL WriteAddedInc(
- HANDLE hfWrite,
- NPLABEL plInc)
- {
- register LPTSTR psz;
- /*
- * Write the "#define " string.
- */
- psz = ids(IDS_POUNDDEFINE);
- while (*psz)
- if (!WriteIncChar(hfWrite, *psz++))
- return FALSE;
- /*
- * Write the symbol, followed by a space.
- */
- if (!WriteSymbol(hfWrite, plInc->pszLabel))
- return FALSE;
- if (!WriteIncChar(hfWrite, CHAR_SPACE))
- return FALSE;
- /*
- * Write the id, followed by a carriage return and newline.
- */
- if (!WriteIDInc(hfWrite, plInc->id))
- return FALSE;
- if (!WriteIncChar(hfWrite, CHAR_RETURN))
- return FALSE;
- if (!WriteIncChar(hfWrite, CHAR_NEWLINE))
- return FALSE;
- return TRUE;
- }
- /************************************************************************
- * WriteSymbol
- *
- * Writes out a "#define DID_xxx " string to hfWrite. If the symbol
- * is smaller than CCHSYMFIELDWIDTH, it will be padded with spaces out
- * to this width.
- *
- * Arguments:
- * HANDLE hfWrite - handle to the file to write to.
- * LPTSTR pszSymbol - symbol to write.
- *
- * Returns:
- * TRUE if successful, FALSE if not.
- *
- ************************************************************************/
- STATICFN BOOL WriteSymbol(
- HANDLE hfWrite,
- LPTSTR pszSymbol)
- {
- register INT cch;
- /*
- * Write the symbol.
- */
- cch = 0;
- while (*pszSymbol) {
- if (!WriteIncChar(hfWrite, *pszSymbol++))
- return FALSE;
- cch++;
- }
- /*
- * Pad the field with blanks out to CCHSYMFIELDWIDTH, if necessary.
- */
- if (cch < CCHSYMFIELDWIDTH) {
- cch = CCHSYMFIELDWIDTH - cch;
- while (cch--)
- if (!WriteIncChar(hfWrite, CHAR_SPACE))
- return FALSE;
- }
- return TRUE;
- }
- /************************************************************************
- * WriteIDInc
- *
- * Writes out an id value to the hfWrite file. The format will be in
- * either hex or decimal, depending on the current mode.
- *
- * Arguments:
- * HANDLE hfWrite - File to write to.
- * INT id - ID to write.
- *
- * Returns:
- * TRUE if successful, FALSE if not.
- *
- ************************************************************************/
- STATICFN BOOL WriteIDInc(
- HANDLE hfWrite,
- INT id)
- {
- register LPTSTR psz;
- TCHAR szValue[CCHIDMAX + 1];
- Myitoa(id, szValue);
- psz = szValue;
- while (*psz)
- if (!WriteIncChar(hfWrite, *psz++))
- return FALSE;
- return TRUE;
- }