/* init.c - routines for managing TOOLS.INI-like files
*
* Modifications
* 15-Jul-87 danl Start of section is [...]
* 05-Aug-1988 mz Use buffer equate for swgoto.
* 05-Jul-1989 bw Use MAXPATHLEN
*
*/
#include
#include
#include "..\h\tools.h"
#include "..\h\strpfx.h"
#define BUFLEN 256
static flagType fMatchMark (char *, char *);
static char *space = "\t ";
/* fMatchMark - see if a tag in in a mark set
*
* We treat the mark set as a collection of whitespace-separated names
*
* pMark pointer to mark set (contents modified)
* pTag tag to find
*
* returns TRUE if match was found
*/
static flagType fMatchMark (pMark, pTag)
char *pMark, *pTag;
{
char *p, c;
while (*pMark != 0) {
pMark = strbscan (p = strbskip (pMark, space), space);
c = *pMark;
*pMark = 0;
if (!stricmp (p, pTag))
return TRUE;
*pMark = c;
}
return FALSE;
}
/* returns pointer to tag if line is marker; NULL otherwise */
char *ismark (buf)
register char *buf;
{
register char *p;
buf = strbskip (buf, space);
if (*buf++ == '[')
if (*(p = strchr (buf, ']')) != '\0') {
*p = 0;
return buf;
}
return NULL;
}
flagType swgoto (fh, tag)
FILE *fh;
char *tag;
{
char buf[BUFLEN];
if (fh) {
while (fgetl (buf, BUFLEN, fh)) {
register char *p;
if ((p = ismark (buf)) != NULL) {
if (fMatchMark (p, tag))
return TRUE;
}
}
}
return FALSE;
}
/* returns fh of file if tag found, else NULL */
FILE *swopen (file, tag)
char *file, *tag;
{
FILE *fh;
char buf[MAXPATHLEN];
if ((fh = pathopen (file, buf, "rb")) == NULL)
return NULL;
if (swgoto (fh, tag))
return fh;
fclose (fh);
return NULL;
}
/* close a switch file */
swclose (fh)
FILE *fh;
{
return fclose (fh);
}
/* read a switch line; return FALSE if end of file. Skips leading spaces
* and lines that begin with ; and blank lines
*/
int swread (buf, len, fh)
char *buf;
int len;
FILE *fh;
{
register char *p;
while (fgetl (buf, len, fh))
if (ismark (buf) != NULL)
break;
else {
p = strbskip (buf, space);
if (*p != 0 && *p != ';') {
strcpy (buf, p);
return TRUE;
}
}
return FALSE;
}
/* Reads lines from the file fh looking in the section pstrTag for one with
* "entry=" and if there are non-white space characters following the '='
* a copy of these characters is returned else NULL is returned.
*
* If fh == 0 then the file $INIT:\TOOLS.INI is used as the switch file
*
* If a non-NULL value is returned, it should eventually be free'd.
*
* N.B. if there are only white space characters, space and tab, following
* the '=', NULL is returned
*
*/
char *swfind (pstrEntry, fh, pstrTag)
char *pstrEntry;
FILE *fh;
char *pstrTag;
{
char *p;
char *q;
FILE *fhIn = fh;
char buf[BUFLEN];
q = NULL;
if (fh || (fh = swopen ("$INIT:\\TOOLS.INI", pstrTag))) {
while (swread (buf, BUFLEN, fh) && !ismark(buf) ) {
if ((p = strchr (buf, '=')) != NULL) {
*p++ = '\0';
if (!strcmpis (buf, pstrEntry)) {
if (*(p = strbskip (p, space)))
q = strdup (p);
break;
}
}
}
}
if (!fhIn)
swclose (fh);
return q;
}
/* Returns a ptr to the separator in buf & fills in sep */
static char *FindSep(char *buf, char **seps, char **sep)
{
char *szBrk;
unsigned i, index, len = 0;
index = UINT_MAX;
*sep = NULL;
// find longest leftmost separator from given list in buf
while (NULL != *seps)
{
szBrk = strstr(buf, *seps);
if (szBrk )
{
i = szBrk - buf;
if (i < index || (i == index && len < strlen(*seps)))
{
index = i;
*sep = *seps;
len = strlen(*sep);
}
}
seps++;
}
if (*sep)
return (buf + index);
else
return NULL;
}
/*
* Parse the given buffer. Return the lhs, rhs and the actual separator.
*
* buf switch line contents (!!!contents modified!!!)
* seps null-terminated list of allowed separators
* lhs ptr to parameter (left-hand side value)
* rhs ptr to value (value to the right of the separator)
* sep actual separator found in buf
*
* Returns TRUE if successful else FALSE.
*/
int swparse(char *buf, char *seps[], char **lhs, char **rhs, char **sep)
{
char *szBrk = NULL;
*lhs = *rhs = *sep = NULL;
if (NULL == buf || '\0' == *buf || (NULL != ismark(buf)))
return FALSE;
buf += strspn(buf, space);
if (';' == *buf)
return FALSE;
// sep
szBrk = FindSep(buf, seps, sep);
// lhs
*lhs = buf;
// rhs
if (szBrk)
{
// place 0 at sep
*szBrk = '\0';
szBrk += strspn(szBrk += strlen(*sep), space);
*rhs = szBrk;
}
return TRUE;
}
static flagType fMatchPat (char *pMark, char *pTag)
{
char *p, c;
while (*pMark != 0) {
pMark = strbscan (p = strbskip (pMark, space), space);
c = *pMark;
*pMark = 0;
if (striprefix (pTag, p))
return TRUE;
*pMark = c;
}
return FALSE;
}
/*
* Variation of goto where the tag is of the form *
*
* fh file handle
* tag tag to match
*
* Retruns ptr to match found if successful else NULL
*/
char *swmatch(FILE *fh, char *tag)
{
char buf[BUFLEN];
if (fh) {
while (fgetl (buf, BUFLEN, fh)) {
register char *p;
if ((p = ismark (buf)) != NULL) {
if (fMatchPat (p, tag))
return (strdup(p));
}
}
}
return NULL;
}