Skip to content
This repository has been archived by the owner on Oct 15, 2024. It is now read-only.

Hexnumber #1903

Merged
merged 18 commits into from
May 19, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@

#ignore all build directories of cmake
build*/
cmake-build*/

#ignore ctags + gdb history files
.ctags
Expand Down
2 changes: 1 addition & 1 deletion cmake/Modules/LibAddMacros.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -554,7 +554,7 @@ function (generate_readme p) # rerun cmake when README.md is changed also allow
contents
"${contents}")
string (REGEX
REPLACE "\"- +infos/author *= *([.@<>a-zéA-Z0-9 %_-]*)\\\\n\""
REPLACE "\"- +infos/author *= *([^\\\\]*)\\\\n\""
"keyNew(\"system/elektra/modules/${p}/infos/author\",\nKEY_VALUE, \"\\1\", KEY_END),"
contents
"${contents}")
Expand Down
7 changes: 7 additions & 0 deletions doc/METADATA.ini
Original file line number Diff line number Diff line change
Expand Up @@ -881,3 +881,10 @@ usedby/plugins= xerces
type= string
description= used to store the name of the xml file's original root element when mounting to a mountpoint which name doesn't correspond to the xml root element.
This metadata will be stored in the mountpoint key. When writing or exporting again, the stored name will be used for the root element of the corresponding xml document.

[unit/base]
type = dec hex
default = dec
usedby/plugins = hexnumber
description = used to specify the base of an integer value. Currently only the hexnumber plugin supports this metadata. It converts any value marked as "hex" from
hexadecimal into decimal when the configuration is read, and back when it is written. The hexnumber plugin also ensures that a value marked as "hex" starts with "0x" or "0X".
3 changes: 2 additions & 1 deletion doc/news/_preparation_next_release.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,8 @@ We added even more functionality, which could not make it to the highlights:

## New Plugins

- <<TODO>>
- The plugin [hexnumber](https://www.libelektra.org/plugins/hexnumber) has been added. It can be used
to convert hexadecimal values into decimal when read, and back to hexadecimal when written.
- <<TODO>>
- <<TODO>>

Expand Down
2 changes: 2 additions & 0 deletions src/include/kdbhelper.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,9 @@ char * elektraVFormat (const char * format, va_list arg_list);

/* Compare */
int elektraStrCmp (const char * s1, const char * s2);
int elektraStrNCmp (const char * s1, const char * s2, size_t n);
int elektraStrCaseCmp (const char * s1, const char * s2);
int elektraStrNCaseCmp (const char * s1, const char * s2, size_t n);
int elektraMemCaseCmp (const char * s1, const char * s2, size_t size);

/* Len */
Expand Down
34 changes: 34 additions & 0 deletions src/libs/elektra/internal.c
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,23 @@ int elektraStrCmp (const char * s1, const char * s2)
return strcmp (s1, s2);
}

/**@brief Compare Strings up to a maximum length.
*
* @param s1 The first string to be compared
* @param s2 The second string to be compared
* @param n The maximum length to be compared
*
* @ingroup internal
* @return a negative number if s1 is less than s2
* @retval 0 if s1 matches s2
* @return a positive number if s1 is greater than s2
**/
int elektraStrNCmp (const char * s1, const char * s2, size_t n)
{
ELEKTRA_ASSERT (s1 != NULL && s2 != NULL, "Got null pointer s1: %p s2: %p", (void *) s1, (void *) s2);

return strncmp (s1, s2, n);
}

/**@brief Compare Strings ignoring case.
*
Expand All @@ -145,6 +162,23 @@ int elektraStrCaseCmp (const char * s1, const char * s2)
return strcasecmp (s1, s2);
}

/**@brief Compare Strings ignoring case up to a maximum length.
*
* @param s1 The first string to be compared
* @param s2 The second string to be compared
* @param n The maximum length to be compared
*
* @ingroup internal
* @return a negative number if s1 is less than s2
* @retval 0 if s1 matches s2
* @return a positive number if s1 is greater than s2
**/
int elektraStrNCaseCmp (const char * s1, const char * s2, size_t n)
{
ELEKTRA_ASSERT (s1 != NULL && s2 != NULL, "Got null pointer s1: %p s2: %p", (void *) s1, (void *) s2);
return strncasecmp (s1, s2, n);
}

/**
* @brief Compare two memory regions but make cmp chars uppercase before
* comparison.
Expand Down
1 change: 1 addition & 0 deletions src/plugins/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,7 @@ Transformations:
- [keytometa](keytometa/) transforms keys to metadata
- [rename](rename/) renames keys according to different rules
- [boolean](boolean/) canonicalizes boolean keys
- [hexnumber](hexnumber/) converts between hexadecimal and decimal

Doing other stuff:

Expand Down
3 changes: 3 additions & 0 deletions src/plugins/hexnumber/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
include (LibAddMacros)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please format this file with the script reformat-cmake.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for noting, we should enforce that with the buildserver. Isn't this just a matter of installing two tools?

Ideally the build server should directly tell that something like that is wrong.

@ingwinlu What do you think?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for noting, we should enforce that with the buildserver.

We already do that in the Travis Linux builds.

Isn't this just a matter of installing two tools?

Yes.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

knock yourself out :D

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@sanssecours It seems you need to manually install libyaml as well as PyYAML for the reformat-cmake script to work. This should probably be reflected in our documentation. Especially because otherwise the script throws an error for each CMake file and also deletes the contents of all these files.

Copy link
Member

@sanssecours sanssecours May 18, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@sanssecours It seems you need to manually install libyaml as well as PyYAML for the reformat-cmake script to work.

As far as I know cmake-format has no dependencies:

pip show cmake-format
#> Name: cmake-format
#> Version: 0.3.6
#> Summary: Can format your listfiles so they don't look like crap
#> Home-page: https://github.com/cheshirekow/cmake_format
#> Author: Josh Bialkowski
#> Author-email: josh.bialkowski@gmail.com
#> License: UNKNOWN
#> Location: /Users/rene/.pyenv/versions/3.6.5/lib/python3.6/site-packages
#> Requires:
#> Required-by:

.

This should probably be reflected in our documentation. Especially because otherwise the script throws an error for each CMake file and also deletes the contents of all these files.

While reformat-cmake is certainly not perfect, it checks for the binaries cmake-format and sponge beforehand. If you did not install one of these tools it should just fail printing a (broken) error message. I tried this myself, first by uninstalling cmake-format and invoking the script. After that I uninstalled moreutils and ran the command again. At no point did the script change any file in my copy of the repo, at least as far as I can tell. Are you sure that the script deleted you CMake files? If so, can you please describe steps to reproduce the problem?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are you sure that the script deleted you CMake files?

It did not delete the files themselves, just their contents. I think this is because stdout of cmake-format is piped back into the CMake file, but stdout is empty because of the error.

As far as I know cmake-format has no dependencies

I also looked at the cmake-format github page and could not find any mention of the dependency. But here the module yaml is imported, which is the cause of the error.

The problem could probably be solved by using the json or python format for the .cmake-format file, because these two modules are part of the python standard library.

If you still want me to, I can try to find out how to reproduce the error.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for the detailed description. I opened pull request #2011, which should fix the problem by checking the exit code of cmake-format CMakeLists.txt before it updates any file.

The problem could probably be solved by using the json or python format for the .cmake-format file, because these two modules are part of the python standard library.

That might even be a better solution, than the one I came up with. Anyway, since I prefer the human readability of YAML over JSON or the Python config style, I did not change the format of the config file.


add_plugin (hexnumber SOURCES hexnumber.h hexnumber.c LINK_ELEKTRA elektra-ease ADD_TEST TEST_README)
97 changes: 97 additions & 0 deletions src/plugins/hexnumber/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
- infos = Information about the hexnumber plugin is in keys below
- infos/author = Klemens Böswirth <k.boeswirth+git@gmail.com>
- infos/licence = BSD
- infos/needs =
- infos/provides = conv check
- infos/recommends =
- infos/placements = postgetstorage presetstorage
- infos/status = nodep unittest maintained
- infos/metadata = unit/base type
- infos/ordering = type
- infos/description = converts hexadecimal values into decimal and back

## Introduction

This plugin is used to read configuration files that use hexadecimal values. All "hex-values" (see below) will be
converted into decimal when Elektra reads values from the mounted file. When Elektra writes back to the file the converted values
will be converted back and stored as before (`0X` will be replaced with `0x`).

### What are "hex-values"?
There are multiple ways you can signal to the hexnumber plugin, that a value should be converted:

1. If a Key has the metadata `unit/base` set to `hex` it will always be interpreted as a hex-value. The plugin will also produce an error,
if the value contained in such a Key does not start with `0x` (or `0X`).
2. If `unit/base` is not present and
- the `type` metadata is set to one of the recognized integer-types (default: `byte`, `short`, `unsigned_short`, `long`, `unsigned_long`,
`long_long`, `unsigned_long_long`)
- AND the configuration value itself starts with `0x` (or `0X`) it will be interpreted as a hex-value.
3. If forced conversion mode (`/force` plugin configuration, see below) is enabled all values starting with `0x` (or `0X`) are considered hex-values.

## Configuration

When mounting a backend with the hexnumber plugin, a few settings can be configured.

1. To enable forced conversion mode set `/force` to any value. In forced conversion mode the plugin tries to convert **ALL** strings
starting with `0x` (or `0X`) into decimal before passing the value on to the rest of Elektra. This can be useful for importing a
configuration file that uses hexadecimal values into Elektra without writing a specification for the file.

NOTE: be careful when using this option, as any configuration value that contains invalid non-hexadecimal characters
(i.e. does not match `0[xX][0-9A-Fa-f]+`) will result in an error.

```
sudo kdb mount test.ecf /examples/hexnumber/forced hexnumber /force=1
```

2. The types recognized as integers can be configured. For this purpose specify all *additional* types you want to be considered for
possible hexadecimal conversion as an Elektra array. All keys with a type from `/accept/types/#`, or one of the default types, will
be converted to hexadecimal if the value starts with `0x` (or `0X`).

```
sudo kdb mount test.ecf /examples/hexnumber/customtypes hexnumber /accept/types/#0=customint /accept/types/#1=othercustomint
```

## Usage & Example
- To mount a simple backend that uses hexadecimal numbers, you can use:
```sh
sudo kdb mount test.ecf user/tests/hexnumber hexnumber
```

- A few examples on how to use the plugin:
```sh
# Example 1: read hex value
kdb set user/tests/hexnumber/hex 0x1F
kdb setmeta user/tests/hexnumber/hex type long

kdb get user/tests/hexnumber/hex
#> 31

# Example 2: decimal value not converted
kdb set user/tests/hexnumber/dec 26
kdb setmeta user/tests/hexnumber/dec type long

kdb get user/tests/hexnumber/dec
#> 26

# Example 3: string untouched
kdb set user/tests/hexnumber/string value
kdb setmeta user/tests/hexnumber/string type string

kdb get user/tests/hexnumber/string
#> value

# Example 4: read hex value with unit/base
kdb set user/tests/hexnumber/hex2 0xF
kdb setmeta user/tests/hexnumber/hex2 unit/base hex

kdb get user/tests/hexnumber/hex2
#> 15

# Undo changes
kdb rm -r user/tests/hexnumber
```

- To unmount the plugin use the following command:
```sh
kdb umount user/tests/hexnumber
#>
```
Loading