📄 configfile.c
字号:
/* * $Id: configfile.c,v 1.21 2007/04/15 19:01:18 bkorb Exp $ * Time-stamp: "2007-04-15 11:22:46 bkorb" * * configuration/rc/ini file handling. *//* * Automated Options copyright 1992-2007 Bruce Korb * * Automated Options is free software. * You may redistribute it and/or modify it under the terms of the * GNU General Public License, as published by the Free Software * Foundation; either version 2, or (at your option) any later version. * * Automated Options is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Automated Options. See the file "COPYING". If not, * write to: The Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * As a special exception, Bruce Korb gives permission for additional * uses of the text contained in his release of AutoOpts. * * The exception is that, if you link the AutoOpts library with other * files to produce an executable, this does not by itself cause the * resulting executable to be covered by the GNU General Public License. * Your use of that executable is in no way restricted on account of * linking the AutoOpts library code into it. * * This exception does not however invalidate any other reasons why * the executable file might be covered by the GNU General Public License. * * This exception applies only to the code released by Bruce Korb under * the name AutoOpts. If you copy code from other sources under the * General Public License into a copy of AutoOpts, as the General Public * License permits, the exception does not apply to the code that you add * in this way. To avoid misleading anyone as to the status of such * modified files, you must delete this exception notice from them. * * If you write modifications of your own for AutoOpts, it is your choice * whether to permit this exception to apply to your modifications. * If you do not wish that, delete this exception notice. *//* = = = START-STATIC-FORWARD = = = *//* static forward declarations maintained by :mkfwd */static voidfilePreset( tOptions* pOpts, char const* pzFileName, int direction );static char*handleComment( char* pzText );static char*handleConfig( tOptions* pOpts, tOptState* pOS, char* pzText, int direction );static char*handleDirective( tOptions* pOpts, char* pzText );static char*handleProgramSection( tOptions* pOpts, char* pzText );static char*handleStructure( tOptions* pOpts, tOptState* pOS, char* pzText, int direction );static char*parseKeyWordType( tOptions* pOpts, char* pzText, tOptionValue* pType );static char*parseLoadMode( char* pzText, tOptionLoadMode* pMode );static char*parseSetMemType( tOptions* pOpts, char* pzText, tOptionValue* pType );static char*parseValueType( char* pzText, tOptionValue* pType );static char*skipUnknown( char* pzText );/* = = = END-STATIC-FORWARD = = = *//*=export_func configFileLoad * * what: parse a configuration file * arg: + char const* + pzFile + the file to load + * * ret_type: const tOptionValue* * ret_desc: An allocated, compound value structure * * doc: * This routine will load a named configuration file and parse the * text as a hierarchically valued option. The option descriptor * created from an option definition file is not used via this interface. * The returned value is "named" with the input file name and is of * type "@code{OPARG_TYPE_HIERARCHY}". It may be used in calls to * @code{optionGetValue()}, @code{optionNextValue()} and * @code{optionUnloadNested()}. * * err: * If the file cannot be loaded or processed, @code{NULL} is returned and * @var{errno} is set. It may be set by a call to either @code{open(2)} * @code{mmap(2)} or other file system calls, or it may be: * @itemize @bullet * @item * @code{ENOENT} - the file was empty. * @item * @code{EINVAL} - the file contents are invalid -- not properly formed. * @item * @code{ENOMEM} - not enough memory to allocate the needed structures. * @end itemize=*/const tOptionValue*configFileLoad( char const* pzFile ){ tmap_info_t cfgfile; tOptionValue* pRes = NULL; tOptionLoadMode save_mode = option_load_mode; char* pzText = text_mmap( pzFile, PROT_READ, MAP_PRIVATE, &cfgfile ); if (TEXT_MMAP_FAILED_ADDR(pzText)) return NULL; /* errno is set */ option_load_mode = OPTION_LOAD_COOKED; pRes = optionLoadNested(pzText, pzFile, strlen(pzFile)); if (pRes == NULL) { int err = errno; text_munmap( &cfgfile ); errno = err; } else text_munmap( &cfgfile ); option_load_mode = save_mode; return pRes;}/*=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 + * * ret_type: const tOptionValue* * ret_desc: a compound value structure * * doc: * This routine will find an entry in a nested value option or configurable. * It will search through the list and return a matching entry. * * err: * The returned result is NULL and errno is set: * @itemize @bullet * @item * @code{EINVAL} - the @code{pOptValue} does not point to a valid * hierarchical option value. * @item * @code{ENOENT} - no entry matched the given name. * @end itemize=*/const tOptionValue*optionFindValue( const tOptDesc* pOptDesc, char const* pzName, char const* pzVal ){ const tOptionValue* pRes = NULL; if ( (pOptDesc == NULL) || (OPTST_GET_ARGTYPE(pOptDesc->fOptState) != OPARG_TYPE_HIERARCHY)) { errno = EINVAL; } else if (pOptDesc->optCookie == NULL) { errno = ENOENT; } else do { tArgList* pAL = pOptDesc->optCookie; int ct = pAL->useCt; void** ppOV = (void**)(pAL->apzArgs); if (ct == 0) { errno = ENOENT; break; } if (pzName == NULL) { pRes = (tOptionValue*)*ppOV; break; } while (--ct >= 0) { const tOptionValue* pOV = *(ppOV++); const tOptionValue* pRV = optionGetValue( pOV, pzName ); if (pRV == NULL) continue; if (pzVal == NULL) { pRes = pOV; break; } } if (pRes == NULL) errno = ENOENT; } while (0); return pRes;}/*=export_func optionFindNextValue * * what: find a hierarcicaly valued option instance * arg: + const tOptDesc* + pOptDesc + 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 + * * ret_type: const tOptionValue* * ret_desc: a compound value structure * * doc: * This routine will find the next entry in a nested value option or * configurable. It will search through the list and return the next entry * that matches the criteria. * * err: * The returned result is NULL and errno is set: * @itemize @bullet * @item * @code{EINVAL} - the @code{pOptValue} does not point to a valid * hierarchical option value. * @item * @code{ENOENT} - no entry matched the given name. * @end itemize=*/const tOptionValue*optionFindNextValue( const tOptDesc* pOptDesc, const tOptionValue* pPrevVal, char const* pzName, char const* pzVal ){ int foundOldVal = 0; tOptionValue* pRes = NULL; if ( (pOptDesc == NULL) || (OPTST_GET_ARGTYPE(pOptDesc->fOptState) != OPARG_TYPE_HIERARCHY)) { errno = EINVAL; } else if (pOptDesc->optCookie == NULL) { errno = ENOENT; } else do { tArgList* pAL = pOptDesc->optCookie; int ct = pAL->useCt; void** ppOV = (void**)pAL->apzArgs; if (ct == 0) { errno = ENOENT; break; } while (--ct >= 0) { tOptionValue* pOV = *(ppOV++); if (foundOldVal) { pRes = pOV; break; } if (pOV == pPrevVal) foundOldVal = 1; } if (pRes == NULL) errno = ENOENT; } while (0); return pRes;}/*=export_func optionGetValue * * what: get a specific value from a hierarcical list * arg: + const tOptionValue* + pOptValue + a hierarchcal value + * arg: + char const* + valueName + name of value to get + * * ret_type: const tOptionValue* * ret_desc: a compound value structure * * doc: * This routine will find an entry in a nested value option or configurable. * If "valueName" is NULL, then the first entry is returned. Otherwise, * the first entry with a name that exactly matches the argument will be * returned. * * err: * The returned result is NULL and errno is set: * @itemize @bullet * @item * @code{EINVAL} - the @code{pOptValue} does not point to a valid * hierarchical option value. * @item * @code{ENOENT} - no entry matched the given name. * @end itemize=*/const tOptionValue*optionGetValue( const tOptionValue* pOld, char const* pzValName ){ tArgList* pAL; tOptionValue* pRes = NULL; if ((pOld == NULL) || (pOld->valType != OPARG_TYPE_HIERARCHY)) { errno = EINVAL; return NULL; } pAL = pOld->v.nestVal; if (pAL->useCt > 0) { int ct = pAL->useCt; void** papOV = (void**)(pAL->apzArgs); if (pzValName == NULL) { pRes = (tOptionValue*)*papOV; } else do { tOptionValue* pOV = *(papOV++); if (strcmp( pOV->pzName, pzValName ) == 0) { pRes = pOV; break; } } while (--ct > 0); } if (pRes == NULL) errno = ENOENT; return pRes;}/*=export_func optionNextValue * * what: get the next value from a hierarchical list * arg: + const tOptionValue* + pOptValue + a hierarchcal list value + * arg: + const tOptionValue* + pOldValue + a value from this list + * * ret_type: const tOptionValue* * ret_desc: a compound value structure * * doc: * This routine will return the next entry after the entry passed in. At the * end of the list, NULL will be returned. If the entry is not found on the * list, NULL will be returned and "@var{errno}" will be set to EINVAL. * The "@var{pOldValue}" must have been gotten from a prior call to this * routine or to "@code{opitonGetValue()}". * * err: * The returned result is NULL and errno is set: * @itemize @bullet * @item * @code{EINVAL} - the @code{pOptValue} does not point to a valid * hierarchical option value or @code{pOldValue} does not point to a * member of that option value. * @item * @code{ENOENT} - the supplied @code{pOldValue} pointed to the last entry. * @end itemize=*/tOptionValue const *optionNextValue(tOptionValue const * pOVList,tOptionValue const * pOldOV ){ tArgList* pAL; tOptionValue* pRes = NULL; int err = EINVAL; if ((pOVList == NULL) || (pOVList->valType != OPARG_TYPE_HIERARCHY)) { errno = EINVAL; return NULL; } pAL = pOVList->v.nestVal; { int ct = pAL->useCt; void** papNV = (void**)(pAL->apzArgs); while (ct-- > 0) { tOptionValue* pNV = *(papNV++); if (pNV == pOldOV) { if (ct == 0) { err = ENOENT; } else { err = 0; pRes = (tOptionValue*)*papNV; } break; } } } if (err != 0) errno = err;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -