Example #1
0
/*
 *  fixupSubblockString
 */
static char*
fixupSubblockString(char const * pzSrc)
{
    char *  pzString;
    char *  pzDest;
    char *  pzCopy;

    pzString = strdup(pzSrc);

    /*
     *  Make sure we find the '=' separator
     */
    {
        char * p = strchr(pzString, '=');
        if (p == NULL)
            die(zNoList, pzString);

        /*
         *  Trim the name
         */
        pzDest = p++;
        while ((pzDest > pzString) && IS_HORIZ_WHITE_CHAR(pzDest[-1])) pzDest--;
        *(pzDest++) = NUL;

        /*
         *  Make sure at least one attribute name is defined
         */
        while (IS_WHITESPACE_CHAR(*p)) p++;
        if (*p == NUL)
            die(zNoList, pzString);

        pzCopy = p;
    }

    for (;;) {
        /*
         *  Attribute names must start with an alpha
         */
        if (! IS_ALPHABETIC_CHAR(*pzCopy)) {
            fprintf(stderr, "ERROR:  attribute names must start "
                    "with an alphabetic character:\n\t%s\n",
                    pzString);
            USAGE(EXIT_FAILURE);
        }

        /*
         *  Copy the name.
         */
        while (IS_OPTION_NAME_CHAR(*pzCopy))
            *pzDest++ = *pzCopy++;

        /*
         *  Skip over one comma (optional) and any white space.
         *  If there is a newline, it must be after the comma.
         */
        while (IS_HORIZ_WHITE_CHAR(*pzCopy)) pzCopy++;
        if (*pzCopy == ',')
            pzCopy++;

        while (IS_WHITESPACE_CHAR(*pzCopy)) pzCopy++;
        if (*pzCopy == NUL)
            break;
        /*
         *  The final string contains only one space between attributes
         */
        *pzDest++ = ' ';
    }

    *pzDest = NUL;

    return pzString;
}
Example #2
0
/*  scanNameEntry
 *
 *  We have an entry that starts with a name.  Find the end of it, cook it
 *  (if called for) and create the name/value association.
 */
static char const*
scanNameEntry(char const* pzName, tOptionValue* pRes)
{
    tOptionValue* pNV;
    char const * pzScan = pzName+1; /* we know first char is a name char */
    char const * pzVal;
    size_t       nameLen = 1;
    size_t       dataLen = 0;

    /*
     *  Scan over characters that name a value.  These names may not end
     *  with a colon, but they may contain colons.
     */
    while (IS_VALUE_NAME_CHAR(*pzScan))   { pzScan++; nameLen++; }
    if (pzScan[-1] == ':')                { pzScan--; nameLen--; }
    while (IS_HORIZ_WHITE_CHAR(*pzScan))    pzScan++;

re_switch:
    switch (*pzScan) {
    case '=':
    case ':':
        while (IS_HORIZ_WHITE_CHAR( (int)*++pzScan ))  ;
        if ((*pzScan == '=') || (*pzScan == ':'))
            goto default_char;
        goto re_switch;

    case '\n':
    case ',':
        pzScan++;
        /* FALLTHROUGH */

    case NUL:
        addStringValue(&(pRes->v.nestVal), pzName, nameLen, NULL, (size_t)0);
        break;

    case '"':
    case '\'':
        pzVal = pzScan;
        pzScan = scanQuotedString( pzScan );
        dataLen = pzScan - pzVal;
        pNV = addStringValue( &(pRes->v.nestVal), pzName, nameLen, pzVal,
                              dataLen );
        if ((pNV != NULL) && (option_load_mode == OPTION_LOAD_COOKED))
            ao_string_cook( pNV->v.strVal, NULL );
        break;

    default:
    default_char:
        /*
         *  We have found some strange text value.  It ends with a newline
         *  or a comma.
         */
        pzVal = pzScan;
        for (;;) {
            char ch = *(pzScan++);
            switch (ch) {
            case NUL:
                pzScan--;
                dataLen = pzScan - pzVal;
                goto string_done;
                /* FALLTHROUGH */

            case '\n':
                if (   (pzScan > pzVal + 2)
                    && (pzScan[-2] == '\\')
                    && (pzScan[ 0] != NUL))
                    continue;
                /* FALLTHROUGH */

            case ',':
                dataLen = (pzScan - pzVal) - 1;
            string_done:
                pNV = addStringValue( &(pRes->v.nestVal), pzName, nameLen,
                                      pzVal, dataLen );
                if (pNV != NULL)
                    removeLineContinue( pNV->v.strVal );
                goto leave_scan_name;
            }
        }
        break;
    } leave_scan_name:;

    return pzScan;
}