more code
This commit is contained in:
parent
f8c5a33d36
commit
7fcb2addfe
@ -4,20 +4,25 @@ FIND_PACKAGE(PkgConfig)
|
|||||||
|
|
||||||
PKG_CHECK_MODULES(JANSSON REQUIRED jansson)
|
PKG_CHECK_MODULES(JANSSON REQUIRED jansson)
|
||||||
PKG_CHECK_MODULES(GLIB2 REQUIRED glib-2.0)
|
PKG_CHECK_MODULES(GLIB2 REQUIRED glib-2.0)
|
||||||
|
PKG_CHECK_MODULES(GOBJECT2 REQUIRED gobject-2.0)
|
||||||
|
|
||||||
SET(SOURCES
|
SET(SOURCES
|
||||||
"src/journal/file.c"
|
"include/edapi/journal/entry.h"
|
||||||
"include/edapi/journal/file.h"
|
"include/edapi/journal/file.h"
|
||||||
|
"src/journal/entry.c"
|
||||||
|
"src/journal/file.c"
|
||||||
)
|
)
|
||||||
|
|
||||||
INCLUDE_DIRECTORIES(
|
INCLUDE_DIRECTORIES(
|
||||||
"include"
|
"include"
|
||||||
${GLIB2_INCLUDE_DIRS}
|
${GLIB2_INCLUDE_DIRS}
|
||||||
|
${GOBJECT2_INCLUDE_DIRS}
|
||||||
${JANSSON_INCLUDE_DIRS}
|
${JANSSON_INCLUDE_DIRS}
|
||||||
)
|
)
|
||||||
|
|
||||||
LINK_DIRECTORIES(
|
LINK_DIRECTORIES(
|
||||||
${GLIB2_LIBRARY_DIRS}
|
${GLIB2_LIBRARY_DIRS}
|
||||||
|
${GOBJECT2_LIBRARY_DIRS}
|
||||||
${JANSSON_LIBRARY_DIRS}
|
${JANSSON_LIBRARY_DIRS}
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -25,5 +30,9 @@ ADD_LIBRARY("edapi" SHARED ${SOURCES})
|
|||||||
TARGET_LINK_LIBRARIES(
|
TARGET_LINK_LIBRARIES(
|
||||||
"edapi"
|
"edapi"
|
||||||
${GLIB2_LIBRARIES}
|
${GLIB2_LIBRARIES}
|
||||||
|
${GOBJECT2_LIBRARIES}
|
||||||
${JANSSON_LIBRARIES}
|
${JANSSON_LIBRARIES}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
ENABLE_TESTING()
|
||||||
|
ADD_SUBDIRECTORY("tests")
|
||||||
|
25
lib/include/edapi/error.h
Normal file
25
lib/include/edapi/error.h
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
#ifndef EDAPI_ERROR_H
|
||||||
|
#define EDAPI_ERROR_H
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
ed_error_success = 0,
|
||||||
|
ed_error_args,
|
||||||
|
ed_error_invalid,
|
||||||
|
ed_error_internal,
|
||||||
|
ed_error_invalid_json,
|
||||||
|
} EDErrorCode;
|
||||||
|
|
||||||
|
#define ED_SUCCESS(r) ((r) == ed_error_success)
|
||||||
|
#define ED_ERROR(r) ((r) != ed_error_success)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Goes to label l if b is true.
|
||||||
|
*/
|
||||||
|
#define goto_if_true(b, l) do { if (b) goto l; } while(0)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Goes to label `l` if r is an error code.
|
||||||
|
*/
|
||||||
|
#define goto_if_error(r, l) do { if (ED_ERROR(r)) goto l; } while(0)
|
||||||
|
|
||||||
|
#endif
|
30
lib/include/edapi/journal/entry.h
Normal file
30
lib/include/edapi/journal/entry.h
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
#ifndef EDAPI_JOURNAL_ENTRY_H
|
||||||
|
#define EDAPI_JOURNAL_ENTRY_H
|
||||||
|
|
||||||
|
#include <edapi/error.h>
|
||||||
|
|
||||||
|
#include <glib.h>
|
||||||
|
#include <glib-object.h>
|
||||||
|
|
||||||
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
|
struct _EDJournalEntryClass {
|
||||||
|
GObjectClass parent_class;
|
||||||
|
|
||||||
|
gpointer padding[42];
|
||||||
|
};
|
||||||
|
|
||||||
|
G_DECLARE_DERIVABLE_TYPE(
|
||||||
|
EDJournalEntry, ed_journal_entry, ED, JOURNALENTRY, GObject);
|
||||||
|
|
||||||
|
#define ED_TYPE_JOURNALENTRY ed_journal_entry_get_type()
|
||||||
|
|
||||||
|
EDJournalEntry *ed_journal_entry_new(void);
|
||||||
|
|
||||||
|
EDErrorCode ed_journal_entry_parse(EDJournalEntry *self,
|
||||||
|
gchar const *line,
|
||||||
|
GError **error);
|
||||||
|
|
||||||
|
G_END_DECLS
|
||||||
|
|
||||||
|
#endif
|
@ -1,6 +1,8 @@
|
|||||||
#ifndef EDAPI_JOURNAL_FILE_H
|
#ifndef EDAPI_JOURNAL_FILE_H
|
||||||
#define EDAPI_JOURNAL_FILE_H
|
#define EDAPI_JOURNAL_FILE_H
|
||||||
|
|
||||||
|
#include <edapi/error.h>
|
||||||
|
|
||||||
#include <glib.h>
|
#include <glib.h>
|
||||||
#include <glib-object.h>
|
#include <glib-object.h>
|
||||||
|
|
||||||
@ -12,6 +14,10 @@ G_DECLARE_FINAL_TYPE(EDJournalFile, ed_journal_file, ED, JOURNALFILE, GObject);
|
|||||||
|
|
||||||
EDJournalFile *ed_journal_file_new(void);
|
EDJournalFile *ed_journal_file_new(void);
|
||||||
|
|
||||||
|
EDErrorCode ed_journal_file_parse(EDJournalFile *file, char const *filename);
|
||||||
|
|
||||||
|
EDErrorCode ed_journal_file_open(EDJournalFile *file, char const *filename);
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
9
lib/include/edapi/util.h
Normal file
9
lib/include/edapi/util.h
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
#ifndef EDAPI_UTIL_H
|
||||||
|
#define EDAPI_UTIL_H
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if a string pointer is NULL or empty
|
||||||
|
*/
|
||||||
|
#define S_EMPTY(s) ((s == NULL) || strlen(s) <= 0)
|
||||||
|
|
||||||
|
#endif
|
67
lib/src/journal/entry.c
Normal file
67
lib/src/journal/entry.c
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
#include <edapi/journal/entry.h>
|
||||||
|
#include <edapi/util.h>
|
||||||
|
|
||||||
|
#include <jansson.h>
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
json_t *entry;
|
||||||
|
} EDJournalEntryPrivate;
|
||||||
|
|
||||||
|
G_DEFINE_QUARK("ed-json-error", ed_json_error);
|
||||||
|
|
||||||
|
G_DEFINE_TYPE_EXTENDED(
|
||||||
|
EDJournalEntry,
|
||||||
|
ed_journal_entry,
|
||||||
|
G_TYPE_OBJECT,
|
||||||
|
0,
|
||||||
|
G_ADD_PRIVATE(EDJournalEntry)
|
||||||
|
);
|
||||||
|
|
||||||
|
static void ed_journal_entry_class_init(EDJournalEntryClass *klass)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ed_journal_entry_init(EDJournalEntry *self)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
EDJournalEntry *ed_journal_entry_new(void)
|
||||||
|
{
|
||||||
|
return g_object_new(
|
||||||
|
ED_TYPE_JOURNALENTRY,
|
||||||
|
NULL
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
EDErrorCode ed_journal_entry_parse(EDJournalEntry *self,
|
||||||
|
gchar const *line,
|
||||||
|
GError **error)
|
||||||
|
{
|
||||||
|
EDJournalEntryPrivate *p = ed_journal_entry_get_instance_private(self);
|
||||||
|
EDErrorCode ret = ed_error_invalid;
|
||||||
|
json_error_t e;
|
||||||
|
|
||||||
|
json_decref(p->entry);
|
||||||
|
p->entry = NULL;
|
||||||
|
|
||||||
|
memset(&e, 0, sizeof(e));
|
||||||
|
|
||||||
|
p->entry = json_loads(line, 0, &e);
|
||||||
|
if (p->entry == NULL) {
|
||||||
|
g_set_error(
|
||||||
|
error,
|
||||||
|
ed_json_error_quark(),
|
||||||
|
ed_error_invalid_json,
|
||||||
|
"%d: %d: %d: %s",
|
||||||
|
e.line,
|
||||||
|
e.column,
|
||||||
|
e.position,
|
||||||
|
e.text
|
||||||
|
);
|
||||||
|
ret = ed_error_invalid_json;
|
||||||
|
} else {
|
||||||
|
ret = ed_error_success;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
@ -1,8 +1,10 @@
|
|||||||
#include <edapi/journal/file.h>
|
#include <edapi/journal/file.h>
|
||||||
|
#include <edapi/util.h>
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
char *filename;
|
gchar *filename;
|
||||||
char *timestamp;
|
gchar *timestamp;
|
||||||
|
int index;
|
||||||
} EDJournalFilePrivate;
|
} EDJournalFilePrivate;
|
||||||
|
|
||||||
struct _EDJournalFile {
|
struct _EDJournalFile {
|
||||||
@ -13,11 +15,12 @@ struct _EDJournalFileClass {
|
|||||||
GObjectClass parent_class;
|
GObjectClass parent_class;
|
||||||
};
|
};
|
||||||
|
|
||||||
G_DEFINE_TYPE_EXTENDED(EDJournalFile,
|
G_DEFINE_TYPE_EXTENDED(
|
||||||
ed_journal_file,
|
EDJournalFile,
|
||||||
G_TYPE_OBJECT,
|
ed_journal_file,
|
||||||
0,
|
G_TYPE_OBJECT,
|
||||||
G_ADD_PRIVATE(EDJournalFile)
|
0,
|
||||||
|
G_ADD_PRIVATE(EDJournalFile)
|
||||||
);
|
);
|
||||||
|
|
||||||
static void ed_journal_file_finalize(GObject *obj)
|
static void ed_journal_file_finalize(GObject *obj)
|
||||||
@ -47,3 +50,67 @@ EDJournalFile *ed_journal_file_new(void)
|
|||||||
{
|
{
|
||||||
return g_object_new(ED_TYPE_JOURNALFILE, NULL);
|
return g_object_new(ED_TYPE_JOURNALFILE, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
EDErrorCode ed_journal_file_parse(EDJournalFile *file, char const *filename)
|
||||||
|
{
|
||||||
|
EDJournalFilePrivate *p = ed_journal_file_get_instance_private(file);
|
||||||
|
gchar *basename = NULL;
|
||||||
|
EDErrorCode ret = ed_error_internal;
|
||||||
|
|
||||||
|
GRegex *new_style = NULL;
|
||||||
|
GMatchInfo *matches = NULL;
|
||||||
|
|
||||||
|
gchar *timestamp = NULL;
|
||||||
|
gchar *index = NULL;
|
||||||
|
|
||||||
|
new_style = g_regex_new(
|
||||||
|
"Journal\\.([\\dT\\-]+)\\.(\\d+)\\.log",
|
||||||
|
0, 0, NULL
|
||||||
|
);
|
||||||
|
goto_if_true(new_style == NULL, done);
|
||||||
|
|
||||||
|
basename = g_path_get_basename(filename);
|
||||||
|
goto_if_true(S_EMPTY(basename), done);
|
||||||
|
|
||||||
|
if (g_regex_match(new_style, basename, 0, &matches)) {
|
||||||
|
timestamp = g_match_info_fetch(matches, 1);
|
||||||
|
index = g_match_info_fetch(matches, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
g_match_info_unref(matches);
|
||||||
|
matches = NULL;
|
||||||
|
|
||||||
|
goto_if_true(S_EMPTY(timestamp), done);
|
||||||
|
goto_if_true(S_EMPTY(index), done);
|
||||||
|
|
||||||
|
g_free(p->timestamp);
|
||||||
|
p->timestamp = g_strdup(timestamp);
|
||||||
|
|
||||||
|
p->index = strtol(index, NULL, 0);
|
||||||
|
|
||||||
|
g_free(p->filename);
|
||||||
|
p->filename = g_strdup(filename);
|
||||||
|
|
||||||
|
ret = ed_error_success;
|
||||||
|
|
||||||
|
done:
|
||||||
|
|
||||||
|
g_free(timestamp);
|
||||||
|
g_free(index);
|
||||||
|
g_free(basename);
|
||||||
|
g_regex_unref(new_style);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
EDErrorCode ed_journal_file_open(EDJournalFile *file, char const *filename)
|
||||||
|
{
|
||||||
|
EDErrorCode r = ed_error_success;
|
||||||
|
|
||||||
|
r = ed_journal_file_parse(file, filename);
|
||||||
|
if (ED_ERROR(r)) {
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
22
lib/tests/CMakeLists.txt
Normal file
22
lib/tests/CMakeLists.txt
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
CMAKE_MINIMUM_REQUIRED(VERSION 3.24)
|
||||||
|
|
||||||
|
PKG_CHECK_MODULES(CMOCKA REQUIRED cmocka)
|
||||||
|
|
||||||
|
SET(TESTS
|
||||||
|
"test-journal-file-parse"
|
||||||
|
)
|
||||||
|
|
||||||
|
INCLUDE_DIRECTORIES(
|
||||||
|
"${CMAKE_CURRENT_SOURCE_DIR}/../include"
|
||||||
|
"${CMOCKA_INCLUDE_DIRS}"
|
||||||
|
)
|
||||||
|
|
||||||
|
FOREACH(TEST ${TESTS})
|
||||||
|
ADD_EXECUTABLE(${TEST} "${TEST}.c")
|
||||||
|
TARGET_LINK_LIBRARIES(
|
||||||
|
"${TEST}"
|
||||||
|
"edapi"
|
||||||
|
${CMOCKA_LIBRARIES}
|
||||||
|
)
|
||||||
|
ADD_TEST(NAME ${TEST} COMMAND ${TEST})
|
||||||
|
ENDFOREACH()
|
30
lib/tests/test-journal-file-parse.c
Normal file
30
lib/tests/test-journal-file-parse.c
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
#include <stdarg.h>
|
||||||
|
#include <setjmp.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <cmocka.h>
|
||||||
|
|
||||||
|
#include <edapi/journal/file.h>
|
||||||
|
|
||||||
|
static void test_new_filename(void **state)
|
||||||
|
{
|
||||||
|
char const *filename = "Journal.2023-04-18T061507.01.log";
|
||||||
|
|
||||||
|
EDJournalFile *file = ed_journal_file_new();
|
||||||
|
EDErrorCode ret = 0;
|
||||||
|
|
||||||
|
assert_non_null(file);
|
||||||
|
|
||||||
|
ret = ed_journal_file_parse(file, filename);
|
||||||
|
assert_int_equal(ret, ed_error_success);
|
||||||
|
|
||||||
|
g_clear_object(&file);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int ac, char **av)
|
||||||
|
{
|
||||||
|
static const struct CMUnitTest tests[] = {
|
||||||
|
cmocka_unit_test(test_new_filename),
|
||||||
|
};
|
||||||
|
|
||||||
|
return cmocka_run_group_tests(tests, NULL, NULL);
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user