summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xbootstrap-bootstrap2
-rw-r--r--bootstrap.conf5
-rw-r--r--configure.ac34
-rw-r--r--guix.scm46
-rw-r--r--include/disfluid-gobject.h4
-rw-r--r--include/disfluid.h37
-rw-r--r--include/disfluid/cache_entry.h24
-rw-r--r--introspection/Makefile.am18
-rw-r--r--introspection/doc.toml2
-rw-r--r--po/POTFILES.in2
-rw-r--r--src/Makefile.am21
-rw-r--r--src/gir/Makefile.am30
-rw-r--r--src/libdisfluid/Makefile.am1
-rw-r--r--src/libdisfluid/disfluid-authors.h66
-rw-r--r--src/libdisfluid/disfluid-cache-entry.h65
-rw-r--r--src/libdisfluid/disfluid-ui.h23
-rw-r--r--src/libdisfluid/main.c54
-rw-r--r--src/vala/Makefile.am37
-rw-r--r--src/vala/about.vala51
-rw-r--r--src/vala/main.vala26
-rw-r--r--src/vala/main_window.vala55
-rw-r--r--tests/run-unit-tests.c1
22 files changed, 518 insertions, 86 deletions
diff --git a/bootstrap-bootstrap b/bootstrap-bootstrap
index b878b3c..0ac2032 100755
--- a/bootstrap-bootstrap
+++ b/bootstrap-bootstrap
@@ -1,3 +1,3 @@
#!/bin/sh
-(cp -r gnulib/top/. . || cp -r "$GNULIB_SRCDIR/top/." . ) && ./bootstrap
+cp -r gnulib/top/. . || cp -r "$GNULIB_SRCDIR/top/." .
diff --git a/bootstrap.conf b/bootstrap.conf
index e212745..e67ead1 100644
--- a/bootstrap.conf
+++ b/bootstrap.conf
@@ -44,13 +44,16 @@ read
realloc-gnu
relocatable-lib-lgpl
remove
+safe-alloc
stdbool
stdint
stdio
strdup
+strftime-fixes
strstr
sys_stat
time
+time_r
tmpfile
useless-if-before-free
valgrind-tests
@@ -79,3 +82,5 @@ gnulib_tool_option_extras='--makefile-name=Makefile.gnulib --with-tests --tests-
checkout_only_file=guix.scm
po_download_command_format="git archive --format=tar translations | tar -x -C %s && echo %s"
+
+# End of bootstrap.conf
diff --git a/configure.ac b/configure.ac
index 21d89d1..2d8bec8 100644
--- a/configure.ac
+++ b/configure.ac
@@ -22,8 +22,10 @@ AM_PROG_AR
LT_INIT([win32-dll])
gl_INIT
AM_MISSING_PROG([CONVERT], [convert])
+AC_ARG_VAR([G_IR_SCANNER_FLAGS], [Extra arguments to g-ir-scanner])
AM_MISSING_PROG([G_IR_SCANNER], [g-ir-scanner])
AM_MISSING_PROG([VAPIGEN], [vapigen])
+AM_MISSING_PROG([VALAC], [valac])
GLIB_GSETTINGS
# Checks for libraries.
@@ -32,6 +34,11 @@ AC_ARG_WITH([gobject],
[register types for the glib runtime @<:@default=check@:>@])],
[],
[: m4_divert_text([DEFAULTS], [with_gobject=check])])
+AC_ARG_WITH([gtk],
+ [AS_HELP_STRING([--with-gtk],
+ [build a gtk user interface @<:@default=check@:>@])],
+ [],
+ [: m4_divert_text([DEFAULTS], [with_gtk=check])])
AM_GNU_GETTEXT([external])
AM_GNU_GETTEXT_VERSION([0.19])
@@ -46,7 +53,10 @@ PKG_CHECK_MODULES([GNUTLS], [gnutls], [
LIBS="$LIBS $GNUTLS_LIBS"
], [AC_MSG_WARN([pkg-config does not know the "gnutls" module])])
AS_IF([test "x$with_gobject" != xno],
- [PKG_CHECK_MODULES([GOBJECT], [gobject-2.0], [AC_MSG_WARN([pkg-config does not know the "gobject-2.0" module])])])
+ [PKG_CHECK_MODULES([GOBJECT], [gobject-2.0],, [AC_MSG_WARN([pkg-config does not know the "gobject-2.0" module])])])
+AS_IF([test "x$with_gtk" != xno],
+ [PKG_CHECK_MODULES([GTK], [gtk4],, [AC_MSG_WARN([pkg-config does not know the "gtk4" module])])
+ PKG_CHECK_MODULES([ADW], [libadwaita-1],, [AC_MSG_WARN([pkg-config does not know the "libadwaita-1" module])])])
# Checks for header files.
AC_CHECK_HEADERS([check.h gnutls/gnutls.h gnutls/crypto.h],,
@@ -61,6 +71,17 @@ AS_IF([test "x$with_gobject" != xno],
[AS_IF([test "x$with_gobject" = xcheck],
[with_gobject=no],
[AC_MSG_FAILURE([--with-gobject was given, but glib-object.h is not found.])])])])
+CPPFLAGS="$SAVE_CPPFLAGS $GTK_CFLAGS $ADW_CFLAGS"
+CFLAGS="$SAVE_CFLAGS $GTK_CFLAGS $ADW_CFLAGS"
+AS_IF([test "x$with_gtk" != xno],
+ [AC_CHECK_HEADERS([gtk/gtk.h],,
+ [AS_IF([test "x$with_gtk" = xcheck],
+ [with_gtk=no],
+ [AC_MSG_FAILURE([--with-gtk was given, but gtk/gtk.h is not found.])])])
+ AC_CHECK_HEADERS([adwaita.h],,
+ [AS_IF([test "x$with_gtk" = xcheck],
+ [with_gtk=no],
+ [AC_MSG_FAILURE([--with-gtk was given, but adwaita.h is not found.])])])])
CPPFLAGS="$SAVE_CPPFLAGS"
CFLAGS="$SAVE_CFLAGS"
@@ -85,6 +106,16 @@ AS_IF([test "x$with_gobject" != xno],
[AS_IF([test "x$with_gobject" = xcheck],
[with_gobject=no],
[AC_MSG_FAILURE([--with-gobject was given, but g_boxed_copy is not found.])])])])
+LIBS="$SAVE_LIBS $GTK_LIBS $ADW_LIBS"
+AS_IF([test "x$with_gtk" != xno],
+ [AC_CHECK_FUNCS([gtk_application_get_type],,
+ [AS_IF([test "x$with_gtk" = xcheck],
+ [with_gtk=no],
+ [AC_MSG_FAILURE([--with-gtk was given, but gtk_application_get_type is not found.])])])
+ AC_CHECK_FUNCS([adw_application_get_type],,
+ [AS_IF([test "x$with_gtk" = xcheck],
+ [with_gtk=no],
+ [AC_MSG_FAILURE([--with-gtk was given, but adw_application_get_type is not found.])])])])
LIBS="$SAVE_LIBS"
i_am_windows=no
@@ -95,6 +126,7 @@ esac
AM_CONDITIONAL([SHLIBS_IN_BINDIR], [test "x$i_am_windows" = "xyes"])
AM_CONDITIONAL([BUILD_GOBJECT], [test "x$with_gobject" != "xno"])
+AM_CONDITIONAL([WITH_GTK], [test "x$with_gtk" != "xno"])
case "$VERSION" in
*-*)
diff --git a/guix.scm b/guix.scm
index 7a3e5ea..60855c1 100644
--- a/guix.scm
+++ b/guix.scm
@@ -212,12 +212,19 @@
(build-system gnu-build-system)
(arguments
(list
+ #:configure-flags
+ #~'("G_IR_SCANNER_FLAGS=--warn-all --warn-error")
#:phases
#~(modify-phases
%standard-phases
(add-before 'bootstrap 'bootstrap-bootstrap
(lambda _
- (invoke "sh" "bootstrap-bootstrap")))
+ (invoke "sh" "bootstrap-bootstrap")
+ (for-each patch-shebang
+ '("autopull.sh" "autogen.sh"))
+ (substitute* "bootstrap-funclib.sh"
+ (("\\$gnulib_tool \\$gnulib_tool_options")
+ "sh $gnulib_tool $gnulib_tool_options"))))
(add-after 'bootstrap 'fix-/bin/sh-in-po
(lambda _
(substitute*
@@ -252,19 +259,15 @@
"announce-gen"
"ar-lib"
"config.guess"
- "config.libpath"
"config.sub"
"depcomp"
"do-release-commit-and-tag"
"git-version-gen"
"gitlog-to-changelog"
- "install-reloc"
"install-sh"
- "libtool-reloc"
"ltmain.sh"
"mdate-sh"
"missing"
- "reloc-ldflags"
"test-driver"
"useless-if-before-free"
"vc-list-files"
@@ -300,37 +303,6 @@
"test-binary-io.sh"
)
(("#!/gnu/store/.*/bin/sh")
- "#!/bin/sh")))
- (with-directory-excursion "tests/libprog"
- (substitute* '(
- "executable-shell-script"
- "test-binary-io.sh"
- "test-execv.sh"
- "test-execve.sh"
- "test-fflush2.sh"
- "test-fseek.sh"
- "test-fseek2.sh"
- "test-fseeko.sh"
- "test-fseeko2.sh"
- "test-fseeko3.sh"
- "test-fseeko4.sh"
- "test-ftell.sh"
- "test-ftell2.sh"
- "test-ftello.sh"
- "test-ftello2.sh"
- "test-ftello4.sh"
- "test-ftruncate.sh"
- "test-init.sh"
- "test-lseek.sh"
- "test-perror.sh"
- "test-select-in.sh"
- "test-select-out.sh"
- "test-setlocale1.sh"
- "test-setlocale2.sh"
- "test-verify.sh"
- "test-xalloc-die.sh"
- )
- (("#!/gnu/store/.*/bin/sh")
"#!/bin/sh"))))
(invoke "sh" "-c" "grep '/gnu/store/' -R disfluid-* && exit 1 ; true")
(mkdir-p #$output)
@@ -348,7 +320,7 @@
texinfo (texlive-updmap.cfg (list texlive))
perl gnulib gtk check (list glib "bin")
gobject-introspection imagemagick
- indent cppi))
+ indent cppi vala))
(inputs
(list gtk libadwaita check gnu-gettext gnutls))
(home-page "https://labo.planete-kraus.eu/disfluid.git")
diff --git a/include/disfluid-gobject.h b/include/disfluid-gobject.h
index f9aa28a..b7e5daa 100644
--- a/include/disfluid-gobject.h
+++ b/include/disfluid-gobject.h
@@ -68,7 +68,7 @@ extern "C"
* @entry: (type DisfluidCacheEntry): the entry to query.
* @date: (out) (transfer full): the request date.
*/
- DISFLUID_API extern void
+ DISFLUID_G_API extern void
disfluid_cache_entry_get_request_gdate (const struct disfluid_cache_entry
*entry, GDateTime ** date);
@@ -77,7 +77,7 @@ extern "C"
* @entry: (type DisfluidCacheEntry): the entry to query.
* @date: (out) (transfer full): the response date.
*/
- DISFLUID_API extern void
+ DISFLUID_G_API extern void
disfluid_cache_entry_get_response_gdate (const struct disfluid_cache_entry
*entry, GDateTime ** date);
diff --git a/include/disfluid.h b/include/disfluid.h
index b7e0211..0f6649e 100644
--- a/include/disfluid.h
+++ b/include/disfluid.h
@@ -117,7 +117,7 @@ extern "C"
*
* Returns: return the news.
*/
- DISFLUID_CONST DISFLUID_API extern const char *disfluid_whats_new (void);
+ DISFLUID_API extern const char *disfluid_whats_new (void);
/**
* disfluid_major_version:
@@ -133,7 +133,7 @@ extern "C"
*
* Returns: the website for disfluid.
*/
- DISFLUID_CONST DISFLUID_API extern const char *disfluid_website (void);
+ DISFLUID_API extern const char *disfluid_website (void);
/**
* disfluid_run_tests:
@@ -160,8 +160,7 @@ extern "C"
*
* Returns: the name of author @i.
*/
- DISFLUID_CONST DISFLUID_API extern const char
- *disfluid_author_name (size_t i);
+ DISFLUID_API extern const char *disfluid_author_name (size_t i);
/**
* disfluid_author_email:
@@ -169,8 +168,7 @@ extern "C"
*
* Returns: (nullable): the optional email address of author @i.
*/
- DISFLUID_CONST DISFLUID_API extern const char
- *disfluid_author_email (size_t i);
+ DISFLUID_API extern const char *disfluid_author_email (size_t i);
/**
* disfluid_author_uri:
@@ -178,8 +176,7 @@ extern "C"
*
* Returns: (nullable): the optional web address of author @i.
*/
- DISFLUID_CONST DISFLUID_API extern const char
- *disfluid_author_uri (size_t i);
+ DISFLUID_API extern const char *disfluid_author_uri (size_t i);
/**
* disfluid_author_is_developer:
@@ -221,7 +218,15 @@ extern "C"
*
* Returns: the credits for translations of your language.
*/
- DISFLUID_CONST DISFLUID_API const char *disfluid_translation_credits (void);
+ DISFLUID_API extern const char *disfluid_translation_credits (void);
+
+ /**
+ * disfluid_copyright_statement:
+ *
+ * Returns: a copyright statement in your language.
+ */
+ DISFLUID_API DISFLUID_DEALLOC_WITH_FREE extern char
+ *disfluid_copyright_statement (void);
/**
* disfluid_compute_cache_key:
@@ -259,6 +264,20 @@ extern "C"
size_t password_length,
size_t max_hash, char *hash);
+ /**
+ * disfluid_greet_world:
+ *
+ * Returns: a greeting in the user’s language.
+ */
+ DISFLUID_API const char *disfluid_greet_world (void);
+
+ /**
+ * disfluid_metaphor_name:
+ *
+ * Returns: a GNOME metaphor name for the application.
+ */
+ DISFLUID_API const char *disfluid_metaphor_name (void);
+
# ifdef __cplusplus
}
# endif /* __cplusplus */
diff --git a/include/disfluid/cache_entry.h b/include/disfluid/cache_entry.h
index dddb92d..7f44357 100644
--- a/include/disfluid/cache_entry.h
+++ b/include/disfluid/cache_entry.h
@@ -360,6 +360,30 @@ extern "C"
# define DISFLUID_CACHE_ENTRY_FREE(ptr) \
{ free (ptr); ptr = NULL; }
+ /**
+ * disfluid_cache_entry_describe_request_date:
+ * @entry: (type DisfluidCacheEntry): the entry to describe.
+ * @description: (out): a short phrase stating the request date.
+ *
+ * Returns: 0 on success, or a negative error code.
+ */
+ DISFLUID_NODISCARD DISFLUID_API extern int
+ disfluid_cache_entry_describe_request_date (const struct
+ disfluid_cache_entry *entry,
+ char **description);
+
+ /**
+ * disfluid_cache_entry_describe_response_date:
+ * @entry: (type DisfluidCacheEntry): the entry to describe.
+ * @description: (out): a short phrase stating the response date.
+ *
+ * Returns: 0 on success, or a negative error code.
+ */
+ DISFLUID_NODISCARD DISFLUID_API extern int
+ disfluid_cache_entry_describe_response_date (const struct
+ disfluid_cache_entry *entry,
+ char **description);
+
# ifdef __cplusplus
}
# endif /* __cplusplus */
diff --git a/introspection/Makefile.am b/introspection/Makefile.am
index 7f24bbb..17143e4 100644
--- a/introspection/Makefile.am
+++ b/introspection/Makefile.am
@@ -1,15 +1,13 @@
-girdir = $(datarootdir)/gir-1.0
+.PHONY: prepare-introspection
-dist_gir_DATA = %D%/Disfluid-$(DLL_VERSION).gir
+# To avoid the race mentioned in src/gir/Makefile.am, this Makefile,
+# which is executed early, prepares the libraries. The recursive call
+# in the gir rule is thus a no-op, everything is OK.
-$(abs_top_srcdir)/src/introspection-files:
- $(MAKE) $(AM_MAKEFLAGS) -C .. src/introspection-files
+prepare-introspection:
+ $(MAKE) $(AM_MAKEFLAGS) -C ../lib libgnu.la
+ $(MAKE) $(AM_MAKEFLAGS) -C .. update-introspected-libs
-$(abs_top_srcdir)/src/introspection-libraries:
- $(MAKE) $(AM_MAKEFLAGS) -C .. src/introspection-libraries
-
-%D%/Disfluid-$(DLL_VERSION).gir: $(abs_top_srcdir)/src/introspection-files $(abs_top_srcdir)/src/introspection-libraries
- $(MAKE) $(AM_MAKEFLAGS) -C .. $$(cat $(abs_top_srcdir)/src/introspection-libraries)
- $(AM_V_GEN) (cd .. && $(G_IR_SCANNER) --warn-all --warn-error --strict --format=gir -i GLib-2.0 -I$(abs_top_srcdir)/include --c-include=disfluid --c-include=disfluid/cache_entry.h -n Disfluid --nsversion=$(DLL_VERSION) --symbol-prefix=disfluid_ --output=%D%/Disfluid-$(DLL_VERSION).gir-t $$(for lib in $$(cat $(abs_top_srcdir)/src/introspection-libraries) ; do echo "--library=$$lib" ; done) --cflags-begin $(GOBJECT_CFLAGS) --cflags-end $$(cat $(abs_top_srcdir)/src/introspection-files)) && mv ../%D%/Disfluid-$(DLL_VERSION).gir-t $(srcdir)/%D%/Disfluid-$(DLL_VERSION).gir
+all: prepare-introspection
EXTRA_DIST = %D%/doc.toml
diff --git a/introspection/doc.toml b/introspection/doc.toml
index 411cf09..18a4f8c 100644
--- a/introspection/doc.toml
+++ b/introspection/doc.toml
@@ -9,4 +9,4 @@ dependencies = [ "GObject-2.0" ]
[dependencies."GObject-2.0"]
name = "GObject"
description = "The base type system library"
-docs_url = "https://docs.gtk.org/gobject/" \ No newline at end of file
+docs_url = "https://docs.gtk.org/gobject/"
diff --git a/po/POTFILES.in b/po/POTFILES.in
index bad10a8..fe71f69 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -1,6 +1,8 @@
desktop/eu.planete_kraus.Disfluid.Devel.desktop.in
desktop/eu.planete_kraus.Disfluid.desktop.in
src/libdisfluid/disfluid-authors.h
+src/libdisfluid/disfluid-cache-entry.h
src/libdisfluid/disfluid-tests.h
+src/libdisfluid/disfluid-ui.h
src/libdisfluid/disfluid-version.h
settings/eu.planete_kraus.Disfluid.gschema.xml.in
diff --git a/src/Makefile.am b/src/Makefile.am
index 5bd97d6..7925ce8 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -5,25 +5,12 @@ RELOCATABLE_LIBRARY_PATH = $(libdir)
include %D%/libdisfluid/Makefile.am
include %D%/gobject/Makefile.am
+include %D%/gir/Makefile.am
include %D%/vala/Makefile.am
DISTCLEANFILES += $(defexec_DATA)
-EXTRA_DIST += %D%/introspection-files %D%/introspection-libraries
+.PHONY: update-introspected-libs
-if BUILD_GOBJECT
-
-%D%/introspection-files: $(INTROSPECTION_LISTS) $(INTROSPECTION_SRC)
- $(AM_V_GEN) (for src in $(INTROSPECTED_FILES) ; do echo "$$src" ; done) > %D%/introspection-files-t && mv %D%/introspection-files-t $(srcdir)/%D%/introspection-files
-
-%D%/introspection-libraries: $(INTROSPECTION_LISTS) $(INTROSPECTION_SRC)
- $(AM_V_GEN) (for lib in $(INTROSPECTED_LIBS) ; do echo "$$lib" ; done) > %D%/introspection-libraries-t && mv %D%/introspection-libraries-t %D%/introspection-libraries
-
-else # not BUILD_GOBJECT
-
-%D%/introspection-files: $(INTROSPECTION_LISTS) $(INTROSPECTION_SRC)
- @(>&2 echo "The introspected files have changed, but gobject compilation is disabled." ; exit 1)
-%D%/introspection-libraries: $(INTROSPECTION_LISTS) $(INTROSPECTION_SRC)
- @(>&2 echo "The introspected files have changed, but gobject compilation is disabled." ; exit 1)
-
-endif # not BUILD_GOBJECT
+update-introspected-libs: $(INTROSPECTED_LIBS)
+ @true
diff --git a/src/gir/Makefile.am b/src/gir/Makefile.am
new file mode 100644
index 0000000..860b2f0
--- /dev/null
+++ b/src/gir/Makefile.am
@@ -0,0 +1,30 @@
+girdir = $(datarootdir)/gir-1.0
+
+dist_gir_DATA = $(srcdir)/%D%/Disfluid-$(DLL_VERSION).gir
+
+AM_G_IR_SCANNER_FLAGS = \
+ --format=gir -i GLib-2.0 -I$(abs_top_srcdir)/include
+
+if BUILD_GOBJECT
+
+# The rule to build the .gir file recursively make the libraries. If
+# you run "make -j all", and the libraries are not up to date, then
+# there is a race to build the libraries by this call, and by the
+# recursive calls due to the gir rules.
+
+# The introspection/Makefile.am is executed early and tries to make
+# sure that the recursive call is a no-op. However, if you bypass the
+# subdir order by executing "make -j src/gir/Disfluid-….gir", with the
+# dll version as …, then the race is still there. Automated build
+# scripts usually don’t do this, so it’s fine.
+
+%D%/Disfluid-$(DLL_VERSION).gir: $(INTROSPECTION_LISTS) $(INTROSPECTION_SRC)
+ $(MAKE) $(AM_MAKEFLAGS) $(INTROSPECTED_LIBS)
+ $(AM_V_GEN) $(G_IR_SCANNER) $(AM_G_IR_SCANNER_FLAGS) $(G_IR_SCANNER_FLAGS) --c-include=disfluid.h --c-include=disfluid/cache_entry.h --c-include=disfluid-gobject.h -n Disfluid --nsversion=$(DLL_VERSION) --symbol-prefix=disfluid_ --output=%D%/Disfluid-$(DLL_VERSION).gir-t $$(for lib in $(INTROSPECTED_LIBS) ; do echo "--library=$$lib" ; done) --cflags-begin $(GOBJECT_CFLAGS) --cflags-end $(INTROSPECTED_FILES) && $(SED) 's/shared-library="[^"]*"/shared-library=""/g' %D%/Disfluid-$(DLL_VERSION).gir-t > %D%/Disfluid-$(DLL_VERSION).gir-fixed && rm %D%/Disfluid-$(DLL_VERSION).gir-t && mv %D%/Disfluid-$(DLL_VERSION).gir-fixed $(srcdir)/%D%/Disfluid-$(DLL_VERSION).gir
+
+else # not BUILD_GOBJECT
+
+%D%/Disfluid-$(DLL_VERSION).gir: $(INTROSPECTION_LISTS) $(INTROSPECTION_SRC)
+ @>&2 echo "The introspection sources changed, so the gir file must be updated. Please configure with gobject." ; exit 1
+
+endif # not BUILD_GOBJECT
diff --git a/src/libdisfluid/Makefile.am b/src/libdisfluid/Makefile.am
index 431fa2d..01a5945 100644
--- a/src/libdisfluid/Makefile.am
+++ b/src/libdisfluid/Makefile.am
@@ -7,6 +7,7 @@ lib_LTLIBRARIES += %D%/libdisfluid.la
%D%/disfluid-cache-entry-hash.h \
%D%/disfluid-init.h \
%D%/disfluid-tests.h \
+ %D%/disfluid-ui.h \
%D%/disfluid-version.h \
%D%/main.c
diff --git a/src/libdisfluid/disfluid-authors.h b/src/libdisfluid/disfluid-authors.h
index 149a556..6ccb8fe 100644
--- a/src/libdisfluid/disfluid-authors.h
+++ b/src/libdisfluid/disfluid-authors.h
@@ -1,6 +1,8 @@
#ifndef DISFLUID_AUTHORS_INCLUDED
# define DISFLUID_AUTHORS_INCLUDED
+# include "safe-alloc.h"
+
static inline size_t count_authors (void);
static inline const char *author_name (size_t i);
@@ -17,6 +19,8 @@ static inline bool author_is_documenter (size_t i);
static inline const char *translation_credits (void);
+static inline char *copyright_statement (void);
+
# include "disfluid-init.h"
struct disfluid_author
@@ -32,7 +36,7 @@ struct disfluid_author
static struct disfluid_author disfluid_authors[] = {
{
- .name = "Vivien Kraus",
+ .name = N_("Vivien Kraus"),
.email = "vivien@planete-kraus.eu",
.uri = NULL,
.is_developer = true,
@@ -59,7 +63,7 @@ author_name (size_t i)
{
if (i < sizeof (disfluid_authors) / sizeof (disfluid_authors[0]))
{
- return disfluid_authors[i].name;
+ return _(disfluid_authors[i].name);
}
return NULL;
}
@@ -131,4 +135,62 @@ translation_credits (void)
return _("translator-credits");
}
+static inline char *
+copyright_statement (void)
+{
+ ensure_init ();
+ int error = 0;
+ char *ret = NULL;
+ char *purpose;
+ error = asprintf (&purpose, _("disfluid interoperable web stack"));
+ if (error < 0)
+ {
+ goto cleanup;
+ }
+ char *copyright_line;
+ error =
+ asprintf (&copyright_line,
+ _("Copyright © %s the respective authors"), "2023");
+ if (error < 0)
+ {
+ goto cleanup_purpose;
+ }
+ char *disclaimer;
+ error = asprintf (&disclaimer,
+ _("This program is free software: "
+ "you can redistribute it and/or modify it "
+ "under the terms of the GNU Affero General Public License "
+ "as published by the Free Software Foundation, "
+ "either version 3 of the License, "
+ "or (at your option) any later version.\n"
+ "This program is distributed in the hope that it will be useful, "
+ "but WITHOUT ANY WARRANTY; "
+ "without even the implied warranty of MERCHANTABILITY "
+ "or FITNESS FOR A PARTICULAR PURPOSE. "
+ "See the GNU Affero General Public License for more details.\n"
+ "You should have received a copy "
+ "of the GNU Affero General Public License "
+ "along with this program. "
+ "If not, see <https://www.gnu.org/licenses/>.\n"));
+ if (error < 0)
+ {
+ goto cleanup_copyright_line;
+ }
+ error = asprintf (&ret, "%s\n%s\n%s", purpose, copyright_line, disclaimer);
+ if (error < 0)
+ {
+ FREE (ret);
+ ret = NULL;
+ goto cleanup_disclaimer;
+ }
+cleanup_disclaimer:
+ FREE (disclaimer);
+cleanup_copyright_line:
+ FREE (copyright_line);
+cleanup_purpose:
+ FREE (purpose);
+cleanup:
+ return ret;
+}
+
#endif /* DISFLUID_AUTHORS_INCLUDED */
diff --git a/src/libdisfluid/disfluid-cache-entry.h b/src/libdisfluid/disfluid-cache-entry.h
index ea76217..eb78a6c 100644
--- a/src/libdisfluid/disfluid-cache-entry.h
+++ b/src/libdisfluid/disfluid-cache-entry.h
@@ -115,6 +115,14 @@ cache_entry_write (const struct disfluid_cache_entry *entry, int fd);
MAYBE_UNUSED static int
cache_entry_fwrite (const struct disfluid_cache_entry *entry, FILE * f);
+MAYBE_UNUSED static int
+cache_entry_describe_request_date (const struct disfluid_cache_entry *entry,
+ char **description);
+
+MAYBE_UNUSED static int
+cache_entry_describe_response_date (const struct disfluid_cache_entry *entry,
+ char **description);
+
# include <assert.h>
# include <flexmember.h>
@@ -198,7 +206,7 @@ cache_entry_init (struct disfluid_cache_entry *entry, size_t max_key,
entry->header_length = 0;
entry->body_length = 0;
char *key = cache_entry_key (entry);
- char *header = cache_entry_key (entry);
+ char *header = cache_entry_header (entry);
*key = '\0';
*header = '\0';
}
@@ -260,14 +268,17 @@ cache_entry_copy (struct disfluid_cache_entry *restrict dest,
{
strcpy (dest_key, src_key);
}
+ dest->key_length = src_key_size;
if (!(src->flags & HEADER_NOT_LOADED))
{
strcpy (dest_header, src_header);
}
+ dest->header_length = src_header_size;
if (!(src->flags & BODY_NOT_LOADED))
{
memcpy (dest_body, src_body, src_body_size);
}
+ dest->body_length = src_body_size;
}
return -flags;
}
@@ -1023,4 +1034,56 @@ cache_entry_fwrite (const struct disfluid_cache_entry *entry, FILE * f)
return cache_entry_save (entry, disfluid_cache_entry_saver_fwrite, f);
}
+static int
+cache_entry_describe_date (const struct timespec *ts, const char *format,
+ char **description)
+{
+ struct tm date;
+ struct tm *result = localtime_r (&(ts->tv_sec), &date);
+ if (result == NULL)
+ {
+ return -1;
+ }
+ char buffer[256];
+ size_t n_buffer = strftime (buffer, sizeof (buffer), "%c", &date);
+ if (n_buffer == 0)
+ {
+ return -1;
+ }
+ if (n_buffer >= sizeof (buffer))
+ {
+ buffer[n_buffer - 1] = '\0';
+ }
+ else
+ {
+ buffer[n_buffer] = '\0';
+ }
+ /* TRANSLATORS: the argument is a date in the preferred format for
+ the locale. */
+ int error = asprintf (description, format, buffer);
+ if (error < 0)
+ {
+ return -2;
+ }
+ return 0;
+}
+
+static int
+cache_entry_describe_request_date (const struct disfluid_cache_entry *entry,
+ char **description)
+{
+ struct timespec ts;
+ cache_entry_get_request_date (entry, &ts);
+ return cache_entry_describe_date (&ts, _("Requested %s"), description);
+}
+
+static int
+cache_entry_describe_response_date (const struct disfluid_cache_entry *entry,
+ char **description)
+{
+ struct timespec ts;
+ cache_entry_get_response_date (entry, &ts);
+ return cache_entry_describe_date (&ts, _("Responded %s"), description);
+}
+
#endif /* DISFLUID_DISFLUID_CACHE_ENTRY_INCLUDED */
diff --git a/src/libdisfluid/disfluid-ui.h b/src/libdisfluid/disfluid-ui.h
new file mode 100644
index 0000000..3555664
--- /dev/null
+++ b/src/libdisfluid/disfluid-ui.h
@@ -0,0 +1,23 @@
+#ifndef DISFLUID_UI_INCLUDED
+# define DISFLUID_UI_INCLUDED
+
+static inline const char *greet_world (void);
+static inline const char *metaphor_name (void);
+
+# include "disfluid-init.h"
+
+static inline const char *
+greet_world (void)
+{
+ ensure_init ();
+ return _("Hello, world!");
+}
+
+static inline const char *
+metaphor_name (void)
+{
+ ensure_init ();
+ return _("Experiences");
+}
+
+#endif /* DISFLUID_UI_INCLUDED */
diff --git a/src/libdisfluid/main.c b/src/libdisfluid/main.c
index 6b21295..5aab482 100644
--- a/src/libdisfluid/main.c
+++ b/src/libdisfluid/main.c
@@ -25,6 +25,7 @@
#include "disfluid-cache-entry-key.h"
#include "disfluid-cache-entry-hash.h"
#include "disfluid-tests.h"
+#include "disfluid-ui.h"
#include "disfluid-version.h"
const char *
@@ -117,6 +118,12 @@ disfluid_translation_credits (void)
return translation_credits ();
}
+char *
+disfluid_copyright_statement (void)
+{
+ return copyright_statement ();
+}
+
size_t
disfluid_cache_entry_size (size_t max_key, size_t max_header, size_t max_body)
{
@@ -238,6 +245,27 @@ disfluid_cache_entry_is_invalidated (const struct disfluid_cache_entry *entry)
return cache_entry_is_invalidated (entry);
}
+size_t
+disfluid_cache_entry_get_key (const struct disfluid_cache_entry *entry,
+ size_t start, size_t max, char *key)
+{
+ return cache_entry_get_key (entry, start, max, key);
+}
+
+size_t
+disfluid_cache_entry_get_header (const struct disfluid_cache_entry *entry,
+ size_t start, size_t max, char *header)
+{
+ return cache_entry_get_header (entry, start, max, header);
+}
+
+size_t
+disfluid_cache_entry_get_body (const struct disfluid_cache_entry *entry,
+ size_t start, size_t max, char *body)
+{
+ return cache_entry_get_body (entry, start, max, body);
+}
+
int
disfluid_cache_entry_load (struct disfluid_cache_entry *entry,
int load_key,
@@ -307,3 +335,29 @@ disfluid_hash_primary_cache_key (const char *method,
return hash_primary_cache_key (method, uri, password, password_length,
max_hash, hash);
}
+
+const char *
+disfluid_greet_world (void)
+{
+ return greet_world ();
+}
+
+const char *
+disfluid_metaphor_name (void)
+{
+ return metaphor_name ();
+}
+
+int
+disfluid_cache_entry_describe_request_date (const struct disfluid_cache_entry
+ *entry, char **description)
+{
+ return cache_entry_describe_request_date (entry, description);
+}
+
+int
+disfluid_cache_entry_describe_response_date (const struct disfluid_cache_entry
+ *entry, char **description)
+{
+ return cache_entry_describe_response_date (entry, description);
+}
diff --git a/src/vala/Makefile.am b/src/vala/Makefile.am
index acbb494..a0e4279 100644
--- a/src/vala/Makefile.am
+++ b/src/vala/Makefile.am
@@ -1,6 +1,3 @@
-introspection/Disfluid-$(DLL_VERSION).gir:
- $(MAKE) $(AM_MAKEFLAGS) -C introspection Disfluid-$(DLL_VERSION).gir
-
vapidir = $(datarootdir)/vala/vapi
dist_vapi_DATA = %D%/disfluid-$(DLL_VERSION).vapi
@@ -10,5 +7,35 @@ VAPIGEN_VERBOSE_ = $(VAPIGEN_VERBOSE_@AM_DEFAULT_V@)
VAPIGEN_VERBOSE_1 = $(VAPIGEN)
VAPIGEN_VERBOSE_0 = @echo " VAPIGEN " $@; $(VAPIGEN) --quiet
-%D%/disfluid-$(DLL_VERSION).vapi: introspection/Disfluid-$(DLL_VERSION).gir
- $(AM_VAPIGEN) --library=disfluid-$(DLL_VERSION) -d $(srcdir)/%D% $(srcdir)/introspection/Disfluid-$(DLL_VERSION).gir
+%D%/disfluid-$(DLL_VERSION).vapi: $(dist_gir_DATA)
+ @$(MKDIR_P) %D%/vapi-t
+ $(AM_VAPIGEN) --library=disfluid-$(DLL_VERSION) -d %D%/vapi-t $(dist_gir_DATA) && mv %D%/vapi-t/disfluid-$(DLL_VERSION).vapi %D%/disfluid-$(DLL_VERSION).vapi-t && rmdir %D%/vapi-t && mv %D%/disfluid-$(DLL_VERSION).vapi-t $(srcdir)/%D%/disfluid-$(DLL_VERSION).vapi
+
+AM_VALAFLAGS = --pkg gtk4 --pkg libadwaita-1
+
+if WITH_GTK
+bin_PROGRAMS += %D%/disfluid
+
+%C%_disfluid_SOURCES = \
+ %D%/main.vala \
+ %D%/about.vala \
+ %D%/cache_entry_widget.vala \
+ %D%/main_window.vala \
+ %D%/disfluid-$(DLL_VERSION).vapi
+
+%C%_disfluid_CPPFLAGS = \
+ -I include -I $(srcdir)/include \
+ -I %D% -I $(srcdir)/%D% \
+ -include config.h \
+ $(GTK_CFLAGS) $(GOBJECT_CFLAGS) $(ADW_CFLAGS)
+
+%C%_disfluid_CFLAGS = \
+ $(GTK_CFLAGS) $(GOBJECT_CFLAGS) $(ADW_CFLAGS)
+
+%C%_disfluid_LDADD = \
+ src/libdisfluid/libdisfluid.la \
+ src/gobject/libdisfluid-gobject.la
+
+%C%_disfluid_LDFLAGS = \
+ $(GTK_LIBS) $(GOBJECT_LIBS) $(ADW_LIBS)
+endif
diff --git a/src/vala/about.vala b/src/vala/about.vala
new file mode 100644
index 0000000..14ff2e8
--- /dev/null
+++ b/src/vala/about.vala
@@ -0,0 +1,51 @@
+namespace Disfluid {
+ Adw.AboutWindow make_about_window () {
+ string appid = "eu.planete_kraus.Disfluid";
+ if (Disfluid.is_nightly ()) {
+ appid += ".Devel";
+ }
+ var window = new Adw.AboutWindow ();
+ window.set_application_icon (appid);
+ window.set_application_name (appid);
+ window.set_version (Disfluid.version ());
+ window.set_release_notes (Disfluid.whats_new ());
+ window.set_release_notes_version (Disfluid.major_version ());
+ window.set_website (Disfluid.website ());
+ var n_authors = Disfluid.count_authors ();
+ string[] developers = new string[0];
+ string[] designers = new string[0];
+ string[] artists = new string[0];
+ string[] documenters = new string[0];
+ for (size_t i = 0; i < n_authors; i++) {
+ var email = Disfluid.author_email (i);
+ var uri = Disfluid.author_uri (i);
+ string full_name = Disfluid.author_name (i);
+ if (email != null) {
+ full_name += " <" + email + ">";
+ } else if (uri != null) {
+ full_name += " " + uri;
+ }
+ if (Disfluid.author_is_developer (i)) {
+ developers += full_name;
+ }
+ if (Disfluid.author_is_designer (i)) {
+ designers += full_name;
+ }
+ if (Disfluid.author_is_artist (i)) {
+ artists += full_name;
+ }
+ if (Disfluid.author_is_documenter (i)) {
+ documenters += full_name;
+ }
+ }
+ window.set_developers (developers);
+ window.set_designers (designers);
+ window.set_artists (artists);
+ window.set_documenters (documenters);
+ var translation_credits = Disfluid.translation_credits ();
+ window.set_translator_credits (translation_credits);
+ window.set_copyright (Disfluid.copyright_statement ());
+ window.set_license_type (Gtk.License.AGPL_3_0);
+ return window;
+ }
+}
diff --git a/src/vala/main.vala b/src/vala/main.vala
new file mode 100644
index 0000000..535baf6
--- /dev/null
+++ b/src/vala/main.vala
@@ -0,0 +1,26 @@
+int main (string[] args) {
+ Intl.setlocale (LocaleCategory.ALL, "");
+ var name = "eu.planete_kraus.Disfluid";
+ if (Disfluid.is_nightly ()) {
+ name += ".Devel";
+ }
+ var app = new Adw.Application(
+ name,
+ ApplicationFlags.FLAGS_NONE
+ );
+ app.activate.connect(() => {
+ var cache_entry = new Disfluid.CacheEntry.alloc (512, 4096, 2 * 1024 * 1024);
+ cache_entry.set_request_gdate (new GLib.DateTime.utc (2023, 03, 26, 19, 38, 00));
+ cache_entry.set_response_gdate (new GLib.DateTime.now ());
+ cache_entry.set_key ("GET https://example.com\r\n");
+ cache_entry.set_response_header ("HTTP/1.1 200 OK\r\nContent-Type: text/plain\r\n");
+ cache_entry.set_response_body ((char[]) "Hello");
+ var cache_entry_view = new Disfluid.CacheEntryView.with_value ("/tmp/test.cache", cache_entry);
+ var cache_view = new Adw.PreferencesPage ();
+ cache_view.add (cache_entry_view);
+ var window = new Disfluid.MainWindow (cache_view);
+ window.set_application (app);
+ window.present();
+ });
+ return app.run(args);
+}
diff --git a/src/vala/main_window.vala b/src/vala/main_window.vala
new file mode 100644
index 0000000..d4dec0d
--- /dev/null
+++ b/src/vala/main_window.vala
@@ -0,0 +1,55 @@
+namespace Disfluid {
+ class MainWindow: Adw.ApplicationWindow {
+ private Adw.WindowTitle _window_title;
+ private Gtk.Box _layout;
+
+ private string? _subtitle = null;
+ private Gtk.Widget? _disfluid_content = null;
+
+ public string? subtitle {
+ get {
+ return this._subtitle;
+ }
+ set {
+ this._subtitle = value;
+ this._window_title.subtitle = value;
+ }
+ }
+
+ public Gtk.Widget? disfluid_content {
+ get {
+ return this._disfluid_content;
+ }
+ set {
+ if (this._disfluid_content != null) {
+ this._layout.remove (this._disfluid_content);
+ }
+ this._disfluid_content = value;
+ if (value != null) {
+ this._layout.append (value);
+ }
+ }
+ }
+
+ construct {
+ this._window_title = new Adw.WindowTitle (Disfluid.metaphor_name (), this._subtitle);
+ var bar = new Adw.HeaderBar ();
+ bar.centering_policy = Adw.CenteringPolicy.STRICT;
+ bar.title_widget = this._window_title;
+ this._layout = new Gtk.Box (Gtk.Orientation.VERTICAL, 0);
+ this._layout.append (bar);
+ if (this._disfluid_content != null) {
+ this._layout.append (this._disfluid_content);
+ }
+ this.content = this._layout;
+ }
+
+ public MainWindow (Gtk.Widget? content) {
+ Object (subtitle: null, disfluid_content: content);
+ }
+
+ public MainWindow.specific (string subtitle, Gtk.Widget? content) {
+ Object (subtitle: subtitle, disfluid_content: content);
+ }
+ }
+}
diff --git a/tests/run-unit-tests.c b/tests/run-unit-tests.c
index c6713fe..a290284 100644
--- a/tests/run-unit-tests.c
+++ b/tests/run-unit-tests.c
@@ -6,6 +6,7 @@ main (int argc, char *argv[])
{
(void) argc;
(void) argv;
+ /* This is just a test runner, do not call bindtextdomain () */
size_t n_tests, n_failures;
char *output = disfluid_run_tests (&n_tests, &n_failures);
free (output);