$darkmode
Elektra 0.11.0
|
Methods to do various operations on Key names. More...
Functions | |
const char * | keyName (const Key *key) |
Returns a pointer to the abbreviated real internal key name. More... | |
ssize_t | keyGetNameSize (const Key *key) |
Bytes needed to store the Key's name (excluding owner). More... | |
const void * | keyUnescapedName (const Key *key) |
Returns a Key's name, separated by NULL bytes and without backslashes for escaping. More... | |
ssize_t | keyGetUnescapedNameSize (const Key *key) |
Returns the size of the Key's unescaped name including embedded and terminating NULL characters. More... | |
ssize_t | keyGetName (const Key *key, char *returnedName, size_t maxSize) |
Get abbreviated Key name (excluding owner). More... | |
ssize_t | keyGetUnescapedName (const Key *key, char *returnedName, size_t maxSize) |
Copies the unescaped name of a Key into returnedName . More... | |
ssize_t | keySetName (Key *key, const char *newName) |
Set a new name to a Key. More... | |
ssize_t | keyAddName (Key *key, const char *newName) |
Add an already escaped name part to the Key's name. More... | |
int | keyReplacePrefix (Key *key, const Key *oldPrefix, const Key *newPrefix) |
Replaces a prefix of the key name of key . More... | |
bool | elektraKeyNameValidate (const char *name, bool isComplete) |
Takes an escaped key name and validates it. More... | |
void | elektraKeyNameCanonicalize (const char *name, char **canonicalName, size_t *canonicalSizePtr, size_t offset, size_t *usizePtr) |
Takes a valid (non-)canonical key name and produces its canonical form. More... | |
void | elektraKeyNameUnescape (const char *canonicalName, char *unescapedName) |
Takes a canonical key name and unescapes it. More... | |
const char * | keyBaseName (const Key *key) |
Returns a pointer to the unescaped Key's name where the basename starts. More... | |
ssize_t | keyGetBaseNameSize (const Key *key) |
Calculates number of bytes needed to store basename of key (including NULL terminator). More... | |
ssize_t | keyGetBaseName (const Key *key, char *returned, size_t maxSize) |
Copy the Key's basename to returned . More... | |
size_t | elektraKeyNameEscapePart (const char *part, char **escapedPart) |
Takes a single key name part and produces its escaped form. More... | |
ssize_t | keyAddBaseName (Key *key, const char *baseName) |
Adds baseName to the name of key . More... | |
ssize_t | keySetBaseName (Key *key, const char *baseName) |
Sets baseName as the new basename for key . More... | |
elektraNamespace | keyGetNamespace (const Key *key) |
Returns the elektraNamespace for a Key. More... | |
ssize_t | keySetNamespace (Key *key, elektraNamespace ns) |
Changes the namespace of a Key. More... | |
int | elektraIsArrayPart (const char *namePart) |
Checks if the given key name part is an array part. More... | |
Methods to do various operations on Key names.
To use them:
These functions make it easier for C programmers to work with key names.
spec:/something
for specification of other keys.proc:/something
for in-memory keys, e.g. commandline.
dir:/something
for dir keys in current working directorysystem:/something
for system keys in /etc or /user:/something
for user keys in home directoryuser:username/something
for other users (deprecated: kdbGet() + kdbSet() currently unsupported)/something
for cascading keys (actually refers to one of the above, see also ksLookup())
int elektraIsArrayPart | ( | const char * | namePart | ) |
Checks if the given key name part is an array part.
The return value of this function can safely be treated as a boolean.
namePart | an arbitrary string that shall be checked |
namePart
is an array part, the index of the first digit in namePart
, or 0 otherwise void elektraKeyNameCanonicalize | ( | const char * | name, |
char ** | canonicalName, | ||
size_t * | canonicalSizePtr, | ||
size_t | offset, | ||
size_t * | usizePtr | ||
) |
Takes a valid (non-)canonical key name and produces its canonical form.
As a side-effect it can also calculate the size of the corresponding unescaped key name.
name | The key name that is processed |
canonicalName | Output buffer for the canonical name |
canonicalSizePtr | Pointer to size of canonicalName |
offset | Offset into canonicalName |
usizePtr | Output variable for the size of the unescaped name |
name
MUST be a valid (non-)canonical key name. If it is not, the result is undefined canonicalName
MUST be a valid first argument for elektraRealloc() when cast to void** canonicalSizePtr
>= offset
offset
MUST be 0 or *canonicalName + offset
MUST point to the zero-termintor of a valid canonical key name that starts at *canonicalName
offset
is 0 then *usizePtr
MUST 0, otherwise *usizePtr
MUST be the correct unescaped size of the existing canonical name in *canonicalName
size_t elektraKeyNameEscapePart | ( | const char * | part, |
char ** | escapedPart | ||
) |
Takes a single key name part and produces its escaped form.
part | A single key name part, i.e. contained '/' will be escaped, '\0' terminates part |
escapedPart | Output buffer for the escaped form |
escapedPart
MUST be a valid first argument for elektraRealloc() when cast to void**
void elektraKeyNameUnescape | ( | const char * | canonicalName, |
char * | unescapedName | ||
) |
Takes a canonical key name and unescapes it.
canonicalName | The canonical name to unescape |
unescapedName | Output buffer for the unescaped name |
canonicalName
MUST be a canonical key name. If this is not the case, the result is undefined. unescapedName
MUST be allocated to the correct size.bool elektraKeyNameValidate | ( | const char * | name, |
bool | isComplete | ||
) |
Takes an escaped key name and validates it.
Complete key names must inlcude a namespace or a leading slash.
name | The escaped key name to check |
isComplete | Whether or not name is supposed to be a complete key name |
#true | If name is a valid key name. |
#false | Otherwise |
ssize_t keyAddBaseName | ( | Key * | key, |
const char * | baseName | ||
) |
Adds baseName
to the name of key
.
baseName
will be escaped before adding it to the name of key
. No other part of the Key's name will be affected.
Assumes that key
is a directory and will append baseName
to it. The function adds the path separator for concatenating.
If key
has the name "system:/dir1/dir2"
and this method is called with baseName
"mykey"
, the resulting key will have the name "system:/dir1/dir2/mykey"
.
When baseName
is 0, nothing will happen and the size of the name is returned.
The escaping rules apply as in above .
A simple example is:
E.g. if you add . it will be escaped:
key | the Key to add the basename to |
baseName | the string to append to the Key's name |
-1 | if the Key has no name |
-1 | on NULL pointers |
-1 | if Key was inserted into KeySet before |
-1 | if the Key was read-only |
-1 | on memory allocation errors |
ssize_t keyAddName | ( | Key * | key, |
const char * | newName | ||
) |
Add an already escaped name part to the Key's name.
The same way as in keySetName() this method finds the canonical pathname:
For example:
Unlike keySetName() it adds relative to the previous name and cannot change the namespace of a Key. For example:
The passed name needs to be valid according the key name rules . It is not allowed to:
key
MUST be a valid #Keykey | the Key where a name should be added |
newName | the new name to add to the name of key |
key
-1 | if key == NULL or newName == NULL |
-1 | newName is not a valid escaped name |
-1 | key is read-only |
const char* keyBaseName | ( | const Key * | key | ) |
Returns a pointer to the unescaped Key's name where the basename starts.
This is a much more efficient version of keyGetBaseName() and you should use it if you are responsible enough to not mess up things. The name might change or even point to a wrong place after a keySetName(). So make sure to copy the memory before the name changes.
keyBaseName() returns "" when the Key has no basename. The reason is
There is also support for really empty basenames:
key | the Key to obtain the basename from |
"" | when the Key has no (base)name |
0 | on NULL pointer |
ssize_t keyGetBaseName | ( | const Key * | key, |
char * | returned, | ||
size_t | maxSize | ||
) |
Copy the Key's basename to returned
.
The copy will include a NULL terminator which will be considered for the returned size. Nothing will be copied if maxSize
is smaller than the size of the basename.
Some examples:
system:/some/keyname
is keyname
"user:/tmp/some key"
is "some key"
key | the Key to extract basename from |
returned | a pre-allocated buffer for storing the basename |
maxSize | size of the buffer returned |
returned
1 | when Key's name is empty |
-1 | on NULL pointers |
-1 | when maxSize is 0 or larger than SSIZE_MAX |
-1 | when maxSize is smaller than the size of the Key's basename |
ssize_t keyGetBaseNameSize | ( | const Key * | key | ) |
Calculates number of bytes needed to store basename of key
(including NULL terminator).
Key names consisting of only root names (e.g. "system:/"
or "user:/"
or "user:domain"
) do not have basenames. In this case the function will return 1, because only a NULL terminator is needed for storage.
Basenames are denoted as:
system:/some/thing/basename
-> basename
user:domain/some/thing/base\/name
> base\/name
key | the Key to get the size of the basename from |
-1 | if the Key or the Key's basename is NULL |
ssize_t keyGetName | ( | const Key * | key, |
char * | returnedName, | ||
size_t | maxSize | ||
) |
Get abbreviated Key name (excluding owner).
When there is not enough space to write the name, nothing will be written and -1 will be returned.
maxSize
is limited to SSIZE_MAX. When this value is exceeded, -1 will be returned. The reason for that is, that any value higher is just a negative return value passed by accident. elektraMalloc() is not as failure tolerant and would try to allocate memory accordingly.
key | the Key to get the name from |
returnedName | pre-allocated buffer to write the Key's name |
maxSize | maximum number of bytes that will fit in returnedName, including the NULL terminator |
returnedName
1 | when only NULL terminator was written |
-1 | when Key's name is longer than maxSize or maxSize is 0 or maxSize is greater than SSIZE_MAX |
-1 | key or returnedName is NULL pointer |
ssize_t keyGetNameSize | ( | const Key * | key | ) |
Bytes needed to store the Key's name (excluding owner).
For an empty Key name you need one byte to store the ending NULL. For that reason, 1 is returned when the name is empty.
key | the Key to get the name size from |
1 | if Key has no name |
-1 | on NULL pointer |
elektraNamespace keyGetNamespace | ( | const Key * | key | ) |
Returns the elektraNamespace for a Key.
To handle every namespace a Key could have, you can use the following snippet:
To loop over all valid namespaces use:
key | the Key to get the namespace from |
KEY_NS_NONE | if Key is NULL |
ssize_t keyGetUnescapedName | ( | const Key * | key, |
char * | returnedName, | ||
size_t | maxSize | ||
) |
Copies the unescaped name of a Key into returnedName
.
It will only copy the whole name. If the buffer is too small, an error code will be returned.
To ensure the buffer is big enough, you can use keyGetUnescapedNameSize() to get the correct size.
key | the Key to extract the unescaped name from |
returnedName | the buffer to write the unescaped name into |
maxSize | maximum number of bytes that can be copied into returnedName |
key
MUST be a valid #Key and key != NULL
returnedName
MUST be allocated to be at least maxSize
bytes big returnedName
must not be NULLreturnedName
-1 | Precondition error |
-2 | the size of the unescaped name is greater than maxSize |
ssize_t keyGetUnescapedNameSize | ( | const Key * | key | ) |
Returns the size of the Key's unescaped name including embedded and terminating NULL characters.
key | the Key where to get the size of the unescaped name from |
-1 | on NULL pointer |
0 | if Key has no name |
const char* keyName | ( | const Key * | key | ) |
Returns a pointer to the abbreviated real internal key
name.
This is a much more efficient version of keyGetName() and can use it if you are responsible enough to not mess up things. You are not allowed to change anything in the returned array. The content of that string may change after keySetName() and similar functions. If you need a copy of the name, consider using keyGetName().
"" | when there is no keyName. The reason is |
Valid key names are:
spec:/something
for specification of other keys.proc:/something
for in-memory keys, e.g. commandline.dir:/something
for dir keys in current working directorysystem:/something
for system keys in /etc or /user:/something
for user keys in home directoryuser:username/something
for other users (deprecated: kdbGet() + kdbSet() currently unsupported)/something
for cascading keys (actually refers to one of the above, see also ksLookup())key | the Key you want to get the name from |
"" | when Key's name is empty |
0 | on NULL pointer |
int keyReplacePrefix | ( | Key * | key, |
const Key * | oldPrefix, | ||
const Key * | newPrefix | ||
) |
Replaces a prefix of the key name of key
.
The function only modifies key
, if is is below (or same as) oldPrefix
(see keyIsBelowOrSame()) and they both have the same namespace (this is not always the case with keyIsBelowOrSame()).
In simple terms this function operates as follows:
key
and oldPrefix
had the same name, then afterwards key
will have the same name as newPrefix
.key
was in the same namespace as and below oldPrefix
, then after calling this function key
will be in the same namespace as and below newPrefix
.key
will not be modified.Note: We use const Key *
arguments for the prefixes instead of const char *
to ensure only valid key names can be passed as arguments.
key | The key that will be manipulated. |
oldPrefix | The name of this key will be removed from the front of the name of key . |
newPrefix | The name of this key will be added to the front of key , after the name of oldPrefix is removed. |
-1 | if key , oldPrefix or newPrefix are NULL or the name of key is marked as read-only |
0 | if key is not below (or same as) oldPrefix , i.e. there is no prefix to replace |
1 | if the prefix was sucessfully replaced |
ssize_t keySetBaseName | ( | Key * | key, |
const char * | baseName | ||
) |
Sets baseName
as the new basename for key
.
Only the basename of the Key will be affected.
A simple example is:
All text after the last '/'
in the Key's name is erased and baseName
is appended. If baseName
is 0 (NULL), then the last part of the Key's name is removed without replacement. The root name of the Key will not be removed though.
Let us suppose key
has name "system:/dir1/dir2/key1"
. If baseName
is "key2"
, the resulting key name will be "system:/dir1/dir2/key2"
. If baseName
is 0 (NULL), the resulting key name will be "system:/dir1/dir2"
. If baseName
is empty, the resulting key name will be "system:/dir1/dir2/%"
, where "%"
denotes an empty base name, as also shown in the following code:
keySetBaseName() does proper escaping on the supplied name argument.
You can use character sequences as baseName
(e.g. "."
(dot), ".."
(dot-dot), "%"
(empty basename)). They will be properly escaped and will not have their usual meaning.
If you want to add to the basename instead of changing it, use keyAddBaseName(). If you do not want any escaping, use keyAddName().
key | the Key whose basename to set |
baseName | the new basename for the Key |
-1 | if Key is NULL |
-1 | if Key was inserted into KeySet before |
-1 | if Key is read-only |
-1 | on allocation errors |
ssize_t keySetName | ( | Key * | key, |
const char * | newName | ||
) |
Set a new name to a Key.
A valid name is one of the forms:
spec:/something
for specification of other keys.proc:/something
for in-memory keys, e.g. commandline.dir:/something
for dir keys in current working directorysystem:/something
for system keys in /etc or /user:/something
for user keys in home directoryuser:username/something
for other users (deprecated: kdbGet() + kdbSet() currently unsupported)/something
for cascading keys (actually refers to one of the above, see also ksLookup())An invalid name either has an invalid namespace or a wrongly escaped \ at the end of the name.
See key names for the exact rules.
The last form has explicitly set the owner, to let the library know in which user folder to save the Key. A owner is a user name. If it is not defined (the second form), current user is used.
You should always follow the guidelines for Key tree structure creation.
A private copy of the Key name will be stored, and the newName
parameter can be freed after this call.
.., . and / will be handled as in filesystem paths. A valid name will be build out of the (valid) name what you pass, e.g. user:///sw/../sw//././MyApp -> user:/sw/MyApp
Trailing slashes will be stripped.
On invalid names, the name stays unchanged.
-1 | if key or keyName is NULL or keyName is empty or invalid |
-1 | if Key was inserted to a KeySet before |
-1 | if Key name is read-only |
key | the Key whose name to set |
newName | the new name for the Key |
ssize_t keySetNamespace | ( | Key * | key, |
elektraNamespace | ns | ||
) |
Changes the namespace of a Key.
The rest of the Key's name remains unchanged.
ns
MUST be a valid namespace and not KEY_NS_NONE key
MUST be a valid #Key, especially key != NULL
key | The #Key whose namespace will be changed |
ns | The new namespace of for key |
-1 | precondition error |
const void* keyUnescapedName | ( | const Key * | key | ) |
Returns a Key's name, separated by NULL bytes and without backslashes for escaping.
Slashes are replaced with NULL bytes. Therefore unescaped names of cascading Keys start with a NULL byte. Otherwise escaped characters, e.g. non-hierarchy slashes, will be unescaped.
This name is essential if you want to iterate over parts of the Key's name, compare Key names or check relations of Keys in the hierarchy.
key | the Key whose unescaped name to get |
0 | on NULL pointers |
"" | if Key's name is empty |