-
Notifications
You must be signed in to change notification settings - Fork 123
rename updates #593
rename updates #593
Changes from 3 commits
9b9fa9d
888412a
28cf3c1
42c993e
63c7e9f
4a56424
a4a3791
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -16,6 +16,34 @@ with the required names or case. | |
|
||
If keys are renamed, their original name is stored in the `origname` MetaKey. | ||
|
||
There are 2 types of transformations: | ||
* basic | ||
* advanced | ||
|
||
|
||
## BASIC TRANSFORMATIONS ## | ||
|
||
are applied before and after the advanced transformations. | ||
|
||
### GET ### | ||
`get/case` | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. one sentence here would be good. |
||
* toupper | ||
* tolower | ||
* unchanged // this is the default value if no configuration is given | ||
converts the whole keyname below the parentKey to upper- or lowercase. if no configuration or `unchanged` is used no transformation is done here. | ||
|
||
### SET ### | ||
`set/case` | ||
* toupper | ||
* tolower | ||
* keyname | ||
* unchanged // this is the default value if no configuration is given | ||
|
||
`toupper` or `tolower` tells the rename plugin to convert the whole keyname below below the parentKey to lower or uppercase. | ||
`unchanged` returnes the key to it's original name | ||
`keyname` tells the plugin to keep the name of the advanced transformation | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. one example would be great! |
||
|
||
## ADVANCED TRANSFORMATIONS ## | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Correct level of title? ( |
||
|
||
## CUT ## | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,9 +1,9 @@ | ||
/** | ||
* @file | ||
* | ||
* @brief A plugin that converts keys to metakeys and vice versa | ||
* \brief A plugin that converts keys to metakeys and vice versa | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. please change, it should be |
||
* | ||
* @copyright BSD License (see doc/COPYING or http://www.libelektra.org) | ||
* \copyright BSD License (see doc/COPYING or http://www.libelektra.org) | ||
* | ||
*/ | ||
|
||
|
@@ -21,15 +21,15 @@ | |
#include <stdio.h> | ||
#include <stdlib.h> | ||
|
||
#include <kdbprivate.h> // for access to sync bit (keyClearSync) | ||
|
||
#define ELEKTRA_ORIGINAL_NAME_META "origname" | ||
#define TOLOWER (-1) | ||
#define TOUPPER 1 | ||
#define UNCHNGD 0 | ||
#define KEYNAME 2 | ||
// TODO defined privately in keyhelpers.c, API break possible.. | ||
char * keyNameGetOneLevel (const char * name, size_t * size); | ||
|
||
static void doConversion (char * newName, int levels, int toCase) | ||
static void doConversion (char * newName, int levels, const int toCase) | ||
{ | ||
int (*conversion) (int); | ||
|
||
|
@@ -74,7 +74,7 @@ static void doConversion (char * newName, int levels, int toCase) | |
} | ||
|
||
Key * elektraKeyCreateNewName (const Key * key, const Key * parentKey, const char * cutPath, const char * replaceWith, | ||
const char * toUpperPath, const char * toLowerPath) | ||
const char * toUpperPath, const char * toLowerPath, const int initialConversion) | ||
{ | ||
size_t addToLen = 0; | ||
if (replaceWith != NULL) addToLen = strlen (replaceWith); | ||
|
@@ -89,9 +89,15 @@ Key * elektraKeyCreateNewName (const Key * key, const Key * parentKey, const cha | |
char * curKeyName = elektraMalloc (keyGetFullNameSize (key)); | ||
keyGetFullName (key, curKeyName, keyGetFullNameSize (key)); | ||
|
||
const char * afterParentString = curKeyName + (strlen (parentKeyName)); | ||
char * afterParentString = curKeyName + (strlen (parentKeyName)); | ||
char * ptr; | ||
|
||
if (initialConversion != UNCHNGD) | ||
{ | ||
doConversion (afterParentString, 0, initialConversion); | ||
replace = 1; | ||
} | ||
|
||
if (cutPath && (cutPath[0] != '/') && ((ptr = strstr (afterParentString, cutPath)) != NULL)) | ||
{ | ||
strncpy (newName, afterParentString, (ptr - afterParentString)); | ||
|
@@ -165,7 +171,8 @@ static void keyAddUnescapedBasePath (Key * key, const char * path) | |
} | ||
} | ||
|
||
static Key * renameGet (Key * key, Key * parentKey, Key * cutConfig, Key * replaceWithConfig, Key * toUpperConfig, Key * toLowerConfig) | ||
static Key * renameGet (Key * key, Key * parentKey, Key * cutConfig, Key * replaceWithConfig, Key * toUpperConfig, Key * toLowerConfig, | ||
Key * getCase) | ||
{ | ||
char * cutPath = 0; | ||
char * replaceWith = 0; | ||
|
@@ -175,6 +182,24 @@ static Key * renameGet (Key * key, Key * parentKey, Key * cutConfig, Key * repla | |
const Key * toMeta = keyGetMeta (key, "rename/to"); | ||
const Key * toUpperMeta = keyGetMeta (key, "rename/toupper"); | ||
const Key * toLowerMeta = keyGetMeta (key, "rename/tolower"); | ||
|
||
int initialConversion = 0; | ||
if (getCase) | ||
{ | ||
const char * str = keyString (getCase); | ||
if (!strcmp (str, "toupper")) | ||
{ | ||
initialConversion = TOUPPER; | ||
} | ||
else if (!strcmp (str, "tolower")) | ||
{ | ||
initialConversion = TOLOWER; | ||
} | ||
else | ||
{ | ||
initialConversion = UNCHNGD; | ||
} | ||
} | ||
/* if the meta config exists, it takes precedence over the global config */ | ||
if (cutMeta) | ||
cutPath = (char *)keyString (cutMeta); | ||
|
@@ -193,7 +218,7 @@ static Key * renameGet (Key * key, Key * parentKey, Key * cutConfig, Key * repla | |
else if (toLowerConfig) | ||
toLowerPath = (char *)keyString (toLowerConfig); | ||
|
||
return elektraKeyCreateNewName (key, parentKey, cutPath, replaceWith, toUpperPath, toLowerPath); | ||
return elektraKeyCreateNewName (key, parentKey, cutPath, replaceWith, toUpperPath, toLowerPath, initialConversion); | ||
} | ||
|
||
static Key * restoreKeyName (Key * key, const Key * parentKey, const Key * configKey) | ||
|
@@ -203,23 +228,16 @@ static Key * restoreKeyName (Key * key, const Key * parentKey, const Key * confi | |
{ | ||
if (strcmp (keyString (origNameKey), keyName (key))) | ||
{ | ||
int hasSync = keyNeedSync (key); // test_bit(key->flags, KEY_FLAG_SYNC); | ||
Key * result = keyDup (key); | ||
keySetName (result, keyString (origNameKey)); | ||
keySetMeta (result, ELEKTRA_ORIGINAL_NAME_META, 0); | ||
|
||
if (!hasSync) | ||
{ | ||
keyClearSync (result); | ||
} | ||
return result; | ||
} | ||
} | ||
else | ||
{ | ||
if (configKey) | ||
{ | ||
int hasSync = keyNeedSync (key); // test_bit(key->flags, KEY_FLAG_SYNC); | ||
Key * result = keyDup (key); | ||
keySetName (result, keyName (parentKey)); | ||
keyAddUnescapedBasePath (result, keyString (configKey)); | ||
|
@@ -231,10 +249,6 @@ static Key * restoreKeyName (Key * key, const Key * parentKey, const Key * confi | |
keyAddUnescapedBasePath (result, relativePath); | ||
} | ||
|
||
if (!hasSync) | ||
{ | ||
keyClearSync (result); | ||
} | ||
return result; | ||
} | ||
} | ||
|
@@ -265,10 +279,14 @@ int elektraRenameGet (Plugin * handle, KeySet * returned, Key * parentKey) | |
Key * toUpper = ksLookupByName (config, "/toupper", KDB_O_NONE); | ||
Key * toLower = ksLookupByName (config, "/tolower", KDB_O_NONE); | ||
Key * replaceWith = ksLookupByName (config, "/replacewith", KDB_O_NONE); | ||
Key * getCase = ksLookupByName (config, "/get/case", KDB_O_NONE); | ||
|
||
|
||
Key * key; | ||
while ((key = ksNext (iterateKs)) != 0) | ||
{ | ||
Key * renamedKey = renameGet (key, parentKey, cutConfig, replaceWith, toUpper, toLower); | ||
|
||
Key * renamedKey = renameGet (key, parentKey, cutConfig, replaceWith, toUpper, toLower, getCase); | ||
|
||
if (renamedKey) | ||
{ | ||
|
@@ -315,29 +333,77 @@ int elektraRenameSet (Plugin * handle, KeySet * returned, Key * parentKey) | |
KeySet * config = elektraPluginGetConfig (handle); | ||
Key * cutConfig = ksLookupByName (config, "/cut", KDB_O_NONE); | ||
|
||
Key * setCase = ksLookupByName (config, "/set/case", KDB_O_NONE); | ||
|
||
int writeConversion = 0; | ||
if (setCase) | ||
{ | ||
const char * str = keyString (setCase); | ||
if (!strcmp (str, "toupper")) | ||
{ | ||
writeConversion = TOUPPER; | ||
} | ||
else if (!strcmp (str, "tolower")) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think its nicer when you leave this customized formatted, don't you agree? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. i honestly have no idea why that line always disappears... |
||
{ | ||
writeConversion = TOLOWER; | ||
} | ||
else if (!strcmp (str, "keyname")) | ||
{ | ||
writeConversion = KEYNAME; | ||
} | ||
else | ||
{ | ||
writeConversion = UNCHNGD; | ||
} | ||
} | ||
ksRewind (iterateKs); | ||
Key * key; | ||
char * parentKeyName = elektraMalloc (keyGetFullNameSize (parentKey)); | ||
keyGetFullName (parentKey, parentKeyName, keyGetFullNameSize (parentKey)); | ||
while ((key = ksNext (iterateKs)) != 0) | ||
{ | ||
Key * renamedKey = restoreKeyName (key, parentKey, cutConfig); | ||
|
||
if (renamedKey) | ||
Key * renamedKey = NULL; | ||
if (writeConversion != KEYNAME) | ||
{ | ||
renamedKey = restoreKeyName (key, parentKey, cutConfig); | ||
|
||
if (!renamedKey) renamedKey = keyDup (key); | ||
if (writeConversion == TOUPPER || writeConversion == TOLOWER) | ||
{ | ||
char * curKeyName = elektraMalloc (keyGetFullNameSize (renamedKey)); | ||
keyGetFullName (renamedKey, curKeyName, keyGetFullNameSize (renamedKey)); | ||
|
||
char * afterParentString = curKeyName + (strlen (parentKeyName)); | ||
|
||
doConversion (afterParentString, 0, writeConversion); | ||
|
||
keySetName (renamedKey, curKeyName); | ||
elektraFree (curKeyName); | ||
} | ||
/* | ||
* if something is restored from the parentKey, do | ||
* not delete the parentKey (might cause troubles) | ||
*/ | ||
if (keyCmp (key, parentKey) != 0) | ||
{ | ||
ksLookup (returned, key, KDB_O_POP); | ||
keyDel (key); | ||
keyDel (ksLookup (returned, key, KDB_O_POP)); | ||
} | ||
ksAppendKey (returned, renamedKey); | ||
keyDel (renamedKey); | ||
} | ||
else | ||
{ | ||
if (keyCmp (key, parentKey) != 0) | ||
{ | ||
keyDel (ksLookupByName (returned, keyString (keyGetMeta (key, ELEKTRA_ORIGINAL_NAME_META)), KDB_O_POP)); | ||
} | ||
ksAppendKey (returned, key); | ||
} | ||
} | ||
|
||
ksDel (iterateKs); | ||
|
||
ksRewind (returned); | ||
elektraFree (parentKeyName); | ||
return 1; /* success */ | ||
} | ||
|
||
|
@@ -349,4 +415,3 @@ Plugin * ELEKTRA_PLUGIN_EXPORT (rename) | |
ELEKTRA_PLUGIN_SET, &elektraRenameSet, | ||
ELEKTRA_PLUGIN_END); | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -225,28 +225,28 @@ static void test_metaConfigTakesPrecedence () | |
static void test_keyCutNamePart () | ||
{ | ||
Key * parentKey = keyNew ("user/tests/rename", KEY_END); | ||
Key * result = elektraKeyCreateNewName (parentKey, parentKey, "wont/cut/this", NULL, NULL, NULL); | ||
Key * result = elektraKeyCreateNewName (parentKey, parentKey, "wont/cut/this", NULL, NULL, NULL, 0); | ||
succeed_if (!result, "parentKey was modified although it should have been ignored"); | ||
|
||
/* cutting works correctly without trailing slash */ | ||
Key * testKey = keyNew ("user/tests/rename/will/cut/this/key1", KEY_END); | ||
result = elektraKeyCreateNewName (testKey, parentKey, "will/cut/this", NULL, NULL, NULL); | ||
result = elektraKeyCreateNewName (testKey, parentKey, "will/cut/this", NULL, NULL, NULL, 0); | ||
succeed_if (result, "key1 was not cut") | ||
succeed_if (!strcmp (keyName (result), "user/tests/rename/key1"), "cutting key1 did not yield the expected result"); | ||
keyDel (testKey); | ||
keyDel (result); | ||
|
||
/* cutting works correctly with trailing slash */ | ||
testKey = keyNew ("user/tests/rename/will/cut/this/key1", KEY_END); | ||
result = elektraKeyCreateNewName (testKey, parentKey, "will/cut/this/", NULL, NULL, NULL); | ||
result = elektraKeyCreateNewName (testKey, parentKey, "will/cut/this/", NULL, NULL, NULL, 0); | ||
succeed_if (result, "key1 was not cut") | ||
succeed_if (!strcmp (keyName (result), "user/tests/rename/key1"), "cutting key1 did not yield the expected result"); | ||
keyDel (testKey); | ||
keyDel (result); | ||
|
||
/* disallow leading slashes */ | ||
testKey = keyNew ("user/tests/rename/wont/cut/this/key1", KEY_END); | ||
result = elektraKeyCreateNewName (testKey, parentKey, "/wont/cut/this", NULL, NULL, NULL); | ||
result = elektraKeyCreateNewName (testKey, parentKey, "/wont/cut/this", NULL, NULL, NULL, 0); | ||
succeed_if (!result, "key was cut although it the cutpath contained a leading slash"); | ||
keyDel (testKey); | ||
keyDel (parentKey); | ||
|
@@ -395,6 +395,26 @@ static void test_mixCase () | |
PLUGIN_CLOSE (); | ||
} | ||
|
||
static void test_write () | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. can you also test the other direction (upper/lower) |
||
{ | ||
Key * parentKey = keyNew ("user/tests/rename", KEY_END); | ||
KeySet * conf = | ||
ksNew (20, keyNew ("system/tolower", KEY_VALUE, "1", KEY_END), keyNew ("system/get/case", KEY_VALUE, "toupper", KEY_END), | ||
keyNew ("system/set/case", KEY_VALUE, "keyname"), KS_END); | ||
KeySet * ks = ksNew (20, keyNew ("user/tests/rename/uppercase/uppercase/uppercase/LOWERCASE", KEY_VALUE, "test", KEY_END), KS_END); | ||
ksAppendKey (ks, parentKey); | ||
PLUGIN_OPEN ("rename"); | ||
succeed_if (plugin->kdbGet (plugin, ks, parentKey) >= 1, "call to kdbGet was not successful"); | ||
Key * key = ksLookupByName (ks, "user/tests/rename/UPPERCASE/UPPERCASE/UPPERCASE/lowercase", KDB_O_NONE); | ||
succeed_if (key, "key1 was not correctly rename"); | ||
succeed_if (plugin->kdbSet (plugin, ks, parentKey) == 1, "call to kdbSet was not successful"); | ||
key = ksLookupByName (ks, "user/tests/rename/UPPERCASE/UPPERCASE/UPPERCASE/lowercase", KDB_O_NONE); | ||
succeed_if (key, "key1s name was not correctly saved"); | ||
keyDel (parentKey); | ||
ksDel (ks); | ||
PLUGIN_CLOSE (); | ||
} | ||
|
||
int main (int argc, char ** argv) | ||
{ | ||
printf ("RENAME TESTS\n"); | ||
|
@@ -415,7 +435,7 @@ int main (int argc, char ** argv) | |
test_toLower (); | ||
test_mixCase (); | ||
test_replaceString (); | ||
|
||
test_write (); | ||
printf ("\ntest_rename RESULTS: %d test(s) done. %d error(s).\n", nbTest, nbError); | ||
|
||
return nbError; | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should not be here?