home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Shareware 1 2 the Maxx
/
sw_1.zip
/
sw_1
/
WINDOWS
/
UTILS
/
INI10.ZIP
/
CONFIG.C
< prev
next >
Wrap
Text File
|
1992-06-08
|
27KB
|
915 lines
/**
* 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 <dbc/config.h>
*
* copyright (c) Fran Finnegan Associates 1986, 1987
* copyright (c) 1988-92 Finnegan O'Malley & Company Inc.
**/
#ifndef LINT_ARGS
#define LINT_ARGS
#endif
#include <io.h>
#include <malloc.h>
// #include <stdio.h>
#include <stdlib.h>
// #include <string.h>
#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);
}