static int isValidArrayKey (Key * key) { Key * copy = keyDup (key); do { if (keyBaseName (copy)[0] == '#') { if (elektraArrayValidateName (copy) == -1) { keyDel (copy); return 0; } } } while (keySetBaseName (copy, 0) != -1); keyDel (copy); return 1; }
/** * @brief Increment the name of the key by one * * Alphabetical order will remain * * e.g. user/abc/\#9 will be changed to * user/abc/\#_10 * * For the start: * user/abc/\# * will be changed to * user/abc/\#0 * * @param key which base name will be incremented * * @retval -1 on error (e.g. too large array, not validated array) * @retval 0 on success */ int elektraArrayIncName(Key *key) { const char * baseName = keyBaseName(key); int arrayElement = elektraArrayValidateName(key); if (arrayElement == -1) { return -1; } ++baseName; // jump over # while(*baseName == '_') // jump over all _ { ++baseName; } kdb_long_long_t oldIndex = 0; if (!arrayElement) { // we have a start element oldIndex = -1; } else { if (elektraReadArrayNumber(baseName, &oldIndex) == -1) { return -1; } } kdb_long_long_t newIndex = oldIndex+1; // we increment by one char newName[ELEKTRA_MAX_ARRAY_SIZE]; elektraWriteArrayNumber(newName, newIndex); keySetBaseName(key, newName); return 0; }
static void validateArray (KeySet * ks, Key * arrayKey, Key * specKey) { Key * tmpArrayParent = keyDup (arrayKey); keySetBaseName (tmpArrayParent, 0); Key * arrayParent = ksLookup (ks, tmpArrayParent, KDB_O_NONE); keyDel (tmpArrayParent); if (arrayParent == NULL) return; KeySet * ksCopy = ksDup (ks); KeySet * subKeys = ksCut (ksCopy, arrayParent); Key * cur; long validCount = 0; while ((cur = ksNext (subKeys)) != NULL) { if (!keyIsDirectBelow (arrayParent, cur)) continue; if (keyBaseName (cur)[0] == '#') { if (elektraArrayValidateName (cur) == 1) { ++validCount; keySetMeta (cur, "spec/internal/valid", ""); } else { KeySet * invalidCutKS = ksCut (subKeys, cur); Key * toMark; while ((toMark = ksNext (invalidCutKS)) != NULL) { if (strcmp (keyName (cur), keyName (toMark))) keySetMeta (toMark, "conflict/invalid", ""); elektraMetaArrayAdd (arrayParent, "conflict/invalid/hasmember", keyName (toMark)); } ksDel (invalidCutKS); } } } ksDel (subKeys); ksDel (ksCopy); validateArrayRange (arrayParent, validCount, specKey); }
/** * @internal * * Returns true (1) for all keys that are part of the array * identified by the supplied array parent. Only the array * eleements themself, but no subkeys of them will be filtered * * @pre The supplied argument has to be of type (const Key *) * and is the parent of the array to be extracted. For example * if the keys of the array comment/# are to be extracted, a key * with the name "comment" has to be supplied * * @param key the key to be checked against the array * @param argument the array parent * @return 1 if the key is part of the array identified by the * array parent, 0 otherwise * */ static int arrayFilter(const Key *key, void *argument) { const Key *arrayParent = (const Key *) argument; return keyIsDirectBelow(arrayParent, key) && elektraArrayValidateName(key); }