Skip to content
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

CCode Updates & Other Minor Enhancements #2066

Merged
merged 119 commits into from Jun 19, 2018

Conversation

sanssecours
Copy link
Member

@sanssecours sanssecours commented Jun 11, 2018

Purpose

This pull request adds support for key name escaping to the CCode plugin. The PR also contains other minor enhancements, including

  • relative storage support for the Tcl plugin, and
  • updates to info/status of various plugins

.

Checklist

  • I checked all commit messages.
  • I added a Markdown Shell Recorder test for the CCode plugin.
  • I ran all tests locally and everything went fine.
  • The PR contains some logging code for the CCode plugin.
  • The release notes should be up to date.

Copy link
Contributor

@markus2330 markus2330 left a comment

Choose a reason for hiding this comment

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

Great maintenance work! Thank you so much!

@@ -55,7 +55,7 @@ kdb find 'fizz'
#> user/tests/find/tests/fizz/buzz
#> user/tests/find/tostfizz

sudo kdb umount /tests/find
Copy link
Contributor

Choose a reason for hiding this comment

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

We should umount nevertheless. The umount feature of the shell recorder should only be there to catch incorrectly written shell recorder scripts.

Copy link
Member Author

Choose a reason for hiding this comment

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

The umount feature of the shell recorder should only be there to catch incorrectly written shell recorder scripts.

I agree. I removed the auto unmount feature in the latest updates. This way an incorrectly written test will always fail.

Copy link
Contributor

Choose a reason for hiding this comment

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

Yes, in general tests should fail if they do not properly clean up everything.

I am currently thinking about writing a tutorial of how to setup a computer with Elektra. In this tutorial it would be wanted that everything stays mounted at the end. It is questionable, however, if this tutorial can be checked via the shell recorder because it has many local dependencies, so maybe it won't be run via the shell recorder anyway.

@@ -91,7 +91,7 @@ kdb ls /tests/examples/kdb-ls/ -v
#> user/tests/examples/kdb-ls/tost
#> user/tests/examples/kdb-ls/tost/level

kdb umount /tests/examples
Copy link
Contributor

Choose a reason for hiding this comment

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

Same here

@@ -71,7 +71,8 @@ kdb find \'fizz\'
#> user/tests/find/tests/fizz/buzz
#> user/tests/find/tostfizz

sudo kdb umount /tests/find
kdb rm \-r /tests/find
kdb umount /tests/find
Copy link
Contributor

Choose a reason for hiding this comment

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

Why is umount here but not above in the source? This seems to be correct.

Copy link
Member Author

Choose a reason for hiding this comment

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

Why is umount here but not above in the source?

I guess my script to remove those pesky man pages where only the date changed also reverted the (single-line) update to the man page.

The man page and the ReadMe for kdb-find should be in sync after the last update again.

### Crypto

- The `crypto` plugin now uses Elektra's `libinvoke` and the `base64` plugin in order to encode and decode Base64 strings. This improvement reduces code duplication between the two plugins. *(Peter Nirschl)*

### Haskell

- An issue when building Haskell plugins with a cached sandbox is fixed in case
Copy link
Contributor

Choose a reason for hiding this comment

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

Thank you for reordering this. We should discuss it in the next meeting how to use your new organization.


### Regex Dispatcher

- The plugin [regexdispatcher](https://www.libelektra.org/plugins/regexdispatcher) has been added. It calculates regex representations for
commonly used specification keywords to be used with the [typechecker](https://www.libelektra.org/plugins/typechecker). Currently the
keywords `check/range`, `check/enum` and `check/validation` are supported. *(Armin Wurzinger)*

### Tcl

- The [`tcl`](http://libelektra.org/plugins/tcl) plugin does not fail anymore, if its configuration file does not exist and you trie to
Copy link
Contributor

Choose a reason for hiding this comment

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

try


```sh
# We use `%` as escape character and map the space character (hex: `20`) to the character `_`.
sudo kdb mount config.tcl user/tests/ccode tcl base64 ccode escape=`bash -c 'printf %x \"%'` chars= chars/20=`bash -c 'printf %x \"_'`
Copy link
Contributor

Choose a reason for hiding this comment

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

What about not requiring chars=?

Copy link
Member Author

Choose a reason for hiding this comment

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

That sounds like a good idea, especially since I did not add chars= at first and had to debug why only adding chars/20 did not work. However, for which key should we look in ksLookupByName then? As far as I know ksLookupByName does not support something like /chars* (glob expression) or /chars.* (regex) as argument.

Copy link
Contributor

Choose a reason for hiding this comment

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

I think the configuration settings passed to the plugin won't be too big. So simply iterate over everything and check if it contains /chars.

if (size > mapping->bufferSize)
{
mapping->bufferSize = size;
mapping->buffer = new unsigned char[mapping->bufferSize];
Copy link
Contributor

Choose a reason for hiding this comment

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

In modern C++ "new" is avoided. Here there is a big memory leak. You should use an array/vector instead. It avoids the memory leak, size is then implicitely available, and vectors have resize().

Copy link
Member Author

Choose a reason for hiding this comment

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

In modern C++ "new" is avoided.

I know. I just replaced malloc with new and free with delete.

Here there is a big memory leak.

I do not think so, since I did not change the way the plugin handles memory. If there is a memory leak, then the Linux Travis ASAN build should also fail, which is not the case.

You should use an array/vector instead. It avoids the memory leak, size is then implicitely available, and vectors have resize().

This certainly makes sense (except for the part about the memory leak of course 😊).

Copy link
Contributor

Choose a reason for hiding this comment

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

The memory leak only occurs if the size is > 1000 (especially in gradually increasing sizes there might be a memleak in every iteration), seems like this is not tested. I did not say you introduced the problem but in C++ it is now easier to fix 😄

And in general it is not safe to translate every malloc -> new because C++ additionally has exceptions which can cause memleaks not possible in C.

@@ -11,27 +11,35 @@

#include <kdbplugin.h>

#ifdef __cplusplus
Copy link
Contributor

Choose a reason for hiding this comment

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

Is there any reason to include this in C code?

Copy link
Member Author

Choose a reason for hiding this comment

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

Since C does not support using or extern "C" we have to remove the code below, if we include the header file in testmod_ccode.c.

CCodeData * d = get_data ();
char buf[1000];
d->buf = buf;
CCodeData * mapping = get_data ();
Copy link
Contributor

Choose a reason for hiding this comment

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

Does this function test every possible character?

For maintenance it would be nice if the check_reversibility can be shared between the different code plugins.

Copy link
Member Author

Choose a reason for hiding this comment

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

Does this function test every possible character?

Nope, not as far as I can tell. I did not write this function though 😊.

Copy link
Contributor

Choose a reason for hiding this comment

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

Yeah, seems like I was in a hurry finishing my master thesis 😄

for line in $TOUMOUNT;
do
mp=$(printf '%s' "$line" | sed -n 's/.*with name \(.*\)/\1/p')
"$KDB" umount "$mp"
Copy link
Contributor

Choose a reason for hiding this comment

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

We should also warn the user that umount was forgotten here.

/** @see elektraDocOpen */
int elektraCcodeOpen (Plugin * handle, Key * key ELEKTRA_UNUSED)
{
CCodeData * const mapping = new CCodeData ();
Copy link
Contributor

Choose a reason for hiding this comment

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

Should be unique_ptr, see vector discussion.

Copy link
Contributor

@markus2330 markus2330 left a comment

Choose a reason for hiding this comment

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

Thank you, great work! Some things need to be changed, though.

retrieve the plugin contract. *(René Schwaiger)*
- The plugin now uses relative key names. This update addresses issue [#51][]. *(René Schwaiger)*

[#51]: https://github.com/ElektraInitiative/libelektra/issues/51
Copy link
Contributor

Choose a reason for hiding this comment

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

issues.libelektra.org/51 is preferred

@@ -211,6 +244,9 @@ Thanks to Michael Zronek and Vanessa Kos.
- The Markdown Shell Recorder now also tests if a command prints nothing to `stdout` if you add the check `#>`. *(René Schwaiger)*
- We fixed some problems in the [Markdown Shell Recorder](https://master.libelektra.org/tests/shell/shell_recorder/tutorial_wrapper) test
of [`kdb ls`](https://master.libelektra.org/doc/help/kdb-ls.md). *(René Schwaiger)*
- The Markdown Shell Recorder test for [`kdb find`](https://master.libelektra.org/doc/help/kdb-find.md) now removes the configuration file
at the end of the test. *(René Schwaiger)*
- We removed the broken auto unmounting feature from the [Markdown Shell Recorder][]. *(René Schwaiger)*
Copy link
Contributor

Choose a reason for hiding this comment

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

What is the behavior now?

Copy link
Member Author

Choose a reason for hiding this comment

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

The Markdown Shell Recorder does not do any auto unmounting. That behavior did not change. I just removed dead code.

{ \
ASSERT_TRUE (x) << y; \
} while (0)
#define succeed_if(x, y) ASSERT_TRUE (x) << y;
Copy link
Contributor

Choose a reason for hiding this comment

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

Copy link
Member Author

Choose a reason for hiding this comment

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

Oh, I forgot to remove the trailing semicolons. This should be fixed in the latest version of the PR.

include (LibAddMacros)
if (DEPENDENCY_PHASE)
include (LibAddTest)
add_gtest (testmod_ccode
Copy link
Contributor

Choose a reason for hiding this comment

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

why not add_plugin_test? Why in the dependency phase?

Copy link
Member Author

Choose a reason for hiding this comment

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

why not add_plugin_test?

I just copied this code from the type plugin. The documentation also states that you should use add_gtest. My favorite approach would be to just use add_plugin, but as far as I can tell this function and add_plugin_test do not support C++ tests for a C++ plugin.

Why in the dependency phase?

Adding the plugin without if (DEPENDENCY_PHASE)… does not work:

CMake Error at cmake/Modules/LibAddTest.cmake:28 (add_executable):
  add_executable cannot create target "testmod_ccode" because another target
  with the same name already exists.  The existing target is an executable
  created in source directory "/Users/rene/Documents/Studium/Master
  Thesis/Configuration Parsing/Source/Elektra/src/plugins".  See
  documentation for policy CMP0002 for more details.
Call Stack (most recent call first):
  src/plugins/ccode/CMakeLists.txt:1 (add_gtest)


CMake Error at cmake/Modules/LibAddMacros.cmake:80 (target_link_libraries):
  Attempt to add link library "elektra-core" to target "testmod_ccode" which
  is not built in this directory.
Call Stack (most recent call first):
  cmake/Modules/LibAddTest.cmake:34 (target_link_elektra)
  src/plugins/ccode/CMakeLists.txt:1 (add_gtest)


CMake Error at cmake/Modules/LibAddTest.cmake:40 (target_link_libraries):
  Attempt to add link library "gtest_main" to target "testmod_ccode" which is
  not built in this directory.
Call Stack (most recent call first):
  src/plugins/ccode/CMakeLists.txt:1 (add_gtest)


CMake Error at cmake/Modules/LibAddTest.cmake:43 (target_link_libraries):
  Attempt to add link library "gtest" to target "testmod_ccode" which is not
  built in this directory.
Call Stack (most recent call first):
  src/plugins/ccode/CMakeLists.txt:1 (add_gtest)


CMake Error at cmake/Modules/LibAddTest.cmake:51 (install):
  install TARGETS given target "testmod_ccode" which does not exist in this
  directory.
Call Stack (most recent call first):
  src/plugins/ccode/CMakeLists.txt:1 (add_gtest)

.

Copy link
Contributor

Choose a reason for hiding this comment

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

add_gtest

Yes, seems like we miss a feature in add_plugin.

Adding the plugin without if (DEPENDENCY_PHASE)… does not work:

I mean that ADDTESTING_PHASE should be the correct phase.

Copy link
Member Author

Choose a reason for hiding this comment

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

I mean that ADDTESTING_PHASE should be the correct phase.

After I changed the phase add_gtest did not find the source files for the test at configuration time any more. I fixed this problem by adding the code

foreach (file ${ARG_SOURCES} ${source}.cpp)
  if (EXISTS "${file}")
    list (APPEND SOURCES "${file}")
  else ()
    list (APPEND SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/${file}")
  endif ()
endforeach ()

to add_gtest. However now the build fails printing an error message about kdb.hpp

In file included from ../src/plugins/ccode/coder.cpp:12:
../src/plugins/ccode/coder.hpp:17:10: fatal error: 'keyset.hpp' file not found
#include <keyset.hpp>
         ^~~~~~~~~~~~

. For now I undid the changes to fix the problem.


#include <keyset.hpp>

using CppKeySet = kdb::KeySet;
Copy link
Contributor

Choose a reason for hiding this comment

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

please limit scope (could be moved to class Coder)

using CppKeySet = kdb::KeySet;
using CppKey = kdb::Key;

using ckdb::elektraModulesClose;
Copy link
Contributor

Choose a reason for hiding this comment

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

It is okay as is but you could also use "using ckdb;".

Copy link
Member Author

Choose a reason for hiding this comment

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

I know, I prefer to only explicitly “import” the functionality I need though.


void testRoundTrip (string const decodedString, string const encodedString = "", CppKeySet config = defaultConfig ())
#ifdef __llvm__
__attribute__ ((annotate ("oclint:suppress[empty if statement]"), annotate ("oclint:suppress[high cyclomatic complexity]"),
Copy link
Contributor

Choose a reason for hiding this comment

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

Does the code below really emits all these problems? Maybe we should create Macros with these attributes?

Copy link
Member Author

Choose a reason for hiding this comment

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

Does the code below really emits all these problems?

Yes. The main problems seem to be the macros succeed_if_same and exit_if_fail. Every time we use them OCLint prints the following two warnings:

  • “too few branches in switch statement”, and
  • “empty if statement”

.

Maybe we should create Macros with these attributes?

Nah, I think it is okay as it is. These annotations should not look pretty. Ideally we should fix the underlying problems, instead of using annotations to disable the warnings.

annotate ("oclint:suppress[high ncss method]"), annotate ("oclint:suppress[too few branches in switch statement]")))
#endif
{
CppKeySet modules{ 0, KS_END };
Copy link
Contributor

Choose a reason for hiding this comment

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

modern C++ style 👍

I wonder about the spacing of the formatter, though.

@@ -19,22 +19,25 @@

#include "action.hpp"

#include <kdbease.h>
Copy link
Contributor

Choose a reason for hiding this comment

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

please add a comment what it is used for (elektraKeyGetRelativeName)

errno = errnosave;
parent.release ();
Copy link
Contributor

Choose a reason for hiding this comment

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

If you happen to start a new C++ plugin: the type plugin solves this much more nicely with a delegate. Then you only have single place where you have to release the ownership.

Copy link
Member Author

Choose a reason for hiding this comment

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

If you happen to start a new C++ plugin: the type plugin solves this much more nicely with a delegate.

I know, I used the delegate approach for the CCode plugin updates (that are part of this PR).

This update should make failures less likely, since now

- the download of the Travis cache,
- the download of a Homebrew bottle, and
- the download or build of a source package

have to fail, for a Homebrew related issue to cause a failed build job.
Before this update the `tcl` plugin would report that it was unable to
read the configuration file, if the `KeySet` managed by the plugin was
empty.
This update addresses part of issue ElektraInitiative#51.
@markus2330 markus2330 merged commit a1fd1ad into ElektraInitiative:master Jun 19, 2018
@markus2330
Copy link
Contributor

Thank you, great job!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants