Line data Source code
1 : /**
2 : * @file
3 : *
4 : * @brief Implementation of proposed API enhancements.
5 : *
6 : * @copyright BSD License (see LICENSE.md or https://www.libelektra.org)
7 : *
8 : */
9 :
10 : #include <string.h>
11 :
12 : #include <kdbprivate.h>
13 :
14 :
15 : /**
16 : * @copydoc ksPrev
17 : */
18 56 : Key * elektraKsPrev (KeySet * ks)
19 : {
20 56 : if (ks->size == 0) return 0;
21 56 : if (ks->current == 0)
22 : {
23 6 : ksRewind (ks);
24 6 : return 0;
25 : }
26 50 : ks->current--;
27 50 : return ks->cursor = ks->array[ks->current];
28 : }
29 :
30 : /**
31 : * @brief Takes the first key and cuts off this common part
32 : * for all other keys, instead name will be prepended
33 : *
34 : * @return a new allocated keyset with keys in user namespace.
35 : *
36 : * The first key is removed in the resulting keyset.
37 : */
38 110217 : KeySet * elektraRenameKeys (KeySet * config, const char * name)
39 : {
40 : Key * root;
41 : Key * cur;
42 110217 : ssize_t rootSize = 0;
43 :
44 110217 : ksRewind (config);
45 :
46 110217 : root = ksNext (config);
47 110217 : rootSize = keyGetNameSize (root);
48 :
49 110217 : keyDel (ksLookup (config, root, KDB_O_POP));
50 :
51 110217 : KeySet * newConfig = ksNew (ksGetSize (config), KS_END);
52 110217 : if (rootSize == -1) return newConfig;
53 :
54 152793 : while ((cur = ksPop (config)) != 0)
55 : {
56 129453 : Key * dupKey = keyDup (cur);
57 129453 : keySetName (dupKey, name);
58 129453 : keyAddName (dupKey, keyName (cur) + rootSize - 1);
59 129453 : ksAppendKey (newConfig, dupKey);
60 129453 : keyDel (cur);
61 : }
62 :
63 : return newConfig;
64 : }
65 :
66 :
67 : /**
68 : * @copydoc keyLock
69 : */
70 14062050 : int elektraKeyLock (Key * key, /*option_t*/ enum elektraLockOptions what)
71 : {
72 14062050 : int ret = 0;
73 :
74 14062050 : if (!key) return -1;
75 :
76 14062050 : if (test_bit (what, KEY_LOCK_NAME))
77 : {
78 14062038 : if (!test_bit (key->flags, KEY_FLAG_RO_NAME))
79 : {
80 1686756 : set_bit (key->flags, KEY_FLAG_RO_NAME);
81 1686756 : set_bit (ret, KEY_LOCK_NAME);
82 : }
83 : }
84 :
85 14062050 : if (test_bit (what, KEY_LOCK_VALUE))
86 : {
87 6 : if (!test_bit (key->flags, KEY_FLAG_RO_VALUE))
88 : {
89 6 : set_bit (key->flags, KEY_FLAG_RO_VALUE);
90 6 : set_bit (ret, KEY_LOCK_VALUE);
91 : }
92 : }
93 :
94 14062050 : if (test_bit (what, KEY_LOCK_META))
95 : {
96 6 : if (!test_bit (key->flags, KEY_FLAG_RO_META))
97 : {
98 6 : set_bit (key->flags, KEY_FLAG_RO_META);
99 6 : set_bit (ret, KEY_LOCK_META);
100 : }
101 : }
102 :
103 : return ret;
104 : }
105 :
106 :
107 : /**
108 : * @copydoc ksPopAtCursor
109 : */
110 359917 : Key * elektraKsPopAtCursor (KeySet * ks, cursor_t pos)
111 : {
112 359917 : if (!ks) return 0;
113 359917 : if (pos < 0) return 0;
114 : if (pos > SSIZE_MAX) return 0;
115 :
116 359917 : size_t c = pos;
117 359917 : if (c >= ks->size) return 0;
118 :
119 359917 : if (c != ks->size - 1)
120 : {
121 207340 : Key ** found = ks->array + c;
122 207340 : Key * k = *found;
123 : /* Move the array over the place where key was found
124 : *
125 : * e.g. c = 2
126 : * size = 6
127 : *
128 : * 0 1 2 3 4 5 6
129 : * |--|--|c |--|--|--|size
130 : * move to (c/pos is overwritten):
131 : * |--|--|--|--|--|
132 : *
133 : * */
134 207340 : memmove (found, found + 1, (ks->size - c - 1) * sizeof (Key *));
135 207340 : *(ks->array + ks->size - 1) = k; // prepare last element to pop
136 : }
137 : else
138 : {
139 : // if c is on last position it is just a ksPop..
140 : // so do nothing..
141 : }
142 :
143 359917 : ksRewind (ks);
144 :
145 359917 : return ksPop (ks);
146 : }
|