📄 configfile.c
字号:
strcpy( pz, pOpts->pzRcName ); } filePreset( pOpts, zFileName, 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)) { idx -= inc; /* go back and reprocess current file */ inc = DIRECTION_PROCESS; } } } /* twice for every path in the home list, ... */}/*=export_func optionFileLoad * * what: Load the locatable config files, in order * * arg: + tOptions* + pOpts + program options descriptor + * arg: + char const* + pzProg + program name + * * ret_type: int * ret_desc: 0 -> SUCCESS, -1 -> FAILURE * * doc: * * This function looks in all the specified directories for a configuration * file ("rc" file or "ini" file) and processes any found twice. The first * time through, they are processed in reverse order (last file first). At * that time, only "immediate action" configurables are processed. For * example, if the last named file specifies not processing any more * configuration files, then no more configuration files will be processed. * Such an option in the @strong{first} named directory will have no effect. * * Once the immediate action configurables have been handled, then the * directories are handled in normal, forward order. In that way, later * config files can override the settings of earlier config files. * * See the AutoOpts documentation for a thorough discussion of the * config file format. * * Configuration files not found or not decipherable are simply ignored. * * err: Returns the value, "-1" if the program options descriptor * is out of date or indecipherable. Otherwise, the value "0" will * always be returned.=*/intoptionFileLoad( tOptions* pOpts, char const* pzProgram ){ if (! SUCCESSFUL( validateOptionsStruct( pOpts, pzProgram ))) return -1; pOpts->pzProgName = pzProgram; internalFileLoad( pOpts ); 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 + * * doc: * Processes the options found in the file named with * pOptDesc->optArg.argString.=*/voidoptionLoadOpt( tOptions* pOpts, tOptDesc* pOptDesc ){ /* * 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 )) { struct stat sb; if (stat( pOptDesc->optArg.argString, &sb ) != 0) { if ((pOpts->fOptSet & OPTPROC_ERRSTOP) == 0) return; fprintf( stderr, zFSErrOptLoad, errno, strerror( errno ), pOptDesc->optArg.argString ); exit(EX_NOINPUT); /* NOT REACHED */ } if (! S_ISREG( sb.st_mode )) { if ((pOpts->fOptSet & OPTPROC_ERRSTOP) == 0) return; fprintf( stderr, zNotFile, pOptDesc->optArg.argString ); exit(EX_NOINPUT); /* NOT REACHED */ } filePreset(pOpts, pOptDesc->optArg.argString, DIRECTION_CALLED); }}/* parseAttributes * * Parse the various attributes of an XML-styled config file entry */LOCAL char*parseAttributes( tOptions* pOpts, char* pzText, tOptionLoadMode* pMode, tOptionValue* pType ){ size_t lenLoadType = strlen( zLoadType ); size_t lenKeyWords = strlen( zKeyWords ); size_t lenSetMem = strlen( zSetMembers ); do { switch (*pzText) { case '/': pType->valType = OPARG_TYPE_NONE; case '>': return pzText; default: case NUL: return NULL; case ' ': case '\t': case '\n': case '\f': case '\r': case '\v': break; } while (isspace( (int)*++pzText )) ; if (strncmp( pzText, zLoadType, lenLoadType ) == 0) { pzText = parseValueType( pzText+lenLoadType, pType ); continue; } if (strncmp( pzText, zKeyWords, lenKeyWords ) == 0) { pzText = parseKeyWordType( pOpts, pzText+lenKeyWords, pType ); continue; } if (strncmp( pzText, zSetMembers, lenSetMem ) == 0) { pzText = parseSetMemType( pOpts, pzText+lenSetMem, pType ); continue; } pzText = parseLoadMode( pzText, pMode ); } while (pzText != NULL); return pzText;}/* parseKeyWordType * * "pzText" points to the character after "words=". * What should follow is a name of a keyword (enumeration) list. */static char*parseKeyWordType( tOptions* pOpts, char* pzText, tOptionValue* pType ){ return skipUnknown( pzText );}/* parseLoadMode * * "pzText" points to some name character. We check for "cooked" or * "uncooked" or "keep". This function should handle any attribute * that does not have an associated value. */static char*parseLoadMode( char* pzText, tOptionLoadMode* pMode ){ { size_t len = strlen(zLoadCooked); if (strncmp( pzText, zLoadCooked, len ) == 0) { if ( (pzText[len] == '>') || (pzText[len] == '/') || isspace((int)pzText[len])) { *pMode = OPTION_LOAD_COOKED; return pzText + len; } goto unknown; } } { size_t len = strlen(zLoadUncooked); if (strncmp( pzText, zLoadUncooked, len ) == 0) { if ( (pzText[len] == '>') || (pzText[len] == '/') || isspace((int)pzText[len])) { *pMode = OPTION_LOAD_UNCOOKED; return pzText + len; } goto unknown; } } { size_t len = strlen(zLoadKeep); if (strncmp( pzText, zLoadKeep, len ) == 0) { if ( (pzText[len] == '>') || (pzText[len] == '/') || isspace((int)pzText[len])) { *pMode = OPTION_LOAD_KEEP; return pzText + len; } goto unknown; } } unknown: return skipUnknown( pzText );}/* parseSetMemType * * "pzText" points to the character after "members=" * What should follow is a name of a "set membership". * A collection of bit flags. */static char*parseSetMemType( tOptions* pOpts, char* pzText, tOptionValue* pType ){ return skipUnknown( pzText );}/* parseValueType * * "pzText" points to the character after "type=" */static char*parseValueType( char* pzText, tOptionValue* pType ){ { size_t len = strlen(zLtypeString); if (strncmp( pzText, zLtypeString, len ) == 0) { if ((pzText[len] == '>') || isspace((int)pzText[len])) { pType->valType = OPARG_TYPE_STRING; return pzText + len; } goto unknown; } } { size_t len = strlen(zLtypeInteger); if (strncmp( pzText, zLtypeInteger, len ) == 0) { if ((pzText[len] == '>') || isspace((int)pzText[len])) { pType->valType = OPARG_TYPE_NUMERIC; return pzText + len; } goto unknown; } } { size_t len = strlen(zLtypeBool); if (strncmp( pzText, zLtypeBool, len ) == 0) { if ((pzText[len] == '>') || isspace(pzText[len])) { pType->valType = OPARG_TYPE_BOOLEAN; return pzText + len; } goto unknown; } } { size_t len = strlen(zLtypeKeyword); if (strncmp( pzText, zLtypeKeyword, len ) == 0) { if ((pzText[len] == '>') || isspace((int)pzText[len])) { pType->valType = OPARG_TYPE_ENUMERATION; return pzText + len; } goto unknown; } } { size_t len = strlen(zLtypeSetMembership); if (strncmp( pzText, zLtypeSetMembership, len ) == 0) { if ((pzText[len] == '>') || isspace((int)pzText[len])) { pType->valType = OPARG_TYPE_MEMBERSHIP; return pzText + len; } goto unknown; } } { size_t len = strlen(zLtypeNest); if (strncmp( pzText, zLtypeNest, len ) == 0) { if ((pzText[len] == '>') || isspace((int)pzText[len])) { pType->valType = OPARG_TYPE_HIERARCHY; return pzText + len; } goto unknown; } } unknown: pType->valType = OPARG_TYPE_NONE; return skipUnknown( pzText );}/* skipUnknown * * Skip over some unknown attribute */static char*skipUnknown( char* pzText ){ for (;; pzText++) { if (isspace( (int)*pzText )) return pzText; switch (*pzText) { case NUL: return NULL; case '/': case '>': return pzText; } }}/* validateOptionsStruct * * 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.) */LOCAL tSuccessvalidateOptionsStruct( tOptions* pOpts, char const* pzProgram ){ if (pOpts == NULL) { fputs( zAO_Bad, stderr ); exit( EX_CONFIG ); } /* * IF the client has enabled translation and the translation procedure * is available, then go do it. */ if ( ((pOpts->fOptSet & OPTPROC_TRANSLATE) != 0) && (pOpts->pTransProc != 0) ) { (*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 ) ) ) { fprintf( stderr, zAO_Err, pOpts->origArgVect[0], NUM_TO_VER( pOpts->structVersion )); if (pOpts->structVersion > OPTIONS_STRUCT_VERSION ) fputs( zAO_Big, stderr ); else fputs( zAO_Sml, 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 ); if (pz == NULL) pOpts->pzProgName = pzProgram; else pOpts->pzProgName = pz+1; pOpts->pzProgPath = pzProgram; /* * when comparing long names, these are equivalent */ strequate( zSepChars ); } return SUCCESS;}/** * Local Variables: * mode: C * c-file-style: "stroustrup" * indent-tabs-mode: nil * End: * end of autoopts/configfile.c */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -