summaryrefslogtreecommitdiff
path: root/src/libopts/configfile.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/libopts/configfile.c')
-rw-r--r--src/libopts/configfile.c816
1 files changed, 381 insertions, 435 deletions
diff --git a/src/libopts/configfile.c b/src/libopts/configfile.c
index 56e22b5db7..8c71111c5b 100644
--- a/src/libopts/configfile.c
+++ b/src/libopts/configfile.c
@@ -1,13 +1,15 @@
/**
* \file configfile.c
*
- * Time-stamp: "2012-03-31 13:56:11 bkorb"
- *
* configuration/rc/ini file handling.
*
+ * @addtogroup autoopts
+ * @{
+ */
+/*
* This file is part of AutoOpts, a companion to AutoGen.
* AutoOpts is free software.
- * AutoOpts is Copyright (c) 1992-2012 by Bruce Korb - all rights reserved
+ * AutoOpts is Copyright (C) 1992-2013 by Bruce Korb - all rights reserved
*
* AutoOpts is available under any one of two licenses. The license
* in use must be one of these two and the choice is under the control
@@ -19,34 +21,34 @@
* The Modified Berkeley Software Distribution License
* See the file "COPYING.mbsd"
*
- * These files have the following md5sums:
+ * These files have the following sha256 sums:
*
- * 43b91e8ca915626ed3818ffb1b71248b pkg/libopts/COPYING.gplv3
- * 06a1a2e4760c90ea5e1dad8dfaac4d39 pkg/libopts/COPYING.lgplv3
- * 66a5cedaf62c4b2637025f049f9b826f pkg/libopts/COPYING.mbsd
+ * 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3
+ * 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3
+ * 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd
*/
/* = = = START-STATIC-FORWARD = = = */
static void
file_preset(tOptions * opts, char const * fname, int dir);
-static char*
-handle_comment(char* pzText);
+static char *
+handle_comment(char* txt);
static char *
-handle_cfg(tOptions * pOpts, tOptState * pOS, char * pzText, int dir);
+handle_cfg(tOptions * opts, tOptState * ost, char * txt, int dir);
static char *
-handle_directive(tOptions * pOpts, char * pzText);
+handle_directive(tOptions * opts, char * txt);
static char *
-aoflags_directive(tOptions * pOpts, char * pzText);
+aoflags_directive(tOptions * opts, char * txt);
static char *
-program_directive(tOptions * pOpts, char * pzText);
+program_directive(tOptions * opts, char * txt);
static char *
-handle_section(tOptions * pOpts, char * pzText);
+handle_section(tOptions * opts, char * txt);
static int
parse_xml_encoding(char ** ppz);
@@ -58,26 +60,34 @@ static void
cook_xml_text(char * pzData);
static char *
-handle_struct(tOptions * pOpts, tOptState * pOS, char * pzText, int dir);
+handle_struct(tOptions * opts, tOptState * ost, char * txt, int dir);
-static char*
-parse_keyword(tOptions * pOpts, char * pzText, tOptionValue * pType);
+static char const *
+parse_keyword(tOptions * opts, char const * txt, tOptionValue * typ);
-static char*
-parse_set_mem(tOptions * pOpts, char * pzText, tOptionValue * pType);
+static char const *
+parse_set_mem(tOptions * opts, char const * txt, tOptionValue * typ);
-static char *
-parse_value(char * pzText, tOptionValue * pType);
-
-static char *
-skip_unkn(char* pzText);
+static char const *
+parse_value(char const * txt, tOptionValue * typ);
/* = = = END-STATIC-FORWARD = = = */
+/**
+ * Skip over some unknown attribute
+ * @param[in] txt start of skpped text
+ * @returns character after skipped text
+ */
+inline static char const *
+skip_unkn(char const * txt)
+{
+ txt = BRK_END_XML_TOKEN_CHARS(txt);
+ return (*txt == NUL) ? NULL : txt;
+}
/*=export_func configFileLoad
*
* what: parse a configuration file
- * arg: + char const* + pzFile + the file to load +
+ * arg: + char const* + fname + the file to load +
*
* ret_type: const tOptionValue*
* ret_desc: An allocated, compound value structure
@@ -106,23 +116,22 @@ skip_unkn(char* pzText);
* @code{ENOMEM} - not enough memory to allocate the needed structures.
* @end itemize
=*/
-const tOptionValue*
-configFileLoad(char const* pzFile)
+const tOptionValue *
+configFileLoad(char const * fname)
{
- tmap_info_t cfgfile;
- tOptionValue* pRes = NULL;
+ tmap_info_t cfgfile;
+ tOptionValue * res = NULL;
tOptionLoadMode save_mode = option_load_mode;
- char* pzText =
- text_mmap(pzFile, PROT_READ, MAP_PRIVATE, &cfgfile);
+ char * txt = text_mmap(fname, PROT_READ, MAP_PRIVATE, &cfgfile);
- if (TEXT_MMAP_FAILED_ADDR(pzText))
+ if (TEXT_MMAP_FAILED_ADDR(txt))
return NULL; /* errno is set */
option_load_mode = OPTION_LOAD_COOKED;
- pRes = optionLoadNested(pzText, pzFile, strlen(pzFile));
+ res = optionLoadNested(txt, fname, strlen(fname));
- if (pRes == NULL) {
+ if (res == NULL) {
int err = errno;
text_munmap(&cfgfile);
errno = err;
@@ -130,16 +139,16 @@ configFileLoad(char const* pzFile)
text_munmap(&cfgfile);
option_load_mode = save_mode;
- return pRes;
+ return res;
}
/*=export_func optionFindValue
*
* what: find a hierarcicaly valued option instance
- * arg: + const tOptDesc* + pOptDesc + an option with a nested arg type +
- * arg: + char const* + name + name of value to find +
- * arg: + char const* + value + the matching value +
+ * arg: + const tOptDesc* + odesc + an option with a nested arg type +
+ * arg: + char const* + name + name of value to find +
+ * arg: + char const* + val + the matching value +
*
* ret_type: const tOptionValue*
* ret_desc: a compound value structure
@@ -158,53 +167,52 @@ configFileLoad(char const* pzFile)
* @code{ENOENT} - no entry matched the given name.
* @end itemize
=*/
-const tOptionValue*
-optionFindValue(const tOptDesc* pOptDesc, char const* pzName,
- char const* pzVal)
+const tOptionValue *
+optionFindValue(const tOptDesc * odesc, char const * name, char const * val)
{
- const tOptionValue* pRes = NULL;
+ const tOptionValue * res = NULL;
- if ( (pOptDesc == NULL)
- || (OPTST_GET_ARGTYPE(pOptDesc->fOptState) != OPARG_TYPE_HIERARCHY)) {
+ if ( (odesc == NULL)
+ || (OPTST_GET_ARGTYPE(odesc->fOptState) != OPARG_TYPE_HIERARCHY)) {
errno = EINVAL;
}
- else if (pOptDesc->optCookie == NULL) {
+ else if (odesc->optCookie == NULL) {
errno = ENOENT;
}
else do {
- tArgList* pAL = pOptDesc->optCookie;
- int ct = pAL->useCt;
- void** ppOV = (void**)(pAL->apzArgs);
+ tArgList* argl = odesc->optCookie;
+ int argct = argl->useCt;
+ void ** poptv = (void**)(argl->apzArgs);
- if (ct == 0) {
+ if (argct == 0) {
errno = ENOENT;
break;
}
- if (pzName == NULL) {
- pRes = (tOptionValue*)*ppOV;
+ if (name == NULL) {
+ res = (tOptionValue*)*poptv;
break;
}
- while (--ct >= 0) {
- const tOptionValue* pOV = *(ppOV++);
- const tOptionValue* pRV = optionGetValue(pOV, pzName);
+ while (--argct >= 0) {
+ const tOptionValue * ov = *(poptv++);
+ const tOptionValue * rv = optionGetValue(ov, name);
- if (pRV == NULL)
+ if (rv == NULL)
continue;
- if (pzVal == NULL) {
- pRes = pOV;
+ if (val == NULL) {
+ res = ov;
break;
}
}
- if (pRes == NULL)
+ if (res == NULL)
errno = ENOENT;
} while (false);
- return pRes;
+ return res;
}
@@ -213,7 +221,7 @@ optionFindValue(const tOptDesc* pOptDesc, char const* pzName,
* FIXME: the handling of 'pzName' and 'pzVal' is just wrong.
*
* what: find a hierarcicaly valued option instance
- * arg: + const tOptDesc* + pOptDesc + an option with a nested arg type +
+ * arg: + const tOptDesc* + odesc + an option with a nested arg type +
* arg: + const tOptionValue* + pPrevVal + the last entry +
* arg: + char const* + name + name of value to find +
* arg: + char const* + value + the matching value +
@@ -237,43 +245,43 @@ optionFindValue(const tOptDesc* pOptDesc, char const* pzName,
* @end itemize
=*/
tOptionValue const *
-optionFindNextValue(const tOptDesc * pOptDesc, const tOptionValue * pPrevVal,
+optionFindNextValue(const tOptDesc * odesc, const tOptionValue * pPrevVal,
char const * pzName, char const * pzVal)
{
bool old_found = false;
- tOptionValue* pRes = NULL;
+ tOptionValue* res = NULL;
(void)pzName;
(void)pzVal;
- if ( (pOptDesc == NULL)
- || (OPTST_GET_ARGTYPE(pOptDesc->fOptState) != OPARG_TYPE_HIERARCHY)) {
+ if ( (odesc == NULL)
+ || (OPTST_GET_ARGTYPE(odesc->fOptState) != OPARG_TYPE_HIERARCHY)) {
errno = EINVAL;
}
- else if (pOptDesc->optCookie == NULL) {
+ else if (odesc->optCookie == NULL) {
errno = ENOENT;
}
else do {
- tArgList* pAL = pOptDesc->optCookie;
- int ct = pAL->useCt;
- void** ppOV = (void**)pAL->apzArgs;
+ tArgList* argl = odesc->optCookie;
+ int ct = argl->useCt;
+ void** poptv = (void**)argl->apzArgs;
while (--ct >= 0) {
- tOptionValue* pOV = *(ppOV++);
+ tOptionValue* pOV = *(poptv++);
if (old_found) {
- pRes = pOV;
+ res = pOV;
break;
}
if (pOV == pPrevVal)
old_found = true;
}
- if (pRes == NULL)
+ if (res == NULL)
errno = ENOENT;
} while (false);
- return pRes;
+ return res;
}
@@ -304,39 +312,38 @@ optionFindNextValue(const tOptDesc * pOptDesc, const tOptionValue * pPrevVal,
* @code{ENOENT} - no entry matched the given name.
* @end itemize
=*/
-const tOptionValue*
-optionGetValue(tOptionValue const * pOld, char const * pzValName)
+tOptionValue const *
+optionGetValue(tOptionValue const * oov, char const * vname)
{
- tArgList * pAL;
- tOptionValue * pRes = NULL;
+ tArgList * arg_list;
+ tOptionValue * res = NULL;
- if ((pOld == NULL) || (pOld->valType != OPARG_TYPE_HIERARCHY)) {
+ if ((oov == NULL) || (oov->valType != OPARG_TYPE_HIERARCHY)) {
errno = EINVAL;
- return pRes;
+ return res;
}
- pAL = pOld->v.nestVal;
+ arg_list = oov->v.nestVal;
- if (pAL->useCt > 0) {
- int ct = pAL->useCt;
- void ** papOV = (void**)(pAL->apzArgs);
+ if (arg_list->useCt > 0) {
+ int ct = arg_list->useCt;
+ void ** ovlist = (void**)(arg_list->apzArgs);
- if (pzValName == NULL) {
- pRes = (tOptionValue*)*papOV;
+ if (vname == NULL) {
+ res = (tOptionValue*)*ovlist;
} else do {
- tOptionValue * pOV = *(papOV++);
- if (strcmp(pOV->pzName, pzValName) == 0) {
- pRes = pOV;
+ tOptionValue * opt_val = *(ovlist++);
+ if (strcmp(opt_val->pzName, vname) == 0) {
+ res = opt_val;
break;
}
} while (--ct > 0);
}
- if (pRes == NULL)
+ if (res == NULL)
errno = ENOENT;
- return pRes;
+ return res;
}
-
/*=export_func optionNextValue
*
* what: get the next value from a hierarchical list
@@ -365,30 +372,30 @@ optionGetValue(tOptionValue const * pOld, char const * pzValName)
* @end itemize
=*/
tOptionValue const *
-optionNextValue(tOptionValue const * pOVList,tOptionValue const * pOldOV )
+optionNextValue(tOptionValue const * ov_list,tOptionValue const * oov )
{
- tArgList* pAL;
- tOptionValue* pRes = NULL;
- int err = EINVAL;
+ tArgList * arg_list;
+ tOptionValue * res = NULL;
+ int err = EINVAL;
- if ((pOVList == NULL) || (pOVList->valType != OPARG_TYPE_HIERARCHY)) {
+ if ((ov_list == NULL) || (ov_list->valType != OPARG_TYPE_HIERARCHY)) {
errno = EINVAL;
return NULL;
}
- pAL = pOVList->v.nestVal;
+ arg_list = ov_list->v.nestVal;
{
- int ct = pAL->useCt;
- void** papNV = (void**)(pAL->apzArgs);
+ int ct = arg_list->useCt;
+ void ** o_list = (void**)(arg_list->apzArgs);
while (ct-- > 0) {
- tOptionValue* pNV = *(papNV++);
- if (pNV == pOldOV) {
+ tOptionValue * nov = *(o_list++);
+ if (nov == oov) {
if (ct == 0) {
err = ENOENT;
} else {
- err = 0;
- pRes = (tOptionValue*)*papNV;
+ err = 0;
+ res = (tOptionValue*)*o_list;
}
break;
}
@@ -396,20 +403,19 @@ optionNextValue(tOptionValue const * pOVList,tOptionValue const * pOldOV )
}
if (err != 0)
errno = err;
- return pRes;
+ return res;
}
-
/**
* Load a file containing presetting information (a configuration file).
*/
static void
file_preset(tOptions * opts, char const * fname, int dir)
{
- tmap_info_t cfgfile;
- tOptState optst = OPTSTATE_INITIALIZER(PRESET);
- unsigned long st_flags = optst.flags;
- char * ftext =
+ tmap_info_t cfgfile;
+ tOptState optst = OPTSTATE_INITIALIZER(PRESET);
+ opt_state_mask_t st_flags = optst.flags;
+ char * ftext =
text_mmap(fname, PROT_READ|PROT_WRITE, MAP_PRIVATE, &cfgfile);
if (TEXT_MMAP_FAILED_ADDR(ftext))
@@ -456,8 +462,10 @@ file_preset(tOptions * opts, char const * fname, int dir)
break;
default:
- goto all_done;
+ ftext = NULL;
}
+ if (ftext == NULL)
+ goto all_done;
break;
case '[':
@@ -473,47 +481,45 @@ file_preset(tOptions * opts, char const * fname, int dir)
}
} while (ftext != NULL);
-all_done:
+ all_done:
text_munmap(&cfgfile);
}
-
/**
- * "pzText" points to a "<!" sequence.
+ * "txt" points to a "<!" sequence.
* Theoretically, we should ensure that it begins with "<!--",
* but actually I don't care that much. It ends with "-->".
*/
-static char*
-handle_comment(char* pzText)
+static char *
+handle_comment(char* txt)
{
- char* pz = strstr(pzText, "-->");
+ char* pz = strstr(txt, "-->");
if (pz != NULL)
pz += 3;
return pz;
}
-
/**
- * "pzText" points to the start of some value name.
+ * "txt" points to the start of some value name.
* The end of the entry is the end of the line that is not preceded by
* a backslash escape character. The string value is always processed
* in "cooked" mode.
*/
static char *
-handle_cfg(tOptions * pOpts, tOptState * pOS, char * pzText, int dir)
+handle_cfg(tOptions * opts, tOptState * ost, char * txt, int dir)
{
- char* pzName = pzText++;
- char* pzEnd = strchr(pzText, NL);
+ char* pzName = txt++;
+ char* pzEnd = strchr(txt, NL);
if (pzEnd == NULL)
- return pzText + strlen(pzText);
+ return txt + strlen(txt);
- pzText = SPN_VALUE_NAME_CHARS(pzText);
- pzText = SPN_WHITESPACE_CHARS(pzText);
- if (pzText > pzEnd) {
+ txt = SPN_VALUE_NAME_CHARS(txt);
+ txt = SPN_WHITESPACE_CHARS(txt);
+ if (txt > pzEnd) {
name_only:
*pzEnd++ = NUL;
- loadOptionLine(pOpts, pOS, pzName, dir, OPTION_LOAD_UNCOOKED);
+ loadOptionLine(opts, ost, pzName, dir, OPTION_LOAD_UNCOOKED);
return pzEnd;
}
@@ -522,11 +528,11 @@ handle_cfg(tOptions * pOpts, tOptState * pOS, char * pzText, int dir)
* or else we must have skipped over white space. Anything else
* is an invalid format and we give up parsing the text.
*/
- if ((*pzText == '=') || (*pzText == ':')) {
- pzText = SPN_WHITESPACE_CHARS(pzText+1);
- if (pzText > pzEnd)
+ if ((*txt == '=') || (*txt == ':')) {
+ txt = SPN_WHITESPACE_CHARS(txt+1);
+ if (txt > pzEnd)
goto name_only;
- } else if (! IS_WHITESPACE_CHAR(pzText[-1]))
+ } else if (! IS_WHITESPACE_CHAR(txt[-1]))
return NULL;
/*
@@ -542,6 +548,7 @@ handle_cfg(tOptions * pOpts, tOptState * pOS, char * pzText, int dir)
switch (ch) {
case NUL:
pcS = NULL;
+ /* FALLTHROUGH */
case NL:
*pcD = NUL;
@@ -549,9 +556,8 @@ handle_cfg(tOptions * pOpts, tOptState * pOS, char * pzText, int dir)
goto copy_done;
case '\\':
- if (*pcS == NL) {
+ if (*pcS == NL)
ch = *(pcS++);
- }
/* FALLTHROUGH */
default:
*(pcD++) = ch;
@@ -569,19 +575,22 @@ handle_cfg(tOptions * pOpts, tOptState * pOS, char * pzText, int dir)
* "pzName" points to what looks like text for one option/configurable.
* It is NUL terminated. Process it.
*/
- loadOptionLine(pOpts, pOS, pzName, dir, OPTION_LOAD_UNCOOKED);
+ loadOptionLine(opts, ost, pzName, dir, OPTION_LOAD_UNCOOKED);
return pzEnd;
}
-
/**
- * "pzText" points to a "<?" sequence.
+ * "txt" points to a "<?" sequence.
* We handle "<?program" and "<?auto-options" directives.
* All others are treated as comments.
+ *
+ * @param[in,out] opts program option descriptor
+ * @param[in] txt scanning pointer
+ * @returns the next character to look at
*/
static char *
-handle_directive(tOptions * pOpts, char * pzText)
+handle_directive(tOptions * opts, char * txt)
{
# define DIRECTIVE_TABLE \
_dt_(zCfgProg, program_directive) \
@@ -610,112 +619,124 @@ handle_directive(tOptions * pOpts, char * pzText)
for (ix = 0; ix < dir_ct; ix++) {
size_t len = strlen(dir_names[ix]);
- if ( (strncmp(pzText + 2, dir_names[ix], len) == 0)
- && (! IS_VALUE_NAME_CHAR(pzText[len+2])) )
- return dir_disp[ix](pOpts, pzText + len + 2);
+ if ( (strncmp(txt + 2, dir_names[ix], len) == 0)
+ && (! IS_VALUE_NAME_CHAR(txt[len+2])) )
+ return dir_disp[ix](opts, txt + len + 2);
}
/*
* We don't know what this is. Skip it.
*/
- pzText = strchr(pzText+2, '>');
- if (pzText != NULL)
- pzText++;
- return pzText;
+ txt = strchr(txt+2, '>');
+ if (txt != NULL)
+ txt++;
+ return txt;
+# undef DIRECTIVE_TABLE
}
/**
- * handle AutoOpts mode flags
+ * handle AutoOpts mode flags.
+ *
+ * @param[in,out] opts program option descriptor
+ * @param[in] txt scanning pointer
+ * @returns the next character to look at
*/
static char *
-aoflags_directive(tOptions * pOpts, char * pzText)
+aoflags_directive(tOptions * opts, char * txt)
{
char * pz;
- pz = SPN_WHITESPACE_CHARS(pzText+1);
- pzText = strchr(pz, '>');
- if (pzText != NULL) {
+ pz = SPN_WHITESPACE_CHARS(txt+1);
+ txt = strchr(pz, '>');
+ if (txt != NULL) {
- size_t len = pzText - pz;
+ size_t len = (unsigned)(txt - pz);
char * ftxt = AGALOC(len + 1, "aoflags");
memcpy(ftxt, pz, len);
ftxt[len] = NUL;
- set_usage_flags(pOpts, ftxt);
+ set_usage_flags(opts, ftxt);
AGFREE(ftxt);
- pzText++;
+ txt++;
}
- return pzText;
+ return txt;
}
/**
* handle program segmentation of config file.
+ *
+ * @param[in,out] opts program option descriptor
+ * @param[in] txt scanning pointer
+ * @returns the next character to look at
*/
static char *
-program_directive(tOptions * pOpts, char * pzText)
+program_directive(tOptions * opts, char * txt)
{
static char const ttlfmt[] = "<?";
size_t ttl_len = sizeof(ttlfmt) + strlen(zCfgProg);
char * ttl = AGALOC(ttl_len, "prog title");
- size_t name_len = strlen(pOpts->pzProgName);
+ size_t name_len = strlen(opts->pzProgName);
memcpy(ttl, ttlfmt, sizeof(ttlfmt) - 1);
memcpy(ttl + sizeof(ttlfmt) - 1, zCfgProg, ttl_len - (sizeof(ttlfmt) - 1));
do {
- pzText = SPN_WHITESPACE_CHARS(pzText+1);
+ txt = SPN_WHITESPACE_CHARS(txt+1);
- if ( (strneqvcmp(pzText, pOpts->pzProgName, (int)name_len) == 0)
- && (IS_END_XML_TOKEN_CHAR(pzText[name_len])) ) {
- pzText += name_len;
+ if ( (strneqvcmp(txt, opts->pzProgName, (int)name_len) == 0)
+ && (IS_END_XML_TOKEN_CHAR(txt[name_len])) ) {
+ txt += name_len;
break;
}
- pzText = strstr(pzText, ttl);
- } while (pzText != NULL);
+ txt = strstr(txt, ttl);
+ } while (txt != NULL);
AGFREE(ttl);
- if (pzText != NULL)
+ if (txt != NULL)
for (;;) {
- if (*pzText == NUL) {
- pzText = NULL;
+ if (*txt == NUL) {
+ txt = NULL;
break;
}
- if (*(pzText++) == '>')
+ if (*(txt++) == '>')
break;
}
- return pzText;
+ return txt;
}
-
/**
- * "pzText" points to a '[' character.
+ * "txt" points to a '[' character.
* The "traditional" [PROG_NAME] segmentation of the config file.
* Do not ever mix with the "<?program prog-name>" variation.
+ *
+ * @param[in,out] opts program option descriptor
+ * @param[in] txt scanning pointer
+ * @returns the next character to look at
*/
static char *
-handle_section(tOptions * pOpts, char * pzText)
+handle_section(tOptions * opts, char * txt)
{
- size_t len = strlen(pOpts->pzPROGNAME);
- if ( (strncmp(pzText+1, pOpts->pzPROGNAME, len) == 0)
- && (pzText[len+1] == ']'))
- return strchr(pzText + len + 2, NL);
+ size_t len = strlen(opts->pzPROGNAME);
+ if ( (strncmp(txt+1, opts->pzPROGNAME, len) == 0)
+ && (txt[len+1] == ']'))
+ return strchr(txt + len + 2, NL);
if (len > 16)
return NULL;
{
char z[24];
- sprintf(z, "[%s]", pOpts->pzPROGNAME);
- pzText = strstr(pzText, z);
+ sprintf(z, "[%s]", opts->pzPROGNAME);
+ txt = strstr(txt, z);
}
- if (pzText != NULL)
- pzText = strchr(pzText, NL);
- return pzText;
+ if (txt != NULL)
+ txt = strchr(txt, NL);
+ return txt;
}
/**
@@ -820,7 +841,7 @@ trim_xml_text(char * intxt, char const * pznm, tOptionLoadMode mode)
if (len >= sizeof(z))
pz = AGALOC(len, "scan name");
- len = sprintf(pz, fmt, pznm);
+ len = (size_t)sprintf(pz, fmt, pznm);
*intxt = ' ';
etext = strstr(intxt, pz);
if (pz != z) AGFREE(pz);
@@ -872,7 +893,7 @@ cook_xml_text(char * pzData)
return;
}
- ch = strtoul(bf, NULL, 16);
+ ch = (int)strtoul(bf, NULL, 16);
/* FALLTHROUGH */
default:
@@ -882,67 +903,70 @@ cook_xml_text(char * pzData)
}
/**
- * "pzText" points to a '<' character, followed by an alpha.
+ * "txt" points to a '<' character, followed by an alpha.
* The end of the entry is either the "/>" following the name, or else a
* "</name>" string.
*/
static char *
-handle_struct(tOptions * pOpts, tOptState * pOS, char * pzText, int dir)
+handle_struct(tOptions * opts, tOptState * ost, char * txt, int dir)
{
tOptionLoadMode mode = option_load_mode;
tOptionValue valu;
- char* pzName = ++pzText;
+ char* pzName = ++txt;
char* pzData;
char* pcNulPoint;
- pzText = SPN_VALUE_NAME_CHARS(pzText);
- pcNulPoint = pzText;
+ txt = SPN_VALUE_NAME_CHARS(txt);
+ pcNulPoint = txt;
valu.valType = OPARG_TYPE_STRING;
- switch (*pzText) {
+ switch (*txt) {
case ' ':
case '\t':
- pzText = parse_attrs(pOpts, pzText, &mode, &valu);
- if (*pzText == '>')
+ txt = (void *)parse_attrs(
+ opts, SPN_WHITESPACE_CHARS(txt), &mode, &valu);
+ if (txt == NULL)
+ return txt;
+ if (*txt == '>')
break;
- if (*pzText != '/')
+ if (*txt != '/')
return NULL;
/* FALLTHROUGH */
case '/':
- if (pzText[1] != '>')
+ if (txt[1] != '>')
return NULL;
- *pzText = NUL;
- pzText += 2;
- loadOptionLine(pOpts, pOS, pzName, dir, mode);
- return pzText;
+ *txt = NUL;
+ txt += 2;
+ loadOptionLine(opts, ost, pzName, dir, mode);
+ return txt;
case '>':
break;
default:
- pzText = strchr(pzText, '>');
- if (pzText != NULL)
- pzText++;
- return pzText;
+ txt = strchr(txt, '>');
+ if (txt != NULL)
+ txt++;
+ return txt;
}
/*
- * If we are here, we have a value. "pzText" points to a closing angle
+ * If we are here, we have a value. "txt" points to a closing angle
* bracket. Separate the name from the value for a moment.
*/
*pcNulPoint = NUL;
- pzData = ++pzText;
- pzText = trim_xml_text(pzText, pzName, mode);
- if (pzText == NULL)
- return pzText;
+ pzData = ++txt;
+ txt = trim_xml_text(txt, pzName, mode);
+ if (txt == NULL)
+ return txt;
/*
* Rejoin the name and value for parsing by "loadOptionLine()".
* Erase any attributes parsed by "parse_attrs()".
*/
- memset(pcNulPoint, ' ', pzData - pcNulPoint);
+ memset(pcNulPoint, ' ', (size_t)(pzData - pcNulPoint));
/*
* If we are getting a "string" value that is to be cooked,
@@ -956,40 +980,39 @@ handle_struct(tOptions * pOpts, tOptState * pOS, char * pzText, int dir)
* "pzName" points to what looks like text for one option/configurable.
* It is NUL terminated. Process it.
*/
- loadOptionLine(pOpts, pOS, pzName, dir, mode);
+ loadOptionLine(opts, ost, pzName, dir, mode);
- return pzText;
+ return txt;
}
-
/**
* Load a configuration file. This may be invoked either from
* scanning the "homerc" list, or from a specific file request.
* (see "optionFileLoad()", the implementation for --load-opts)
*/
LOCAL void
-intern_file_load(tOptions* pOpts)
+intern_file_load(tOptions * opts)
{
uint32_t svfl;
int idx;
int inc;
- char zFileName[ AG_PATH_MAX+1 ];
+ char f_name[ AG_PATH_MAX+1 ];
- if (pOpts->papzHomeList == NULL)
+ if (opts->papzHomeList == NULL)
return;
- svfl = pOpts->fOptSet;
+ svfl = opts->fOptSet;
inc = DIRECTION_PRESET;
/*
* Never stop on errors in config files.
*/
- pOpts->fOptSet &= ~OPTPROC_ERRSTOP;
+ opts->fOptSet &= ~OPTPROC_ERRSTOP;
/*
* Find the last RC entry (highest priority entry)
*/
- for (idx = 0; pOpts->papzHomeList[ idx+1 ] != NULL; ++idx) ;
+ for (idx = 0; opts->papzHomeList[ idx+1 ] != NULL; ++idx) ;
/*
* For every path in the home list, ... *TWICE* We start at the last
@@ -998,8 +1021,8 @@ intern_file_load(tOptions* pOpts)
* Then we go back up, doing the normal options.
*/
for (;;) {
- struct stat StatBuf;
- cch_t* pzPath;
+ struct stat sb;
+ cch_t * path;
/*
* IF we've reached the bottom end, change direction
@@ -1009,18 +1032,18 @@ intern_file_load(tOptions* pOpts)
idx = 0;
}
- pzPath = pOpts->papzHomeList[ idx ];
+ path = opts->papzHomeList[ idx ];
/*
* IF we've reached the top end, bail out
*/
- if (pzPath == NULL)
+ if (path == NULL)
break;
idx += inc;
- if (! optionMakePath(zFileName, (int)sizeof(zFileName),
- pzPath, pOpts->pzProgPath))
+ if (! optionMakePath(f_name, (int)sizeof(f_name),
+ path, opts->pzProgPath))
continue;
/*
@@ -1028,47 +1051,46 @@ intern_file_load(tOptions* pOpts)
* THEN append the Resource Configuration file name
* ELSE we must have the complete file name
*/
- if (stat(zFileName, &StatBuf) != 0)
+ if (stat(f_name, &sb) != 0)
continue; /* bogus name - skip the home list entry */
- if (S_ISDIR(StatBuf.st_mode)) {
- size_t len = strlen(zFileName);
- size_t nln = strlen(pOpts->pzRcName) + 1;
- char * pz = zFileName + len;
+ if (S_ISDIR(sb.st_mode)) {
+ size_t len = strlen(f_name);
+ size_t nln = strlen(opts->pzRcName) + 1;
+ char * pz = f_name + len;
- if (len + 1 + nln >= sizeof(zFileName))
+ if (len + 1 + nln >= sizeof(f_name))
continue;
if (pz[-1] != DIRCH)
*(pz++) = DIRCH;
- memcpy(pz, pOpts->pzRcName, nln);
+ memcpy(pz, opts->pzRcName, nln);
}
- file_preset(pOpts, zFileName, inc);
+ file_preset(opts, f_name, inc);
/*
* IF we are now to skip config files AND we are presetting,
* THEN change direction. We must go the other way.
*/
{
- tOptDesc * pOD = pOpts->pOptDesc + pOpts->specOptIdx.save_opts+1;
- if (DISABLED_OPT(pOD) && PRESETTING(inc)) {
+ tOptDesc * od = opts->pOptDesc + opts->specOptIdx.save_opts + 1;
+ if (DISABLED_OPT(od) && PRESETTING(inc)) {
idx -= inc; /* go back and reprocess current file */
inc = DIRECTION_PROCESS;
}
}
} /* twice for every path in the home list, ... */
- pOpts->fOptSet = svfl;
+ opts->fOptSet = svfl;
}
-
/*=export_func optionFileLoad
*
* what: Load the locatable config files, in order
*
- * arg: + tOptions* + pOpts + program options descriptor +
- * arg: + char const* + pzProg + program name +
+ * arg: + tOptions* + opts + program options descriptor +
+ * arg: + char const* + prog + program name +
*
* ret_type: int
* ret_desc: 0 -> SUCCESS, -1 -> FAILURE
@@ -1097,330 +1119,254 @@ intern_file_load(tOptions* pOpts)
* always be returned.
=*/
int
-optionFileLoad(tOptions * pOpts, char const * pzProgram)
+optionFileLoad(tOptions * opts, char const * prog)
{
- if (! SUCCESSFUL(validate_struct(pOpts, pzProgram)))
+ if (! SUCCESSFUL(validate_struct(opts, prog)))
return -1;
+ /*
+ * The pointer to the program name is "const". However, the
+ * structure is in writable memory, so we coerce the address
+ * of this pointer to point to writable memory.
+ */
{
char const ** pp =
- (char const **)(void *)&(pOpts->pzProgName);
- *pp = pzProgram;
+ (char const **)(void *)&(opts->pzProgName);
+ *pp = prog;
}
- intern_file_load(pOpts);
+ intern_file_load(opts);
return 0;
}
-
/*=export_func optionLoadOpt
* private:
*
* what: Load an option rc/ini file
- * arg: + tOptions* + pOpts + program options descriptor +
- * arg: + tOptDesc* + pOptDesc + the descriptor for this arg +
+ * arg: + tOptions* + opts + program options descriptor +
+ * arg: + tOptDesc* + odesc + the descriptor for this arg +
*
* doc:
* Processes the options found in the file named with
- * pOptDesc->optArg.argString.
+ * odesc->optArg.argString.
=*/
void
-optionLoadOpt(tOptions * pOpts, tOptDesc * pOptDesc)
+optionLoadOpt(tOptions * opts, tOptDesc * odesc)
{
struct stat sb;
+ if (opts <= OPTPROC_EMIT_LIMIT)
+ return;
+
/*
* IF the option is not being disabled, THEN load the file. There must
* be a file. (If it is being disabled, then the disablement processing
* already took place. It must be done to suppress preloading of ini/rc
* files.)
*/
- if ( DISABLED_OPT(pOptDesc)
- || ((pOptDesc->fOptState & OPTST_RESET) != 0))
+ if ( DISABLED_OPT(odesc)
+ || ((odesc->fOptState & OPTST_RESET) != 0))
return;
- if (stat(pOptDesc->optArg.argString, &sb) != 0) {
- if ((pOpts->fOptSet & OPTPROC_ERRSTOP) == 0)
+ if (stat(odesc->optArg.argString, &sb) != 0) {
+ if ((opts->fOptSet & OPTPROC_ERRSTOP) == 0)
return;
- fprintf(stderr, zFSErrOptLoad, errno, strerror(errno),
- pOptDesc->optArg.argString);
- exit(EX_NOINPUT);
+ fserr_exit(opts->pzProgName, "stat", odesc->optArg.argString);
/* NOT REACHED */
}
if (! S_ISREG(sb.st_mode)) {
- if ((pOpts->fOptSet & OPTPROC_ERRSTOP) == 0)
+ if ((opts->fOptSet & OPTPROC_ERRSTOP) == 0)
return;
-
- fprintf(stderr, zNotFile, pOptDesc->optArg.argString);
- exit(EX_NOINPUT);
+ errno = EINVAL;
+ fserr_exit(opts->pzProgName, "stat", odesc->optArg.argString);
/* NOT REACHED */
}
- file_preset(pOpts, pOptDesc->optArg.argString, DIRECTION_CALLED);
+ file_preset(opts, odesc->optArg.argString, DIRECTION_CALLED);
}
-
/**
* Parse the various attributes of an XML-styled config file entry
+ *
+ * @returns NULL on failure, otherwise the scan point
*/
-LOCAL char*
-parse_attrs(tOptions * pOpts, char * pzText, tOptionLoadMode * pMode,
+LOCAL char const *
+parse_attrs(tOptions * opts, char const * txt, tOptionLoadMode * pMode,
tOptionValue * pType)
{
- size_t len;
-
- do {
- if (! IS_WHITESPACE_CHAR(*pzText))
- switch (*pzText) {
- case '/': pType->valType = OPARG_TYPE_NONE;
- case '>': return pzText;
-
- default:
- case NUL: return NULL;
- }
+ size_t len = 0;
- pzText = SPN_WHITESPACE_CHARS(pzText+1);
- len = SPN_LOWER_CASE_CHARS(pzText) - pzText;
+ for (;;) {
+ len = (size_t)(SPN_LOWER_CASE_CHARS(txt) - txt);
- switch (find_xat_attribute_id(pzText, len)) {
- case XAT_KWD_TYPE:
- pzText = parse_value(pzText+len, pType);
+ /*
+ * The enumeration used in this switch is derived from this switch
+ * statement itself. The "find_option_xat_attribute_cmd" function
+ * will return XAT_CMD_MEMBERS for the "txt" string value
+ * "members", etc.
+ */
+ switch (find_option_xat_attribute_cmd(txt, len)) {
+ case XAT_CMD_TYPE:
+ txt = parse_value(txt+len, pType);
break;
- case XAT_KWD_WORDS:
- pzText = parse_keyword(pOpts, pzText+len, pType);
+ case XAT_CMD_WORDS:
+ txt = parse_keyword(opts, txt+len, pType);
break;
- case XAT_KWD_MEMBERS:
- pzText = parse_set_mem(pOpts, pzText+len, pType);
+ case XAT_CMD_MEMBERS:
+ txt = parse_set_mem(opts, txt+len, pType);
break;
- case XAT_KWD_COOKED:
- pzText += len;
- if (! IS_END_XML_TOKEN_CHAR(*pzText))
+ case XAT_CMD_COOKED:
+ txt += len;
+ if (! IS_END_XML_TOKEN_CHAR(*txt))
goto invalid_kwd;
*pMode = OPTION_LOAD_COOKED;
break;
- case XAT_KWD_UNCOOKED:
- pzText += len;
- if (! IS_END_XML_TOKEN_CHAR(*pzText))
+ case XAT_CMD_UNCOOKED:
+ txt += len;
+ if (! IS_END_XML_TOKEN_CHAR(*txt))
goto invalid_kwd;
*pMode = OPTION_LOAD_UNCOOKED;
break;
- case XAT_KWD_KEEP:
- pzText += len;
- if (! IS_END_XML_TOKEN_CHAR(*pzText))
+ case XAT_CMD_KEEP:
+ txt += len;
+ if (! IS_END_XML_TOKEN_CHAR(*txt))
goto invalid_kwd;
*pMode = OPTION_LOAD_KEEP;
break;
default:
- case XAT_KWD_INVALID:
+ case XAT_INVALID_CMD:
invalid_kwd:
pType->valType = OPARG_TYPE_NONE;
- return skip_unkn(pzText);
+ return skip_unkn(txt);
}
- } while (pzText != NULL);
- return pzText;
+ if (txt == NULL)
+ return NULL;
+ txt = SPN_WHITESPACE_CHARS(txt);
+ switch (*txt) {
+ case '/': pType->valType = OPARG_TYPE_NONE;
+ /* FALLTHROUGH */
+ case '>': return txt;
+ }
+ if (! IS_LOWER_CASE_CHAR(*txt))
+ return NULL;
+ }
}
-
/**
- * "pzText" points to the character after "words=".
+ * "txt" points to the character after "words=".
* What should follow is a name of a keyword (enumeration) list.
+ *
+ * @param opts unused
+ * @param[in] txt keyword to skip over
+ * @param type unused value type
+ * @returns pointer after skipped text
*/
-static char*
-parse_keyword(tOptions * pOpts, char * pzText, tOptionValue * pType)
+static char const *
+parse_keyword(tOptions * opts, char const * txt, tOptionValue * typ)
{
- (void)pOpts;
- (void)pType;
+ (void)opts;
+ (void)typ;
- return skip_unkn(pzText);
+ return skip_unkn(txt);
}
-
/**
- * "pzText" points to the character after "members="
+ * "txt" points to the character after "members="
* What should follow is a name of a "set membership".
* A collection of bit flags.
+ *
+ * @param opts unused
+ * @param[in] txt keyword to skip over
+ * @param type unused value type
+ * @returns pointer after skipped text
*/
-static char*
-parse_set_mem(tOptions * pOpts, char * pzText, tOptionValue * pType)
+static char const *
+parse_set_mem(tOptions * opts, char const * txt, tOptionValue * typ)
{
- (void)pOpts;
- (void)pType;
+ (void)opts;
+ (void)typ;
- return skip_unkn(pzText);
+ return skip_unkn(txt);
}
-
/**
- * "pzText" points to the character after "type="
+ * parse the type. The keyword "type" was found, now figure out
+ * the type that follows the type.
+ *
+ * @param[in] txt points to the '=' character after the "type" keyword.
+ * @param[out] typ where to store the type found
+ * @returns the next byte after the type name
*/
-static char *
-parse_value(char * pzText, tOptionValue * pType)
+static char const *
+parse_value(char const * txt, tOptionValue * typ)
{
size_t len = 0;
- if (*(pzText++) != '=')
+ if (*(txt++) != '=')
goto woops;
- len = SPN_OPTION_NAME_CHARS(pzText) - pzText;
+ len = (size_t)(SPN_OPTION_NAME_CHARS(txt) - txt);
- if ((len == 0) || (! IS_END_XML_TOKEN_CHAR(pzText[len]))) {
+ if ((len == 0) || (! IS_END_XML_TOKEN_CHAR(txt[len]))) {
woops:
- pType->valType = OPARG_TYPE_NONE;
- return skip_unkn(pzText + len);
+ typ->valType = OPARG_TYPE_NONE;
+ return skip_unkn(txt + len);
}
- switch (find_value_type_id(pzText, len)) {
+ /*
+ * The enumeration used in this switch is derived from this switch
+ * statement itself. The "find_option_value_type_cmd" function
+ * will return VTP_CMD_INTEGER for the "txt" string value
+ * "integer", etc.
+ */
+ switch (find_option_value_type_cmd(txt, len)) {
default:
- case VTP_KWD_INVALID: goto woops;
+ case VTP_INVALID_CMD: goto woops;
- case VTP_KWD_STRING:
- pType->valType = OPARG_TYPE_STRING;
+ case VTP_CMD_STRING:
+ typ->valType = OPARG_TYPE_STRING;
break;
- case VTP_KWD_INTEGER:
- pType->valType = OPARG_TYPE_NUMERIC;
+ case VTP_CMD_INTEGER:
+ typ->valType = OPARG_TYPE_NUMERIC;
break;
- case VTP_KWD_BOOL:
- case VTP_KWD_BOOLEAN:
- pType->valType = OPARG_TYPE_BOOLEAN;
+ case VTP_CMD_BOOL:
+ case VTP_CMD_BOOLEAN:
+ typ->valType = OPARG_TYPE_BOOLEAN;
break;
- case VTP_KWD_KEYWORD:
- pType->valType = OPARG_TYPE_ENUMERATION;
+ case VTP_CMD_KEYWORD:
+ typ->valType = OPARG_TYPE_ENUMERATION;
break;
- case VTP_KWD_SET:
- case VTP_KWD_SET_MEMBERSHIP:
- pType->valType = OPARG_TYPE_MEMBERSHIP;
+ case VTP_CMD_SET:
+ case VTP_CMD_SET_MEMBERSHIP:
+ typ->valType = OPARG_TYPE_MEMBERSHIP;
break;
- case VTP_KWD_NESTED:
- case VTP_KWD_HIERARCHY:
- pType->valType = OPARG_TYPE_HIERARCHY;
+ case VTP_CMD_NESTED:
+ case VTP_CMD_HIERARCHY:
+ typ->valType = OPARG_TYPE_HIERARCHY;
}
- return pzText + len;
-}
-
-
-/**
- * Skip over some unknown attribute
- */
-static char *
-skip_unkn(char* pzText)
-{
- for (;; pzText++) {
- if (IS_END_XML_TOKEN_CHAR(*pzText)) return pzText;
- if (*pzText == NUL) return NULL;
- }
+ return txt + len;
}
-
-/**
- * Make sure the option descriptor is there and that we understand it.
- * This should be called from any user entry point where one needs to
- * worry about validity. (Some entry points are free to assume that
- * the call is not the first to the library and, thus, that this has
- * already been called.)
+/** @}
*
- * Upon successful completion, pzProgName and pzProgPath are set.
- *
- * @param pOpts program options descriptor
- * @param pzProgram name of program, from argv[]
- * @returns SUCCESS or FAILURE
- */
-LOCAL tSuccess
-validate_struct(tOptions * pOpts, char const * pzProgram)
-{
- if (pOpts == NULL) {
- fputs(zAO_Bad, stderr);
- return FAILURE;
- }
-
- /*
- * IF the client has enabled translation and the translation procedure
- * is available, then go do it.
- */
- if ( ((pOpts->fOptSet & OPTPROC_TRANSLATE) != 0)
- && (pOpts->pTransProc != NULL) ) {
- /*
- * If option names are not to be translated at all, then do not do
- * it for configuration parsing either. (That is the bit that really
- * gets tested anyway.)
- */
- if ((pOpts->fOptSet & OPTPROC_NO_XLAT_MASK) == OPTPROC_NXLAT_OPT)
- pOpts->fOptSet |= OPTPROC_NXLAT_OPT_CFG;
- (*pOpts->pTransProc)();
- pOpts->fOptSet &= ~OPTPROC_TRANSLATE;
- }
-
- /*
- * IF the struct version is not the current, and also
- * either too large (?!) or too small,
- * THEN emit error message and fail-exit
- */
- if ( ( pOpts->structVersion != OPTIONS_STRUCT_VERSION )
- && ( (pOpts->structVersion > OPTIONS_STRUCT_VERSION )
- || (pOpts->structVersion < OPTIONS_MINIMUM_VERSION )
- ) ) {
- static char const aover[] =
- STR(AO_CURRENT)":"STR(AO_REVISION)":"STR(AO_AGE)"\n";
-
- fprintf(stderr, zAO_Err, pzProgram, NUM_TO_VER(pOpts->structVersion));
- if (pOpts->structVersion > OPTIONS_STRUCT_VERSION )
- fputs(zAO_Big, stderr);
- else
- fputs(zAO_Sml, stderr);
-
- fwrite(aover, sizeof(aover) - 1, 1, stderr);
- return FAILURE;
- }
-
- /*
- * If the program name hasn't been set, then set the name and the path
- * and the set of equivalent characters.
- */
- if (pOpts->pzProgName == NULL) {
- char const * pz = strrchr(pzProgram, DIRCH);
- char const ** pp =
- (char const **)(void **)&(pOpts->pzProgName);
-
- if (pz != NULL) {
- *pp = pz+1;
- } else {
- *pp = pzProgram;
- pz = pathfind(getenv("PATH"), (char *)pzProgram, "rx");
- if (pz != NULL)
- pzProgram = (void *)pz;
- }
-
- pp = (char const **)(void **)&(pOpts->pzProgPath);
- *pp = pzProgram;
-
- /*
- * when comparing long names, these are equivalent
- */
- strequate(zSepChars);
- }
-
- return SUCCESS;
-}
-
-
-/**
* Local Variables:
* mode: C
* c-file-style: "stroustrup"