-
Notifications
You must be signed in to change notification settings - Fork 123
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
WIP: Units plugin #2614
WIP: Units plugin #2614
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1345,3 +1345,9 @@ description:the contract was malformed | |
severity:error | ||
ingroup:kdb | ||
macro:MALFORMED_CONTRACT | ||
|
||
number:214 | ||
description:value of key is not a valid SI-unit | ||
severity:error | ||
ingroup:plugin | ||
module:units | ||
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. add newline |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
include (LibAddMacros) | ||
|
||
add_plugin (units | ||
SOURCES units.h | ||
units.c | ||
TEST_README) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
- infos = Information about the units plugin is in keys below | ||
- infos/author = Josef Wechselauer <e1326671@student.tuwien.ac.at> | ||
- infos/licence = BSD | ||
- infos/needs = | ||
- infos/provides = check/transformation | ||
- infos/recommends = | ||
- infos/placements = presetstorage | ||
- infos/status = unfinished | ||
- infos/metadata = check/units | ||
- infos/description = validates and transforms values entered as units | ||
|
||
## Introduction | ||
|
||
This plugin provides the capability to enter values with additional SI units. The unit will be checked if it as a valid SI base-unit, additional SI prefixes will be validated and the value re-calculated to it's base-unit in respect to the prefix. | ||
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. it's -> its |
||
|
||
E.g. If the value **1 km** is entered, it will be checked if **m** is a valid SI unit and **k** is a valid SI prefix. If both are valid, the prefix will be used to calculate the correct value with the base unit, which would be 1000 m in this example. The value is stored without the SI unit (in this case without the **m**). | ||
|
||
This plugin is written in C. | ||
|
||
## Usage | ||
|
||
## Dependencies | ||
|
||
None. | ||
|
||
## Examples | ||
|
||
```sh | ||
sudo kdb mount /tests/units.ini /tests/units ini units | ||
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. Is ini needed? Otherwise use the default (by not specifying "ini") |
||
#> Mount a config file with the units plugin | ||
|
||
sudo kdb setmeta /tests/units check/units any | ||
#> Check the /tests/units key for validity | ||
|
||
kdb set /tests/units "1m" | ||
#> Suceeds, since the value is a valid decimal with SI-unit representation. | ||
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. This needs to match with the output. |
||
|
||
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. What does |
||
kdb set /tests/units "35453.327468 µH" | ||
#> Suceeds, since the value is a valid decimal with SI-unit representation. | ||
|
||
kdb set /tests/units "32" | ||
#> Throws an error: value of key is not a representation for a value with a SI-unit | ||
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. Which error? (See shell recorder tests/shell/shell_recorder/tutorial_wrapper/README.md for how to specify errors) |
||
|
||
kdb set /tests/units "12 n" | ||
#> Throws an error: value of key is not a representation for a value with a SI-unit | ||
#> This could be changed in a further step (see issue #1398) to be valid, as for example the user wants to enter 1k to represent 1000 without an SI-Unit. | ||
#> For now, this is ignored as the entered units should be checked for correctness | ||
|
||
kdb set /tests/units 432 km | ||
#> Throws an error: quotes are expected. | ||
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. expected -> needed because of the shell |
||
``` | ||
|
||
|
||
## Limitations | ||
|
||
None. |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
/** | ||
* @file | ||
* | ||
* @brief Source file for the units plugin | ||
* | ||
* @copyright BSD License (see LICENSE.md or https://www.libelektra.org) | ||
* | ||
*/ | ||
|
||
#include <kdberrors.h> | ||
#include "units.h" | ||
#include <regex.h> | ||
#include <kdbhelper.h> | ||
#include <stdio.h> | ||
#include <string.h> | ||
#include <stdlib.h> | ||
|
||
int is_valid_key(Key * key, Key * parentKey) | ||
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 be static |
||
{ | ||
const Key * meta = keyGetMeta(key, "check/units"); | ||
if (!meta) return 1; | ||
const char* value = keyString(key); | ||
const char * prefix = "(Y|Z|E|P|T|G|M|k|h|da|d|c|m|µ|n|p|f|a|z|y)"; | ||
const char * unit = "?(m|g|s|A|K|mol|cd|rad|sr|Hz|N|Pa|J|W|C|V|F|Ω|Ohm|S|Wb|T|H|C|lm|lx|Bq|Gy|Sv|kat|l|L)"; | ||
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. formatting broken |
||
char regexString[256]; | ||
snprintf(regexString, sizeof regexString, "%s%s%s%s%s", "^([0-9]+)\\.?([0-9]*)\\s*", prefix, "?", unit, "$"); | ||
|
||
regex_t regex; | ||
regmatch_t offsets; | ||
int compile_failure = regcomp (®ex, regexString, REG_NOSUB | REG_EXTENDED | REG_NEWLINE); | ||
if (compile_failure) return -1; | ||
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. No error set when the compilation fails. |
||
// regexec returns 0 on a successful match | ||
int match = !(regexec (®ex, value, 0, &offsets, 0)); | ||
regfree (®ex); | ||
|
||
if(!match) { | ||
ELEKTRA_SET_ERRORF (214, parentKey, "Validation of key %s with value %s failed.", keyName (key), keyString (key)); | ||
} | ||
|
||
return match; | ||
|
||
} | ||
|
||
int elektraUnitsGet (Plugin * handle ELEKTRA_UNUSED, KeySet * returned, Key * parentKey) | ||
{ | ||
if (!elektraStrCmp (keyName (parentKey), "system/elektra/modules/units")) | ||
{ | ||
KeySet * contract = | ||
ksNew (30, keyNew ("system/elektra/modules/units", KEY_VALUE, "units plugin waits for your orders", KEY_END), | ||
keyNew ("system/elektra/modules/units/exports", KEY_END), | ||
keyNew ("system/elektra/modules/units/exports/get", KEY_FUNC, elektraUnitsGet, KEY_END), | ||
keyNew ("system/elektra/modules/units/exports/set", KEY_FUNC, elektraUnitsSet, KEY_END), | ||
#include ELEKTRA_README | ||
keyNew ("system/elektra/modules/units/infos/version", KEY_VALUE, PLUGINVERSION, KEY_END), KS_END); | ||
ksAppend (returned, contract); | ||
ksDel (contract); | ||
|
||
return ELEKTRA_PLUGIN_STATUS_SUCCESS; | ||
} | ||
// get all keys | ||
|
||
return ELEKTRA_PLUGIN_STATUS_NO_UPDATE; | ||
} | ||
|
||
int elektraUnitsSet (Plugin * handle ELEKTRA_UNUSED, KeySet * returned ELEKTRA_UNUSED, Key * parentKey ELEKTRA_UNUSED) | ||
{ | ||
// set all keys | ||
// this function is optional | ||
Key * cur; | ||
ksRewind (returned); | ||
while ((cur = ksNext (returned)) != NULL) | ||
{ | ||
const Key * meta = keyGetMeta (cur, "check/units"); | ||
if (!meta) continue; | ||
int is_valid = is_valid_key (cur, parentKey); | ||
if (!is_valid) return ELEKTRA_PLUGIN_STATUS_ERROR; | ||
} | ||
return ELEKTRA_PLUGIN_STATUS_SUCCESS; | ||
} | ||
|
||
Plugin * ELEKTRA_PLUGIN_EXPORT | ||
{ | ||
// clang-format off | ||
return elektraPluginExport ("units", | ||
ELEKTRA_PLUGIN_GET, &elektraUnitsGet, | ||
ELEKTRA_PLUGIN_SET, &elektraUnitsSet, | ||
ELEKTRA_PLUGIN_END); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
/** | ||
* @file | ||
* | ||
* @brief Header file for the units plugin | ||
* | ||
* @copyright BSD License (see LICENSE.md or https://www.libelektra.org) | ||
* | ||
*/ | ||
|
||
#ifndef ELEKTRA_PLUGIN_UNITS_H | ||
#define ELEKTRA_PLUGIN_UNITS_H | ||
|
||
#include <kdbplugin.h> | ||
|
||
|
||
int elektraUnitsGet (Plugin * handle, KeySet * ks, Key * parentKey); | ||
int elektraUnitsSet (Plugin * handle, KeySet * ks, Key * parentKey); | ||
|
||
Plugin * ELEKTRA_PLUGIN_EXPORT; | ||
|
||
#endif |
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.
twice?