Permalink
Browse files

highlevel: update according to code review

  • Loading branch information...
kodebach authored and sanssecours committed Dec 22, 2018
1 parent 9c7b44a commit 6cadc5d7460f28216622e48960b73a746bdb03f4
@@ -34,6 +34,36 @@ nbproject/
.DS_Store
.directory

#ignore pyc files
*.pyc

#ignore CLion project files
.idea/
cmake-build-*/
## User-specific stuff
.idea/**/workspace.xml
.idea/**/tasks.xml
.idea/**/usage.statistics.xml
.idea/**/dictionaries
.idea/**/shelf

## Generated files
.idea/**/contentModel.xml

## Sensitive or high-churn files
.idea/**/dataSources/
.idea/**/dataSources.ids
.idea/**/dataSources.local.xml
.idea/**/sqlDataSources.xml
.idea/**/dynamic.xml
.idea/**/uiDesigner.xml
.idea/**/dbnavigator.xml

# File-based project format
*.iws

# Editor-based Rest Client
.idea/httpRequests

*.iml
modules.xml
.idea/misc.xml
*.ipr
@@ -0,0 +1 @@
Elektra
@@ -0,0 +1,58 @@
<component name="ProjectCodeStyleConfiguration">
<code_scheme name="Project" version="173">
<option name="OTHER_INDENT_OPTIONS">
<value>
<option name="USE_TAB_CHARACTER" value="true" />
</value>
</option>
<option name="RIGHT_MARGIN" value="140" />
<Objective-C>
<option name="INDENT_NAMESPACE_MEMBERS" value="0" />
<option name="INDENT_C_STRUCT_MEMBERS" value="8" />
<option name="INDENT_CLASS_MEMBERS" value="8" />
<option name="INDENT_INSIDE_CODE_BLOCK" value="8" />
<option name="NAMESPACE_BRACE_PLACEMENT" value="2" />
<option name="FUNCTION_BRACE_PLACEMENT" value="2" />
<option name="BLOCK_BRACE_PLACEMENT" value="2" />
<option name="SPACE_AFTER_POINTER_IN_DECLARATION" value="true" />
<option name="SPACE_AFTER_REFERENCE_IN_DECLARATION" value="true" />
</Objective-C>
<Objective-C-extensions>
<extensions>
<pair source="cpp" header="hpp" fileNamingConvention="NONE" />
<pair source="c" header="h" fileNamingConvention="NONE" />
</extensions>
</Objective-C-extensions>
<codeStyleSettings language="CMake">
<option name="ALIGN_MULTILINE_PARAMETERS_IN_CALLS" value="true" />
<option name="SPACE_BEFORE_METHOD_CALL_PARENTHESES" value="true" />
<option name="SPACE_BEFORE_METHOD_PARENTHESES" value="true" />
<indentOptions>
<option name="INDENT_SIZE" value="8" />
<option name="TAB_SIZE" value="8" />
<option name="USE_TAB_CHARACTER" value="true" />
</indentOptions>
</codeStyleSettings>
<codeStyleSettings language="ObjectiveC">
<option name="BRACE_STYLE" value="5" />
<option name="CLASS_BRACE_STYLE" value="2" />
<option name="ELSE_ON_NEW_LINE" value="true" />
<option name="SPACE_BEFORE_METHOD_CALL_PARENTHESES" value="true" />
<option name="SPACE_BEFORE_METHOD_PARENTHESES" value="true" />
<option name="TERNARY_OPERATION_SIGNS_ON_NEXT_LINE" value="false" />
<option name="KEEP_SIMPLE_METHODS_IN_ONE_LINE" value="false" />
<option name="IF_BRACE_FORCE" value="3" />
<option name="FOR_BRACE_FORCE" value="3" />
<indentOptions>
<option name="INDENT_SIZE" value="8" />
<option name="TAB_SIZE" value="8" />
<option name="USE_TAB_CHARACTER" value="true" />
</indentOptions>
</codeStyleSettings>
<codeStyleSettings language="Python">
<indentOptions>
<option name="USE_TAB_CHARACTER" value="true" />
</indentOptions>
</codeStyleSettings>
</code_scheme>
</component>
@@ -0,0 +1,5 @@
<component name="ProjectCodeStyleConfiguration">
<state>
<option name="USE_PER_PROJECT_SETTINGS" value="true" />
</state>
</component>
@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Encoding" addBOMForNewFiles="with NO BOM" />
</project>
@@ -0,0 +1,12 @@
<component name="InspectionProjectProfileManager">
<profile version="1.0">
<option name="myName" value="Project Default" />
<inspection_tool class="PyPep8Inspection" enabled="true" level="WEAK WARNING" enabled_by_default="true">
<option name="ignoredErrors">
<list>
<option value="W191" />
</list>
</option>
</inspection_tool>
</profile>
</component>
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>
@@ -214,9 +214,9 @@ macro (add_headers HDR_FILES)
${SRC_HDR_FILES})

set_source_files_properties (${BINARY_INCLUDE_DIR}/kdberrors.h PROPERTIES GENERATED ON SKIP_AUTOMOC ON)
set_source_files_properties (${BINARY_INCLUDE_DIR}/elektra_error_codes.h PROPERTIES GENERATED ON SKIP_AUTOMOC ON)
set_source_files_properties (${BINARY_INCLUDE_DIR}/elektra_errors.h PROPERTIES GENERATED ON SKIP_AUTOMOC ON)
set_source_files_properties (${BINARY_INCLUDE_DIR}/elektra_errors_private.h PROPERTIES GENERATED ON SKIP_AUTOMOC ON)
set_source_files_properties (${BINARY_INCLUDE_DIR}/elektra/errorcodes.h PROPERTIES GENERATED ON SKIP_AUTOMOC ON)
set_source_files_properties (${BINARY_INCLUDE_DIR}/elektra/errors.h PROPERTIES GENERATED ON SKIP_AUTOMOC ON)
set_source_files_properties (${BINARY_INCLUDE_DIR}/elektra/errorsprivate.h PROPERTIES GENERATED ON SKIP_AUTOMOC ON)
list (APPEND ${HDR_FILES}
"${BINARY_INCLUDE_DIR}/kdberrors.h")
endmacro (add_headers)
@@ -51,212 +51,9 @@ Furthermore, we will:
- enforce that every key has a type
- use `elektraError` as extra parameter (for prototyping and examples you can pass 0)


### Basic

(needed for lcdproc)

```c
Elektra * elektraOpen (const char * application, const KeySet * defaultSpec, ElektraError ** error);
void elektraReload (Elektra * handle, ElektraError ** error);
void elektraParse (Elektra * handle, int argc, char ** argv, char ** environ); // pass environ?
void elektraDefault (Elektra * handle);
void elektraClose (Elektra * handle);
```

If `NULL` is passed as error, the API will try to continue if possible.
On fatal errors, i.e. on API misuse or when it is not safe to use the
handle afterwards, the API aborts with `exit`.

If you want to avoid `elektraOpen` or later `elektraReload` to fail, make
sure to use pass a `KeySet`, that has your whole specification included
(and defaults everywhere needed).

### Error Handling

```c
ElektraErrorCode elektraErrorCode (ElektraError * error);
const char * elektraErrorDescription (ElektraError * error);
ElektraErrorSeverity elektraErrorSeverity (ElektraError * error);
ElektraErrorGroup elektraErrorGroup (ElektraError * error);
ElektraErrorModule elektraErrorModule (ElektraError * error);
void elektraErrorFree (ElektraError * error);
```

`elektraErrorSeverity` tells you if you need to quit your application because of severe
issues that are permanent (severity == ELEKTRA_ERROR_SEVERITY_FATAL). Otherwise, developers can just print the message and
continue. (Default settings might be used then.)

### Simple Getters

(most of them needed for lcdproc)


```c
// getters
const char * elektraGetString (Elektra * elektra, const char * name);
kdb_boolean_t elektraGetBoolean (Elektra * elektra, const char * name);
kdb_char_t elektraGetChar (Elektra * elektra, const char * name);
kdb_octet_t elektraGetOctet (Elektra * elektra, const char * name);
kdb_short_t elektraGetShort (Elektra * elektra, const char * name);
kdb_unsigned_short_t elektraGetUnsignedShort (Elektra * elektra, const char * name);
kdb_long_t elektraGetLong (Elektra * elektra, const char * name);
kdb_unsigned_long_t elektraGetUnsignedLong (Elektra * elektra, const char * name);
kdb_long_long_t elektraGetLongLong (Elektra * elektra, const char * name);
kdb_unsigned_long_long_t elektraGetUnsignedLongLong (Elektra * elektra, const char * name);
kdb_float_t elektraGetFloat (Elektra * elektra, const char * name);
kdb_double_t elektraGetDouble (Elektra * elektra, const char * name);
kdb_long_double_t elektraGetLongDouble (Elektra * elektra, const char * name);
```

### Arrays

(needed for lcdproc)


```c
size_t elektraArraySize (Elektra * handle, const char * name);
const char * elektraGetStringArrayElement (Elektra * elektra, const char * name, size_t index);
// same types as above
```

## Code-Generation

(needed for lcdproc)


For every entry in the specification, such as:

```
[key]
default=10
type=long
```

The code generator yields:

- `kdb_long_t elektraGetKey(Elektra * handle);`
- a `KeySet` to be used as defaultSpec
- `elektraOpenOrgApplication()`

All spec keys together are part of the KeySet that is automatically applied
on failures in lower-level calls when using:
`elektraOpenOrgApplication()` where `OrgApplication` is the org and application name.

## Enum

In the specification:

```
[server/serverScreen]
check/enum/#0=off
check/enum/#1=on
check/enum/#2=blank
```

The code generator emits:

```
typedef enum
{
ELEKTRA_ENUM_SERVER_SERVERSCREEN_OFF = 0,
ELEKTRA_ENUM_SERVER_SERVERSCREEN_ON = 1,
ELEKTRA_ENUM_SERVER_SERVERSCREEN_BLANK = 2,
} ElektraEnumScreen;
```

Which can be used as:

```
ElektraEnumScreen elektraGetEnum(...);
```

```
[server]
define/type/serverscreenstatus
define/type/serverscreenstatus/check/enum/#0=off
define/type/serverscreenstatus/check/enum/#1=on
define/type/serverscreenstatus/check/enum/#2=blank
```

Then we can define:

```
[server/serverScreen]
type = serverscreenstatus
```

```
typedef enum
{
ELEKTRA_ENUM_SERVER_SERVERSCREEN_OFF = 0,
ELEKTRA_ENUM_SERVER_SERVERSCREEN_ON = 1,
ELEKTRA_ENUM_SERVER_SERVERSCREEN_BLANK = 2,
} ElektraEnumScreenStatus;
```

## Extensions

(not needed for lcdproc)

```c
// gives you a duplicate for other threads (same application+version), automatically calls elektraErrorClear
Elektra * elektraDup (Elektra * handle);
enum ElektraType
{
ELEKTRA_TYPE_BOOLEAN,
ELEKTRA_TYPE_NONE,
...
};
ElektraType elektraGetType (Elektra * handle);
KDB * elektraGetKDB (Elektra * handle);
KeySet * elektraGetKeySet (Elektra * handle, const char * cutkey);
KeySet * elektraGetKeyHierarchy (Elektra * handle, const char * cutkey);
// enum, int, tristate
void elektraSetInt (Elektra * handle, const char * name, int value);
```

### Lower-level type API

(not needed for lcdproc)

```c
// will be used internally in elektraGetInt, are for other APIs useful, too
int keyGetInt (Key * key);
// and so on
```

### recursive KeyHierarchy

(needed for lcdproc in a client)

A tree of `KeyHierarchy` elements, each element has a `Key` embedded.
Can be transformed from/to keysets.
With iterators to iterate over sub `KeyHierarchy` elements.

```c
keyhHasChildren (KeyHierarchy * kh);
// TODO, add rest of API
```

### todos

- const char * vs. string type?
- merging on conflicts? (maybe libelektra-tools dynamically loaded?)
- some API calls have a question mark next to it

## Rationale

1. Very easy to get started with, to get a key needs 3 lines of codes:
1. Very easy to get started with, to get a key needs 3 lines of codes (without error handling):

```c
Elektra *handle = elektraOpen ("/sw/elektra/kdb/#0/current", 0);
Oops, something went wrong.

0 comments on commit 6cadc5d

Please sign in to comment.