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

Modules & Logger #79

Draft
wants to merge 6 commits into
base: master
Choose a base branch
from
Draft
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
70 changes: 70 additions & 0 deletions parts/esp32-components/lifesensor_common/include/logger.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
#ifndef LIFESENSOR_COMMON_LOGGER_H
#define LIFESENSOR_COMMON_LOGGER_H

#include <stddef.h>

enum lifesensor_logger_scope_type {
LIFESENSOR_LOGGER_SCOPE_NONE,
LIFESENSOR_LOGGER_SCOPE_LIST,
LIFESENSOR_LOGGER_SCOPE_MAP
};

struct lifesensor_logger_scope {
int (*printf)(const char *fmt, ...);
enum lifesensor_logger_scope_type type;
size_t entries;
size_t level;
};
typedef struct lifesensor_logger_scope Lifesensor_logger_scope;

struct lifesensor_logger {
void (*enter_map)(
struct lifesensor_logger_scope* scope,
struct lifesensor_logger_scope* subscope,
char *name
);
void (*enter_list)(
struct lifesensor_logger_scope* scope,
struct lifesensor_logger_scope* subscope,
char *name
);
void (*exit)(
struct lifesensor_logger_scope* scope,
struct lifesensor_logger_scope* subscope
);

void (*log_uint)(
struct lifesensor_logger_scope* scope,
unsigned long int value,
char *name
);
void (*log_int)(
struct lifesensor_logger_scope* scope,
long int value,
char *name
);
void (*log_float)(
struct lifesensor_logger_scope* scope,
float value,
char *name
);
void (*log_char)(
struct lifesensor_logger_scope* scope,
char value,
char *name
);
void (*log_str)(
struct lifesensor_logger_scope* scope,
char *value,
char *name
);
void (*log_ptr)(
struct lifesensor_logger_scope* scope,
void *value,
char *name
);
};
typedef struct lifesensor_logger Lifesensor_logger;


#endif
12 changes: 12 additions & 0 deletions parts/esp32-components/lifesensor_common/include/logger_json.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#ifndef LIFESENSOR_COMMON_LOGGER_JSON_H
#define LIFESENSOR_COMMON_LOGGER_JSON_H

#include "logger.h"

void
lifesensor_logger_json_init(
Lifesensor_logger *logger,
Lifesensor_logger_scope *scope,
int (*printf)(const char *fmt, ...));

#endif
12 changes: 12 additions & 0 deletions parts/esp32-components/lifesensor_common/include/logger_yaml.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#ifndef LIFESENSOR_COMMON_LOGGER_YAML_H
#define LIFESENSOR_COMMON_LOGGER_YAML_H

#include "logger.h"

void
lifesensor_logger_yaml_init(
Lifesensor_logger *logger,
Lifesensor_logger_scope *scope,
int (*printf)(const char *fmt, ...));

#endif
177 changes: 177 additions & 0 deletions parts/esp32-components/lifesensor_common/include/macro/map.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,177 @@
#ifndef LIFESENSOR_COMMON_MAP_H
#define LIFESENSOR_COMMON_MAP_H

/**
* macro _MAP_EVAL*(...)
* these macros let the preprocessor expand the inital arguments multiple times,
* which results in multiple evaluation runs of the initial arguments.
*/
#define _MAP_EVAL1(...) __VA_ARGS__
#define _MAP_EVAL2(...) _MAP_EVAL1(_MAP_EVAL1(__VA_ARGS__))
#define _MAP_EVAL4(...) _MAP_EVAL2(_MAP_EVAL2(__VA_ARGS__))
#define _MAP_EVAL16(...) _MAP_EVAL4(_MAP_EVAL4(__VA_ARGS__))
#define _MAP_EVAL256(...) _MAP_EVAL16(_MAP_EVAL16(__VA_ARGS__))

/**
* macro _MAP_NOP
* this macro expands to nothing and can be used to break up another macro from
* its arguments to stop the preprocessor from expanding the macro.
*/
#define _MAP_NOP /*empty*/

/**
* macros _MAP_POP{0,1}(F, X, ...)
* these macros are called as _MAP_POP{0,1}(F, ...) and take the first argument
* of the variadic arguments and apply the function F to it.
* If any variadic arguments remain they call their sibling macro which does
* the same. The use of the sibling and _MAP_NOP macro ensures that the
* preprocessor does not detect a recursion call and stops processing.
*/
#define _MAP_POP0(F, X, ...) \
F(X) \
__VA_OPT__(, _MAP_POP1 _MAP_NOP(F, __VA_ARGS__))
#define _MAP_POP1(F, X, ...) \
F(X) \
__VA_OPT__(, _MAP_POP0 _MAP_NOP(F, __VA_ARGS__))

/**
* macro MAP(F, ...)
* Maps the function F to each of the variadic arguments and uses a comma as
* delimiter.
* I.e. MAP(F,1,2,3) results in F(1), F(2), F(3)
*/
#define MAP(F, ...) __VA_OPT__(_MAP_EVAL256(_MAP_POP0(F, __VA_ARGS__)))

/**
* see _MAP_POP{0,1}
*/
#define _MAP1_POP0(F, P0, X, ...) \
F(P0, X) \
__VA_OPT__(, _MAP1_POP1 _MAP_NOP(F, P0, __VA_ARGS__))
#define _MAP1_POP1(F, P0, X, ...) \
F(P0, X) \
__VA_OPT__(, _MAP1_POP0 _MAP_NOP(F, P0, __VA_ARGS__))

/**
* macro MAP1(F, P0, ...)
* Maps the parameterized function F to each of the variadic arguments
* and uses a comma as delimiter.
* I.e. MAP1(F,A,1,2,3) results in F(A,1), F(A,2), F(A,3)
*/
#define MAP1(F, P0, ...) \
__VA_OPT__(_MAP_EVAL256(_MAP1_POP0(F, P0, __VA_ARGS__)))

/**
* see _MAP_POP{0,1}
*/
#define _MAP2_POP0(F, P0, P1, X, ...) \
F(P0, P1, X) \
__VA_OPT__(, _MAP2_POP1 _MAP_NOP(F, P0, P1, __VA_ARGS__))
#define _MAP2_POP1(F, P0, P1, X, ...) \
F(P0, P1, X) \
__VA_OPT__(, _MAP2_POP0 _MAP_NOP(F, P0, P1, __VA_ARGS__))

/**
* macro MAP2(F, P0, P1, ...)
* Maps the parameterized function F to each of the variadic arguments
* and uses a comma as delimiter.
* I.e. MAP2(F,A,B,1,2,3) results in F(A,B,1), F(A,B,2), F(A,B,3)
*/
#define MAP2(F, P0, P1, ...) \
__VA_OPT__(_MAP_EVAL256(_MAP2_POP0(F, P0, P1, __VA_ARGS__)))

/**
* see _MAP_POP{0,1}
*/
#define _MAP3_POP0(F, P0, P1, P2, X, ...) \
F(P0, P1, P2, X) \
__VA_OPT__(, _MAP3_POP1 _MAP_NOP(F, P0, P1, P2, __VA_ARGS__))
#define _MAP3_POP1(F, P0, P1, P2, X, ...) \
F(P0, P1, P2, X) \
__VA_OPT__(, _MAP3_POP0 _MAP_NOP(F, P0, P1, P2, __VA_ARGS__))

/**
* macro MAP3(F, P0, P1, P2, ...)
* Maps the parameterized function F to each of the variadic arguments
* and uses a comma as delimiter.
* I.e. MAP3(F,A,B,C,1,2,3) results in F(A,B,C,1), F(A,B,C,2), F(A,B,C,3)
*/
#define MAP3(F, P0, P1, P2, ...) \
__VA_OPT__(_MAP_EVAL256(_MAP3_POP0(F, P0, P1, P2, __VA_ARGS__)))

/**
* see _MAP_POP{0,1}
*/
#define _MAPD_POP0(D, F, X, ...) \
F(X) \
__VA_OPT__(D _MAPD_POP1 _MAP_NOP(D, F, __VA_ARGS__))
#define _MAPD_POP1(D, F, X, ...) \
F(X) \
__VA_OPT__(D _MAPD_POP0 _MAP_NOP(D, F, __VA_ARGS__))

/**
* macro MAP(D, F, ...)
* Maps the function F to each of the variadic arguments and uses D as
* delimiter.
* I.e. MAP(+,F,1,2,3) results in F(1) + F(2) + F(3)
*/
#define MAPD(D, F, ...) __VA_OPT__(_MAP_EVAL256(_MAPD_POP0(D, F, __VA_ARGS__)))

/**
* see _MAP_POP{0,1}
*/
#define _MAPD1_POP0(D, F, P0, X, ...) \
F(P0, X) \
__VA_OPT__(D _MAPD1_POP1 _MAP_NOP(D, F, P0, __VA_ARGS__))
#define _MAPD1_POP1(D, F, P0, X, ...) \
F(P0, X) \
__VA_OPT__(D _MAPD1_POP0 _MAP_NOP(D, F, P0, __VA_ARGS__))

/**
* macro MAPD1(D, F, P0, ...)
* Maps the parameterized function F to each of the variadic arguments
* and uses D as delimiter.
* I.e. MAPD1(+,F,A,1,2,3) results in F(A,1) + F(A,2) + F(A,3)
*/
#define MAPD1(D, F, P0, ...) \
__VA_OPT__(_MAP_EVAL256(_MAPD1_POP0(D, F, P0, __VA_ARGS__)))

/**
* see _MAP_POP{0,1}
*/
#define _MAPD2_POP0(D, F, P0, P1, X, ...) \
F(P0, P1, X) \
__VA_OPT__(D _MAPD2_POP1 _MAP_NOP(D, F, P0, P1, __VA_ARGS__))
#define _MAPD2_POP1(D, F, P0, P1, X, ...) \
F(P0, P1, X) \
__VA_OPT__(D _MAPD2_POP0 _MAP_NOP(D, F, P0, P1, __VA_ARGS__))

/**
* macro MAPD2(D, F, P0, P1, ...)
* Maps the parameterized function F to each of the variadic arguments
* and uses D as delimiter.
* I.e. MAPD2(+,F,A,B,1,2,3) results in F(A,B,1) + F(A,B,2) + F(A,B,3)
*/
#define MAPD2(D, F, P0, P1, ...) \
__VA_OPT__(_MAP_EVAL256(_MAPD2_POP0(D, F, P0, P1, __VA_ARGS__)))

/**
* see _MAP_POP{0,1}
*/
#define _MAPD3_POP0(D, F, P0, P1, P2, X, ...) \
F(P0, P1, P2, X) \
__VA_OPT__(D _MAPD3_POP1 _MAP_NOP(D, F, P0, P1, P2, __VA_ARGS__))
#define _MAPD3_POP1(D, F, P0, P1, P2, X, ...) \
F(P0, P1, P2, X) \
__VA_OPT__(D _MAPD3_POP0 _MAP_NOP(D, F, P0, P1, P2, __VA_ARGS__))

/**
* macro MAPD3(D, F, P0, P1, P2, ...)
* Maps the parameterized function F to each of the variadic arguments
* and uses D as delimiter.
* I.e. MAPD3(+,F,A,B,C,1,2,3) results in F(A,B,C,1) + F(A,B,C,2) + F(A,B,C,3)
*/
#define MAPD3(D, F, P0, P1, P2, ...) \
__VA_OPT__(_MAP_EVAL256(_MAPD3_POP0(D, F, P0, P1, P2, __VA_ARGS__)))

#endif
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#ifndef LIFESENSOR_COMMON_STATIC_ALLOC_H
#define LIFESENSOR_COMMON_STATIC_ALLOC_H

#define STATIC_ALLOC(TYPE, SIZE, ...) (TYPE[SIZE]){__VA_ARGS__}

#endif
35 changes: 35 additions & 0 deletions parts/esp32-components/lifesensor_common/include/module.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
#ifndef LIFESENSOR_COMMON_MODULE_H
#define LIFESENSOR_COMMON_MODULE_H

#include "logger.h"
#include "macro/map.h"
#include <stddef.h>

#define INIT_LIFESENSOR_MODULE(TYPE, NAME, INIT, DUMP, /* SUBMODULES */...) \
{ \
.parent = NULL, \
.type = #TYPE, \
.name = (NAME), \
.init = (INIT), \
.dump = (DUMP), \
.submodule_offsets = (ptrdiff_t[]){__VA_OPT__(MAP1(offsetof, TYPE, __VA_ARGS__), ) 0}, \
}

struct lifesensor_module
{
struct lifesensor_module *parent;
char *name;
char *type;
void (*dump)(
struct lifesensor_module *module,
Lifesensor_logger *logger,
Lifesensor_logger_scope *scope);
void (*init)(
struct lifesensor_module *module);
ptrdiff_t *submodule_offsets;
};
typedef struct lifesensor_module Lifesensor_module;

void lifesensor_module_init(Lifesensor_module *module);
void lifesensor_module_dump(Lifesensor_module *module, Lifesensor_logger *logger, Lifesensor_logger_scope *scope);
#endif
Loading