Annotation of mstools/samples/sdktools/dlgedit/rwinc.c, revision 1.1

1.1     ! root        1: 
        !             2: /******************************************************************************\
        !             3: *       This is a part of the Microsoft Source Code Samples. 
        !             4: *       Copyright (C) 1993 Microsoft Corporation.
        !             5: *       All rights reserved. 
        !             6: *       This source code is only intended as a supplement to 
        !             7: *       Microsoft Development Tools and/or WinHelp documentation.
        !             8: *       See these sources for detailed information regarding the 
        !             9: *       Microsoft samples programs.
        !            10: \******************************************************************************/
        !            11: 
        !            12: /****************************** Module Header *******************************
        !            13: * Module Name: rwinc.c
        !            14: *
        !            15: * Does the include file reading and writing.
        !            16: *
        !            17: * Functions:
        !            18: *
        !            19: *    OpenIncludeFile()
        !            20: *    FreeInclude()
        !            21: *    WriteInc()
        !            22: *    LoadIncludeFile()
        !            23: *    GetChar()
        !            24: *    ReadChar()
        !            25: *    GetLabel()
        !            26: *    GetValue()
        !            27: *    GetWord()
        !            28: *    FindDefine()
        !            29: *    GetNextInc()
        !            30: *    RWToOffset()
        !            31: *    WriteIncChar()
        !            32: *    WriteIncFlush()
        !            33: *    WriteChangedInc()
        !            34: *    WriteDeletedInc()
        !            35: *    WriteAddedInc()
        !            36: *    WriteSymbol()
        !            37: *    WriteIDInc()
        !            38: *
        !            39: * Comments:
        !            40: *
        !            41: ****************************************************************************/
        !            42: 
        !            43: #include "dlgedit.h"
        !            44: #include "dlgfuncs.h"
        !            45: #include "dlgextrn.h"
        !            46: 
        !            47: #include <ctype.h>
        !            48: 
        !            49: 
        !            50: /*
        !            51:  * Field width that the symbol is printed within.  This indirectly
        !            52:  * determines where the id value starts, because blanks are added
        !            53:  * after the symbol is printed up to this width value.
        !            54:  */
        !            55: #define CCHSYMFIELDWIDTH    27
        !            56: 
        !            57: /*
        !            58:  * Return codes from the file reading functions.
        !            59:  */
        !            60: #define READ_OK             1
        !            61: #define READ_EOF            2
        !            62: #define READ_BAD            3
        !            63: #define READ_WRONG          4
        !            64: #define BAD_POINTER         ((VOID *)0xFFFF)
        !            65: 
        !            66: /*
        !            67:  * Return codes from the GetNextInc function.
        !            68:  */
        !            69: #define GNI_DONE            0
        !            70: #define GNI_NOCHANGE        1
        !            71: #define GNI_CHANGED         2
        !            72: #define GNI_DELETED         3
        !            73: #define GNI_ADDED           4
        !            74: 
        !            75: static BYTE abBuffer[CCHFILEBUFFER];    /* Buffer for read file data.       */
        !            76: static TCHAR achBuffer[CCHFILEBUFFER];  /* Unicode buffer for data.         */
        !            77: static INT cbBuf;                       /* Pointer into achBuffer.          */
        !            78: static DWORD cchFile;                   /* Count of characters read.        */
        !            79: static DWORD cchFileMax;                /* Max characters in file.          */
        !            80: static DWORD fposLastDefine;            /* Saves location of "#define".     */
        !            81: static DWORD fposWordStart;             /* Saves start of id value.         */
        !            82: static BOOL fAtNewLine;                 /* At start or \r or \n.            */
        !            83: static HANDLE hfInclude;                /* The current include file.        */
        !            84: 
        !            85: STATICFN BOOL LoadIncludeFile(VOID);
        !            86: STATICFN LPTSTR GetChar(VOID);
        !            87: STATICFN LPTSTR ReadChar(VOID);
        !            88: STATICFN INT GetLabel(BOOL *pfDups);
        !            89: STATICFN INT GetValue(PINT pnValue);
        !            90: STATICFN INT GetWord(LPTSTR pch);
        !            91: STATICFN INT FindDefine(VOID);
        !            92: STATICFN INT GetNextInc(NPLABEL *pplReturn, BOOL fFirst);
        !            93: STATICFN BOOL RWToOffset(HANDLE hfWrite, DWORD lOffset);
        !            94: STATICFN BOOL WriteIncChar(HANDLE hfWrite, TCHAR ch);
        !            95: STATICFN BOOL WriteIncFlush(HANDLE hfWrite);
        !            96: STATICFN BOOL WriteChangedInc(HANDLE hfWrite, NPLABEL plInc);
        !            97: STATICFN BOOL WriteDeletedInc(HANDLE hfWrite, NPLABEL plInc);
        !            98: STATICFN BOOL WriteAddedInc(HANDLE hfWrite, NPLABEL plInc);
        !            99: STATICFN BOOL WriteSymbol(HANDLE hfWrite, LPTSTR pszSymbol);
        !           100: STATICFN BOOL WriteIDInc(HANDLE hfWrite, INT id);
        !           101: 
        !           102: 
        !           103: 
        !           104: /****************************************************************************
        !           105: * OpenIncludeFile
        !           106: *
        !           107: * This function attempts to open and load the include file with name
        !           108: * pointed to by pszOpenInclude.  If pszOpenInclude is just a file name, and
        !           109: * not a path, then the path is taken from szFullLoadFile.  Otherwise
        !           110: * pszOpenInclude itself is used.  The full pathname is put in
        !           111: * szFullIncludeFile and pszIncludeFile is set to point to just the file
        !           112: * name in it.  
        !           113: *
        !           114: * If fDoOpen is TRUE, the file is opened.  If it is FALSE, it is assumed
        !           115: * that hfInc contains the file handle to the opened include file and this
        !           116: * handle is used.  In addition, the caller is responsible for closing
        !           117: * any passed in file handle if an error occurs.
        !           118: *
        !           119: * Any existing includes are freed,  szFullIncludeFile is set to the full 
        !           120: * include path, pszIncludeFile is set to the filename portion of this full 
        !           121: * path and hfInclude will contain the file handle to the include file.
        !           122: *
        !           123: * Arguments:
        !           124: *   LPTSTR pszOpenInclude - name of the include file to open.
        !           125: *
        !           126: * Returns:
        !           127: *   If the load is successful, TRUE is returned.  Otherwise,
        !           128: *   FALSE is returned.
        !           129: *
        !           130: ****************************************************************************/
        !           131: 
        !           132: BOOL OpenIncludeFile(
        !           133:     LPTSTR pszOpenInclude)
        !           134: {
        !           135:     TCHAR szFullIncludeFileTemp[CCHMAXPATH];
        !           136:     HCURSOR hcurSave;
        !           137:     BOOL fSuccess = FALSE;
        !           138: 
        !           139:     hcurSave = SetCursor(hcurWait);
        !           140: 
        !           141:     if (FileInPath(pszOpenInclude) == pszOpenInclude) {
        !           142:         lstrcpy(szFullIncludeFileTemp, szFullResFile);
        !           143:         lstrcpy(FileInPath(szFullIncludeFileTemp), pszOpenInclude);
        !           144:     }
        !           145:     else {
        !           146:         lstrcpy(szFullIncludeFileTemp, pszOpenInclude);
        !           147:     }
        !           148: 
        !           149:     /*
        !           150:      * Close any existing include file and free memory.
        !           151:      */
        !           152:     FreeInclude();
        !           153: 
        !           154:     if ((hfInclude = CreateFile(szFullIncludeFileTemp, GENERIC_READ,
        !           155:             FILE_SHARE_READ, NULL, OPEN_EXISTING,
        !           156:             FILE_FLAG_SEQUENTIAL_SCAN, NULL)) != (HANDLE)-1) {
        !           157:         if (LoadIncludeFile()) {
        !           158:             lstrcpy(szFullIncludeFile, szFullIncludeFileTemp);
        !           159:             pszIncludeFile = FileInPath(szFullIncludeFile);
        !           160:             fSuccess = TRUE;
        !           161:         }
        !           162: 
        !           163:         CloseHandle(hfInclude);
        !           164:     }
        !           165: 
        !           166:     /*
        !           167:      * Update the status windows symbol combo box.  Update other fields
        !           168:      * also, in case the currently selected control's symbol was affected
        !           169:      * by the reading of the new include file.
        !           170:      */
        !           171:     StatusFillSymbolList(plInclude);
        !           172:     StatusUpdate();
        !           173: 
        !           174:     ShowFileStatus(TRUE);
        !           175:     SetCursor(hcurSave);
        !           176: 
        !           177:     return fSuccess;
        !           178: }
        !           179: 
        !           180: 
        !           181: 
        !           182: /************************************************************************
        !           183: * LoadIncludeFile
        !           184: *
        !           185: * This function creates or adds to plInclude with all the #define
        !           186: * statements in the file with handle hfInclude.
        !           187: *
        !           188: * Returns:
        !           189: *     TRUE - Load succeeded.
        !           190: *     FALSE - Load failed (a read error).
        !           191: *
        !           192: ************************************************************************/
        !           193: 
        !           194: STATICFN BOOL LoadIncludeFile(VOID)
        !           195: {
        !           196:     INT RetCode;
        !           197:     BOOL fDups = FALSE;
        !           198: 
        !           199:     /*
        !           200:      * Set char count, get file cb.
        !           201:      */
        !           202:     cchFile = 0L;
        !           203:     cchFileMax = GetFileSize((HANDLE)hfInclude, NULL);
        !           204:     cbBuf = CCHFILEBUFFER;
        !           205:     fAtNewLine = TRUE;
        !           206: 
        !           207:     /*
        !           208:      * Loop through and extract all id definitions.
        !           209:      */
        !           210:     while ((RetCode = FindDefine()) != READ_EOF) {
        !           211:         if (RetCode == READ_BAD || (RetCode = GetLabel(&fDups)) == READ_BAD) {
        !           212:             Message(MSG_INTERNAL);
        !           213:             return FALSE;
        !           214:         }
        !           215:     }
        !           216: 
        !           217:     /*
        !           218:      * Warn the user if there were duplicate symbols,
        !           219:      * or symbols with duplicate ids.
        !           220:      */
        !           221:     if (fDups)
        !           222:         Message(MSG_IDUPIDS);
        !           223: 
        !           224:     return TRUE;
        !           225: }
        !           226: 
        !           227: 
        !           228: 
        !           229: /****************************************************************************
        !           230: * FindDefine
        !           231: *
        !           232: * This function looks for ^#define[\s\t], that "#define" at the start
        !           233: * of a line and followed by a space or a tab.
        !           234: *
        !           235: * Returns:
        !           236: *     READ_OK -> All OK & #define found.
        !           237: *     READ_EOF -> All OK, but EOF found before #define.
        !           238: *     READ_BAD = Failure on read.
        !           239: *
        !           240: ****************************************************************************/
        !           241: 
        !           242: STATICFN INT FindDefine(VOID)
        !           243: {
        !           244:     LPTSTR pchIn;
        !           245:     LPTSTR pchCmp;
        !           246:     BOOL fLastAtNewLine;
        !           247: 
        !           248: tryagain:
        !           249: 
        !           250:     /*
        !           251:      * Skip blank lines looking for a newline followed by a '#'.
        !           252:      */
        !           253:     while (TRUE) {
        !           254:         fLastAtNewLine = fAtNewLine;
        !           255:         pchIn = GetChar();
        !           256: 
        !           257:         if (pchIn == NULL)
        !           258:             return READ_EOF;
        !           259:         else if (pchIn == BAD_POINTER)
        !           260:             return READ_BAD;
        !           261:         else if (fLastAtNewLine && *pchIn == CHAR_POUND)
        !           262:             break;
        !           263:     }
        !           264: 
        !           265:     /*
        !           266:      * At this point a newline followed by a '#' has been found.
        !           267:      * Begin checking for "define".  Save away the file offset,
        !           268:      * in case we have really found one.
        !           269:      */
        !           270:     fposLastDefine = cchFile - 1;
        !           271:     pchCmp = ids(IDS_DEFINE);
        !           272:     do {
        !           273:         pchIn = GetChar();
        !           274: 
        !           275:         if (pchIn == BAD_POINTER)
        !           276:             return READ_BAD;
        !           277:         else if (pchIn == NULL || *pchIn != *pchCmp++)
        !           278:             goto tryagain;
        !           279:     } while (*pchCmp);
        !           280: 
        !           281:     /*
        !           282:      * Finally, look for the trailing space or tab after the "#define".
        !           283:      */
        !           284:     pchIn = GetChar();
        !           285:     if (pchIn == BAD_POINTER)
        !           286:         return READ_BAD;
        !           287:     else if (pchIn == NULL || (*pchIn != CHAR_SPACE && *pchIn != CHAR_TAB))
        !           288:         goto tryagain;
        !           289: 
        !           290:     return READ_OK;
        !           291: }
        !           292: 
        !           293: 
        !           294: 
        !           295: /************************************************************************
        !           296: * GetLabel
        !           297: *
        !           298: * This function gets the next two words from the file hfInclude and treats
        !           299: * them as a label and id, respectively.  It allocates another LABEL
        !           300: * and string to hold this information.
        !           301: *
        !           302: * Arguments:
        !           303: *   BOOL *pfDups = Points to a BOOL that will be set to TRUE if AddLabel
        !           304: *                  finds a duplicate symbol or id.
        !           305: *
        !           306: * Returns:
        !           307: *     READ_OK -> All OK.
        !           308: *     READ_BAD = Failure on read.
        !           309: *
        !           310: ************************************************************************/
        !           311: 
        !           312: STATICFN INT GetLabel(
        !           313:     BOOL *pfDups)
        !           314: {
        !           315:     INT id;
        !           316:     INT RetCode;
        !           317:     TCHAR szLabel[CCHTEXTMAX];
        !           318: 
        !           319:     /*
        !           320:      * Get string and ID at current position
        !           321:      */
        !           322:     switch (RetCode = GetWord(szLabel)) {
        !           323:         case READ_OK:
        !           324:             if ((RetCode = GetValue(&id)) == READ_OK) {
        !           325:                 AddLabel(szLabel, id, fposLastDefine,
        !           326:                         (INT)(fposWordStart - fposLastDefine),
        !           327:                         &plInclude, &plDelInclude, NULL, pfDups);
        !           328:             }
        !           329: 
        !           330:             break;
        !           331: 
        !           332:         default:
        !           333:             break;
        !           334:     }
        !           335: 
        !           336:     return RetCode;
        !           337: }
        !           338: 
        !           339: 
        !           340: 
        !           341: /************************************************************************
        !           342: * GetWord
        !           343: *
        !           344: * This function uses GetChar to get the next word from the include
        !           345: * file.  First it removes tabs and spaces, then it collects everything
        !           346: * to the next white space.  Finally it null terminates the word.
        !           347: *
        !           348: * Arguments:
        !           349: *     LPTSTR pch  - Where to put the word.
        !           350: *
        !           351: * Returns:
        !           352: *     READ_OK - a word was found.
        !           353: *     READ_EOF - EOF was found.
        !           354: *     READ_BAD - Error on Read.
        !           355: *     READ_WRONG - Found other than ' ' or '\t' followed by a letter,
        !           356: *                   number or _, +, -.
        !           357: *
        !           358: ************************************************************************/
        !           359: 
        !           360: STATICFN INT GetWord(
        !           361:     LPTSTR pch)
        !           362: {
        !           363:     TCHAR ch;
        !           364:     LPTSTR pchIn;
        !           365: 
        !           366:     /*
        !           367:      * Skip spaces.
        !           368:      */
        !           369:     while ((pchIn = GetChar()) != NULL && pchIn != BAD_POINTER &&
        !           370:                 ((ch = *pchIn) == CHAR_SPACE || ch == CHAR_TAB))
        !           371:         ;
        !           372: 
        !           373:     /*
        !           374:      * Errors or EOF?
        !           375:      */
        !           376:     if (pchIn == NULL)
        !           377:         return READ_EOF;
        !           378:     else if (pchIn == BAD_POINTER)
        !           379:         return READ_BAD;
        !           380:     if (!iscsym(ch) && ch != CHAR_MINUS && ch != CHAR_PLUS)
        !           381:         return READ_WRONG;
        !           382: 
        !           383:     /*
        !           384:      * Save starting location of the word in the file.
        !           385:      */
        !           386:     fposWordStart = cchFile - 1;
        !           387: 
        !           388:     /*
        !           389:      * Pick out the current word.
        !           390:      */
        !           391:     do {
        !           392:         *pch++ = ch;
        !           393:     } while ((pchIn = GetChar()) != NULL && pchIn != BAD_POINTER &&
        !           394:             (ch = *pchIn) != CHAR_SPACE && ch != CHAR_TAB &&
        !           395:             ch != CHAR_NEWLINE && ch != CHAR_RETURN);
        !           396: 
        !           397:     /*
        !           398:      * Errors or EOF?
        !           399:      */
        !           400:     if (pchIn == NULL)
        !           401:         return READ_WRONG;
        !           402:     else if (pchIn == BAD_POINTER)
        !           403:         return READ_BAD;
        !           404: 
        !           405:     /*
        !           406:      * Null terminate the word.
        !           407:      */
        !           408:     *pch = (TCHAR)0;
        !           409: 
        !           410:     return READ_OK;
        !           411: }
        !           412: 
        !           413: 
        !           414: 
        !           415: /************************************************************************
        !           416: * GetChar
        !           417: *
        !           418: * This function returns a pointer to the next character in the
        !           419: * stream hfInclude.  It calls ReadChar to do the actual work.
        !           420: *
        !           421: * As it is reading the stream, it will compress a comment sequence to
        !           422: * a single space.  This means that from a slash+asterisk to the next
        !           423: * asterisk+slash and from a pair of slashes to the end of the line all
        !           424: * that will be returned is a single space character.
        !           425: *
        !           426: * Returns:
        !           427: *     A pointer to next character in the stream hfInclude.
        !           428: *     NULL => End of file.
        !           429: *     BAD_POINTER => Problems reading file.
        !           430: *
        !           431: ************************************************************************/
        !           432: 
        !           433: STATICFN LPTSTR GetChar(VOID)
        !           434: {
        !           435:     register LPTSTR pch;
        !           436: 
        !           437:     /*
        !           438:      * Read the next character.
        !           439:      */
        !           440:     pch = ReadChar();
        !           441:     if (pch == NULL || pch == BAD_POINTER)
        !           442:         return pch;
        !           443: 
        !           444:     /*
        !           445:      * Possibly starting a comment?
        !           446:      */
        !           447:     if (*pch == CHAR_SLASH) {
        !           448:         /*
        !           449:          * Starting a traditional comment?
        !           450:          */
        !           451:         if (*(pch + 1) == CHAR_ASTERISK) {
        !           452:             /*
        !           453:              * Read the '*'.
        !           454:              */
        !           455:             pch = ReadChar();
        !           456:             if (pch == NULL || pch == BAD_POINTER)
        !           457:                 return pch;
        !           458: 
        !           459:             /*
        !           460:              * Read until the next asterisk+slash is found.
        !           461:              */
        !           462:             do {
        !           463:                 pch = ReadChar();
        !           464:                 if (pch == NULL || pch == BAD_POINTER)
        !           465:                     return pch;
        !           466:             } while (*pch != CHAR_ASTERISK || *(pch + 1) != CHAR_SLASH);
        !           467: 
        !           468:             /*
        !           469:              * Read the final '/'.
        !           470:              */
        !           471:             pch = ReadChar();
        !           472:             if (pch == NULL || pch == BAD_POINTER)
        !           473:                 return pch;
        !           474: 
        !           475:             /*
        !           476:              * Change it to a space.
        !           477:              */
        !           478:             *pch = CHAR_SPACE;
        !           479:         }
        !           480:         /*
        !           481:          * Starting a single line comment?
        !           482:          */
        !           483:         else if (*(pch + 1) == CHAR_SLASH) {
        !           484:             /*
        !           485:              * Read up to the end of line.
        !           486:              */
        !           487:             do {
        !           488:                 pch = ReadChar();
        !           489:                 if (pch == NULL || pch == BAD_POINTER)
        !           490:                     return pch;
        !           491:             } while (*(pch + 1) != CHAR_RETURN && *(pch + 1) != CHAR_NEWLINE);
        !           492: 
        !           493:             /*
        !           494:              * Convert the last character before the newline into a space.
        !           495:              */
        !           496:             *pch = CHAR_SPACE;
        !           497:         }
        !           498:     }
        !           499: 
        !           500:     return pch;
        !           501: }
        !           502: 
        !           503: 
        !           504: 
        !           505: /************************************************************************
        !           506: * ReadChar
        !           507: *
        !           508: * This function returns a pointer to the next character in the
        !           509: * stream hfInclude, but does it in a buffered fashion.  That is, abBuffer
        !           510: * is filled from hfInclude and pointers are returned to there.
        !           511: * Note that after ReadChar is called, all previous pointers
        !           512: * returned are meaningless.
        !           513: *
        !           514: * Returns:
        !           515: *     A pointer to next character in the stream hfInclude.
        !           516: *     NULL => End of file.
        !           517: *     BAD_POINTER => Problems reading file.
        !           518: *
        !           519: * Comments:
        !           520: *     May cause abBuffer to be filled from file with handle hfInclude.
        !           521: *     cbBuf is changed.
        !           522: *     cchFile is changed.
        !           523: *     Sets fAtNewLine = TRUE if char returned is '\n' or '\r', or FALSE
        !           524: *         otherwise.  Not changed unless a character is returned.
        !           525: *
        !           526: ************************************************************************/
        !           527: 
        !           528: STATICFN LPTSTR ReadChar(VOID)
        !           529: {
        !           530:     register LPTSTR pch;
        !           531:     INT cbRead;
        !           532: 
        !           533:     if (cchFile >= cchFileMax)
        !           534:         return NULL;
        !           535: 
        !           536:     if (cbBuf >= CCHFILEBUFFER) {
        !           537:         if ((cbRead = _lread((HFILE)hfInclude, abBuffer, CCHFILEBUFFER)) == -1)
        !           538:             return BAD_POINTER;
        !           539: 
        !           540:         MultiByteToWideChar(CP_ACP, 0, abBuffer, cbRead, achBuffer,
        !           541:                 CCHFILEBUFFER);
        !           542: 
        !           543:         cbBuf = 0;
        !           544:     }
        !           545: 
        !           546:     pch = achBuffer + cbBuf;
        !           547:     cbBuf++;
        !           548:     cchFile++;
        !           549: 
        !           550:     if (*pch == CHAR_DOSEOF) {
        !           551:         cchFile = cchFileMax;
        !           552:         return NULL;
        !           553:     }
        !           554: 
        !           555:     fAtNewLine = (*pch == CHAR_RETURN || *pch == CHAR_NEWLINE) ? TRUE : FALSE;
        !           556: 
        !           557:     return pch;
        !           558: }
        !           559: 
        !           560: 
        !           561: 
        !           562: /************************************************************************
        !           563: * GetValue
        !           564: *
        !           565: * This function reads the next word in the file hfInclude with GetWord
        !           566: * and converts that word to a number.
        !           567: *
        !           568: * If the second character of the word is an 'x' or 'X', the word is
        !           569: * assumed to be a hex number and it is converted appropriately.
        !           570: *
        !           571: * Arguments:
        !           572: *     npsValue - Where to put the value of the next word in file.
        !           573: *
        !           574: * Returns:
        !           575: *     READ_OK - success.
        !           576: *     READ_BAD - am error occured.
        !           577: *     READ_WRONG - Something other than a number was found.
        !           578: *
        !           579: ************************************************************************/
        !           580: 
        !           581: STATICFN INT GetValue(
        !           582:     PINT pnValue)
        !           583: {
        !           584:     TCHAR achValue[CCHTEXTMAX];
        !           585:     LPTSTR pch;
        !           586:     INT RetValue;
        !           587: 
        !           588:     *pnValue = 0;
        !           589:     if ((RetValue = GetWord(achValue)) != READ_OK)
        !           590:         return RetValue;
        !           591: 
        !           592:     /*
        !           593:      * Verify we have only a number.
        !           594:      */
        !           595:     pch = achValue;
        !           596:     if (pch[1] == CHAR_CAP_X || pch[1] == CHAR_X) {
        !           597:         if (*pch != CHAR_0) {
        !           598:             RetValue = READ_WRONG;
        !           599:         }
        !           600:         else {
        !           601:             for (pch += 2; *pch; pch++) {
        !           602:                 if (!iswxdigit(*pch)) {
        !           603:                     RetValue = READ_WRONG;
        !           604:                     break;
        !           605:                 }
        !           606:             }
        !           607: 
        !           608:             if (RetValue == READ_OK)
        !           609:                 *pnValue = axtoi(&achValue[2]);
        !           610:         }
        !           611:     }
        !           612:     else {
        !           613:         if (!iswdigit(*pch) && *pch != CHAR_MINUS && *pch != CHAR_PLUS) {
        !           614:             RetValue = READ_WRONG;
        !           615:         }
        !           616:         else {
        !           617:             for (pch++; *pch; pch++) {
        !           618:                 if (!iswdigit(*pch)) {
        !           619:                     RetValue = READ_WRONG;
        !           620:                     break;
        !           621:                 }
        !           622:             }
        !           623: 
        !           624:             if (RetValue == READ_OK)
        !           625:                 *pnValue = awtoi(achValue);
        !           626:         }
        !           627:     }
        !           628: 
        !           629:     return RetValue;
        !           630: }
        !           631: 
        !           632: 
        !           633: 
        !           634: /************************************************************************
        !           635: * FreeInclude
        !           636: *
        !           637: * This function frees the memory associated with an include file,
        !           638: * sets global variables to match, and closes the currently open
        !           639: * include file.  It frees plInclude, plDelInclude and all the LABELs in them.
        !           640: * It sets gfIncChged to FALSE, sets pszIncludeFile to NULL, and
        !           641: * closes any open include file.
        !           642: *
        !           643: ************************************************************************/
        !           644: 
        !           645: VOID FreeInclude(VOID)
        !           646: {
        !           647:     FreeLabels(&plInclude);
        !           648:     FreeLabels(&plDelInclude);
        !           649:     gfIncChged = FALSE;
        !           650:     pszIncludeFile = NULL;
        !           651: }
        !           652: 
        !           653: 
        !           654: 
        !           655: /************************************************************************
        !           656: * WriteInc
        !           657: *
        !           658: * This function writes the labels in plInclude to an include file.
        !           659: *
        !           660: * Arguments:
        !           661: *   HANDLE hfWrite - handle to the file to write to.
        !           662: *
        !           663: * Returns:
        !           664: *   TRUE if successful, FALSE if not.
        !           665: *
        !           666: ************************************************************************/
        !           667: 
        !           668: BOOL WriteInc(
        !           669:     HANDLE hfWrite)
        !           670: {
        !           671:     INT nGNIRet;
        !           672:     NPLABEL plInc;
        !           673:     BOOL fEOF;
        !           674: 
        !           675:     /*
        !           676:      * Is there an include file already specified?  If so,
        !           677:      * open it.  If not, we are effectively at EOF now.
        !           678:      */
        !           679:     if (pszIncludeFile) {
        !           680:         if ((hfInclude = CreateFile(szFullIncludeFile, GENERIC_READ,
        !           681:                 FILE_SHARE_READ, NULL, OPEN_EXISTING,
        !           682:                 FILE_FLAG_SEQUENTIAL_SCAN, NULL)) == (HANDLE)-1) {
        !           683:             //if the include file is missing or locked...
        !           684:             return FALSE;
        !           685:         }
        !           686: 
        !           687:         fEOF = FALSE;
        !           688:     }
        !           689:     else {
        !           690:         fEOF = TRUE;
        !           691:     }
        !           692: 
        !           693:     cchFile = 0;
        !           694:     cbWritePos = 0;
        !           695:     cbBuf = CCHFILEBUFFER;
        !           696:     fAtNewLine = TRUE;
        !           697: 
        !           698:     /*
        !           699:      * Loop through all the includes.
        !           700:      */
        !           701:     nGNIRet = GetNextInc(&plInc, TRUE);
        !           702:     while (nGNIRet != GNI_DONE) {
        !           703:         switch (nGNIRet) {
        !           704:             case GNI_NOCHANGE:
        !           705:                 break;
        !           706: 
        !           707:             case GNI_CHANGED:
        !           708:                 if (!WriteChangedInc(hfWrite, plInc))
        !           709:                     return FALSE;
        !           710: 
        !           711:                 break;
        !           712: 
        !           713:             case GNI_DELETED:
        !           714:                 if (!WriteDeletedInc(hfWrite, plInc))
        !           715:                     return FALSE;
        !           716: 
        !           717:                 break;
        !           718: 
        !           719:             case GNI_ADDED:
        !           720:                 /*
        !           721:                  * The first time we reach an added label, we know that
        !           722:                  * there are no more changed or deleted ones to handle
        !           723:                  * so we read/write up to the end of the old include file.
        !           724:                  * This only has to be done once.
        !           725:                  */
        !           726:                 if (!fEOF) {
        !           727:                     if (!RWToOffset(hfWrite, FPOS_MAX))
        !           728:                         return FALSE;
        !           729: 
        !           730:                     fEOF = TRUE;
        !           731: 
        !           732:                     /*
        !           733:                      * In the unlikely case that the read include file
        !           734:                      * does not end with a carriage return and/or
        !           735:                      * linefeed character, add them before beginning
        !           736:                      * to write added labels.  This ensures that the
        !           737:                      * first label added always starts on a new line.
        !           738:                      */
        !           739:                     if (!fAtNewLine) {
        !           740:                         if (!WriteIncChar(hfWrite, CHAR_RETURN))
        !           741:                             return FALSE;
        !           742: 
        !           743:                         if (!WriteIncChar(hfWrite, CHAR_NEWLINE))
        !           744:                             return FALSE;
        !           745:                     }
        !           746:                 }
        !           747: 
        !           748:                 if (!WriteAddedInc(hfWrite, plInc))
        !           749:                     return FALSE;
        !           750: 
        !           751:                 break;
        !           752:         }
        !           753: 
        !           754:         nGNIRet = GetNextInc(&plInc, FALSE);
        !           755:     }
        !           756: 
        !           757:     /*
        !           758:      * Write the rest of the file, if there is any left.
        !           759:      */
        !           760:     if (!fEOF)
        !           761:         if (!RWToOffset(hfWrite, FPOS_MAX))
        !           762:             return FALSE;
        !           763: 
        !           764:     /*
        !           765:      * Flush any remaining characters in the write buffer.
        !           766:      */
        !           767:     if (!WriteIncFlush(hfWrite))
        !           768:         return FALSE;
        !           769: 
        !           770:     /*
        !           771:      * If we just opened the old include file, close it.
        !           772:      */
        !           773:     if (pszIncludeFile)
        !           774:         CloseHandle(hfInclude);
        !           775: 
        !           776:     return TRUE;
        !           777: }
        !           778: 
        !           779: 
        !           780: 
        !           781: /************************************************************************
        !           782: * GetNextInc
        !           783: *
        !           784: * This routine will return the next label in the plInclude and plDelInclude
        !           785: * linked lists, as well as the status of the returned label.
        !           786: *
        !           787: * The labels will be returned in order based upon their location in the
        !           788: * lists, which is their order found in the include file if their fpos
        !           789: * field is not FPOS_MAX.  This routine looks at the next label in both the
        !           790: * plInclude and plDelInclude lists and returns the one with the lowest
        !           791: * fpos.  Labels are returned from plInclude and plDelInclude in order of
        !           792: * their fpos until all have been returned with a valid fpos.  After this,
        !           793: * all new includes are returned from plInclude.
        !           794: *
        !           795: * Call it with fFirst equal to TRUE to initialize it.
        !           796: *
        !           797: * Arguments:
        !           798: *   NPLABEL *pplReturn - label to return.
        !           799: *   BOOL fFirst - TRUE if initializing.
        !           800: *
        !           801: * Returns:
        !           802: *   GNI_DONE     - No more labels exist.
        !           803: *   GNI_NOCHANGE - An existing label is being returned.
        !           804: *   GNI_CHANGED  - An existing label with a changed id is being returned.
        !           805: *   GNI_DELETED  - A deleted label is being returned.
        !           806: *   GNI_ADDED    - An added label is being returned.
        !           807: *
        !           808: ************************************************************************/
        !           809: 
        !           810: STATICFN INT GetNextInc(
        !           811:     NPLABEL *pplReturn,
        !           812:     BOOL fFirst)
        !           813: {
        !           814:     static NPLABEL plCur;
        !           815:     static NPLABEL plDelCur;
        !           816: 
        !           817:     /*
        !           818:      * Initialize if this is the first time.
        !           819:      */
        !           820:     if (fFirst) {
        !           821:         plCur = plInclude;
        !           822:         plDelCur = plDelInclude;
        !           823:     }
        !           824: 
        !           825:     /*
        !           826:      * Are we out of valid includes?
        !           827:      */
        !           828:     if (!plCur) {
        !           829:         /*
        !           830:          * If there are deleted ones left, return the next one.
        !           831:          * Otherwise we are done.
        !           832:          */
        !           833:         if (plDelCur) {
        !           834:             *pplReturn = plDelCur;
        !           835:             plDelCur = plDelCur->npNext;
        !           836:             return GNI_DELETED;
        !           837:         }
        !           838:         else {
        !           839:             return GNI_DONE;
        !           840:         }
        !           841:     }
        !           842:     /*
        !           843:      * Have we reached the added includes (fpos == FPOS_MAX)?
        !           844:      */
        !           845:     else if (plCur->fpos == FPOS_MAX) {
        !           846:         /*
        !           847:          * If there are deleted ones remaining, return them first.
        !           848:          * Otherwise, return the next added one.
        !           849:          */
        !           850:         if (plDelCur) {
        !           851:             *pplReturn = plDelCur;
        !           852:             plDelCur = plDelCur->npNext;
        !           853:             return GNI_DELETED;
        !           854:         }
        !           855:         else {
        !           856:             *pplReturn = plCur;
        !           857:             plCur = plCur->npNext;
        !           858:             return GNI_ADDED;
        !           859:         }
        !           860:     }
        !           861:     else {
        !           862:         /*
        !           863:          * Return either the next label or the next deleted label,
        !           864:          * based on whether there are any deleted labels and who
        !           865:          * has the lowest file position (fpos).
        !           866:          */
        !           867:         if (plDelCur && plDelCur->fpos < plCur->fpos) {
        !           868:             *pplReturn = plDelCur;
        !           869:             plDelCur = plDelCur->npNext;
        !           870:             return GNI_DELETED;
        !           871:         }
        !           872:         else {
        !           873:             *pplReturn = plCur;
        !           874:             plCur = plCur->npNext;
        !           875:             /*
        !           876:              * Return either GNI_CHANGE or GNI_NOCHANGE based on
        !           877:              * whether the original id value has been changed.
        !           878:              */
        !           879:             return ((*pplReturn)->id == (*pplReturn)->idOrig) ?
        !           880:                     GNI_NOCHANGE : GNI_CHANGED;
        !           881:         }
        !           882:     }
        !           883: }
        !           884: 
        !           885: 
        !           886: 
        !           887: /************************************************************************
        !           888: * RWToOffset
        !           889: *
        !           890: * This routine reads from the current include file and writes to the
        !           891: * hfWrite file up to the lOffset position in the file.  If lOffset is
        !           892: * set to FPOS_MAX, reads/writes are performed up to the end of the
        !           893: * read file.
        !           894: *
        !           895: * Arguments:
        !           896: *   HANDLE hfWrite - handle to the file to write to.
        !           897: *   DWORD lOffset - where to write up to.
        !           898: *
        !           899: * Returns:
        !           900: *   TRUE if successful, FALSE if not.
        !           901: *
        !           902: * Comments:
        !           903: *   This routine relies on cchFile and cchFileMax to be properly updated
        !           904: *   by the reading and writing routines.
        !           905: *
        !           906: ************************************************************************/
        !           907: 
        !           908: STATICFN BOOL RWToOffset(
        !           909:     HANDLE hfWrite,
        !           910:     DWORD lOffset)
        !           911: {
        !           912:     LPTSTR pchIn;
        !           913:     DWORD cbWrite;
        !           914: 
        !           915:     if (lOffset == FPOS_MAX)
        !           916:         lOffset = cchFileMax;
        !           917: 
        !           918:     for (cbWrite = lOffset - cchFile; cbWrite; cbWrite--) {
        !           919:         /*
        !           920:          * NULL can be returned if there is an EOF character found in
        !           921:          * the file.  This is not an error, and we will stop reading
        !           922:          * and writing at this point.
        !           923:          */
        !           924:         if ((pchIn = ReadChar()) == NULL)
        !           925:             return TRUE;
        !           926: 
        !           927:         /*
        !           928:          * If BAD_POINTER is returned, there was an error reading the
        !           929:          * include file.
        !           930:          */
        !           931:         if (pchIn == BAD_POINTER)
        !           932:             return FALSE;
        !           933: 
        !           934:         /*
        !           935:          * Write out the character.
        !           936:          */
        !           937:         if (!WriteIncChar(hfWrite, *pchIn))
        !           938:             return FALSE;
        !           939:     }
        !           940: 
        !           941:     return TRUE;
        !           942: }
        !           943: 
        !           944: 
        !           945: 
        !           946: /************************************************************************
        !           947: * WriteIncChar
        !           948: *
        !           949: * This routine writes a character (ch) to the hfWrite file, doing it in a
        !           950: * buffered fashion.  Because it is buffered, before closing the file
        !           951: * any remaining characters in the buffer must be "flushed" to disk.
        !           952: *
        !           953: * Arguments:
        !           954: *   HANDLE hfWrite - handle to the file to write to.
        !           955: *   TCHAR ch - character to write.
        !           956: *
        !           957: * Returns:
        !           958: *   TRUE if successful, FALSE if not.
        !           959: *
        !           960: * Comments:
        !           961: * The globals gachWriteBuffer and cbWritePos are updated by this routine.
        !           962: *
        !           963: ************************************************************************/
        !           964: 
        !           965: STATICFN BOOL WriteIncChar(
        !           966:     HANDLE hfWrite,
        !           967:     TCHAR ch)
        !           968: {
        !           969:     INT cbWritten;
        !           970: 
        !           971:     gachWriteBuffer[cbWritePos++] = ch;
        !           972: 
        !           973:     /*
        !           974:      * Is the buffer full?
        !           975:      */
        !           976:     if (cbWritePos == CCHFILEBUFFER) {
        !           977:         CHAR abWriteBuffer[CCHFILEBUFFER];
        !           978:         BOOL fDefCharUsed;
        !           979: 
        !           980:         WideCharToMultiByte(CP_ACP, 0, gachWriteBuffer, CCHFILEBUFFER,
        !           981:                 abWriteBuffer, CCHFILEBUFFER, NULL, &fDefCharUsed);
        !           982: 
        !           983:         cbWritten = (INT)_lwrite((HFILE)hfWrite, abWriteBuffer, cbWritePos);
        !           984:         if (cbWritten != cbWritePos)
        !           985:             return FALSE;
        !           986: 
        !           987:         cbWritePos = 0;
        !           988:     }
        !           989: 
        !           990:     return TRUE;
        !           991: }
        !           992: 
        !           993: 
        !           994: 
        !           995: /************************************************************************
        !           996: * WriteIncFlush
        !           997: *
        !           998: * This routine flushes the write buffer.  This must be done before
        !           999: * the file is closed or data can be lost.
        !          1000: *
        !          1001: * Arguments:
        !          1002: *   HANDLE hfWrite - handle to the file to write to.
        !          1003: *
        !          1004: * Returns:
        !          1005: *   TRUE if successful, FALSE if not.
        !          1006: *
        !          1007: * Comments:
        !          1008: *   The global cbWritePos is updated by this routine.
        !          1009: *
        !          1010: ************************************************************************/
        !          1011: 
        !          1012: STATICFN BOOL WriteIncFlush(
        !          1013:     HANDLE hfWrite)
        !          1014: {
        !          1015:     INT cbWritten;
        !          1016: 
        !          1017:     /*
        !          1018:      * Are any bytes remaining in the buffer?
        !          1019:      */
        !          1020:     if (cbWritePos) {
        !          1021:         CHAR abWriteBuffer[CCHFILEBUFFER];
        !          1022:         BOOL fDefCharUsed;
        !          1023: 
        !          1024:         WideCharToMultiByte(CP_ACP, 0, gachWriteBuffer, cbWritePos,
        !          1025:                 abWriteBuffer, CCHFILEBUFFER, NULL, &fDefCharUsed);
        !          1026: 
        !          1027:         cbWritten = (INT)_lwrite((HFILE)hfWrite, abWriteBuffer, cbWritePos);
        !          1028:         if (cbWritten != cbWritePos)
        !          1029:             return FALSE;
        !          1030: 
        !          1031:         cbWritePos = 0;
        !          1032:     }
        !          1033: 
        !          1034:     return TRUE;
        !          1035: }
        !          1036: 
        !          1037: 
        !          1038:  
        !          1039: /************************************************************************
        !          1040: * WriteChangedInc
        !          1041: *
        !          1042: * This routine writes out a label that has had its id changed since the
        !          1043: * include file was last read.
        !          1044: *
        !          1045: * Arguments:
        !          1046: *   HANDLE hfWrite - File to write to.
        !          1047: *   NPLABEL plInc  - Label to write.
        !          1048: *
        !          1049: * Returns:
        !          1050: *   TRUE if successful, FALSE if not.
        !          1051: *
        !          1052: * History:
        !          1053: *   03/13/90 Byron Dazey - Created.
        !          1054: ************************************************************************/
        !          1055: 
        !          1056: STATICFN BOOL WriteChangedInc(
        !          1057:     HANDLE hfWrite,
        !          1058:     NPLABEL plInc)
        !          1059: {
        !          1060:     TCHAR ch;
        !          1061:     LPTSTR pchIn;
        !          1062: 
        !          1063:     if (!RWToOffset(hfWrite, plInc->fpos + plInc->nValueOffset))
        !          1064:         return FALSE;
        !          1065: 
        !          1066:     /*
        !          1067:      * Consume the old id value (up to the next space, tab,
        !          1068:      * beginning of a comment, newline or return).
        !          1069:      */
        !          1070:     while ((pchIn = ReadChar()) != NULL && pchIn != BAD_POINTER &&
        !          1071:             (ch = *pchIn) != CHAR_SPACE && ch != CHAR_TAB &&
        !          1072:             ch != CHAR_SLASH && ch != CHAR_NEWLINE && ch != CHAR_RETURN)
        !          1073:         ;
        !          1074: 
        !          1075:     /*
        !          1076:      * It is an error if ReadChar returns BAD_POINTER.  Note that it
        !          1077:      * is NOT an error if it reaches EOF (and returns NULL).
        !          1078:      */
        !          1079:     if (pchIn == BAD_POINTER)
        !          1080:         return FALSE;
        !          1081: 
        !          1082:     /*
        !          1083:      * Write the new one.
        !          1084:      */
        !          1085:     if (!WriteIDInc(hfWrite, plInc->id))
        !          1086:         return FALSE;
        !          1087: 
        !          1088:     /*
        !          1089:      * Remember to write the last character read after the old value.
        !          1090:      */
        !          1091:     if (pchIn != NULL)
        !          1092:         if (!WriteIncChar(hfWrite, *pchIn))
        !          1093:             return FALSE;
        !          1094: 
        !          1095:     return TRUE;
        !          1096: }
        !          1097: 
        !          1098: 
        !          1099: 
        !          1100: /************************************************************************
        !          1101: * WriteDeletedInc
        !          1102: *
        !          1103: * This routine deletes a label in the include file, closing up the
        !          1104: * space.  The entire line will be deleted, unless a comment is found
        !          1105: * after the id value.  If so, the comment and following characters will
        !          1106: * be left.
        !          1107: *
        !          1108: * Arguments:
        !          1109: *   HANDLE hfWrite - File to write to.
        !          1110: *   NPLABEL plInc  - Label to delete.
        !          1111: *
        !          1112: * Returns:
        !          1113: *   TRUE if successful, FALSE if not.
        !          1114: *
        !          1115: * History:
        !          1116: *   03/13/90 Byron Dazey - Created.
        !          1117: ************************************************************************/
        !          1118: 
        !          1119: STATICFN BOOL WriteDeletedInc(
        !          1120:     HANDLE hfWrite,
        !          1121:     NPLABEL plInc)
        !          1122: {
        !          1123:     register INT i;
        !          1124:     TCHAR ch;
        !          1125:     LPTSTR pchIn;
        !          1126: 
        !          1127:     /*
        !          1128:      * Read and write up to the #define to be deleted.
        !          1129:      */
        !          1130:     if (!RWToOffset(hfWrite, plInc->fpos))
        !          1131:         return FALSE;
        !          1132: 
        !          1133:     /*
        !          1134:      * Consume up to the id value.
        !          1135:      */
        !          1136:     for (i = plInc->nValueOffset; i; i--)
        !          1137:         if ((pchIn = ReadChar()) == NULL || pchIn == BAD_POINTER)
        !          1138:             return FALSE;
        !          1139: 
        !          1140:     /*
        !          1141:      * Consume the id value and following characters up to the end of
        !          1142:      * the line or the beginning of a comment.
        !          1143:      */
        !          1144:     while ((pchIn = ReadChar()) != NULL && pchIn != BAD_POINTER &&
        !          1145:             (ch = *pchIn) != CHAR_NEWLINE && ch != CHAR_RETURN &&
        !          1146:             ch != CHAR_SLASH)
        !          1147:         ;
        !          1148: 
        !          1149:     if (pchIn == BAD_POINTER)
        !          1150:         return FALSE;
        !          1151: 
        !          1152:     /*
        !          1153:      * We are done if we have reached EOF.
        !          1154:      */
        !          1155:     if (pchIn == NULL)
        !          1156:         return TRUE;
        !          1157: 
        !          1158:     /*
        !          1159:      * If the beginning of a comment was found, be sure to write the
        !          1160:      * character back out and leave the rest of the comment.
        !          1161:      */
        !          1162:     if (ch == CHAR_SLASH) {
        !          1163:         if (!WriteIncChar(hfWrite, ch))
        !          1164:             return FALSE;
        !          1165:     }
        !          1166:     else {
        !          1167:         /*
        !          1168:          * At this point either a newline or a return was found
        !          1169:          * and we are going to consume it.  We also want to check
        !          1170:          * for a return following the newline, or a newline
        !          1171:          * following the return and consume it also.
        !          1172:          */
        !          1173:         if ((ch == CHAR_NEWLINE && *(pchIn + 1) == CHAR_RETURN) ||
        !          1174:                 (ch == CHAR_RETURN && *(pchIn + 1) == CHAR_NEWLINE))
        !          1175:             if (ReadChar() == BAD_POINTER)
        !          1176:                 return FALSE;
        !          1177:     }
        !          1178: 
        !          1179:     return TRUE;
        !          1180: }
        !          1181: 
        !          1182: 
        !          1183: 
        !          1184: /************************************************************************
        !          1185: * WriteAddedInc
        !          1186: *
        !          1187: * Adds a label to the new include file.
        !          1188: *
        !          1189: * Arguments:
        !          1190: *   HANDLE hfWrite - File to write to.
        !          1191: *   NPLABEL plInc  - Label to add.
        !          1192: *
        !          1193: * Returns:
        !          1194: *   TRUE if successful, FALSE if not.
        !          1195: *
        !          1196: * History:
        !          1197: *   03/13/90 Byron Dazey - Created.
        !          1198: ************************************************************************/
        !          1199: 
        !          1200: STATICFN BOOL WriteAddedInc(
        !          1201:     HANDLE hfWrite,
        !          1202:     NPLABEL plInc)
        !          1203: {
        !          1204:     register LPTSTR psz;
        !          1205: 
        !          1206:     /*
        !          1207:      * Write the "#define " string.
        !          1208:      */
        !          1209:     psz = ids(IDS_POUNDDEFINE);
        !          1210:     while (*psz)
        !          1211:         if (!WriteIncChar(hfWrite, *psz++))
        !          1212:             return FALSE;
        !          1213: 
        !          1214:     /*
        !          1215:      * Write the symbol, followed by a space.
        !          1216:      */
        !          1217:     if (!WriteSymbol(hfWrite, plInc->pszLabel))
        !          1218:         return FALSE;
        !          1219:     if (!WriteIncChar(hfWrite, CHAR_SPACE))
        !          1220:         return FALSE;
        !          1221: 
        !          1222:     /*
        !          1223:      * Write the id, followed by a carriage return and newline.
        !          1224:      */
        !          1225:     if (!WriteIDInc(hfWrite, plInc->id))
        !          1226:         return FALSE;
        !          1227:     if (!WriteIncChar(hfWrite, CHAR_RETURN))
        !          1228:         return FALSE;
        !          1229:     if (!WriteIncChar(hfWrite, CHAR_NEWLINE))
        !          1230:         return FALSE;
        !          1231: 
        !          1232:     return TRUE;
        !          1233: }
        !          1234: 
        !          1235: 
        !          1236: 
        !          1237: /************************************************************************
        !          1238: * WriteSymbol
        !          1239: *
        !          1240: * Writes out a "#define DID_xxx  " string to hfWrite.  If the symbol
        !          1241: * is smaller than CCHSYMFIELDWIDTH, it will be padded with spaces out
        !          1242: * to this width.
        !          1243: *
        !          1244: * Arguments:
        !          1245: *   HANDLE hfWrite - handle to the file to write to.
        !          1246: *   LPTSTR pszSymbol - symbol to write.
        !          1247: *
        !          1248: * Returns:
        !          1249: *   TRUE if successful, FALSE if not.
        !          1250: *
        !          1251: ************************************************************************/
        !          1252: 
        !          1253: STATICFN BOOL WriteSymbol(
        !          1254:     HANDLE hfWrite,
        !          1255:     LPTSTR pszSymbol)
        !          1256: {
        !          1257:     register INT cch;
        !          1258: 
        !          1259:     /*
        !          1260:      * Write the symbol.
        !          1261:      */
        !          1262:     cch = 0;
        !          1263:     while (*pszSymbol) {
        !          1264:         if (!WriteIncChar(hfWrite, *pszSymbol++))
        !          1265:             return FALSE;
        !          1266: 
        !          1267:         cch++;
        !          1268:     }
        !          1269: 
        !          1270:     /*
        !          1271:      * Pad the field with blanks out to CCHSYMFIELDWIDTH, if necessary.
        !          1272:      */
        !          1273:     if (cch < CCHSYMFIELDWIDTH) {
        !          1274:         cch = CCHSYMFIELDWIDTH - cch;
        !          1275:         while (cch--)
        !          1276:             if (!WriteIncChar(hfWrite, CHAR_SPACE))
        !          1277:                 return FALSE;
        !          1278:     }
        !          1279: 
        !          1280:     return TRUE;
        !          1281: }
        !          1282: 
        !          1283: 
        !          1284: 
        !          1285: /************************************************************************
        !          1286: * WriteIDInc
        !          1287: *
        !          1288: * Writes out an id value to the hfWrite file.  The format will be in
        !          1289: * either hex or decimal, depending on the current mode.
        !          1290: *
        !          1291: * Arguments:
        !          1292: *   HANDLE hfWrite - File to write to.
        !          1293: *   INT id         - ID to write.
        !          1294: *
        !          1295: * Returns:
        !          1296: *   TRUE if successful, FALSE if not.
        !          1297: *
        !          1298: ************************************************************************/
        !          1299: 
        !          1300: STATICFN BOOL WriteIDInc(
        !          1301:     HANDLE hfWrite,
        !          1302:     INT id)
        !          1303: {
        !          1304:     register LPTSTR psz;
        !          1305:     TCHAR szValue[CCHIDMAX + 1];
        !          1306: 
        !          1307:     Myitoa(id, szValue);
        !          1308: 
        !          1309:     psz = szValue;
        !          1310:     while (*psz)
        !          1311:         if (!WriteIncChar(hfWrite, *psz++))
        !          1312:             return FALSE;
        !          1313: 
        !          1314:     return TRUE;
        !          1315: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.