Skip to content

Commit

Permalink
modules/kvs: add kvs_util_normalize_key()
Browse files Browse the repository at this point in the history
Add a utility function kvs_util_normalize_key() which
- transforms consecutive path separators into one
- drops leading path separators
- drops trailing path separators
- preserves "." as such

Add unit tests.
  • Loading branch information
garlick committed Sep 6, 2017
1 parent 9dcd16a commit c3b2d07
Show file tree
Hide file tree
Showing 3 changed files with 103 additions and 0 deletions.
43 changes: 43 additions & 0 deletions src/modules/kvs/kvs_util.c
Original file line number Diff line number Diff line change
Expand Up @@ -90,3 +90,46 @@ int kvs_util_json_hash (const char *hash_name, json_t *o, href_t ref)
free (s);
return rc;
}

char *kvs_util_normalize_key (const char *key, bool *want_directory)
{
const char sep = '.';
char *cpy = strdup (key);
int i, len = strlen (key) + 1;
bool has_sep_suffix = false;

if (cpy) {
/* Transform duplicate path separators into a single one.
*/
for (i = 0; i < len; ) {
if (cpy[i] == sep && cpy[i + 1] == sep) {
memmove (&cpy[i], &cpy[i + 1], len - i - 1);
len--;
}
else
i++;
}
/* Eliminate leading path separator
*/
if (len > 2 && cpy[0] == sep) {
memmove (&cpy[0], &cpy[1], len - 1);
len--;
}
/* Eliminate trailing path separator
*/
if (len > 2 && cpy[len - 2] == sep) {
cpy[len - 2] = '\0';
len--;
has_sep_suffix = true;
}
if (cpy[0] == '.')
has_sep_suffix = true;
if (want_directory)
*want_directory = has_sep_suffix;
}
return cpy;
}

/*
* vi:tabstop=4 shiftwidth=4 expandtab
*/
7 changes: 7 additions & 0 deletions src/modules/kvs/kvs_util.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,13 @@ int kvs_util_json_encoded_size (json_t *o, size_t *size);
*/
int kvs_util_json_hash (const char *hash_name, json_t *o, href_t ref);

/* Normalize a KVS key
* Returns new key string (caller must free), or NULL with errno set.
* On success, 'want_directory' is set to true if key had a trailing
* path separator.
*/
char *kvs_util_normalize_key (const char *key, bool *want_directory);

#endif /* !_FLUX_KVS_JSON_UTIL_H */

/*
Expand Down
53 changes: 53 additions & 0 deletions src/modules/kvs/test/kvs_util.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,58 @@
#include "src/modules/kvs/kvs_util.h"
#include "src/modules/kvs/types.h"

void test_norm (void)
{
char *s;
bool dirflag;

s = kvs_util_normalize_key ("a.b.c.d.e", &dirflag);
ok (s != NULL && !strcmp (s, "a.b.c.d.e") && dirflag == false,
"kvs_util_normalize_key works on normal key");
free (s);

s = kvs_util_normalize_key ("a.b.c..d.e", &dirflag);
ok (s != NULL && !strcmp (s, "a.b.c.d.e") && dirflag == false,
"kvs_util_normalize_key transforms consecutive path separators to one");
free (s);

s = kvs_util_normalize_key (".a.b.c.d.e", &dirflag);
ok (s != NULL && !strcmp (s, "a.b.c.d.e") && dirflag == false,
"kvs_util_normalize_key drops one leading path separator");
free (s);

s = kvs_util_normalize_key ("....a.b.c.d.e", &dirflag);
ok (s != NULL && !strcmp (s, "a.b.c.d.e") && dirflag == false,
"kvs_util_normalize_key drops several leading path separators");
free (s);

s = kvs_util_normalize_key ("a.b.c.d.e.", &dirflag);
ok (s != NULL && !strcmp (s, "a.b.c.d.e") && dirflag == true,
"kvs_util_normalize_key drops one trailing path separator");
free (s);

s = kvs_util_normalize_key ("a.b.c.d.e.....", &dirflag);
ok (s != NULL && !strcmp (s, "a.b.c.d.e") && dirflag == true,
"kvs_util_normalize_key drops several trailing path separators");
free (s);

s = kvs_util_normalize_key (".a....b.c.....d..e.....", &dirflag);
ok (s != NULL && !strcmp (s, "a.b.c.d.e") && dirflag == true,
"kvs_util_normalize_key fixes a big mess");
free (s);

s = kvs_util_normalize_key (".", &dirflag);
ok (s != NULL && !strcmp (s, "."),
"kvs_util_normalize_key leaves one standalone separator as is");
free (s);

s = kvs_util_normalize_key ("....", &dirflag);
ok (s != NULL && !strcmp (s, "."),
"kvs_util_normalize_key transforms several standalone separators to one");
free (s);
}


int main (int argc, char *argv[])
{
json_t *obj;
Expand Down Expand Up @@ -94,6 +146,7 @@ int main (int argc, char *argv[])
free (s1);
s1 = NULL;

test_norm ();

done_testing ();
return (0);
Expand Down

0 comments on commit c3b2d07

Please sign in to comment.