⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 autoopts.c

📁 基于ntp协议的网络时间服务程序
💻 C
📖 第 1 页 / 共 3 页
字号:
/* *  $Id: autoopts.c,v 4.25 2007/04/15 19:01:18 bkorb Exp $ *  Time-stamp:      "2007-04-15 11:10:40 bkorb" * *  This file contains all of the routines that must be linked into *  an executable to use the generated option processing.  The optional *  routines are in separately compiled modules so that they will not *  necessarily be linked in. *//* *  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. */static char const zNil[] = "";/* = = = START-STATIC-FORWARD = = = *//* static forward declarations maintained by :mkfwd */static tSuccessfindOptDesc( tOptions* pOpts, tOptState* pOptState );static tSuccessnextOption( tOptions* pOpts, tOptState* pOptState );static tSuccessdoPresets( tOptions* pOpts );static intcheckConsistency( tOptions* pOpts );/* = = = END-STATIC-FORWARD = = = */LOCAL void *ao_malloc( size_t sz ){    void * res = malloc(sz);    if (res == NULL) {        fprintf( stderr, "malloc of %d bytes failed\n", (int)sz );        exit( EXIT_FAILURE );    }    return res;}#undef  malloc#define malloc(_s) ao_malloc(_s)LOCAL void *ao_realloc( void *p, size_t sz ){    void * res = realloc(p, sz);    if (res == NULL) {        fprintf( stderr, "realloc of %d bytes at 0x%p failed\n", (int)sz, p );        exit( EXIT_FAILURE );    }    return res;}#undef  realloc#define realloc(_p,_s) ao_realloc(_p,_s)LOCAL voidao_free( void *p ){    if (p != NULL)        free(p);}#undef  free#define free(_p) ao_free(_p)LOCAL char *ao_strdup( char const *str ){    char * res = strdup(str);    if (res == NULL) {        fprintf( stderr, "strdup of %d byte string failed\n", (int)strlen(str) );        exit( EXIT_FAILURE );    }    return res;}#undef  strdup#define strdup(_p) ao_strdup(_p)#ifndef HAVE_PATHFIND#  include "compat/pathfind.c"#endif#ifndef HAVE_SNPRINTF#  include "compat/snprintf.c"#endif#ifndef HAVE_STRDUP#  include "compat/strdup.c"#endif#ifndef HAVE_STRCHR#  include "compat/strchr.c"#endif/* *  handleOption * *  This routine handles equivalencing, sets the option state flags and *  invokes the handler procedure, if any. */LOCAL tSuccesshandleOption( tOptions* pOpts, tOptState* pOptState ){    /*     *  Save a copy of the option procedure pointer.     *  If this is an equivalence class option, we still want this proc.     */    tOptDesc* pOD = pOptState->pOD;    tOptProc* pOP = pOD->pOptProc;    if (pOD->fOptState & OPTST_ALLOC_ARG)        AGFREE(pOD->optArg.argString);    pOD->optArg.argString = pOptState->pzOptArg;    /*     *  IF we are presetting options, then we will ignore any un-presettable     *  options.  They are the ones either marked as such.     */    if (  ((pOpts->fOptSet & OPTPROC_PRESETTING) != 0)       && ((pOD->fOptState & OPTST_NO_INIT) != 0)       )        return PROBLEM;    /*     *  IF this is an equivalence class option,     *  THEN     *      Save the option value that got us to this option     *      entry.  (It may not be pOD->optChar[0], if this is an     *      equivalence entry.)     *      set the pointer to the equivalence class base     */    if (pOD->optEquivIndex != NO_EQUIVALENT) {        tOptDesc* p = pOpts->pOptDesc + pOD->optEquivIndex;        /*         * IF the current option state has not been defined (set on the         *    command line), THEN we will allow continued resetting of         *    the value.  Once "defined", then it must not change.         */        if ((pOD->fOptState & OPTST_DEFINED) != 0) {            /*             *  The equivalenced-to option has been found on the command             *  line before.  Make sure new occurrences are the same type.             *             *  IF this option has been previously equivalenced and             *     it was not the same equivalenced-to option,             *  THEN we have a usage problem.             */            if (p->optActualIndex != pOD->optIndex) {                fprintf( stderr, (char*)zMultiEquiv, p->pz_Name, pOD->pz_Name,                         (pOpts->pOptDesc + p->optActualIndex)->pz_Name);                return FAILURE;            }        } else {            /*             *  Set the equivalenced-to actual option index to no-equivalent             *  so that we set all the entries below.  This option may either             *  never have been selected before, or else it was selected by             *  some sort of "presetting" mechanism.             */            p->optActualIndex = NO_EQUIVALENT;        }        if (p->optActualIndex != pOD->optIndex) {            /*             *  First time through, copy over the state             *  and add in the equivalence flag             */            p->optActualValue = pOD->optValue;            p->optActualIndex = pOD->optIndex;            pOptState->flags |= OPTST_EQUIVALENCE;        }        /*         *  Copy the most recent option argument.  set membership state         *  is kept in ``p->optCookie''.  Do not overwrite.         */        p->optArg.argString = pOD->optArg.argString;        pOD = p;    } else {        pOD->optActualValue = pOD->optValue;        pOD->optActualIndex = pOD->optIndex;    }    pOD->fOptState &= OPTST_PERSISTENT_MASK;    pOD->fOptState |= (pOptState->flags & ~OPTST_PERSISTENT_MASK);    /*     *  Keep track of count only for DEFINED (command line) options.     *  IF we have too many, build up an error message and bail.     */    if (  (pOD->fOptState & OPTST_DEFINED)       && (++pOD->optOccCt > pOD->optMaxCt)  )  {        if ((pOpts->fOptSet & OPTPROC_ERRSTOP) != 0) {            char const * pzEqv =                (pOD->optEquivIndex != NO_EQUIVALENT) ? zEquiv : zNil;            fputs( zErrOnly, stderr );            if (pOD->optMaxCt > 1)                fprintf(stderr, zAtMost, pOD->optMaxCt, pOD->pz_Name, pzEqv);            else                fprintf(stderr, zOnlyOne, pOD->pz_Name, pzEqv);        }        return FAILURE;    }    /*     *  If provided a procedure to call, call it     */    if (pOP != (tpOptProc)NULL)        (*pOP)( pOpts, pOD );    return SUCCESS;}/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *  HUNT FOR OPTIONS IN THE ARGUMENT LIST * *  The next four procedures are "private" to nextOption(). *  nextOption() uses findOptDesc() to find the next descriptor and it, in *  turn, uses longOptionFind() and shortOptionFind() to actually do the hunt. * *  longOptionFind * *  Find the long option descriptor for the current option */LOCAL tSuccesslongOptionFind( tOptions* pOpts, char* pzOptName, tOptState* pOptState ){    ag_bool    disable  = AG_FALSE;    char*      pzEq     = strchr( pzOptName, '=' );    tOptDesc*  pOD      = pOpts->pOptDesc;    int        idx      = 0;    int        idxLim   = pOpts->optCt;    int        matchCt  = 0;    int        matchIdx = 0;    int        nameLen;    /*     *  IF the value is attached to the name,     *  THEN clip it off.     *  Either way, figure out how long our name is     */    if (pzEq != NULL) {        nameLen = (int)(pzEq - pzOptName);        *pzEq = NUL;    } else nameLen = strlen( pzOptName );    do  {        if (SKIP_OPT(pOD))            continue;        if (strneqvcmp( pzOptName, pOD->pz_Name, nameLen ) == 0) {            /*             *  IF we have a complete match             *  THEN it takes priority over any already located partial             */            if (pOD->pz_Name[ nameLen ] == NUL) {                matchCt  = 1;                matchIdx = idx;                break;            }        }        /*         *  IF       there is a disable name         *     *AND* no argument value has been supplied         *              (disabled options may have no argument)         *     *AND* the option name matches the disable name         *  THEN ...         */        else if (  (pOD->pz_DisableName != NULL)                && (strneqvcmp(pzOptName, pOD->pz_DisableName, nameLen) == 0)                )  {            disable  = AG_TRUE;            /*             *  IF we have a complete match             *  THEN it takes priority over any already located partial             */            if (pOD->pz_DisableName[ nameLen ] == NUL) {                matchCt  = 1;                matchIdx = idx;                break;            }        }        else            continue;        /*         *  We found a partial match, either regular or disabling.         *  Remember the index for later.         */        matchIdx = idx;        if (++matchCt > 1)            break;    } while (pOD++, (++idx < idxLim));    if (pzEq != NULL)        *(pzEq++) = '=';    /*     *  Make sure we either found an exact match or found only one partial     */    if (matchCt == 1) {        /*         *  IF we found a disablement name,         *  THEN set the bit in the callers' flag word         */        if (disable)            pOptState->flags |= OPTST_DISABLED;        pOptState->pOD      = pOpts->pOptDesc + matchIdx;        pOptState->pzOptArg = pzEq;        pOptState->optType  = TOPT_LONG;        return SUCCESS;    }    /*     *  IF there is no equal sign     *     *AND* we are using named arguments     *     *AND* there is a default named option,

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -