Exemplo n.º 1
0
static teDirectives
findDirective(char* pzDirName)
{
    teDirectives res = (teDirectives)0;
    const tDirTable *  pTbl = dirTable;

    do  {
        if (strneqvcmp(pzDirName, pTbl->pzDirName, pTbl->nameSize) != 0)
            continue;

        /*
         *  A directive name ends with either white space or a NUL
         */
        if (IS_END_TOKEN_CHAR(pzDirName[ pTbl->nameSize ]))
            return res;

    } while (pTbl++, ++res < DIRECTIVE_CT);

    {
        char ch;
        if (strlen(pzDirName) > 32) {
            ch = pzDirName[32];
            pzDirName[32] = NUL;
        } else {
            ch = NUL;
        }

        fprintf(pfTrace, "WARNING:  in %s on line %d unknown directive:\n"
                "\t#%s\n", pCurCtx->pzCtxFname, pCurCtx->lineNo, pzDirName);

        if (ch != NUL)
            pzDirName[32] = ch;
    }
    return res;
}
Exemplo n.º 2
0
/*=gfunc string_starts_eqv_p
 *
 * what:   caseless string start
 * general_use:
 *
 * exparg: text, text to test for pattern
 * exparg: match, pattern/substring to search for
 *
 * string: "=*"
 *
 * doc:  Test to see if a string starts with an equivalent string.
=*/
static tSuccess
Select_Equivalent_Start(char const * sample, char const * pattern)
{
    size_t   vlen = strlen(pattern);

    return (strneqvcmp(sample, pattern, (int)vlen) == 0)
           ? SUCCESS
           : FAILURE;
}
Exemplo n.º 3
0
/**
 * Parse the option usage flags string.  Any parsing problems yield
 * a zero (no flags set) result.  This function is internal to
 * set_usage_flags().
 *
 * @param[in] fnt   Flag Name Table - maps a name to a mask
 * @param[in] txt   the text to process.  If NULL, then
 *                  getenv("AUTOOPTS_USAGE") is used.
 * @returns a bit mask indicating which \a fnt entries were found.
 */
static unsigned int
parse_usage_flags(ao_flag_names_t const * fnt, char const * txt)
{
    unsigned int res = 0;

    /*
     * The text may be passed in.  If not, use the environment variable.
     */
    if (txt == NULL) {
        txt = getenv("AUTOOPTS_USAGE");
        if (txt == NULL)
            return 0;
    }

    txt = SPN_WHITESPACE_CHARS(txt);
    if (*txt == NUL)
        return 0;

    /*
     * search the string for table entries.  We must understand everything
     * we see in the string, or we give up on it.
     */
    for (;;) {
        int ix = 0;

        for (;;) {
            if (strneqvcmp(txt, fnt[ix].fnm_name, (int)fnt[ix].fnm_len) == 0)
                break;
            if (++ix >= AOUF_COUNT)
                return 0;
        }

        /*
         *  Make sure we have a full match.  Look for whitespace,
         *  a comma, or a NUL byte.
         */
        if (! IS_END_LIST_ENTRY_CHAR(txt[fnt[ix].fnm_len]))
            return 0;

        res |= 1U << ix;
        txt = SPN_WHITESPACE_CHARS(txt + fnt[ix].fnm_len);

        switch (*txt) {
        case NUL:
            return res;

        case ',':
            txt = SPN_WHITESPACE_CHARS(txt + 1);
            /* Something must follow the comma */

        default:
            continue;
        }
    }
}
Exemplo n.º 4
0
/**
 *  print out the options that match the given name.
 *
 * @param pOpts      option data
 * @param opt_name   name of option to look for
 */
static void
opt_ambiguities(tOptions * opts, char const * name, int nm_len)
{
    char const * const hyph =
        NAMED_OPTS(opts) ? "" : LONG_OPT_MARKER;

    tOptDesc * pOD = opts->pOptDesc;
    int        idx = 0;

    fputs(zambig_list_msg, stderr);
    do  {
        if (pOD->pz_Name == NULL)
            continue; /* doc option */

        if (strneqvcmp(name, pOD->pz_Name, nm_len) == 0)
            fprintf(stderr, zambig_file, hyph, pOD->pz_Name);

        else if (  (pOD->pz_DisableName != NULL)
                && (strneqvcmp(name, pOD->pz_DisableName, nm_len) == 0)
                )
            fprintf(stderr, zambig_file, hyph, pOD->pz_DisableName);
    } while (pOD++, (++idx < opts->optCt));
}
Exemplo n.º 5
0
/*
 *  set_first_idx
 *
 *  Go through all our different kinds of defines.  On the first occurrence
 *  of each different name, check for an index value.  If not supplied,
 *  then insert ``[OPT_VALUE_FIRST_INDEX]'' after the object name.
 */
static void
set_first_idx(void)
{
    char    zNm[ 128 ] = { NUL };
    int     nmLn = 1;
    int     ct   = blkUseCt;
    char**  ppz  = papzBlocks;

    if (ct == 0)
        exit(EXIT_FAILURE);

    for (; --ct >= 0; ppz++) {
        char *  pzOld = *ppz;
        int     changed = (strneqvcmp(pzOld, zNm, nmLn) != 0);
        char *  pzNew;

        /*
         *  IF the name still matches, then check the following character.
         *  If it is whitespace or an open bracket, then
         *  it's the old type.  Continue to the next entry.
         */
        if (! changed) {
            if (isspace(pzOld[ nmLn ]) || (pzOld[nmLn] == '['))
                continue;
        }

        pzNew = zNm;
        nmLn  = 0;
        while (isalnum(*pzOld)
               || (*pzOld == '_') || (*pzOld == '-') || (*pzOld == '^')) {
            nmLn++;
            *(pzNew++) = *(pzOld++);
        }
        *pzNew = NUL;

        /*
         *  IF the source has specified its own index, then do not
         *  supply our own new one.
         */
        if (*pzOld != '[') {
            pzNew = (char*)malloc(strlen(pzOld) + nmLn + 10);
            sprintf(pzNew, "%s[%d]%s", zNm,
                    (int)OPT_VALUE_FIRST_INDEX, pzOld);
            free((void*)(*ppz));
            *ppz = pzNew;
        }
    }
}
Exemplo n.º 6
0
/*  handleDirective
 *
 *  "pzText" points to a "<?" sequence.
 *  For the moment, we only handle "<?program" directives.
 */
static char*
handleDirective(
    tOptions*     pOpts,
    char*         pzText )
{
    char   ztitle[32] = "<?";
    size_t title_len = strlen( zProg );
    size_t name_len;

    if (  (strncmp( pzText+2, zProg, title_len ) != 0)
       || (! isspace( (int)pzText[title_len+2] )) )  {
        pzText = strchr( pzText+2, '>' );
        if (pzText != NULL)
            pzText++;
        return pzText;
    }

    name_len = strlen( pOpts->pzProgName );
    strcpy( ztitle+2, zProg );
    title_len += 2;

    do  {
        pzText += title_len;

        if (isspace((int)*pzText)) {
            while (isspace((int)*pzText))  pzText++;
            if (  (strneqvcmp( pzText, pOpts->pzProgName, (int)name_len) == 0)
               && (pzText[name_len] == '>'))  {
                pzText += name_len + 1;
                break;
            }
        }

        pzText = strstr( pzText, ztitle );
    } while (pzText != NULL);

    return pzText;
}
Exemplo n.º 7
0
/*
 *  eval_true - should a string be interpreted as TRUE?
 *
 *  It is always true unless:
 *
 *  1.  it is the empty string
 *  2.  it starts with a digit and the number evaluates to zero
 *  3.  it starts with either "#f" or "#F"
 *  4.  For its length or its first five characters (whichever is less)
 *      it matches the string "false"
 */
static ag_bool
eval_true(void)
{
    ag_bool needFree;
    ag_bool res = AG_TRUE;
    char const * pz = evalExpression(&needFree);

    if (IS_DEC_DIGIT_CHAR(*pz))
        res = (atoi(pz) == 0) ? AG_FALSE : AG_TRUE;

    else switch (*pz) {
    case NUL:
        res = AG_FALSE;
        break;

    case '#':
        if ((pz[1] == 'f') || (pz[1] == 'F'))
            res = AG_FALSE;
        break;

    case 'f':
    case 'F':
    {
        int len = strlen(pz);
        if (len > 5)
            len = 5;
        if (strneqvcmp(EVAL_TRUE_FALSE_STR, pz, len) == 0)
            res = AG_FALSE;
        break;
    }
    }

    if (needFree)
        AGFREE(pz);

    return res;
}
Exemplo n.º 8
0
/**
 * 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 * 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(opts->pzProgName);

    memcpy(ttl, ttlfmt, sizeof(ttlfmt) - 1);
    memcpy(ttl + sizeof(ttlfmt) - 1, zCfgProg, ttl_len - (sizeof(ttlfmt) - 1));

    do  {
        txt = SPN_WHITESPACE_CHARS(txt+1);

        if (  (strneqvcmp(txt, opts->pzProgName, (int)name_len) == 0)
           && (IS_END_XML_TOKEN_CHAR(txt[name_len])) ) {
            txt += name_len;
            break;
        }

        txt = strstr(txt, ttl);
    } while (txt != NULL);

    AGFREE(ttl);
    if (txt != NULL)
        for (;;) {
            if (*txt == NUL) {
                txt = NULL;
                break;
            }
            if (*(txt++) == '>')
                break;
        }

    return txt;
}
Exemplo n.º 9
0
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 *
 *  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 tSuccess
longOptionFind(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;
    char       opt_name_buf[128];

    /*
     *  IF the value is attached to the name,
     *  copy it off so we can NUL terminate.
     */
    if (pzEq != NULL) {
        nameLen = (int)(pzEq - pzOptName);
        if (nameLen >= sizeof(opt_name_buf))
            return FAILURE;
        memcpy(opt_name_buf, pzOptName, nameLen);
        opt_name_buf[nameLen] = NUL;
        pzOptName = opt_name_buf;
        pzEq++;

    } else nameLen = strlen(pzOptName);

    do  {
        /*
         *  If option disabled or a doc option, skip to next
         */
        if (pOD->pz_Name == NULL)
            continue;

        if (  SKIP_OPT(pOD)
           && (pOD->fOptState != (OPTST_OMITTED | OPTST_NO_INIT)))
            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));

    /*
     *  Make sure we either found an exact match or found only one partial
     */
    if (matchCt == 1) {
        pOD = pOpts->pOptDesc + matchIdx;

        if (SKIP_OPT(pOD)) {
            fprintf(stderr, zDisabledErr, pOpts->pzProgName, pOD->pz_Name);
            if (pOD->pzText != NULL)
                fprintf(stderr, " -- %s", pOD->pzText);
            fputc('\n', stderr);
            (*pOpts->pUsageProc)(pOpts, EXIT_FAILURE);
            /* NOTREACHED */
        }

        /*
         *  IF we found a disablement name,
         *  THEN set the bit in the callers' flag word
         */
        if (disable)
            pOptState->flags |= OPTST_DISABLED;

        pOptState->pOD      = pOD;
        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,
     *  THEN return that option.
     */
    if (  (pzEq == NULL)
       && NAMED_OPTS(pOpts)
       && (pOpts->specOptIdx.default_opt != NO_EQUIVALENT)) {
        pOptState->pOD = pOpts->pOptDesc + pOpts->specOptIdx.default_opt;

        pOptState->pzOptArg = pzOptName;
        pOptState->optType  = TOPT_DEFAULT;
        return SUCCESS;
    }

    /*
     *  IF we are to stop on errors (the default, actually)
     *  THEN call the usage procedure.
     */
    if ((pOpts->fOptSet & OPTPROC_ERRSTOP) != 0) {
        fprintf(stderr, (matchCt == 0) ? zIllOptStr : zAmbigOptStr,
                pOpts->pzProgPath, pzOptName);
        (*pOpts->pUsageProc)(pOpts, EXIT_FAILURE);
    }

    return FAILURE;
}
Exemplo n.º 10
0
LOCAL void
set_usage_flags(tOptions * opts, char const * flg_txt)
{
    typedef struct {
        size_t          fnm_len;
        uint32_t        fnm_mask;
        char const *    fnm_name;
    } ao_flag_names_t;

#   define _aof_(_n, _f)   AOUF_ ## _n ## _ID,
    typedef enum { AOFLAG_TABLE AOUF_COUNT } ao_flag_id_t;
#   undef  _aof_

#   define _aof_(_n, _f)   AOUF_ ## _n = (1 << AOUF_ ## _n ## _ID),
    typedef enum { AOFLAG_TABLE } ao_flags_t;
#   undef  _aof_

#   define _aof_(_n, _f)   { sizeof(#_n)-1, _f, #_n },
    static ao_flag_names_t const fn_table[AOUF_COUNT] = {
        AOFLAG_TABLE
    };
#   undef  _aof_

    ao_flags_t flg = 0;

    if (flg_txt == NULL) {
        flg_txt = getenv("AUTOOPTS_USAGE");
        if (flg_txt == NULL) return;
    }

    while (IS_WHITESPACE_CHAR(*flg_txt))  flg_txt++;
    if (*flg_txt == NUL)
        return;

    for (;;) {
        int ix = 0;
        ao_flag_names_t const * fnt = fn_table;

        for (;;) {
            if (strneqvcmp(flg_txt, fnt->fnm_name, fnt->fnm_len) == 0)
                break;
            if (++ix >= AOUF_COUNT)
                return;
            fnt++;
        }

        /*
         *  Make sure we have a full match.  Look for whitespace,
         *  a comma, or a NUL byte.
         */
        if (! IS_END_LIST_ENTRY_CHAR(flg_txt[fnt->fnm_len]))
            return;

        flg |= 1 << ix;
        flg_txt  += fnt->fnm_len;
        while (IS_WHITESPACE_CHAR(*flg_txt))  flg_txt++;

        if (*flg_txt == NUL)
            break;

        if (*flg_txt == ',') {
            /*
             *  skip the comma and following white space
             */
            while (IS_WHITESPACE_CHAR(*++flg_txt))  ;
            if (*flg_txt == NUL)
                break;
        }
    }

    {
        ao_flag_names_t const * fnm = fn_table;

        while (flg != 0) {
            if ((flg & 1) != 0) {
                if ((fnm->fnm_mask & OPTPROC_LONGOPT) != 0)
                     opts->fOptSet &= fnm->fnm_mask;
                else opts->fOptSet |= fnm->fnm_mask;
            }
            flg >>= 1;
            fnm++;
        }
    }
}
Exemplo n.º 11
0
/**
 *  The template output goes to stdout.  Perhaps because output
 *  is for a CGI script.  In any case, this case must be handled
 *  specially.
 */
static void
do_stdout_tpl(tTemplate * pTF)
{
    char   const *    pzRes;
    SCM    res;

    pzLastScheme = NULL; /* We cannot be in Scheme processing */

    switch (setjmp (fileAbort)) {
    case SUCCESS:
        break;

    case PROBLEM:
        if (*pzOopsPrefix != NUL) {
            fprintf(stdout, DO_STDOUT_TPL_ABANDONED, pzOopsPrefix);
            pzOopsPrefix = zNil;
        }
        fclose(stdout);
        return;

    default:
        fprintf(stdout, DO_STDOUT_TPL_BADR, pzOopsPrefix);

    case FAILURE:
        exit(EXIT_FAILURE);
    }

    pzCurSfx      = DO_STDOUT_TPL_NOSFX;
    currDefCtx    = rootDefCtx;
    pCurFp        = &fpRoot;
    fpRoot.pFile  = stdout;
    fpRoot.pzOutName = DO_STDOUT_TPL_STDOUT;
    fpRoot.flags  = FPF_NOUNLINK | FPF_STATIC_NM;
    if (OPT_VALUE_TRACE >= TRACE_EVERYTHING)
        fputs(DO_STDOUT_TPL_START_STD, pfTrace);

    /*
     *  IF there is a CGI prefix for error messages,
     *  THEN divert all output to a temporary file so that
     *  the output will be clean for any error messages we have to emit.
     */
    if (*pzOopsPrefix == NUL)
        generateBlock(pTF, pTF->aMacros, pTF->aMacros + pTF->macroCt);

    else {
        (void)ag_scm_out_push_new(SCM_UNDEFINED);

        generateBlock(pTF, pTF->aMacros, pTF->aMacros + pTF->macroCt);

        /*
         *  Read back in the spooled output.  Make sure it starts with
         *  a content-type: prefix.  If not, we supply our own HTML prefix.
         */
        res   = ag_scm_out_pop(SCM_BOOL_T);
        pzRes = AG_SCM_CHARS(res);

        /* 13:  "content-type:" */
        if (strneqvcmp(pzRes, DO_STDOUT_TPL_CONTENT, 13) != 0)
            fputs(DO_STDOUT_TPL_CONTENT, stdout);

        fwrite(pzRes, AG_SCM_STRLEN(res), (size_t)1, stdout);
    }

    fclose(stdout);
}
Exemplo n.º 12
0
/**
 *  Determine the number of options that match the name
 *
 * @param pOpts      option data
 * @param opt_name   name of option to look for
 * @param nm_len     length of provided name
 * @param index      pointer to int for option index
 * @param disable    pointer to bool to mark disabled option
 * @return count of options that match
 */
static int
opt_match_ct(tOptions * opts, char const * name, int nm_len,
             int * ixp, bool * disable)
{
    int   matchCt  = 0;
    int   idx      = 0;
    int   idxLim   = opts->optCt;
    tOptDesc * pOD = opts->pOptDesc;

    do  {
        /*
         *  If option disabled or a doc option, skip to next
         */
        if (pOD->pz_Name == NULL)
            continue;

        if (  SKIP_OPT(pOD)
           && (pOD->fOptState != (OPTST_OMITTED | OPTST_NO_INIT)))
            continue;

        if (strneqvcmp(name, pOD->pz_Name, nm_len) == 0) {
            /*
             *  IF we have a complete match
             *  THEN it takes priority over any already located partial
             */
            if (pOD->pz_Name[ nm_len ] == NUL) {
                *ixp = idx;
                return 1;
            }
        }

        /*
         *  IF       there is a disable name
         *     *AND* the option name matches the disable name
         *  THEN ...
         */
        else if (  (pOD->pz_DisableName != NULL)
                && (strneqvcmp(name, pOD->pz_DisableName, nm_len) == 0)
                )  {
            *disable = true;

            /*
             *  IF we have a complete match
             *  THEN it takes priority over any already located partial
             */
            if (pOD->pz_DisableName[ nm_len ] == NUL) {
                *ixp = idx;
                return 1;
            }
        }

        else
            continue; /* does not match any option */

        /*
         *  We found a full or partial match, either regular or disabling.
         *  Remember the index for later.
         */
        *ixp = idx;
        ++matchCt;

    } while (pOD++, (++idx < idxLim));

    return matchCt;
}