Skip to content

Commit

Permalink
Merge pull request #6 from Ajatt-Tools/refactor
Browse files Browse the repository at this point in the history
Refactor
  • Loading branch information
btrkeks authored May 3, 2024
2 parents 9715a7c + e253c4f commit 00d02f3
Show file tree
Hide file tree
Showing 35 changed files with 2,783 additions and 3,391 deletions.
11 changes: 11 additions & 0 deletions .clang-format
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
BinPackArguments: true
BreakStringLiterals: false
ColumnLimit: 100
IndentCaseLabels: true
IndentPPDirectives: BeforeHash
IndentWidth: 4
PenaltyBreakComment: 0
SortIncludes: true
SpaceBeforeParens: ControlStatementsExceptForEachMacros
UseTab: Never
AllowShortFunctionsOnASingleLine: None
95 changes: 73 additions & 22 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -8,25 +8,28 @@ IDIR=include
SDIR=src
LDIR=lib

CPPFLAGS=-D_POSIX_C_SOURCE=200809L -DNOTIFICATIONS -I$(IDIR)
LDLIBS=-ffunction-sections -fdata-sections -Wl,--gc-sections \
-lcurl -lmecab -pthread $(shell pkg-config --libs gtk+-3.0) \
$(shell pkg-config --libs libnotify) -llmdb -lglib-2.0
CPPFLAGS += -D_POSIX_C_SOURCE=200809L -DNOTIFICATIONS -I$(IDIR)
LDLIBS += -ffunction-sections -fdata-sections -Wl,--gc-sections \
-lcurl -lmecab -pthread $(shell pkg-config --libs gtk+-3.0) $(shell pkg-config --libs libnotify) -llmdb

O_HAVEX11 := 1 # X11 integration
ifeq ($(strip $(O_HAVEX11)),1)
CPPFLAGS += -DHAVEX11
LDLIBS += -lXfixes -lX11
endif

CFLAGS= ${CPPFLAGS} $(shell pkg-config --cflags gtk+-3.0) $(shell pkg-config --cflags libnotify)
DEBUG_CFLAGS=-DDEBUG -g3 -Wall -Wextra -Wpedantic -Wstrict-prototypes -Wdouble-promotion -Wshadow \
-Wno-unused-parameter -Wno-sign-conversion -Wno-unused-function \
-fsanitize=undefined,address -fsanitize-undefined-trap-on-error
CFLAGS := -Werror $(shell pkg-config --cflags gtk+-3.0) $(shell pkg-config --cflags libnotify) $(CFLAGS)
DEBUG_CFLAGS=-DDEBUG \
-Wall -Wextra -Wpedantic -Wstrict-prototypes -Wdouble-promotion -Wshadow \
-Wno-unused-parameter -Wno-sign-conversion -Wno-unused-function -Wpointer-arith \
-Wmissing-prototypes -Wstrict-prototypes -Wstrict-overflow -Wcast-align \
-Wno-maybe-uninitialized \
-fsanitize=leak,address,undefined -fsanitize-undefined-trap-on-error -fstack-protector-strong \
-Og -ggdb
RELEASE_CFLAGS=-O3 -flto -march=native

FILES=gtk3popup.c util.c platformdep.c deinflector.c settings.c dbreader.c ankiconnectc.c database.c jppron.c pdjson.c
FILES_H=ankiconnectc.h dbreader.h deinflector.h gtk3popup.h settings.h util.h platformdep.h database.h jppron.h pdjson.h
FILES=dictpopup.c util.c platformdep.c deinflector.c settings.c db.c ankiconnectc.c database.c jppron.c pdjson.c
FILES_H=ankiconnectc.h db.h deinflector.h settings.h util.h platformdep.h database.h jppron.h pdjson.h
SRC=$(addprefix $(SDIR)/,$(FILES))
SRC_H=$(addprefix $(IDIR)/,$(FILES_H))

Expand All @@ -35,24 +38,25 @@ CFLAGS_CREATE=-I$(IDIR) -isystem$(LIBDIR)/lmdb/libraries/liblmdb -D_POSIX_C_SOUR
LDLIBS_CREATE=-ffunction-sections -fdata-sections -Wl,--gc-sections \
-lzip $(shell pkg-config --libs glib-2.0) -llmdb

FILES_CREATE=dbwriter.c pdjson.c util.c settings.c
FILES_H_CREATE=dbwriter.h pdjson.h util.h buf.h settings.h
FILES_CREATE=db.c pdjson.c util.c settings.c
FILES_H_CREATE=db.h pdjson.h util.h buf.h settings.h

SRC_CREATE=$(addprefix $(SDIR)/,$(FILES_CREATE)) $(LMDB_FILES)
SRC_H_CREATE=$(addprefix $(IDIR)/,$(FILES_H_CREATE))

default: dictpopup dictpopup-create
debug: dictpopup-debug dictpopup-create-debug
bins := dictpopup dictpopup-create

all: $(bins)
all: CFLAGS+=$(RELEASE_CFLAGS)

debug: $(bins)
debug: CFLAGS+=$(DEBUG_CFLAGS)

dictpopup: $(SRC) $(SRC_H)
$(CC) $(CFLAGS) $(RELEASE_CFLAGS) -o $@ src/dictpopup.c $(SRC) $(LDLIBS)
dictpopup-debug: $(SRC) $(SRC_H)
$(CC) $(CFLAGS) $(DEBUG_CFLAGS) -o $@ src/dictpopup.c $(SRC) $(LDLIBS)
$(CC) $(CFLAGS) $(CPPFLAGS) -o $@ src/gtk3popup.c $(SRC) $(LDLIBS)

dictpopup-create: $(SRC_CREATE) $(SRC_H_CREATE)
$(CC) $(CFLAGS_CREATE) $(RELEASE_CFLAGS) -o $@ src/dictpopup_create.c $(SRC_CREATE) $(LDLIBS_CREATE)
dictpopup-create-debug: $(SRC_CREATE) $(SRC_H_CREATE)
$(CC) $(CFLAGS_CREATE) $(DEBUG_CFLAGS) -o $@ src/dictpopup_create.c $(SRC_CREATE) $(LDLIBS_CREATE)
$(CC) $(CFLAGS_CREATE) -o $@ src/dictpopup_create.c $(SRC_CREATE) $(LDLIBS_CREATE)

release:
version=$$(git describe); prefix=dictpopup-$${version#v}; \
Expand Down Expand Up @@ -83,12 +87,59 @@ uninstall:
$(CONFIG_DIR)/config.ini

clean:
rm -f dictpopup dictpopup-create dictpopup-debug dictpopup-create-debug tests
rm -f dictpopup dictpopup-create tests

tests: $(SRC) $(SRC_H)
$(CC) $(CFLAGS) $(DEBUG_CFLAGS) -o $@ $(SDIR)/test.c $(SRC) $(LDLIBS)

check test: tests
./tests

.PHONY: all clean install uninstall tests debug

c_analyse_targets := $(SRC:%=%-analyse)
c_analyse_targets := $(filter-out src/pdjson.c-analyse, $(c_analyse_targets))

h_analyse_targets := $(SRC_H:%=%-analyse)

analyse: CFLAGS+=$(DEBUG_CFLAGS)
analyse: $(c_analyse_targets) $(h_analyse_targets)

$(c_analyse_targets): %-analyse:
echo "$(c_analyse_targets)"
# -W options here are not clang compatible, so out of generic CFLAGS
gcc $< -o /dev/null -c \
-std=gnu99 -Ofast -fwhole-program -Wall -Wextra \
-Wlogical-op -Wduplicated-cond \
-fanalyzer $(CFLAGS) $(CPPFLAGS) $(LDFLAGS) $(LDLIBS)
clang $< -o /dev/null -c -std=gnu99 -Ofast -Weverything \
-Wno-documentation-unknown-command \
-Wno-language-extension-token \
-Wno-disabled-macro-expansion \
-Wno-padded \
-Wno-covered-switch-default \
-Wno-gnu-zero-variadic-macro-arguments \
-Wno-declaration-after-statement \
-Wno-cast-qual \
-Wno-unused-command-line-argument \
$(extra_clang_flags) \
$(CFLAGS) $(CPPFLAGS) $(LDFLAGS) $(LDLIBS)
$(MAKE) $*-shared-analyse

$(h_analyse_targets): %-analyse:
$(MAKE) $*-shared-analyse

%-shared-analyse: %
# cppcheck is a bit dim about unused functions/variables, leave that to
# clang/GCC
cppcheck $< -I$(IDIR) --library=gtk.cfg --library=gnu.cfg \
--std=c99 --quiet --inline-suppr --force \
--enable=all --suppress=missingIncludeSystem \
--suppress=unusedFunction --suppress=unmatchedSuppression \
--suppress=unreadVariable --suppress=constParameterCallback \
--max-ctu-depth=32 --error-exitcode=1
# clang-analyzer-unix.Malloc does not understand _drop_()
clang-tidy $< --quiet -checks=-clang-analyzer-unix.Malloc -- -std=gnu99 -I$(IDIR) $(shell pkg-config --cflags gtk+-3.0)
clang-format --dry-run --Werror $<


.PHONY: all clean install uninstall tests debug analyze
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ This will allow for a faster lookup.

## Usage
Select a word and call `dictpopup` (using a shortcut). It is also possible to give an argument instead: `dictpopup WORD`.
If something is not working as expected, you can add the command line argument `-d` to receive debug messages or add `-c` to print the config on stdout.
If something is not working as expected, you can add `DP_DEBUG=1` before the command or add the command line option `-c` to print the config on stdout.

The "+" sign adds the currently shown definition to Anki after prompting you to copy a sentence.
If there is text selected in the popup window, it will be used instead as a definition.
Expand Down
1 change: 1 addition & 0 deletions TODO
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ High priority
- Allow for an easier replacement of the frontend
- Expose API to frontend like init() and end()?
-> Write a "Yomichan search"-like window application reusing the same backend
- Create config file in ~/.config if not existent

Mid priority
- Implement the reading label as a text view to allow for editing -> initiate new search on Enter press
Expand Down
46 changes: 25 additions & 21 deletions include/ankiconnectc.h
Original file line number Diff line number Diff line change
@@ -1,30 +1,33 @@
#ifndef ANKICONNECTC_H
#define ANKICONNECTC_H

#include <stddef.h>

typedef struct {
char *deck;
char *notetype;
char *deck;
char *notetype;

size_t num_fields;
char **fieldnames;
char **fieldentries;
char **tags;
size_t num_fields;
char **fieldnames;
char **fieldentries;
char **tags;
} ankicard;

void ankicard_free(ankicard ac);

/*
* Print the contents of an ankicard
* Print the contents of an ankicard
*/
void ac_print_ankicard(ankicard ac);

typedef struct {
union {
char* string;
char** stringv;
_Bool boolean;
} data;
_Bool ok; // Signalizes if there was an error on not. The error msg is stored in data.string
union {
char *string;
char **stringv;
_Bool boolean;
} data;
_Bool ok; // Signalizes if there was an error on not. The error msg is
// stored in data.string
} retval_s;

/*
Expand All @@ -37,23 +40,24 @@ retval_s ac_get_decks(void);
*/
retval_s ac_get_notetypes(void);

/*
* Search the Anki database for the entry @entry in the field @field and deck @deck.
/*
* Search the Anki database for the entry @entry in the field @field and deck
* @deck.
* @deck can be null.
* The search result will be stored in data.boolen if there was no error.
*/
retval_s ac_search(_Bool include_suspended, char* deck, char* field, char* entry);
retval_s ac_search(_Bool include_suspended, char *deck, char *field, char *entry);

/*
/*
* Performs a search as in ac_search, but in the Anki gui.
*/
retval_s ac_gui_search(const char* deck, const char* field, const char* entry);
retval_s ac_gui_search(const char *deck, const char *field, const char *entry);

/*
* Stores the file at @path in the Anki media collection under the name @filename.
* Doesn't overwrite existing files.
* Stores the file at @path in the Anki media collection under the name
* @filename. Doesn't overwrite existing files.
*/
retval_s ac_store_file(char const* filename, char const* path);
retval_s ac_store_file(const char *filename, const char *path);

/* Add ankicard to anki */
retval_s ac_addNote(ankicard ac);
Expand Down
65 changes: 28 additions & 37 deletions include/buf.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,11 @@
#include <stdlib.h> // realloc

#ifndef BUF_INIT_CAPACITY
# define BUF_INIT_CAPACITY 8
#define BUF_INIT_CAPACITY 8
#endif

#ifndef BUF_ABORT
# define BUF_ABORT abort()
#define BUF_ABORT abort()
#endif

struct buf {
Expand All @@ -40,59 +40,50 @@ struct buf {
char buffer[];
};

#define buf_ptr(v) \
((struct buf *)((char *)(v) - offsetof(struct buf, buffer)))
#define buf_ptr(v) ((struct buf *)((char *)(v)-offsetof(struct buf, buffer)))

#define buf_free(v) \
do { \
if (v) { \
free(buf_ptr((v))); \
(v) = 0; \
} \
#define buf_free(v) \
do { \
if (v) { \
free(buf_ptr((v))); \
(v) = 0; \
} \
} while (0)

#define buf_size(v) \
((v) ? buf_ptr((v))->size : 0)
#define buf_size(v) ((v) ? buf_ptr((v))->size : 0)

#define buf_capacity(v) \
((v) ? buf_ptr((v))->capacity : 0)
#define buf_capacity(v) ((v) ? buf_ptr((v))->capacity : 0)

#define buf_push(v, e) \
do { \
if (buf_capacity((v)) == buf_size((v))) { \
(v) = buf_grow1(v, sizeof(*(v)), \
!buf_capacity((v)) ? \
BUF_INIT_CAPACITY : \
buf_capacity((v))); \
} \
(v)[buf_ptr((v))->size++] = (e); \
#define buf_push(v, e) \
do { \
if (buf_capacity((v)) == buf_size((v))) { \
(v) = buf_grow1(v, sizeof(*(v)), \
!buf_capacity((v)) ? BUF_INIT_CAPACITY : buf_capacity((v))); \
} \
(v)[buf_ptr((v))->size++] = (e); \
} while (0)

#define buf_pop(v) \
((v)[--buf_ptr(v)->size])
#define buf_pop(v) ((v)[--buf_ptr(v)->size])

#define buf_grow(v, n) \
((v) = buf_grow1((v), sizeof(*(v)), n))
#define buf_grow(v, n) ((v) = buf_grow1((v), sizeof(*(v)), n))

#define buf_trunc(v, n) \
((v) = buf_grow1((v), sizeof(*(v)), n - buf_capacity(v)))
#define buf_trunc(v, n) ((v) = buf_grow1((v), sizeof(*(v)), n - buf_capacity(v)))

#define buf_clear(v) \
((v) ? (buf_ptr((v))->size = 0) : 0)
#define buf_clear(v) ((v) ? (buf_ptr((v))->size = 0) : 0)


static void *
buf_grow1(void *v, size_t esize, ptrdiff_t n)
{
static void *buf_grow1(void *v, size_t esize, ptrdiff_t n) {
struct buf *p;
size_t max = (size_t)-1 - sizeof(struct buf);
if (v) {
p = buf_ptr(v);
if (n > 0 && p->capacity + n > max / esize)
goto fail; /* overflow */
p = realloc(p, sizeof(struct buf) + esize * (p->capacity + n));
if (!p)
void *tmp = realloc(p, sizeof(struct buf) + esize * (p->capacity + n));
if (!tmp) {
free(p);
goto fail;
}
p = tmp;
p->capacity += n;
if (p->size > p->capacity)
p->size = p->capacity;
Expand Down
20 changes: 10 additions & 10 deletions include/database.h
Original file line number Diff line number Diff line change
@@ -1,23 +1,23 @@
#include <stdbool.h>
#include <lmdb.h>
#include "util.h"
#include <lmdb.h>
#include <stdbool.h>

typedef struct {
stringbuilder_s lastval;
MDB_env *env;
MDB_dbi dbi1;
MDB_dbi dbi2;
MDB_txn *txn;
bool readonly;
stringbuilder_s lastval;
MDB_env *env;
MDB_dbi dbi1;
MDB_dbi dbi2;
MDB_txn *txn;
bool readonly;
} database;

database opendb(const char* path, bool readonly);
database opendb(const char *path, bool readonly);
void closedb(database);
/*
* Add to database, allowing duplicates if they are added directly after another
*/
void addtodb1(database db, s8 key, s8 val);
void addtodb2(database db, s8 key, s8 val);

s8* getfiles(database db, s8 key);
s8 *getfiles(database db, s8 key);
s8 getfromdb2(database db, s8 key);
Loading

0 comments on commit 00d02f3

Please sign in to comment.