Line data Source code
1 : /**
2 : * @file
3 : *
4 : * @brief Elektra High Level API.
5 : *
6 : * @copyright BSD License (see doc/LICENSE.md or http://www.libelektra.org)
7 : */
8 :
9 : #include "elektra.h"
10 : #include "elektra/conversion.h"
11 : #include "elektra/errors.h"
12 : #include "kdbease.h"
13 : #include "kdbhelper.h"
14 : #include "kdbprivate.h"
15 : #include <string.h>
16 :
17 : #ifdef __cplusplus
18 : extern "C" {
19 : #endif
20 :
21 : #define CHECK_ERROR(elektra, error) \
22 : if (error == NULL) \
23 : { \
24 : elektraFatalError (elektra, elektraErrorNullError (__func__)); \
25 : return; \
26 : }
27 :
28 : /**
29 : * \addtogroup highlevel High-level API
30 : * @{
31 : */
32 :
33 : /**
34 : * Helper function for code generation.
35 : *
36 : * Finds a Key from its relative name. Also checks type metadata,
37 : * if @p type is not NULL.
38 : *
39 : * @param elektra The Elektra instance to use.
40 : * @param name The relative name of the key.
41 : * @param type The expected type metadata value.
42 : * @return the Key referenced by @p name or NULL, if a fatal error occurs and the fatal error handler returns to this function
43 : * The returned pointer remains valid until the KeySet inside @p elektra is modified. Calls to elektraSet*() functions may
44 : * cause such modifications. In any case, it becomes invalid when elektraClose() is called on @p elektra.
45 : */
46 664 : Key * elektraFindKey (Elektra * elektra, const char * name, KDBType type)
47 : {
48 664 : elektraSetLookupKey (elektra, name);
49 664 : Key * const resultKey = ksLookup (elektra->config, elektra->lookupKey, 0);
50 664 : if (resultKey == NULL)
51 : {
52 0 : elektraFatalError (elektra, elektraErrorKeyNotFound (keyName (elektra->lookupKey)));
53 0 : return NULL;
54 : }
55 :
56 664 : if (type != NULL)
57 : {
58 660 : const char * actualType = keyString (keyGetMeta (resultKey, "type"));
59 660 : if (strcmp (actualType, type) != 0)
60 : {
61 2 : elektraFatalError (elektra, elektraErrorWrongType (keyName (elektra->lookupKey), type, actualType));
62 0 : return NULL;
63 : }
64 : }
65 :
66 : return resultKey;
67 : }
68 :
69 : /**
70 : * Resolves the reference stored in a key.
71 : * 1. Get the raw string value.
72 : * 2. Resolve that reference.
73 : * 3. Return resulting keyname relative to the parent key of the given Elektra instance.
74 : *
75 : * IMPORTANT: this method DOES NOT check the type metadata of the key, it is only intended
76 : * to be used by the code-generation API.
77 : *
78 : * @param elektra The Elektra instance to use.
79 : * @param name The (relative) name of the key.
80 : * @return the resolved version of the reference stored in the specified key (relative to the parent key of @p elektra)
81 : * or NULL, if the key was not found, or the reference resolves two a key not below the parent key. The empty string is
82 : * returned, if the value was the empty string (no resolution is attempted).
83 : * The returned pointer becomes invalid when this function is called again (even with the same arguments). It is also
84 : * invalidated when elektraFindReferenceArrayElement() or elektraClose() are called on @p elektra.
85 : */
86 2 : const char * elektraFindReference (Elektra * elektra, const char * name)
87 : {
88 2 : elektraSetLookupKey (elektra, name);
89 2 : Key * const resultKey = ksLookup (elektra->config, elektra->lookupKey, 0);
90 2 : if (resultKey == NULL)
91 : {
92 : return NULL;
93 : }
94 :
95 0 : const char * reference = keyString (resultKey);
96 :
97 0 : if (strlen (reference) == 0)
98 : {
99 : return "";
100 : }
101 :
102 0 : if (elektra->resolvedReference != NULL)
103 : {
104 0 : elektraFree (elektra->resolvedReference);
105 0 : elektra->resolvedReference = NULL;
106 : }
107 :
108 0 : elektra->resolvedReference = elektraResolveReference (reference, elektra->lookupKey, elektra->parentKey);
109 :
110 0 : size_t len = strlen (elektra->resolvedReference);
111 0 : if (len < elektra->parentKeyLength ||
112 0 : strncmp (keyName (elektra->parentKey), elektra->resolvedReference, elektra->parentKeyLength) != 0)
113 : {
114 : return NULL;
115 : }
116 :
117 0 : return &elektra->resolvedReference[elektra->parentKeyLength];
118 : }
119 :
120 : /**
121 : * Reads the type metadata of a given key.
122 : *
123 : * @param elektra An Elektra instance.
124 : * @param keyname The name of the key whose type information shall be read.
125 : * @return the KDBType of the key
126 : */
127 2 : KDBType elektraGetType (Elektra * elektra, const char * keyname)
128 : {
129 2 : elektraSetLookupKey (elektra, keyname);
130 2 : const Key * key = elektraFindKey (elektra, keyname, NULL);
131 2 : const Key * metaKey = keyGetMeta (key, "type");
132 2 : return metaKey == NULL ? NULL : keyString (metaKey);
133 : }
134 :
135 : /**
136 : * Get the raw string value of a key.
137 : *
138 : * @param elektra The Elektra instance to use.
139 : * @param name The (relative) name of the key.
140 : * @return the raw value of the specified key or NULL, if the key was not found
141 : * The returned pointer remains valid until the internal state of @p elektra is modified.
142 : * Calls to elektraSet*() functions may cause such modifications. In any case, it becomes
143 : * invalid when elektraClose() is called on @p elektra.
144 : */
145 8 : const char * elektraGetRawString (Elektra * elektra, const char * name)
146 : {
147 8 : elektraSetLookupKey (elektra, name);
148 8 : Key * const resultKey = ksLookup (elektra->config, elektra->lookupKey, 0);
149 8 : return resultKey == NULL ? NULL : keyString (resultKey);
150 : }
151 :
152 : /**
153 : * Set the raw string value of a key.
154 : *
155 : * @param elektra The Elektra instance to use.
156 : * @param name The (relative) name of the key.
157 : * @param value The raw value to set.
158 : * @param type The type to set in the metadata of the key.
159 : * @param error Pointer to an ElektraError. Will be set in case saving fails.
160 : */
161 624 : void elektraSetRawString (Elektra * elektra, const char * name, const char * value, KDBType type, ElektraError ** error)
162 : {
163 624 : CHECK_ERROR (elektra, error);
164 624 : elektraSetLookupKey (elektra, name);
165 624 : Key * const key = keyDup (elektra->lookupKey);
166 624 : keySetMeta (key, "type", type);
167 624 : keySetString (key, value);
168 624 : elektraSaveKey (elektra, key, error);
169 : }
170 :
171 : #define ELEKTRA_GET_VALUE(KEY_TO_VALUE, KDB_TYPE, elektra, keyname, result) \
172 : const Key * key = elektraFindKey (elektra, keyname, KDB_TYPE); \
173 : if (key == NULL || !KEY_TO_VALUE (key, &result)) \
174 : { \
175 : elektraFatalError (elektra, elektraErrorConversionFromString (KDB_TYPE, keyname, keyString (key))); \
176 : result = 0; \
177 : }
178 :
179 : /**
180 : * Gets a string value.
181 : *
182 : * @param elektra The elektra instance to use.
183 : * @param keyname The (relative) name of the key to look up.
184 : * @return the string stored at the given key
185 : * The returned pointer remains valid until the internal state of @p elektra is modified.
186 : * Calls to elektraSet*() functions may cause such modifications. In any case, it becomes
187 : * invalid when elektraClose() is called on @p elektra.
188 : */
189 18 : const char * elektraGetString (Elektra * elektra, const char * keyname)
190 : {
191 : const char * result;
192 18 : ELEKTRA_GET_VALUE (elektraKeyToString, KDB_TYPE_STRING, elektra, keyname, result);
193 18 : return result;
194 : }
195 :
196 : /**
197 : * Gets a boolean value.
198 : *
199 : * @param elektra The elektra instance to use.
200 : * @param keyname The (relative) name of the key to look up.
201 : * @return the boolean stored at the given key
202 : */
203 10 : kdb_boolean_t elektraGetBoolean (Elektra * elektra, const char * keyname)
204 : {
205 : kdb_boolean_t result;
206 10 : ELEKTRA_GET_VALUE (elektraKeyToBoolean, KDB_TYPE_BOOLEAN, elektra, keyname, result);
207 10 : return result;
208 : }
209 :
210 : /**
211 : * Gets a char value.
212 : *
213 : * @param elektra The elektra instance to use.
214 : * @param keyname The (relative) name of the key to look up.
215 : * @return the char stored at the given key
216 : */
217 512 : kdb_char_t elektraGetChar (Elektra * elektra, const char * keyname)
218 : {
219 : kdb_char_t result;
220 512 : ELEKTRA_GET_VALUE (elektraKeyToChar, KDB_TYPE_CHAR, elektra, keyname, result);
221 512 : return result;
222 : }
223 :
224 : /**
225 : * Gets an octet value.
226 : *
227 : * @param elektra The elektra instance to use.
228 : * @param keyname The (relative) name of the key to look up.
229 : * @return the octet stored at the given key
230 : */
231 10 : kdb_octet_t elektraGetOctet (Elektra * elektra, const char * keyname)
232 : {
233 : kdb_octet_t result;
234 10 : ELEKTRA_GET_VALUE (elektraKeyToOctet, KDB_TYPE_OCTET, elektra, keyname, result);
235 6 : return result;
236 : }
237 :
238 : /**
239 : * Gets a short value.
240 : *
241 : * @param elektra The elektra instance to use.
242 : * @param keyname The (relative) name of the key to look up.
243 : * @return the short stored at the given key
244 : */
245 12 : kdb_short_t elektraGetShort (Elektra * elektra, const char * keyname)
246 : {
247 : kdb_short_t result;
248 12 : ELEKTRA_GET_VALUE (elektraKeyToShort, KDB_TYPE_SHORT, elektra, keyname, result);
249 8 : return result;
250 : }
251 :
252 : /**
253 : * Gets a unsigned short value.
254 : *
255 : * @param elektra The elektra instance to use.
256 : * @param keyname The (relative) name of the key to look up.
257 : * @return the unsigned short stored at the given key
258 : */
259 10 : kdb_unsigned_short_t elektraGetUnsignedShort (Elektra * elektra, const char * keyname)
260 : {
261 : kdb_unsigned_short_t result;
262 10 : ELEKTRA_GET_VALUE (elektraKeyToUnsignedShort, KDB_TYPE_UNSIGNED_SHORT, elektra, keyname, result);
263 6 : return result;
264 : }
265 :
266 : /**
267 : * Gets a long value.
268 : *
269 : * @param elektra The elektra instance to use.
270 : * @param keyname The (relative) name of the key to look up.
271 : * @return the long stored at the given key
272 : */
273 20 : kdb_long_t elektraGetLong (Elektra * elektra, const char * keyname)
274 : {
275 : kdb_long_t result;
276 20 : ELEKTRA_GET_VALUE (elektraKeyToLong, KDB_TYPE_LONG, elektra, keyname, result);
277 16 : return result;
278 : }
279 :
280 : /**
281 : * Gets a unsigned long value.
282 : *
283 : * @param elektra The elektra instance to use.
284 : * @param keyname The (relative) name of the key to look up.
285 : * @return the unsigned long stored at the given key
286 : */
287 10 : kdb_unsigned_long_t elektraGetUnsignedLong (Elektra * elektra, const char * keyname)
288 : {
289 : kdb_unsigned_long_t result;
290 10 : ELEKTRA_GET_VALUE (elektraKeyToUnsignedLong, KDB_TYPE_UNSIGNED_LONG, elektra, keyname, result);
291 6 : return result;
292 : }
293 :
294 : /**
295 : * Gets a long long value.
296 : *
297 : * @param elektra The elektra instance to use.
298 : * @param keyname The (relative) name of the key to look up.
299 : * @return the long long stored at the given key
300 : */
301 10 : kdb_long_long_t elektraGetLongLong (Elektra * elektra, const char * keyname)
302 : {
303 : kdb_long_long_t result;
304 10 : ELEKTRA_GET_VALUE (elektraKeyToLongLong, KDB_TYPE_LONG_LONG, elektra, keyname, result);
305 6 : return result;
306 : }
307 :
308 : /**
309 : * Gets a long long value.
310 : *
311 : * @param elektra The elektra instance to use.
312 : * @param keyname The (relative) name of the key to look up.
313 : * @return the unsigned long long stored at the given key
314 : */
315 10 : kdb_unsigned_long_long_t elektraGetUnsignedLongLong (Elektra * elektra, const char * keyname)
316 : {
317 : kdb_unsigned_long_long_t result;
318 10 : ELEKTRA_GET_VALUE (elektraKeyToUnsignedLongLong, KDB_TYPE_UNSIGNED_LONG_LONG, elektra, keyname, result);
319 6 : return result;
320 : }
321 :
322 : /**
323 : * Gets a float value.
324 : *
325 : * @param elektra The elektra instance to use.
326 : * @param keyname The (relative) name of the key to look up.
327 : * @return the float stored at the given key
328 : */
329 10 : kdb_float_t elektraGetFloat (Elektra * elektra, const char * keyname)
330 : {
331 : kdb_float_t result;
332 10 : ELEKTRA_GET_VALUE (elektraKeyToFloat, KDB_TYPE_FLOAT, elektra, keyname, result);
333 10 : return result;
334 : }
335 :
336 : /**
337 : * Gets a double value.
338 : *
339 : * @param elektra The elektra instance to use.
340 : * @param keyname The (relative) name of the key to look up.
341 : * @return the double stored at the given key
342 : */
343 12 : kdb_double_t elektraGetDouble (Elektra * elektra, const char * keyname)
344 : {
345 : kdb_double_t result;
346 12 : ELEKTRA_GET_VALUE (elektraKeyToDouble, KDB_TYPE_DOUBLE, elektra, keyname, result);
347 12 : return result;
348 : }
349 :
350 : #ifdef ELEKTRA_HAVE_KDB_LONG_DOUBLE
351 :
352 : /**
353 : * Gets a long double value.
354 : *
355 : * @param elektra The elektra instance to use.
356 : * @param keyname The (relative) name of the key to look up.
357 : * @return the long double stored at the given key
358 : */
359 2 : kdb_long_double_t elektraGetLongDouble (Elektra * elektra, const char * keyname)
360 : {
361 : kdb_long_double_t result;
362 2 : ELEKTRA_GET_VALUE (elektraKeyToLongDouble, KDB_TYPE_LONG_DOUBLE, elektra, keyname, result);
363 2 : return result;
364 : }
365 :
366 : #endif // ELEKTRA_HAVE_KDB_LONG_DOUBLE
367 :
368 : #define ELEKTRA_SET_VALUE(VALUE_TO_STRING, KDB_TYPE, elektra, keyname, value, error) \
369 : CHECK_ERROR (elektra, error); \
370 : char * string = VALUE_TO_STRING (value); \
371 : if (string == 0) \
372 : { \
373 : *error = elektraErrorConversionToString (KDB_TYPE, keyname); \
374 : return; \
375 : } \
376 : elektraSetRawString (elektra, keyname, string, KDB_TYPE, error); \
377 : elektraFree (string);
378 :
379 : /**
380 : * Sets a string value.
381 : *
382 : * @param elektra The elektra instance to use.
383 : * @param keyname The (relative) name to write to.
384 : * @param value The new string value.
385 : * @param error Pass a reference to an ElektraError pointer.
386 : * Will only be set in case of an error.
387 : */
388 14 : void elektraSetString (Elektra * elektra, const char * keyname, const char * value, ElektraError ** error)
389 : {
390 14 : CHECK_ERROR (elektra, error);
391 14 : elektraSetRawString (elektra, keyname, value, KDB_TYPE_STRING, error);
392 : }
393 :
394 : /**
395 : * Sets a boolean value.
396 : *
397 : * @param elektra The elektra instance to use.
398 : * @param keyname The (relative) name to write to.
399 : * @param value The new boolean value.
400 : * @param error Pass a reference to an ElektraError pointer.
401 : * Will only be set in case of an error.
402 : */
403 10 : void elektraSetBoolean (Elektra * elektra, const char * keyname, kdb_boolean_t value, ElektraError ** error)
404 : {
405 10 : ELEKTRA_SET_VALUE (elektraBooleanToString, KDB_TYPE_BOOLEAN, elektra, keyname, value, error);
406 : }
407 :
408 : /**
409 : * Sets a char value.
410 : *
411 : * @param elektra The elektra instance to use.
412 : * @param keyname The (relative) name to write to.
413 : * @param value The new char value.
414 : * @param error Pass a reference to an ElektraError pointer.
415 : * Will only be set in case of an error.
416 : */
417 514 : void elektraSetChar (Elektra * elektra, const char * keyname, kdb_char_t value, ElektraError ** error)
418 : {
419 514 : ELEKTRA_SET_VALUE (elektraCharToString, KDB_TYPE_CHAR, elektra, keyname, value, error);
420 : }
421 :
422 : /**
423 : * Sets an octet value.
424 : *
425 : * @param elektra The elektra instance to use.
426 : * @param keyname The (relative) name to write to.
427 : * @param value The new octet value.
428 : * @param error Pass a reference to an ElektraError pointer.
429 : * Will only be set in case of an error.
430 : */
431 4 : void elektraSetOctet (Elektra * elektra, const char * keyname, kdb_octet_t value, ElektraError ** error)
432 : {
433 4 : ELEKTRA_SET_VALUE (elektraOctetToString, KDB_TYPE_OCTET, elektra, keyname, value, error);
434 : }
435 :
436 : /**
437 : * Sets a short value.
438 : *
439 : * @param elektra The elektra instance to use.
440 : * @param keyname The (relative) name to write to.
441 : * @param value The new short value.
442 : * @param error Pass a reference to an ElektraError pointer.
443 : * Will only be set in case of an error.
444 : */
445 4 : void elektraSetShort (Elektra * elektra, const char * keyname, kdb_short_t value, ElektraError ** error)
446 : {
447 4 : ELEKTRA_SET_VALUE (elektraShortToString, KDB_TYPE_SHORT, elektra, keyname, value, error);
448 : }
449 :
450 : /**
451 : * Sets a unsigned short value.
452 : *
453 : * @param elektra The elektra instance to use.
454 : * @param keyname The (relative) name to write to.
455 : * @param value The new unsigned short value.
456 : * @param error Pass a reference to an ElektraError pointer.
457 : * Will only be set in case of an error.
458 : */
459 4 : void elektraSetUnsignedShort (Elektra * elektra, const char * keyname, kdb_unsigned_short_t value, ElektraError ** error)
460 : {
461 4 : ELEKTRA_SET_VALUE (elektraUnsignedShortToString, KDB_TYPE_UNSIGNED_SHORT, elektra, keyname, value, error);
462 : }
463 :
464 : /**
465 : * Sets a long value.
466 : *
467 : * @param elektra The elektra instance to use.
468 : * @param keyname The (relative) name to write to.
469 : * @param value The new long value.
470 : * @param error Pass a reference to an ElektraError pointer.
471 : * Will only be set in case of an error.
472 : */
473 14 : void elektraSetLong (Elektra * elektra, const char * keyname, kdb_long_t value, ElektraError ** error)
474 : {
475 14 : ELEKTRA_SET_VALUE (elektraLongToString, KDB_TYPE_LONG, elektra, keyname, value, error);
476 : }
477 :
478 : /**
479 : * Sets a unsigned long value.
480 : *
481 : * @param elektra The elektra instance to use.
482 : * @param keyname The (relative) name to write to.
483 : * @param value The new unsigned long value.
484 : * @param error Pass a reference to an ElektraError pointer.
485 : * Will only be set in case of an error.
486 : */
487 4 : void elektraSetUnsignedLong (Elektra * elektra, const char * keyname, kdb_unsigned_long_t value, ElektraError ** error)
488 : {
489 4 : ELEKTRA_SET_VALUE (elektraUnsignedLongToString, KDB_TYPE_UNSIGNED_LONG, elektra, keyname, value, error);
490 : }
491 :
492 : /**
493 : * Sets a long long value.
494 : *
495 : * @param elektra The elektra instance to use.
496 : * @param keyname The (relative) name to write to.
497 : * @param value The new long long value.
498 : * @param error Pass a reference to an ElektraError pointer.
499 : * Will only be set in case of an error.
500 : */
501 4 : void elektraSetLongLong (Elektra * elektra, const char * keyname, kdb_long_long_t value, ElektraError ** error)
502 : {
503 4 : ELEKTRA_SET_VALUE (elektraLongLongToString, KDB_TYPE_LONG_LONG, elektra, keyname, value, error);
504 : }
505 :
506 : /**
507 : * Sets a unsigned long long value.
508 : *
509 : * @param elektra The elektra instance to use.
510 : * @param keyname The (relative) name to write to.
511 : * @param value The new unsigned long long value.
512 : * @param error Pass a reference to an ElektraError pointer.
513 : * Will only be set in case of an error.
514 : */
515 4 : void elektraSetUnsignedLongLong (Elektra * elektra, const char * keyname, kdb_unsigned_long_long_t value, ElektraError ** error)
516 : {
517 4 : ELEKTRA_SET_VALUE (elektraUnsignedLongLongToString, KDB_TYPE_UNSIGNED_LONG_LONG, elektra, keyname, value, error);
518 : }
519 :
520 : /**
521 : * Sets a float value.
522 : *
523 : * @param elektra The elektra instance to use.
524 : * @param keyname The (relative) name to write to.
525 : * @param value The new float value.
526 : * @param error Pass a reference to an ElektraError pointer.
527 : * Will only be set in case of an error.
528 : */
529 18 : void elektraSetFloat (Elektra * elektra, const char * keyname, kdb_float_t value, ElektraError ** error)
530 : {
531 18 : ELEKTRA_SET_VALUE (elektraFloatToString, KDB_TYPE_FLOAT, elektra, keyname, value, error);
532 : }
533 :
534 : /**
535 : * Sets a double value.
536 : *
537 : * @param elektra The elektra instance to use.
538 : * @param keyname The (relative) name to write to.
539 : * @param value The new double value.
540 : * @param error Pass a reference to an ElektraError pointer.
541 : * Will only be set in case of an error.
542 : */
543 10 : void elektraSetDouble (Elektra * elektra, const char * keyname, kdb_double_t value, ElektraError ** error)
544 : {
545 10 : ELEKTRA_SET_VALUE (elektraDoubleToString, KDB_TYPE_DOUBLE, elektra, keyname, value, error);
546 : }
547 :
548 : #ifdef ELEKTRA_HAVE_KDB_LONG_DOUBLE
549 :
550 : /**
551 : * Sets a long double value.
552 : *
553 : * @param elektra The elektra instance to use.
554 : * @param keyname The (relative) name to write to.
555 : * @param value The new long double value.
556 : * @param error Pass a reference to an ElektraError pointer.
557 : * Will only be set in case of an error.
558 : */
559 4 : void elektraSetLongDouble (Elektra * elektra, const char * keyname, kdb_long_double_t value, ElektraError ** error)
560 : {
561 4 : ELEKTRA_SET_VALUE (elektraLongDoubleToString, KDB_TYPE_LONG_DOUBLE, elektra, keyname, value, error);
562 : }
563 :
564 : #endif // ELEKTRA_HAVE_KDB_LONG_DOUBLE
565 :
566 : /**
567 : * @}
568 : */
569 :
570 : #ifdef __cplusplus
571 : };
572 : #endif
|