🎉 ✨ project structure and some usefull functions.
parent
7cfcf55988
commit
93b7231bb1
|
@ -0,0 +1,4 @@
|
|||
build
|
||||
.cache
|
||||
*~*
|
||||
*\#*
|
|
@ -0,0 +1,13 @@
|
|||
cmake_minimum_required(VERSION 3.29)
|
||||
|
||||
project(moka)
|
||||
|
||||
set(CMAKE_EXPORT_COMPILE_COMMANDS On)
|
||||
|
||||
add_subdirectory(lib)
|
||||
add_subdirectory(src)
|
||||
add_subdirectory(tests)
|
||||
|
||||
set_property(TARGET moka-core PROPERTY C_STANDARD 99)
|
||||
set_property(TARGET moka-tests PROPERTY C_STANDARD 99)
|
||||
set_property(TARGET moka PROPERTY C_STANDARD 99)
|
|
@ -0,0 +1,18 @@
|
|||
.PHONY: build check install tests
|
||||
|
||||
build:
|
||||
cmake -B build
|
||||
cmake --build build
|
||||
|
||||
tests: build
|
||||
@build/tests/moka-tests \
|
||||
&& echo -e "\e[32m=== All tests passed ===\e[0m" \
|
||||
|| echo -e "\e[31m=== Some tests failed ===\e[0m"
|
||||
|
||||
install: tests
|
||||
sudo cmake --install build
|
||||
|
||||
check:
|
||||
@cppcheck --enable=all -q lib src tests \
|
||||
--suppress=missingIncludeSystem \
|
||||
--suppress=unusedFunction
|
|
@ -0,0 +1,19 @@
|
|||
cmake_minimum_required(VERSION 3.29)
|
||||
|
||||
project(moka-lib)
|
||||
|
||||
add_library(moka-core
|
||||
commons.c
|
||||
status.c
|
||||
vec.c
|
||||
str.c
|
||||
)
|
||||
|
||||
target_compile_options(moka-core
|
||||
PUBLIC -Wall -Wextra
|
||||
)
|
||||
|
||||
target_include_directories(moka-core
|
||||
PUBLIC ${CMAKE_SOURCE_DIR}/lib
|
||||
)
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
#include "commons.h"
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
#ifndef MK_COMMON_H
|
||||
#define MK_COMMON_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#define MK_STRLEN 4096
|
||||
#define MK_ENUM_ENUM(X) X
|
||||
#define MK_ENUM_STRING(X) #X
|
||||
|
||||
#define MK_ENUM_H(PREFIX, DEF) \
|
||||
typedef enum {DEF(MK_ENUM_ENUM)} PREFIX; \
|
||||
extern char const* PREFIX ## Str []
|
||||
|
||||
#define MK_ENUM_C(PREFIX, DEF) \
|
||||
char const* PREFIX ## Str [] = {DEF(MK_ENUM_STRING)}
|
||||
|
||||
#endif
|
|
@ -0,0 +1,83 @@
|
|||
#include "status.h"
|
||||
|
||||
MK_ENUM_C(Status, STATUS_KIND);
|
||||
|
||||
void message_init(struct message* self,
|
||||
Status kind,
|
||||
char const* what)
|
||||
{
|
||||
assert(self);
|
||||
assert(what);
|
||||
|
||||
self->kind = kind;
|
||||
self->what = strdup(what);
|
||||
}
|
||||
|
||||
void message_free(struct message* self)
|
||||
{
|
||||
assert(self);
|
||||
free(self->what);
|
||||
}
|
||||
|
||||
void status_init(struct status* self)
|
||||
{
|
||||
assert(self);
|
||||
vec_init(&self->messages);
|
||||
}
|
||||
|
||||
void status_free(struct status* self)
|
||||
{
|
||||
assert(self);
|
||||
vec_free_elements(&self->messages, (void*) message_free);
|
||||
vec_free(&self->messages);
|
||||
}
|
||||
void status_push(struct status* self,
|
||||
Status kind,
|
||||
char const* format,
|
||||
...)
|
||||
{
|
||||
char msg[MK_STRLEN];
|
||||
va_list lst;
|
||||
va_start(lst, format);
|
||||
|
||||
vsnprintf(msg, MK_STRLEN, format, lst);
|
||||
|
||||
struct message* message = malloc(sizeof(struct message));
|
||||
message_init(message, kind, msg);
|
||||
|
||||
vec_push(&self->messages, message);
|
||||
va_end(lst);
|
||||
}
|
||||
|
||||
void status_dump(struct status* self)
|
||||
{
|
||||
assert(self);
|
||||
|
||||
for (size_t i=0; i<self->messages.size; i++)
|
||||
{
|
||||
struct message const* msg = self->messages.data[i];
|
||||
|
||||
printf("%s| %s\n",
|
||||
StatusStr[msg->kind] + strlen("STATUS_"),
|
||||
msg->what
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
bool status_is_ok(struct status* self)
|
||||
{
|
||||
assert(self);
|
||||
|
||||
for (size_t i=0; i<self->messages.size; i++)
|
||||
{
|
||||
struct message const* m = self->messages.data[i];
|
||||
|
||||
if (m->kind == STATUS_ERROR)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
#ifndef MK_STATUS_H
|
||||
#define MK_STATUS_H
|
||||
|
||||
#include "commons.h"
|
||||
#include "vec.h"
|
||||
|
||||
#define STATUS_KIND(G) \
|
||||
G(STATUS_ERROR),\
|
||||
G(STATUS_WARNING)
|
||||
|
||||
MK_ENUM_H(Status, STATUS_KIND);
|
||||
|
||||
struct message
|
||||
{
|
||||
Status kind;
|
||||
char* what;
|
||||
};
|
||||
|
||||
struct status
|
||||
{
|
||||
struct vec messages;
|
||||
};
|
||||
|
||||
void message_init(struct message* self,
|
||||
Status kind,
|
||||
char const* what);
|
||||
void message_free(struct message* self);
|
||||
|
||||
void status_init(struct status* self);
|
||||
void status_free(struct status* self);
|
||||
|
||||
void status_push(struct status* self,
|
||||
Status kind,
|
||||
char const* format,
|
||||
...);
|
||||
|
||||
void status_dump(struct status* self);
|
||||
|
||||
bool status_is_ok(struct status* self);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,70 @@
|
|||
#include "str.h"
|
||||
|
||||
void str_init(struct str* self)
|
||||
{
|
||||
assert(self);
|
||||
self->size = 0;
|
||||
self->capacity = 0;
|
||||
self->value = NULL;
|
||||
}
|
||||
|
||||
void str_free(struct str* self)
|
||||
{
|
||||
assert(self);
|
||||
free(self->value);
|
||||
self->value = NULL;
|
||||
self->size = 0;
|
||||
self->capacity = 0;
|
||||
}
|
||||
|
||||
void str_push(struct str* self, char element)
|
||||
{
|
||||
assert(self);
|
||||
|
||||
if (self->capacity == 0)
|
||||
{
|
||||
self->capacity = 1;
|
||||
self->value = calloc(self->capacity, sizeof(char));
|
||||
}
|
||||
|
||||
if (self->size + 2 >= self->capacity)
|
||||
{
|
||||
self->capacity *= 2;
|
||||
char* data = realloc(self->value, sizeof(char) * self->capacity);
|
||||
assert(data);
|
||||
self->value = data;
|
||||
}
|
||||
|
||||
self->value[self->size] = element;
|
||||
self->size++;
|
||||
self->value[self->size] = '\0';
|
||||
}
|
||||
|
||||
void str_extend(struct str* self, char const* rhs)
|
||||
{
|
||||
assert(self);
|
||||
assert(rhs);
|
||||
|
||||
size_t sz = strlen(rhs);
|
||||
|
||||
for (size_t i=0; i<sz; i++)
|
||||
{
|
||||
str_push(self, rhs[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void str_format(struct str* self, char const* format, ...)
|
||||
{
|
||||
assert(self);
|
||||
assert(format);
|
||||
char buffer[MK_STRLEN];
|
||||
|
||||
va_list lst;
|
||||
va_start(lst, format);
|
||||
|
||||
vsnprintf(buffer, MK_STRLEN, format, lst);
|
||||
|
||||
va_end(lst);
|
||||
|
||||
str_extend(self, buffer);
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
#ifndef MK_STR_H
|
||||
#define MK_STR_H
|
||||
|
||||
#include "commons.h"
|
||||
#include "vec.h"
|
||||
|
||||
struct str
|
||||
{
|
||||
size_t size;
|
||||
size_t capacity;
|
||||
char* value;
|
||||
};
|
||||
|
||||
void str_init(struct str* self);
|
||||
void str_free(struct str* self);
|
||||
|
||||
void str_push(struct str* self, char element);
|
||||
void str_extend(struct str* self, char const* rhs);
|
||||
void str_format(struct str* self, char const* format, ...);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,67 @@
|
|||
#include "vec.h"
|
||||
|
||||
void vec_init(struct vec* self)
|
||||
{
|
||||
assert(self);
|
||||
self->capacity = 0;
|
||||
self->size = 0;
|
||||
self->data = NULL;
|
||||
}
|
||||
|
||||
void vec_free_elements(struct vec* self, void (*func)(void*))
|
||||
{
|
||||
assert(self);
|
||||
|
||||
for (size_t i=0; i<self->size; i++)
|
||||
{
|
||||
if (func != NULL)
|
||||
{
|
||||
func(self->data[i]);
|
||||
}
|
||||
|
||||
free(self->data[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void vec_free(struct vec* self)
|
||||
{
|
||||
assert(self);
|
||||
free(self->data);
|
||||
self->data = NULL;
|
||||
self->size = 0;
|
||||
self->capacity = 0;
|
||||
}
|
||||
|
||||
void vec_push(struct vec* self, void* element)
|
||||
{
|
||||
assert(self);
|
||||
assert(element);
|
||||
|
||||
if (self->capacity == 0)
|
||||
{
|
||||
self->capacity = 1;
|
||||
self->data = calloc(self->capacity, sizeof(void*));
|
||||
}
|
||||
else if (self->size + 1 >= self->capacity)
|
||||
{
|
||||
self->capacity *= 2;
|
||||
void** data = realloc(
|
||||
self->data,
|
||||
self->capacity * sizeof(void*)
|
||||
);
|
||||
assert(data);
|
||||
self->data = data;
|
||||
}
|
||||
|
||||
self->data[self->size] = element;
|
||||
self->size++;
|
||||
}
|
||||
|
||||
void* vec_pop(struct vec* self)
|
||||
{
|
||||
assert(self);
|
||||
assert(self->size > 0);
|
||||
void* element = self->data[self->size - 1];
|
||||
self->size--;
|
||||
return element;
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
#ifndef MK_VEC_H
|
||||
#define MK_VEC_H
|
||||
|
||||
#include "commons.h"
|
||||
|
||||
struct vec
|
||||
{
|
||||
size_t capacity;
|
||||
size_t size;
|
||||
void** data;
|
||||
};
|
||||
|
||||
void vec_init(struct vec* self);
|
||||
void vec_free_elements(struct vec* self, void (*func)(void*));
|
||||
void vec_free(struct vec* self);
|
||||
|
||||
void vec_push(struct vec* self, void* element);
|
||||
void* vec_pop(struct vec* self);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,15 @@
|
|||
cmake_minimum_required(VERSION 3.29)
|
||||
|
||||
project(moka-bin)
|
||||
|
||||
add_executable(moka
|
||||
main.c
|
||||
)
|
||||
|
||||
install(TARGETS moka)
|
||||
|
||||
add_dependencies(moka moka-core)
|
||||
|
||||
target_link_libraries(moka
|
||||
moka-core
|
||||
)
|
|
@ -0,0 +1,4 @@
|
|||
int main()
|
||||
{
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
cmake_minimum_required(VERSION 3.29)
|
||||
|
||||
project(moka-tests)
|
||||
|
||||
|
||||
add_executable(moka-tests
|
||||
main.c
|
||||
)
|
||||
|
||||
find_package(PkgConfig REQUIRED)
|
||||
pkg_check_modules(CHECK check REQUIRED IMPORTED_TARGET)
|
||||
|
||||
add_dependencies(moka-tests moka-core)
|
||||
|
||||
target_link_libraries(moka-tests
|
||||
moka-core
|
||||
PkgConfig::CHECK
|
||||
)
|
|
@ -0,0 +1,16 @@
|
|||
#include <commons.h>
|
||||
#include <check.h>
|
||||
|
||||
|
||||
int main()
|
||||
{
|
||||
Suite* s = suite_create("Moka Frontend");
|
||||
|
||||
|
||||
SRunner* runner = srunner_create(s);
|
||||
srunner_run_all(runner, CK_VERBOSE);
|
||||
int failed = srunner_ntests_failed(runner);
|
||||
srunner_free(runner);
|
||||
|
||||
return (failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
|
||||
}
|
Loading…
Reference in New Issue