/* * 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; }
/* 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; }