/** * module DBC\CONFIG * * purpose Used to access "CONFIG.SYS-format" and "WIN.INI-format" files. * Similar to Windows Initialization File functions. * The following file format is processed: * * ; comment * [SectionName] or [SectionName] ; comment * KeyName=string or KeyName=string ; comment * KeyName= or KeyName= ; null string * =string or =string ; blank KeyName * KeyName or KeyName ; same as KeyName= * * Comments must be on separate lines or else the ';' must be * preceded by a blank (to allow ';' to occur in strings). * Blanks are not allowed between "SectionName" and the brackets. * "SectionName" and "KeyName" are not case-dependent, so the * strings may contain any combination of upper and lower case. * If there is no equal sign, the entire line is assumed the key. * The existence of an equal sign (after the removal of comments) * determines that a string exists; otherwise it is assumed Null. * Blanks around "KeyName" and "string" are ignored. A null or * blank KeyName (when an equal sign is present) is assumed to be * a single blank. Blank lines are allowed anywhere and ignored. * SectionNames must be unique, since only the first one is used. * KeyNames should be unique, since all are processed similarly. * * logic The file is processed sequentially. Each line is read, detabbed * and parsed and then a "call-back" function is called with the * resulting line components determined. The components are: * * FilePre file line (including comments) * * and (if available) * * FileKey -> FilePost left of the equal sign * (a blank if there is no key) * and FileString -> FilePost right of the equal sign * (Null if there is no string) * * The call-back function returns a code to indicate continued * scanning. The parser returns if either the end-of-file is * reached or the call-back function ended the parsing. * * cautions Argument checking is not performed. * * includes * * copyright (c) Fran Finnegan Associates 1986, 1987 * copyright (c) 1988-92 Finnegan O'Malley & Company Inc. **/ #ifndef LINT_ARGS #define LINT_ARGS #endif #include #include // #include #include // #include #include "ascii.i" // #include "const.i" #include "filespec.i" // #include "string.i" // #include "config.i" #define NAME_SIZE 64 /* for FileNames, SectionNames and KeyNames */ #define LINE_SIZE 256 /* for file lines */ #define ABOUT_TO_BEGIN -1 /* to call-back: about to begin reading file */ #define NOT_IN_SECTION NO /* to call-back: not in Section requested */ #define ARE_IN_SECTION YES /* to call-back: are in Section requested */ #define END_OF_PROCESS 2 /* to call-back: end-of-process was reached */ #define CONTINUE 1 /* to ParseFile: continue reading file */ #define STOP 2 /* to ParseFile: stop reading file */ #define ACCESS_EXISTS 0 /* "access" existence-only mode */ #define ACCESS_UNLINK 6 /* "access" read-and-write mode */ int gbConfigCloseFileOnExit = NO; int gbConfigDeleteBakOnExit = YES; static char *_="\x20\x28\x63\x29 \x31\x39\x39\x32 \x46\x69\x6E\x6E\x65\x67\x61\x6E \x4F\x27\x4D\x61\x6C\x6C\x65\x79\x2E\x20"; static int mfnGetConfigString(int); static int mfnWriteConfigString(int); static int mfnGetConfigSection(int); static int mfnGetConfigKeys(int); static void CloseFile(void); static void ParseFile(char *, char *, int (*)(int)); static void ParseSection(char *, char *); static void ParseKey(char *, char *); static char *MemoryGetString(char *, int, char far **); static char far *mlpmemConfig; /* memory file in process */ static FILE *mpfileConfig; /* stream file in process */ static char *mpszUserDefault; /* user supplied */ static char *mpszUserReturned; /* user supplied */ static unsigned int muiUserSize; /* user supplied */ static char *mpszUserString; /* user supplied */ static char *mpszFileKey; /* pointer to mszFilePost */ static char *mpszFileString; /* pointer to mszFilePost */ static int miReturn; /* return code */ static int mbWriteRequest; /* WriteConfig... request */ static char mszUserFile [NAME_SIZE], /* "d:\\path\\filename.ext" */ mszUserSection[NAME_SIZE], /* "[SectionName]" or "" */ mszUserKey [NAME_SIZE], /* "KeyName" or " " */ mszFilePre [LINE_SIZE], /* pre-parsing line */ mszFilePost [LINE_SIZE]; /* post-parsing line */ /*p*/ /** * function GetConfigInt * * purpose Similar to Windows "GetProfileInt". * * logic Calls "GetConfigString". * * cautions Unless the file contains a valid int, the default is returned. * * usage iKeyValue = GetConfigInt(pszFilespec, pszSection, pszKey, * iDefault); * * arguments pszFilespec "d:\\path\\filename.ext" format. * pszFilespec must not be NULL. * pszSection "SectionName" of "[SectionName]". * pszSection may be NULL, implying "". * pszKey "KeyName" of "KeyName=string". * pszKey may be NULL, implying " ". * iDefault Default int if the SectionName/KeyName * combination does not exist or is Null. * * returns iKeyValue = int value of the key string. * * modifies no externals. * * examples iDOSbuffers = GetConfigInt("C:\\CONFIG.SYS", NULL, "buffers", * -1); * * copyright (c) Fran Finnegan Associates 1986, 1987 **/ extern int GetMemoryInt(lpmemConfig, pszSection, pszKey, iDefault) char far *lpmemConfig, *pszSection, *pszKey; int iDefault; { auto int iReturn; CloseFile(); mlpmemConfig = lpmemConfig; iReturn = GetConfigInt(NULL, pszSection, pszKey, iDefault); mlpmemConfig = (char far *)NULL; return (iReturn); } extern int GetConfigInt(pszFilespec, pszSection, pszKey, iDefault) char *pszFilespec, *pszSection, *pszKey; int iDefault; { auto char szReturned[12]; /* [12] should be sufficient */ return ((GetConfigString(pszFilespec, pszSection, pszKey, "", szReturned, sizeof(szReturned)) and strspn(szReturned, "+-0123456789"))? atoi(szReturned): iDefault); } /*p*/ /** * function GetConfigString * * purpose Similar to Windows "GetProfileString". * * logic See "arguments" below. * * cautions The "Returned" buffer must be at least 2 bytes long. It should * be one byte longer than the longest expected "string". * * usage iLength = GetConfigString(pszFilespec, pszSection, pszKey, * pszDefault, pszReturned, uisize); * * arguments pszFilespec "d:\\path\\filename.ext" format. * pszFilespec must not be NULL. * pszSection "SectionName" of "[SectionName]". * pszSection may be NULL, implying "". * Blanks around pszSection are ignored. * Brackets are not included, but added herein. * If pszSection == "": * SectionNames in the file are ignored. * pszKey "KeyName" of "KeyName=string". * pszKey may be NULL, implying " ". * Blanks around pszKey are ignored. * If pszKey == "": * A null or blank KeyName is searched for. * pszDefault Default string if the SectionName/KeyName * combination does not exist or is Null. * If pszDefault == NULL: * The KeyName itself is the default. * If pszDefault == "": * The Null string is the default. * The default is used if either the KeyName does * not exist or the Key string exists but is Null. * pszReturned Returned-string buffer (at least 2 bytes). * uisize Returned-string buffer size. * * returns iLength = int length of returned string. 0 indicates Null (""). * * modifies no externals. * * examples auto char szDOSshell[64]; * * iDOSshell = GetConfigString("C:\\CONFIG.SYS", NULL, "shell", * "C:\\COMMAND.COM", szDOSshell, sizeof(szDOSshell)); * * copyright (c) Fran Finnegan Associates 1986, 1987 **/ extern int GetMemoryString(lpmemConfig, pszSection, pszKey, pszDefault, pszReturned, uisize) char far *lpmemConfig, *pszSection, *pszKey, *pszDefault, *pszReturned; unsigned int uisize; { auto int iReturn; CloseFile(); mlpmemConfig = lpmemConfig; iReturn = GetConfigString(NULL, pszSection, pszKey, pszDefault, pszReturned, uisize); mlpmemConfig = (char far *)NULL; return (iReturn); } extern int GetConfigString(pszFilespec, pszSection, pszKey, pszDefault, pszReturned, uisize) char *pszFilespec, *pszSection, *pszKey, *pszDefault, *pszReturned; unsigned int uisize; { ParseKey(mszUserKey, pszKey); /* Key */ mpszUserDefault = pszDefault; /* Default */ mpszUserReturned = pszReturned; /* Returned */ muiUserSize = uisize; /* Size */ ParseFile(pszFilespec, pszSection, mfnGetConfigString); return (miReturn); } /*p*/ static int mfnGetConfigString(iCase) int iCase; { static FILE *pfileConfig; /* stream file last processed */ static int bInSection = NO, bKeyFound = NO, iFile_cnt = -1; static char szUserFile [NAME_SIZE], szUserSection[NAME_SIZE]; register char *pC; switch (iCase) { case ABOUT_TO_BEGIN: bKeyFound = NO; *mpszUserReturned = Null; if (muiUserSize < 2) /* buffer size must be at least 2 bytes */ return (STOP); memset(mpszUserReturned, Null, muiUserSize--); /* -- insures a string */ if (bInSection and pfileConfig and pfileConfig == mpfileConfig and iFile_cnt == mpfileConfig->_cnt and no ferror(mpfileConfig) and IsStrEquiv(szUserFile , mszUserFile ) and IsStrEquiv(szUserSection, mszUserSection) and fgets(mszFilePre, LINE_SIZE, mpfileConfig)) { /* has '\n' */ StrTrunc(mszFilePre, " \t\r\n"); // StrDetab(mszFilePre); if (!IsStrNull(mszFilePre) and *mszFilePre != ';') { if (pC = strstr(mszFilePre, " ;")) *pC = Null; /* remove comments */ StrCrop(mszFilePre, " "); /* now "Key = String" */ if (!IsStrNull(mszFilePre)) { /* or "Key=" or "Key" */ if (pC = strchr(mszFilePre, '=')) { /* if an equal sign */ *pC++ = Null; /* end Key */ pC = StrSkip(pC, " "); /* skip to String */ StrTrunc(mszFilePre, " "); /* truncate Key */ } if (IsStrEquiv(mszFilePre, mszUserKey)) { bKeyFound = YES; if (pC) strncpy(mpszUserReturned, pC, muiUserSize); mfnGetConfigString(END_OF_PROCESS); /* recursion! */ if (gbConfigCloseFileOnExit) CloseFile(); return (STOP); } } } } strcpy(szUserFile , mszUserFile ); strcpy(szUserSection, mszUserSection); bInSection = NO; break; case ARE_IN_SECTION: bInSection = YES; if (mpszFileKey and IsStrEquiv(mpszFileKey, mszUserKey)) { bKeyFound = YES; strncpy(mpszUserReturned, mpszFileString, muiUserSize); if (IsStrNULL(mpszUserDefault)) mpszUserDefault = mpszFileKey; return (STOP); /* Key was found */ } break; case NOT_IN_SECTION: if (bInSection) { bInSection = NO; return (STOP); /* was in, but am now not */ } break; case END_OF_PROCESS: if (bKeyFound) while (!IsStrNull(mpszUserReturned)) { pC = StrNull(mpszUserReturned) - 1; if (*pC != '\\') break; *pC = '\0'; if (no fgets(mszFilePre, LINE_SIZE, mpfileConfig)) break; /* has '\n' */ StrTrunc(mszFilePre, " \t\r\n"); // StrDetab(mszFilePre); StrLeft(mszFilePre, " "); strncpy(pC, mszFilePre, muiUserSize - strlen(mpszUserReturned)); } if (IsStrNull(mpszUserReturned)) strncpy(mpszUserReturned, (mpszUserDefault? mpszUserDefault: mszUserKey), muiUserSize); miReturn = strlen(mpszUserReturned); iFile_cnt = (pfileConfig = mpfileConfig)? mpfileConfig->_cnt: -1; break; /* the '=' in the above line is OK */ } return (CONTINUE); } /*p*/ /** * function WriteConfigString * * purpose Similar to Windows "WriteProfileString". * Writes "KeyName=string" in the requested "SectionName" * (replacing an existing KeyName if it already exists). * * logic See "arguments" below. The original file (if it exists) is * renamed to "*.BAK" after the new file is written. * * cautions none. * * usage iSuccess = WriteConfigString(pszFilespec, pszSection, pszKey, * pszString); * * arguments pszFilespec "d:\\path\\filename.ext" format. * pszFilespec must not be NULL. * pszSection "SectionName" of "[SectionName]". * pszSection may be NULL, implying "". * Blanks around pszSection are ignored. * Brackets are not included, but added herein. * If pszSection == "": * SectionNames in the file are ignored. * pszKey "KeyName" of "KeyName=string". * pszKey may be NULL, implying " ". * Blanks around pszKey are ignored. * If pszKey == "": * A blank KeyName is written. * pszString "string" of "KeyName=string". * If pszString is NULL, the old "KeyName=string" * is removed. A Null ("") pszString is permitted. * * returns iSuccess = TRUE if successful, FALSE if not. * * modifies no externals. * * examples iSuccess = WriteConfigString("C:\\CONFIG.SYS", NULL, "files", * "32"); * * copyright (c) Fran Finnegan Associates 1986, 1987 **/ extern int WriteConfigString(pszFilespec, pszSection, pszKey, pszString) char *pszFilespec, *pszSection, *pszKey, *pszString; { mbWriteRequest = YES; ParseKey(mszUserKey, pszKey); /* Key */ mpszUserString = pszString; /* String */ ParseFile(pszFilespec, pszSection, mfnWriteConfigString); mbWriteRequest = NO; return (miReturn); } /*p*/ static int mfnWriteConfigString(iCase) int iCase; { static FILE *pfileTMP; static int bWritten; static char *pszCrLf, szCrLf[] = "\n", szBAK[] = "BAK", szTMP[] = "TMP", szFILEformat[] = "%s\n"; auto char szFilespec[FILESPEC ], szDrive [FILESPEC_DRIVE], szPath [FILESPEC_PATH ], szName [FILESPEC_NAME ], szExt [FILESPEC_EXT ]; switch (iCase) { case ABOUT_TO_BEGIN: miReturn = NO; /* used as a Section indicator */ if (*mszUserFile == ' ') return (STOP); /* old Filespec can not be a blank (NULL) */ ParseFilespec(mszUserFile, szDrive, szPath, szName, szExt); if (IsStrEquiv(szExt, szBAK) or IsStrEquiv(szExt, szTMP)) return (STOP); /* old Filespec can not be *.BAK or *.TMP */ if (!access(mszUserFile, ACCESS_EXISTS)) { /* if exist *.old */ MakeFilespec(szFilespec, szDrive, szPath, szName, szBAK); if (!access(szFilespec, ACCESS_EXISTS)) /* if exist *.BAK */ if (access(szFilespec, ACCESS_UNLINK) or unlink(szFilespec)) return (STOP); /* could not delete *.BAK */ } MakeFilespec(szFilespec, szDrive, szPath, szName, szTMP); if (!access(szFilespec, ACCESS_EXISTS) or /* if exist *.TMP */ no (pfileTMP = fopen(szFilespec, "wt"))) /* no new *.TMP */ return (STOP); /* could not open *.TMP */ pszCrLf = ""; bWritten = mpszUserString == NULL; /* assume written for removal */ break; case ARE_IN_SECTION: if (IsStrNull(mszFilePre)) break; if (*mszFilePost == '[') { fprintf(pfileTMP, pszCrLf); pszCrLf = szCrLf; } miReturn = YES; /* used as a Section indicator */ if (mpszFileKey and IsStrEquiv(mpszFileKey, mszUserKey)) { /* a match */ if (!IsStrNULL(mpszUserString)) { /* replace */ strcpy(StrSkip(mszFilePre, " "), &mszUserKey[*mszUserKey == ' ']); strcat(mszFilePre, (*mszUserKey != ' ' and *mszFilePre == ' ')? " = ": "="); strcat(mszFilePre, mpszUserString); } bWritten++; /* may be written here (in Section) multiple times */ } if (!(IsStrNULL(mpszUserString) and /* !(string NULL & it is a match) */ mpszFileKey and IsStrEquiv(mpszFileKey, mszUserKey))) fprintf(pfileTMP, szFILEformat, /*StrEntab()*/ mszFilePre); /* old/new */ break; case NOT_IN_SECTION: if (IsStrNull(mszFilePre)) break; if (miReturn and /* used as a Section indicator */ not bWritten) { /* append */ fprintf(pfileTMP, "%s=%s\n", &mszUserKey[*mszUserKey == ' '], mpszUserString); /* add */ bWritten = YES; } if (*mszFilePost == '[') { fprintf(pfileTMP, pszCrLf); pszCrLf = szCrLf; } fprintf(pfileTMP, szFILEformat, /*StrEntab()*/ mszFilePre); /* old */ break; case END_OF_PROCESS: if (no miReturn and /* used as a Section indicator */ !IsStrNull(mszUserSection)) { /* never NULL */ fprintf(pfileTMP, pszCrLf); fprintf(pfileTMP, szFILEformat, mszUserSection); /* add */ } if (not bWritten) { strcpy(mszFilePre, &mszUserKey[*mszUserKey == ' ']); strcat(mszFilePre, "="); strcat(mszFilePre, mpszUserString); fprintf(pfileTMP, szFILEformat, /*StrEntab()*/ mszFilePre); /* add */ } fprintf(pfileTMP, "%c", A_EOF); /* EOF */ fclose(pfileTMP); ParseFilespec(mszUserFile, szDrive, szPath, szName, szExt); MakeFilespec(szFilespec, szDrive, szPath, szName, szBAK); rename(mszUserFile, szFilespec); /* rename *.old *.BAK */ if (gbConfigDeleteBakOnExit) unlink(szFilespec); MakeFilespec(szFilespec, szDrive, szPath, szName, szTMP); rename(szFilespec, mszUserFile); /* rename *.TMP *.old */ miReturn = YES; /* OK */ break; } return (CONTINUE); } /*p*/ /** * function GetConfigSection * * purpose Gets an entire Section. Each line is placed in the "Returned" * buffer and terminated with a CR/LF (to be compatible with the * Windows "DrawText" function). The buffer is Null-terminated. * * logic See "arguments" below. * * cautions The "Returned" buffer must be at least 2 bytes long. It should * be long enough to accomodate the longest expected Section. * * usage iLines = GetConfigSection(pszFilespec, pszSection, pszReturned, * uiSize); * * arguments pszFilespec "d:\\path\\filename.ext" format. * pszFilespec must not be NULL. * pszSection "SectionName" of "[SectionName]". * pszSection must be supplied and not be NULL. * Blanks around pszSection are ignored. * Brackets are not included, but added herein. * pszReturned Returned-string buffer (at least 2 bytes). * uiSize Returned-string buffer size. * * returns iLines = number of lines found. 0 indicates that the Section * was not found or had no lines. * * modifies no externals. * * examples auto char szWinIniColors[512]; * * iWinIniColors = GetConfigSection("C:\\WIN\\SYS\\WIN.INI", * "Colors", szWinIniColors, sizeof(szWinIniColors)); * * copyright (c) Fran Finnegan Associates 1986, 1987 **/ extern int GetMemorySection(lpmemConfig, pszSection, pszReturned, uiSize) char far *lpmemConfig, *pszSection, *pszReturned; unsigned int uiSize; { auto int iReturn; CloseFile(); mlpmemConfig = lpmemConfig; iReturn = GetConfigSection(NULL, pszSection, pszReturned, uiSize); mlpmemConfig = (char far *)NULL; return (iReturn); } extern int GetConfigSection(pszFilespec, pszSection, pszReturned, uiSize) char *pszFilespec, *pszSection, *pszReturned; unsigned int uiSize; { mpszUserReturned = pszReturned; /* Returned */ muiUserSize = uiSize; /* Size */ ParseFile(pszFilespec, pszSection, mfnGetConfigSection); return (miReturn); } /*p*/ static int mfnGetConfigSection(iCase) int iCase; { register int iLength; auto char *pC; switch (iCase) { case ABOUT_TO_BEGIN: miReturn = 0; /* used as a line counter */ *mpszUserReturned = Null; if (muiUserSize < 2 or IsStrNull(mszUserSection)) return (STOP); memset(mpszUserReturned, Null, muiUserSize--); break; case ARE_IN_SECTION: if (*mszFilePre != ';' and /* ignore comment */ miReturn++) { /* used as a line counter */ if (pC = strstr(mszFilePre, " ;")) { *pC = Null; /* remove comment */ StrTrunc(mszFilePre, " "); } iLength = strlen(strcat(mszFilePre, "\r\n")); if (iLength > muiUserSize) mszFilePre[iLength = muiUserSize] = Null; strcpy(mpszUserReturned, mszFilePre); mpszUserReturned += iLength; /* effectively concats */ if ((muiUserSize -= iLength) == 0) return (STOP); /* no more room */ } break; case NOT_IN_SECTION: if (miReturn) /* used as a line counter */ return (STOP); /* was in, but am now not */ break; case END_OF_PROCESS: if (miReturn) /* was in */ miReturn--; /* ignore "[Section]" line */ break; } return (CONTINUE); } /*p*/ /** * function GetConfigKeys * * purpose Gets a set of Keys. Each key is placed in the "Returned" * buffer and terminated with a CR/LF (to be compatible with the * Windows "DrawText" function). The buffer is Null-terminated. * * logic See "arguments" below. * * cautions The "Returned" buffer must be at least 2 bytes long. It should * be long enough to accomodate the longest expected set of Keys. * * usage iKeys = GetConfigKeys(pszFilespec, pszSection, pszReturned, * uiSize); * * arguments pszFilespec "d:\\path\\filename.ext" format. * pszFilespec must not be NULL. * pszSection "SectionName" of "[SectionName]". * pszSection may be NULL, implying "". * Blanks around pszSection are ignored. * Brackets are not included, but added herein. * pszReturned Returned-string buffer (at least 2 bytes). * uiSize Returned-string buffer size. * * returns iKeys = number of keys found. 0 indicates that the Section * was not found or no keys were found. * * modifies no externals. * * examples auto char szWinIniFonts[1 K]; * * iWinIniFonts = GetConfigKeys("C:\\WIN\\SYS\\WIN.INI", * "Fonts", szWinIniFonts, sizeof(szWinIniFonts)); * * copyright (c) Fran Finnegan Associates 1986, 1987 **/ extern int GetMemoryKeys(lpmemConfig, pszSection, pszReturned, uiSize) char far *lpmemConfig, *pszSection, *pszReturned; unsigned int uiSize; { auto int iReturn; CloseFile(); mlpmemConfig = lpmemConfig; iReturn = GetConfigKeys(NULL, pszSection, pszReturned, uiSize); mlpmemConfig = (char far *)NULL; return (iReturn); } extern int GetConfigKeys(pszFilespec, pszSection, pszReturned, uiSize) char *pszFilespec, *pszSection, *pszReturned; unsigned int uiSize; { mpszUserReturned = pszReturned; /* Returned */ muiUserSize = uiSize; /* Size */ ParseFile(pszFilespec, pszSection, mfnGetConfigKeys); return (miReturn); } /*p*/ static int mfnGetConfigKeys(iCase) int iCase; { register int iLength; switch (iCase) { case ABOUT_TO_BEGIN: miReturn = 0; /* used as a key counter */ *mpszUserReturned = Null; if (muiUserSize < 2) return (STOP); memset(mpszUserReturned, Null, muiUserSize--); break; case ARE_IN_SECTION: if (mpszFileKey) { miReturn++; /* used as a key counter */ iLength = strlen(strcat(mpszFileKey, "\r\n")); /* BEWARE! */ if (iLength > muiUserSize) mpszFileKey[iLength = muiUserSize] = Null; strcpy(mpszUserReturned, mpszFileKey); mpszUserReturned += iLength; /* effectively concats */ if ((muiUserSize -= iLength) == 0) return (STOP); /* no more room */ } break; case NOT_IN_SECTION: if (miReturn) /* used as a key counter */ return (STOP); /* was in, but am now not */ break; } return (CONTINUE); } /*p*/ static void CloseFile() { if (mpfileConfig) { fclose(mpfileConfig); mpfileConfig = NULL; } } /***/ static void ParseFile(pszFilespec, pszSection, pfnCallBack) char *pszFilespec, *pszSection; int (*pfnCallBack)(int); { static char szPreviousFile[FILESPEC]; /* previous request */ static char szBlankKey[] = " \r\n"; /* used for blank key */ register int bFileUserSection; register char *pC; ParseKey(mszUserFile, pszFilespec); /* Filespec */ ParseSection(mszUserSection, pszSection); /* Section */ if ((*pfnCallBack)(ABOUT_TO_BEGIN) == CONTINUE) { if (mpfileConfig and IsStrEquiv(szPreviousFile, mszUserFile)) rewind(mpfileConfig); else { CloseFile(); if (no mlpmemConfig) mpfileConfig = fopen(strcpy(szPreviousFile, mszUserFile), "rt"); } if (mpfileConfig or mlpmemConfig) { bFileUserSection = IsStrNull(mszUserSection); /* in Section? */ while (mlpmemConfig? MemoryGetString(mszFilePre, LINE_SIZE, &mlpmemConfig): fgets(mszFilePre, LINE_SIZE, mpfileConfig)) { /* has '\n' */ StrTrunc(mszFilePre, " \t\r\n"); // StrDetab(mszFilePre); mpszFileKey = mpszFileString = NULL; /* assume no "Key = String" */ *mszFilePost = Null; if (!IsStrNull(mszFilePre) and *mszFilePre != ';') { strcpy(mszFilePost, mszFilePre); if (pC = strstr(mszFilePost, " ;")) *pC = Null; /* remove comments */ StrCrop(mszFilePost, " "); /* now "Key = String" */ if (!IsStrNull(mszFilePost)) if (*mszFilePost == '[') /* assume a "[SectionName]" */ bFileUserSection = IsStrNull(mszUserSection)? YES: IsStrEquiv(mszUserSection, mszFilePost); else { /* assume a "Key = string" */ if (pC = strchr(mszFilePost, '=')) { *pC++ = Null; mpszFileString = StrSkip(pC, " "); StrTrunc(mszFilePost, " "); } else mpszFileString = ""; /* BEWARE OF STRCATTING! */ mpszFileKey = !IsStrNull(mszFilePost)? mszFilePost: szBlankKey; /* BEWARE OF STRCATTING! */ szBlankKey[1] = Null; /* to allow for strcatting */ } } if ((*pfnCallBack)(bFileUserSection) == STOP) /* do call-back */ break; } } (*pfnCallBack)(END_OF_PROCESS); /* file may not have been read */ if (mbWriteRequest or gbConfigCloseFileOnExit) CloseFile(); } } /*p*/ static void ParseSection(pszTo, pszFrom) char *pszTo, *pszFrom; { *pszTo++ = '['; /* add '[' */ if (pszFrom) { strncpy(pszTo, StrSkip(pszFrom, " "), NAME_SIZE - 3); StrTrunc(pszTo, " "); } else *pszTo = Null; if (IsStrNull(pszTo)) /* if pszTo == "[]", */ *--pszTo = Null; /* SectionNames are to be ignored */ else strcat(pszTo, "]"); /* add ']' */ } /***/ static void ParseKey(pszTo, pszFrom) char *pszTo, *pszFrom; { if (pszFrom) { strncpy(pszTo, StrSkip(pszFrom, " "), NAME_SIZE - 1); StrTrunc(pszTo, " "); } else *pszTo = Null; if (IsStrNull(pszTo)) { /* if pszTo == "", */ *pszTo++ = ' '; /* KeyNames must be at least " " */ *pszTo = Null; } } /***/ static char *MemoryGetString(pszBuffer, iN, plpmemMemory) char *pszBuffer; register int iN; char far **plpmemMemory; { register char cChar; auto char *pszString; if ( **plpmemMemory == A_EOF or **plpmemMemory == Null /* or no iN */ ) return (NULL); pszString = pszBuffer; pszString[--iN] = Null; while (iN--) { while ((cChar = **plpmemMemory) == '\r') ++*plpmemMemory; if ((*pszString = cChar) == '\n') *++pszString = Null; if (cChar) ++*plpmemMemory; if (no *pszString++) break; } return (pszBuffer); }