This thread contains a patchset. You're looking at the original emails,
but you may wish to use the patch review UI.
Review patch
6
2
[PATCH gcli 1/2] Bump required C Language Standard to C11
We have made this decision after thinking and discussing. Reasons are:
- C99 is now 25 years old and one can safely assume that any modern system
supports it - C11 is now 13 years old and all platforms that we have
tested so far have been supporting C11 for years now. This also applies
to all the compilers we have been using to build gcli so far.
- Compatibility with more optional libraries
I plan to integrate the lowdown library for Markdown rendering. It requires
C11. I have previously encountered such a case too.
- More modern language features:
We can now use anonymous unions and static assertions.
- gcli is a tool for a modern development workflow:
Thus we can assume a reasonably modern system - where C11 is supported.
If you have a system where these changes cause trouble and heart
ache or you wish to complain about this decision please do so on our
mailing list or IRC.
Signed-off-by: Nico Sonack <nsonack@herrhotzenplotz.de>
---
HACKING.md | 10 +++++ -----
Makefile.in | 10 +++++ -----
README.md | 2 + -
3 files changed, 11 insertions(+), 11 deletions(-)
diff --git a/HACKING.md b/HACKING.md
index bade1822..8ad37f63 100644
--- a/HACKING.md
+++ b/HACKING.md
@@ -211,14 +211,14 @@ Please use the BSD Style conventions for formatting your code. This means:
I know we're not using punchcards anymore, however it makes the code
way more readable.
- - Use C99
+ - Use C11
- Please don't use C11 or even more modern features. Reason being that
+ Please don't use C17 or even more modern features. Reason being that
I want gcli to be portable to older platforms where either no modern
compilers are available or where we have to rely on old gcc versions
- and/or buggy vendor compilers. Notable forbidden features are
- `_Static_assert` and anonymous unions. If you use the compiler flags
- I mentioned above you should get notified by the compiler.
+ and/or buggy vendor compilers. This also means that GNU extensions
+ are forbidden. If you use the compiler flags I mentioned above
+ you should get notified by the compiler.
There is a `.editorconfig` included in the source code that should
automatically provide you with all needed
diff --git a/Makefile.in b/Makefile.in
index 49cab5d5..e1845fb7 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -31,9 +31,9 @@ COPTFLAGS_xlc_release= -qpic -qoptimize=4
COPTFLAGS= $(COPTFLAGS_$(CCOM)_$(OPTIMISE))
COPTFLAGS_FOR_BUILD= $(COPTFLAGS_$(CCOM_FOR_BUILD)_$(OPTIMISE))
- CSTDFLAGS_gcc= -std=c99 -pedantic
- CSTDFLAGS_clang= -std=c99 -pedantic
- CSTDFLAGS_xlc= -qlanglvl=stdc99
+ CSTDFLAGS_gcc= -std=c11 -pedantic
+ CSTDFLAGS_clang= -std=c11 -pedantic
+ CSTDFLAGS_xlc= -qlanglvl=stdc11
CSTDFLAGS= $(CSTDFLAGS_$(CCOM))
CSTDFLAGS_FOR_BUILD= $(CSTDFLAGS_$(CCOM_FOR_BUILD))
@@ -47,10 +47,10 @@ CFLAGS_FOR_BUILD= $(CSTDFLAGS_FOR_BUILD) $(COPTFLAGS_FOR_BUILD) -I@SRCDIR@/inclu
############## CPPFLAGS ######################
ENV_CPPFLAGS= @ENV_CPPFLAGS@
- CPPFLAGS= -DHAVE_CONFIG_H=1 -DHAVE_SYS_QUEUE_H=1 -DHAVE_GETOPT_H=1 -D_XOPEN_SOURCE=600 $(ENV_CPPFLAGS)
+ CPPFLAGS= -DHAVE_CONFIG_H=1 -DHAVE_SYS_QUEUE_H=1 -DHAVE_GETOPT_H=1 -D_XOPEN_SOURCE=700 $(ENV_CPPFLAGS)
ENV_CPPFLAGS_FOR_BUILD= @ENV_CPPFLAGS_FOR_BUILD@
- CPPFLAGS_FOR_BUILD= -DHAVE_CONFIG_H -DYY_NO_UNPUT -DYY_NO_INPUT -D_XOPEN_SOURCE=600 $(ENV_CPPFLAGS_FOR_BUILD)
+ CPPFLAGS_FOR_BUILD= -DHAVE_CONFIG_H -DYY_NO_UNPUT -DYY_NO_INPUT -D_XOPEN_SOURCE=700 $(ENV_CPPFLAGS_FOR_BUILD)
# CFLAGS for dependency tracking for various compilers
CCDEPFLAGS_gcc= -MD -MF ${@:.o=.d}
diff --git a/README.md b/README.md
index a3ab3970..98da255c 100644
--- a/README.md
+++ b/README.md
@@ -45,7 +45,7 @@ Required dependencies:
- libcurl
- yacc (System V yacc, Berkeley Yacc or Bison should suffice)
- lex (flex is preferred)
- - C99 Compiler and linker
+ - C11 Compiler and linker
- make
- pkg-config
--
2.45.2
[PATCH gcli 2/2] Integrate lowdown for Markdown rendering
This optionally integrates the lowdown Markdown library.
It is used for rendering Markdown on the terminal. Colour handling
has been integrated - for that reason I had to move the pretty_print
routine into the main gcli code and also removed the test because
the results would now be different when printed with lowdown.
Signed-off-by: Nico Sonack <nsonack@herrhotzenplotz.de>
---
Makefile.in | 27 +++++++ ----
configure | 24 ++++++++++
include/gcli/cmd/cmd.h | 5 ++
src/cmd/cmd.c | 98 +++++++++++++++++++++++++++++++++++++
src/cmd/comment.c | 2 + -
src/cmd/issues.c | 2 + -
src/cmd/milestones.c | 2 + -
src/cmd/pulls.c | 2 + -
src/cmd/releases.c | 2 + -
src/cmd/status.c | 3 + -
tests/Kyuafile | 4 --
tests/pretty-print.c | 106 -----------------------------------------
thirdparty/sn/sn.c | 43 -----------------
thirdparty/sn/sn.h | 3 --
14 files changed, 152 insertions(+), 171 deletions(-)
delete mode 100644 tests/pretty-print.c
diff --git a/Makefile.in b/Makefile.in
index e1845fb7..fddfe030 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -70,19 +70,28 @@ LIBATFC_LIBS= @LIBATFC_LIBS@
LIBEDIT_FOUND= @LIBEDIT_FOUND@
LIBEDIT_CFLAGS_1= @LIBEDIT_CFLAGS@
LIBEDIT_LIBS_1= @LIBEDIT_LIBS@
- LIBEDIT_CFLAGS= ${LIBEDIT_CFLAGS_$(LIBEDIT_FOUND)}
- LIBEDIT_LIBS= ${LIBEDIT_LIBS_$(LIBEDIT_FOUND)}
+ LIBEDIT_CFLAGS= $(LIBEDIT_CFLAGS_$(LIBEDIT_FOUND))
+ LIBEDIT_LIBS= $(LIBEDIT_LIBS_$(LIBEDIT_FOUND))
LIBEDIT_CPPFLAGS_1= -DHAVE_LIBEDIT=1
- LIBEDIT_CPPFLAGS= ${LIBEDIT_CPPFLAGS_$(LIBEDIT_FOUND)}
+ LIBEDIT_CPPFLAGS= $(LIBEDIT_CPPFLAGS_$(LIBEDIT_FOUND))
############## READLINE #########################################
LIBREADLINE_FOUND= @LIBREADLINE_FOUND@
LIBREADLINE_CFLAGS_1= @LIBREADLINE_CFLAGS@
LIBREADLINE_LIBS_1= @LIBREADLINE_LIBS@
- LIBREADLINE_CFLAGS= ${LIBREADLINE_CFLAGS_$(LIBREADLINE_FOUND)}
- LIBREADLINE_LIBS= ${LIBREADLINE_LIBS_$(LIBREADLINE_FOUND)}
+ LIBREADLINE_CFLAGS= $(LIBREADLINE_CFLAGS_$(LIBREADLINE_FOUND))
+ LIBREADLINE_LIBS= $(LIBREADLINE_LIBS_$(LIBREADLINE_FOUND))
LIBREADLINE_CPPFLAGS_1= -DHAVE_LIBREADLINE=1
- LIBREADLINE_CPPFLAGS= ${LIBREADLINE_CPPFLAGS_$(LIBREADLINE_FOUND)}
+ LIBREADLINE_CPPFLAGS= $(LIBREADLINE_CPPFLAGS_$(LIBREADLINE_FOUND))
+
+ ############## LOWDOWN #########################################
+ LIBLOWDOWN_FOUND= @LIBLOWDOWN_FOUND@
+ LIBLOWDOWN_CFLAGS_1= @LIBLOWDOWN_CFLAGS@
+ LIBLOWDOWN_LIBS_1= @LIBLOWDOWN_LIBS@
+ LIBLOWDOWN_CFLAGS= $(LIBLOWDOWN_CFLAGS_$(LIBLOWDOWN_FOUND))
+ LIBLOWDOWN_LIBS= $(LIBLOWDOWN_LIBS_$(LIBLOWDOWN_FOUND))
+ LIBLOWDOWN_CPPFLAGS_1= -DHAVE_LIBLOWDOWN=1
+ LIBLOWDOWN_CPPFLAGS= $(LIBLOWDOWN_CPPFLAGS_$(LIBLOWDOWN_FOUND))
############## LIBCRYPTO ########################################
LIBCRYPTO_CFLAGS= @LIBCRYPTO_CFLAGS@
@@ -282,7 +291,8 @@ $(TEMPLATE_HEADERS) $(TEMPLATE_SRCS): pgen
gcli: libgcli.a $(GCLI_OBJS)
$(CCACHE) $(CC) $(CFLAGS) $(CPPFLAGS) $(LDFLAGS) -o gcli \
$(GCLI_OBJS) libgcli.a $(LIBCURL_LIBS) $(LIBEDIT_LIBS) \
- $(LIBREADLINE_LIBS) $(LIBCRYPTO_LIBS)
+ $(LIBREADLINE_LIBS) $(LIBCRYPTO_LIBS) \
+ $(LIBLOWDOWN_LIBS)
libgcli.a: $(LIBGCLI_OBJS)
$(AR) -rc libgcli.a $(LIBGCLI_OBJS)
@@ -295,6 +305,7 @@ $(LIBGCLI_OBJS): $(TEMPLATE_HEADERS) $(TEMPLATE_SRCS)
@mkdir -p $$(dirname $@)
$(CCACHE) $(CC) $(CFLAGS) $(CCDEPFLAGS) $(CPPFLAGS) \
$(LIBCURL_CFLAGS) $(LIBCRYPTO_CFLAGS) \
+ $(LIBLOWDOWN_CFLAGS) $(LIBLOWDOWN_CPPFLAGS) \
-DIN_LIBGCLI=1 -c -o $@ $<
.c.gcli.o:
@@ -303,6 +314,7 @@ $(LIBGCLI_OBJS): $(TEMPLATE_HEADERS) $(TEMPLATE_SRCS)
$(LIBEDIT_CPPFLAGS) $(LIBREADLINE_CPPFLAGS) \
$(LIBCURL_CFLAGS) $(LIBEDIT_CFLAGS) \
$(LIBREADLINE_CFLAGS) $(LIBCRYPTO_CFLAGS) \
+ $(LIBLOWDOWN_CFLAGS) $(LIBLOWDOWN_CPPFLAGS) \
-c -o $@ $<
.c.pgen.o:
@@ -326,7 +338,6 @@ TEST_PROGRAMS = \
tests/gitea-parse \
tests/bugzilla-parse \
tests/url-encode \
- tests/pretty-print \
tests/jsongen \
tests/base64 \
tests/difftests
diff --git a/configure b/configure
index 13b9be05..a894fbcd 100755
--- a/configure
+++ b/configure
@@ -148,6 +148,7 @@ PREFIX=/usr/local
OPTIMISE=
ENABLE_LIBEDIT=1
ENABLE_LIBREADLINE=1
+ ENABLE_LIBLOWDOWN=1
# Parse flags
while [ $# -gt 0 ]; do
@@ -176,6 +177,14 @@ while [ $# -gt 0 ]; do
ENABLE_LIBREADLINE=0
shift
;;
+ --enable-liblowdown)
+ ENABLE_LIBLOWDOWN=1
+ shift
+ ;;
+ --disable-liblowdown)
+ ENABLE_LIBLOWDOWN=0
+ shift
+ ;;
--debug)
OPTIMISE=debug
shift
@@ -262,6 +271,13 @@ else
LIBREADLINE_FOUND=0
fi
+ # Lowdown
+ if [ $ENABLE_LIBLOWDOWN -eq 1 ]; then
+ find_package lowdown LIBLOWDOWN optional
+ else
+ LIBLOWDOWN_FOUND=0
+ fi
+
###################################################################
# TESTS and other programs
###################################################################
@@ -299,6 +315,9 @@ sed \
-e "s|@LIBREADLINE_FOUND@|$LIBREADLINE_FOUND|g" \
-e "s|@LIBREADLINE_CFLAGS@|$LIBREADLINE_CFLAGS|g" \
-e "s|@LIBREADLINE_LIBS@|$LIBREADLINE_LIBS|g" \
+ -e "s|@LIBLOWDOWN_FOUND@|$LIBLOWDOWN_FOUND|g" \
+ -e "s|@LIBLOWDOWN_CFLAGS@|$LIBLOWDOWN_CFLAGS|g" \
+ -e "s|@LIBLOWDOWN_LIBS@|$LIBLOWDOWN_LIBS|g" \
-e "s|@CONFIGURE_CMD_ARGS@|$CONFIGURE_CMD_ARGS|g" \
-e "s|@CC@|$CC|g" \
-e "s|@CCOM@|$CCOM|g" \
@@ -356,5 +375,10 @@ echo " Using libreadline:"
echo " LIBREADLINE_CFLAGS: ${LIBREADLINE_CFLAGS}"
echo " LIBREADLINE_LIBS: ${LIBREADLINE_LIBS}"
fi
+ if [ $LIBLOWDOWN_FOUND -eq 1 ]; then
+ echo " Using lowdown:"
+ echo " LIBLOWDOWN_CFLAGS: ${LIBLOWDOWN_CFLAGS}"
+ echo " LIBLOWDOWN_LIBS: ${LIBLOWDOWN_LIBS}"
+ fi
echo ""
echo "Configuration done. You may now run make."
diff --git a/include/gcli/cmd/cmd.h b/include/gcli/cmd/cmd.h
index 1767bb11..4b76d544 100644
--- a/include/gcli/cmd/cmd.h
+++ b/include/gcli/cmd/cmd.h
@@ -34,6 +34,8 @@
#include <config.h>
#endif
+ #include <stdio.h>
+
#include <gcli/gcli.h>
#include <sn/sn.h>
@@ -65,4 +67,7 @@ void delete_repo(bool always_yes, const char *owner, const char *repo);
/* List of subcommand entry points */
int subcommand_api(int argc, char *argv[]);
+ void gcli_pretty_print(char const *input, int indent, int maxlinelen,
+ FILE *stream);
+
#endif /* GCLI_CMD_CMD_H */
diff --git a/src/cmd/cmd.c b/src/cmd/cmd.c
index ed2e723c..3ad75075 100644
--- a/src/cmd/cmd.c
+++ b/src/cmd/cmd.c
@@ -39,6 +39,13 @@
#include <curl/curl.h>
+ #ifdef HAVE_LIBLOWDOWN
+ #include <sys/queue.h>
+
+ #include <locale.h>
+ #include <lowdown.h>
+ #endif
+
void
copyright(void)
{
@@ -150,3 +157,94 @@ delete_repo(bool always_yes, const char *owner, const char *repo)
if (gcli_repo_delete(g_clictx, owner, repo) < 0)
errx(1, "gcli: error: failed to delete repo");
}
+
+ #ifdef HAVE_LIBLOWDOWN
+ void
+ gcli_pretty_print(char const *input, int indent, int maxlinelen, FILE *stream)
+ {
+ size_t input_size;
+ struct lowdown_buf *out;
+ struct lowdown_doc *doc;
+ struct lowdown_node *n;
+ struct lowdown_opts opts = {0};
+ void *rndr;
+
+ input_size = strlen(input);
+
+ if (setlocale(LC_CTYPE, "en_US.UTF-8") == NULL)
+ err(1, NULL);
+
+ opts.feat |= LOWDOWN_FENCED|LOWDOWN_TASKLIST|LOWDOWN_TABLES;
+ if (!gcli_config_have_colours(g_clictx))
+ opts.oflags |= (LOWDOWN_TERM_NOANSI|LOWDOWN_TERM_NOCOLOUR);
+
+ opts.vmargin = 1;
+ opts.hmargin = indent - 4; /* somehow there's always 4 spaces being emitted by lowdown */
+ opts.cols = maxlinelen;
+
+ if ((doc = lowdown_doc_new(&opts)) == NULL)
+ err(1, NULL);
+
+ if ((n = lowdown_doc_parse(doc, NULL, input, input_size, NULL)) == NULL)
+ err(1, NULL);
+
+ if ((out = lowdown_buf_new(256)) == NULL)
+ err(1, NULL);
+
+ if ((rndr = lowdown_term_new(&opts)) == NULL)
+ err(1, NULL);
+
+ if (!lowdown_term_rndr(out, rndr, n))
+ err(1, NULL);
+
+ fwrite(out->data, 1, out->size, stream);
+
+ lowdown_term_free(rndr);
+ lowdown_buf_free(out);
+ lowdown_node_free(n);
+ lowdown_doc_free(doc);
+ }
+ #else
+ static int
+ word_length(const char *x)
+ {
+ int l = 0;
+
+ while (*x && !isspace(*x++))
+ l++;
+ return l;
+ }
+
+ void
+ gcli_pretty_print(const char *input, int indent, int maxlinelen, FILE *out)
+ {
+ const char *it = input;
+
+ if (!it)
+ return;
+
+ while (*it) {
+ int linelength = indent;
+ fprintf(out, "%*.*s", indent, indent, "");
+
+ do {
+ int w = word_length(it) + 1;
+
+ if (it[w - 1] == '\n') {
+ fprintf(out, "%.*s", w - 1, it);
+ it += w;
+ break;
+ } else if (it[w - 1] == '\0') {
+ w -= 1;
+ }
+
+ fprintf(out, "%.*s", w, it);
+ it += w;
+ linelength += w;
+
+ } while (*it && (linelength < maxlinelen));
+
+ fputc('\n', out);
+ }
+ }
+ #endif
diff --git a/src/cmd/comment.c b/src/cmd/comment.c
index 9a1b63e4..564b948c 100644
--- a/src/cmd/comment.c
@@ -200,7 +200,7 @@ gcli_print_comment_list(struct gcli_comment_list const *const list)
gcli_setbold(), list->comments[i].author, gcli_resetbold(),
list->comments[i].date,
list->comments[i].id);
- pretty_print(list->comments[i].body, 9, 80, stdout);
+ gcli_pretty_print(list->comments[i].body, 9, 80, stdout);
putchar('\n');
}
}
diff --git a/src/cmd/issues.c b/src/cmd/issues.c
index 606226d5..6f27faf5 100644
--- a/src/cmd/issues.c
+++ b/src/cmd/issues.c
@@ -208,7 +208,7 @@ void
gcli_issue_print_op(struct gcli_issue const *const it)
{
if (it->body)
- pretty_print(it->body, 4, 80, stdout);
+ gcli_pretty_print(it->body, 4, 80, stdout);
}
static void
diff --git a/src/cmd/milestones.c b/src/cmd/milestones.c
index 43d2a167..defa7b64 100644
--- a/src/cmd/milestones.c
+++ b/src/cmd/milestones.c
@@ -128,7 +128,7 @@ gcli_print_milestone(struct gcli_milestone const *const milestone)
if (milestone->description && strlen(milestone->description)) {
printf("\nDESCRIPTION:\n");
- pretty_print(milestone->description, 4, 80, stdout);
+ gcli_pretty_print(milestone->description, 4, 80, stdout);
}
}
diff --git a/src/cmd/pulls.c b/src/cmd/pulls.c
index 041d7dc4..a3ff300f 100644
--- a/src/cmd/pulls.c
+++ b/src/cmd/pulls.c
@@ -250,7 +250,7 @@ void
gcli_pull_print_op(struct gcli_pull const *const pull)
{
if (pull->body)
- pretty_print(pull->body, 4, 80, stdout);
+ gcli_pretty_print(pull->body, 4, 80, stdout);
}
static void
diff --git a/src/cmd/releases.c b/src/cmd/releases.c
index 6572c1ab..f79aab85 100644
--- a/src/cmd/releases.c
+++ b/src/cmd/releases.c
@@ -96,7 +96,7 @@ gcli_print_release(enum gcli_output_flags const flags,
/* body */
if (it->body) {
putchar('\n');
- pretty_print(it->body, 13, 80, stdout);
+ gcli_pretty_print(it->body, 13, 80, stdout);
}
putchar('\n');
diff --git a/src/cmd/status.c b/src/cmd/status.c
index c3797c7e..2f044d71 100644
--- a/src/cmd/status.c
+++ b/src/cmd/status.c
@@ -91,7 +91,7 @@ gcli_print_notifications(struct gcli_notification_list const *const list)
printf("\n");
- pretty_print(list->notifications[i].title, 4, 80, stdout);
+ gcli_pretty_print(list->notifications[i].title, 4, 80, stdout);
putchar('\n');
}
}
@@ -174,4 +174,3 @@ subcommand_status(int argc, char *argv[])
return EXIT_SUCCESS;
}
-
diff --git a/tests/Kyuafile b/tests/Kyuafile
index 77ad1658..7cc95bb8 100644
--- a/tests/Kyuafile
+++ b/tests/Kyuafile
@@ -30,10 +30,6 @@ atf_test_program{
name = 'url-encode'
}
- atf_test_program{
- name = 'pretty-print'
- }
-
atf_test_program{
name = 'jsongen'
}
diff --git a/tests/pretty-print.c b/tests/pretty-print.c
deleted file mode 100644
index c5379853..00000000
--- a/tests/pretty-print.c
@@ -1,106 +0,0 @@
- /*
- * Copyright 2023 Nico Sonack <nsonack@herrhotzenplotz.de>
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials provided
- * with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
- * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
- * OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
- #include <sn/sn.h>
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <unistd.h>
-
- #include <atf-c.h>
-
- static char *
- test_string(char const *const input)
- {
- FILE *f;
- long length;
- char *buf;
- static char const *const fname = "/tmp/gcli_pretty_print_test";
-
- f = fopen(fname, "w");
- pretty_print(input, 4, 80, f);
-
- length = ftell(f);
- fflush(f);
- fclose(f);
-
- f = fopen(fname, "r");
- buf = malloc(length + 1);
- fread(buf, 1, length, f);
- buf[length] = '\0';
-
- fclose(f);
- unlink(fname);
-
- return buf;
- }
-
- ATF_TC_WITHOUT_HEAD(simple_one_line);
- ATF_TC_BODY(simple_one_line, tc)
- {
- char *formatted = test_string("<empty>");
- ATF_CHECK_STREQ(formatted, " <empty>\n");
- }
-
- ATF_TC_WITHOUT_HEAD(long_line_doesnt_break);
- ATF_TC_BODY(long_line_doesnt_break, tc)
- {
- char const *const input =
- "0123456789012345678901234567890123456789012345678901234567890123456789"
- "0123456789012345678901234567890123456789012345678901234567890123456789";
- char *formatted = test_string(input);
- char const expected[] =
- " 0123456789012345678901234567890123456789012345678901234567890123456789012345"
- "6789012345678901234567890123456789012345678901234567890123456789\n";
-
- ATF_CHECK_STREQ(formatted, expected);
- }
-
- ATF_TC_WITHOUT_HEAD(line_overflow_break);
- ATF_TC_BODY(line_overflow_break, tc)
- {
- char const *const input =
- "0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 "
- "0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789";
- char *formatted = test_string(input);
- char const expected[] =
- " 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 \n"
- " 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 \n"
- " 0123456789 0123456789\n";
- ATF_CHECK_STREQ(formatted, expected);
- }
-
- ATF_TP_ADD_TCS(tp)
- {
- ATF_TP_ADD_TC(tp, simple_one_line);
- ATF_TP_ADD_TC(tp, long_line_doesnt_break);
- ATF_TP_ADD_TC(tp, line_overflow_break);
-
- return atf_no_error();
- }
diff --git a/thirdparty/sn/sn.c b/thirdparty/sn/sn.c
index 8eb9785f..66b6e4d6 100644
--- a/thirdparty/sn/sn.c
+++ b/thirdparty/sn/sn.c
@@ -158,49 +158,6 @@ sn_asprintf(const char *fmt, ...)
return result;
}
- static int
- word_length(const char *x)
- {
- int l = 0;
-
- while (*x && !isspace(*x++))
- l++;
- return l;
- }
-
- void
- pretty_print(const char *input, int indent, int maxlinelen, FILE *out)
- {
- const char *it = input;
-
- if (!it)
- return;
-
- while (*it) {
- int linelength = indent;
- fprintf(out, "%*.*s", indent, indent, "");
-
- do {
- int w = word_length(it) + 1;
-
- if (it[w - 1] == '\n') {
- fprintf(out, "%.*s", w - 1, it);
- it += w;
- break;
- } else if (it[w - 1] == '\0') {
- w -= 1;
- }
-
- fprintf(out, "%.*s", w, it);
- it += w;
- linelength += w;
-
- } while (*it && (linelength < maxlinelen));
-
- fputc('\n', out);
- }
- }
-
int
sn_mmap_file(const char *path, void **buffer)
{
diff --git a/thirdparty/sn/sn.h b/thirdparty/sn/sn.h
index 1b501c5c..7dc1631c 100644
--- a/thirdparty/sn/sn.h
+++ b/thirdparty/sn/sn.h
@@ -105,9 +105,6 @@ char *sn_asprintf(const char *fmt, ...) PRINTF_FORMAT(1, 2);
// modifies the underlying string
char *sn_strip_suffix(char *it, const char *suffix);
- /* pretty functions */
- void pretty_print(const char *input, int indent, int maxlinelen, FILE *out);
-
/* io file mapping */
int sn_mmap_file(const char *path, void **buffer);
int sn_read_file(char const *path, char **buffer);
--
2.45.2
Re: [PATCH gcli 2/2] Integrate lowdown for Markdown rendering
On Fri Aug 16, 2024 at 4:46 PM UTC, Nico Sonack wrote:
> This optionally integrates the lowdown Markdown library.
>
> It is used for rendering Markdown on the terminal. Colour handling
> has been integrated - for that reason I had to move the pretty_print
> routine into the main gcli code and also removed the test because
> the results would now be different when printed with lowdown.
>
> diff --git a/Makefile.in b/Makefile.in
Can we split this patch up and separate moving the pretty_print code
and removing the test, from the adding of lowdown support.
What do you think about adding some config for this too,
perhaps `render_markdown = yes`. We should probably add a flag also.
This can be done in another series and isn't blocking.
- g
[PATCH gcli v2 1/3] Bump required C Language Standard to C11
We have made this decision after thinking and discussing. Reasons are:
- C99 is now 25 years old and one can safely assume that any modern system
supports it - C11 is now 13 years old and all platforms that we have
tested so far have been supporting C11 for years now. This also applies
to all the compilers we have been using to build gcli so far.
- Compatibility with more optional libraries
I plan to integrate the lowdown library for Markdown rendering. It requires
C11. I have previously encountered such a case too.
- More modern language features:
We can now use anonymous unions and static assertions.
- gcli is a tool for a modern development workflow:
Thus we can assume a reasonably modern system - where C11 is supported.
If you have a system where these changes cause trouble and heart
ache or you wish to complain about this decision please do so on our
mailing list or IRC.
Signed-off-by: Nico Sonack <nsonack@herrhotzenplotz.de>
---
I have split this into 3 separate patches now. Good idea!
Also, as for the render-markdown option: that sounds like a very good idea!
Nico
HACKING.md | 10 +++++ -----
Makefile.in | 10 +++++ -----
README.md | 2 + -
3 files changed, 11 insertions(+), 11 deletions(-)
diff --git a/HACKING.md b/HACKING.md
index bade1822..8ad37f63 100644
--- a/HACKING.md
+++ b/HACKING.md
@@ -211,14 +211,14 @@ Please use the BSD Style conventions for formatting your code. This means:
I know we're not using punchcards anymore, however it makes the code
way more readable.
- - Use C99
+ - Use C11
- Please don't use C11 or even more modern features. Reason being that
+ Please don't use C17 or even more modern features. Reason being that
I want gcli to be portable to older platforms where either no modern
compilers are available or where we have to rely on old gcc versions
- and/or buggy vendor compilers. Notable forbidden features are
- `_Static_assert` and anonymous unions. If you use the compiler flags
- I mentioned above you should get notified by the compiler.
+ and/or buggy vendor compilers. This also means that GNU extensions
+ are forbidden. If you use the compiler flags I mentioned above
+ you should get notified by the compiler.
There is a `.editorconfig` included in the source code that should
automatically provide you with all needed
diff --git a/Makefile.in b/Makefile.in
index 49cab5d5..e1845fb7 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -31,9 +31,9 @@ COPTFLAGS_xlc_release= -qpic -qoptimize=4
COPTFLAGS= $(COPTFLAGS_$(CCOM)_$(OPTIMISE))
COPTFLAGS_FOR_BUILD= $(COPTFLAGS_$(CCOM_FOR_BUILD)_$(OPTIMISE))
- CSTDFLAGS_gcc= -std=c99 -pedantic
- CSTDFLAGS_clang= -std=c99 -pedantic
- CSTDFLAGS_xlc= -qlanglvl=stdc99
+ CSTDFLAGS_gcc= -std=c11 -pedantic
+ CSTDFLAGS_clang= -std=c11 -pedantic
+ CSTDFLAGS_xlc= -qlanglvl=stdc11
CSTDFLAGS= $(CSTDFLAGS_$(CCOM))
CSTDFLAGS_FOR_BUILD= $(CSTDFLAGS_$(CCOM_FOR_BUILD))
@@ -47,10 +47,10 @@ CFLAGS_FOR_BUILD= $(CSTDFLAGS_FOR_BUILD) $(COPTFLAGS_FOR_BUILD) -I@SRCDIR@/inclu
############## CPPFLAGS ######################
ENV_CPPFLAGS= @ENV_CPPFLAGS@
- CPPFLAGS= -DHAVE_CONFIG_H=1 -DHAVE_SYS_QUEUE_H=1 -DHAVE_GETOPT_H=1 -D_XOPEN_SOURCE=600 $(ENV_CPPFLAGS)
+ CPPFLAGS= -DHAVE_CONFIG_H=1 -DHAVE_SYS_QUEUE_H=1 -DHAVE_GETOPT_H=1 -D_XOPEN_SOURCE=700 $(ENV_CPPFLAGS)
ENV_CPPFLAGS_FOR_BUILD= @ENV_CPPFLAGS_FOR_BUILD@
- CPPFLAGS_FOR_BUILD= -DHAVE_CONFIG_H -DYY_NO_UNPUT -DYY_NO_INPUT -D_XOPEN_SOURCE=600 $(ENV_CPPFLAGS_FOR_BUILD)
+ CPPFLAGS_FOR_BUILD= -DHAVE_CONFIG_H -DYY_NO_UNPUT -DYY_NO_INPUT -D_XOPEN_SOURCE=700 $(ENV_CPPFLAGS_FOR_BUILD)
# CFLAGS for dependency tracking for various compilers
CCDEPFLAGS_gcc= -MD -MF ${@:.o=.d}
diff --git a/README.md b/README.md
index a3ab3970..98da255c 100644
--- a/README.md
+++ b/README.md
@@ -45,7 +45,7 @@ Required dependencies:
- libcurl
- yacc (System V yacc, Berkeley Yacc or Bison should suffice)
- lex (flex is preferred)
- - C99 Compiler and linker
+ - C11 Compiler and linker
- make
- pkg-config
--
2.45.2
[PATCH gcli v2 2/3] cmd: Move pretty print to cmd code and remove associated test
This is done to later add support for lowdown which needs special
handling for disabling colour output.
Signed-off-by: Nico Sonack <nsonack@herrhotzenplotz.de>
---
Makefile.in | 1 -
include/gcli/cmd/cmd.h | 5 ++
src/cmd/cmd.c | 43 +++++++++++++++++
src/cmd/comment.c | 2 + -
src/cmd/issues.c | 2 + -
src/cmd/milestones.c | 2 + -
src/cmd/pulls.c | 2 + -
src/cmd/releases.c | 2 + -
src/cmd/status.c | 3 + -
tests/Kyuafile | 4 --
tests/pretty-print.c | 106 -----------------------------------------
thirdparty/sn/sn.c | 43 -----------------
thirdparty/sn/sn.h | 3 --
13 files changed, 54 insertions(+), 164 deletions(-)
delete mode 100644 tests/pretty-print.c
diff --git a/Makefile.in b/Makefile.in
index e1845fb7..362aee32 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -326,7 +326,6 @@ TEST_PROGRAMS = \
tests/gitea-parse \
tests/bugzilla-parse \
tests/url-encode \
- tests/pretty-print \
tests/jsongen \
tests/base64 \
tests/difftests
diff --git a/include/gcli/cmd/cmd.h b/include/gcli/cmd/cmd.h
index 1767bb11..4b76d544 100644
--- a/include/gcli/cmd/cmd.h
+++ b/include/gcli/cmd/cmd.h
@@ -34,6 +34,8 @@
#include <config.h>
#endif
+ #include <stdio.h>
+
#include <gcli/gcli.h>
#include <sn/sn.h>
@@ -65,4 +67,7 @@ void delete_repo(bool always_yes, const char *owner, const char *repo);
/* List of subcommand entry points */
int subcommand_api(int argc, char *argv[]);
+ void gcli_pretty_print(char const *input, int indent, int maxlinelen,
+ FILE *stream);
+
#endif /* GCLI_CMD_CMD_H */
diff --git a/src/cmd/cmd.c b/src/cmd/cmd.c
index ed2e723c..a1496e22 100644
--- a/src/cmd/cmd.c
+++ b/src/cmd/cmd.c
@@ -150,3 +150,46 @@ delete_repo(bool always_yes, const char *owner, const char *repo)
if (gcli_repo_delete(g_clictx, owner, repo) < 0)
errx(1, "gcli: error: failed to delete repo");
}
+
+ static int
+ word_length(const char *x)
+ {
+ int l = 0;
+
+ while (*x && !isspace(*x++))
+ l++;
+ return l;
+ }
+
+ void
+ gcli_pretty_print(const char *input, int indent, int maxlinelen, FILE *out)
+ {
+ const char *it = input;
+
+ if (!it)
+ return;
+
+ while (*it) {
+ int linelength = indent;
+ fprintf(out, "%*.*s", indent, indent, "");
+
+ do {
+ int w = word_length(it) + 1;
+
+ if (it[w - 1] == '\n') {
+ fprintf(out, "%.*s", w - 1, it);
+ it += w;
+ break;
+ } else if (it[w - 1] == '\0') {
+ w -= 1;
+ }
+
+ fprintf(out, "%.*s", w, it);
+ it += w;
+ linelength += w;
+
+ } while (*it && (linelength < maxlinelen));
+
+ fputc('\n', out);
+ }
+ }
diff --git a/src/cmd/comment.c b/src/cmd/comment.c
index 9a1b63e4..564b948c 100644
--- a/src/cmd/comment.c
@@ -200,7 +200,7 @@ gcli_print_comment_list(struct gcli_comment_list const *const list)
gcli_setbold(), list->comments[i].author, gcli_resetbold(),
list->comments[i].date,
list->comments[i].id);
- pretty_print(list->comments[i].body, 9, 80, stdout);
+ gcli_pretty_print(list->comments[i].body, 9, 80, stdout);
putchar('\n');
}
}
diff --git a/src/cmd/issues.c b/src/cmd/issues.c
index 606226d5..6f27faf5 100644
--- a/src/cmd/issues.c
+++ b/src/cmd/issues.c
@@ -208,7 +208,7 @@ void
gcli_issue_print_op(struct gcli_issue const *const it)
{
if (it->body)
- pretty_print(it->body, 4, 80, stdout);
+ gcli_pretty_print(it->body, 4, 80, stdout);
}
static void
diff --git a/src/cmd/milestones.c b/src/cmd/milestones.c
index 43d2a167..defa7b64 100644
--- a/src/cmd/milestones.c
+++ b/src/cmd/milestones.c
@@ -128,7 +128,7 @@ gcli_print_milestone(struct gcli_milestone const *const milestone)
if (milestone->description && strlen(milestone->description)) {
printf("\nDESCRIPTION:\n");
- pretty_print(milestone->description, 4, 80, stdout);
+ gcli_pretty_print(milestone->description, 4, 80, stdout);
}
}
diff --git a/src/cmd/pulls.c b/src/cmd/pulls.c
index 041d7dc4..a3ff300f 100644
--- a/src/cmd/pulls.c
+++ b/src/cmd/pulls.c
@@ -250,7 +250,7 @@ void
gcli_pull_print_op(struct gcli_pull const *const pull)
{
if (pull->body)
- pretty_print(pull->body, 4, 80, stdout);
+ gcli_pretty_print(pull->body, 4, 80, stdout);
}
static void
diff --git a/src/cmd/releases.c b/src/cmd/releases.c
index 6572c1ab..f79aab85 100644
--- a/src/cmd/releases.c
+++ b/src/cmd/releases.c
@@ -96,7 +96,7 @@ gcli_print_release(enum gcli_output_flags const flags,
/* body */
if (it->body) {
putchar('\n');
- pretty_print(it->body, 13, 80, stdout);
+ gcli_pretty_print(it->body, 13, 80, stdout);
}
putchar('\n');
diff --git a/src/cmd/status.c b/src/cmd/status.c
index c3797c7e..2f044d71 100644
--- a/src/cmd/status.c
+++ b/src/cmd/status.c
@@ -91,7 +91,7 @@ gcli_print_notifications(struct gcli_notification_list const *const list)
printf("\n");
- pretty_print(list->notifications[i].title, 4, 80, stdout);
+ gcli_pretty_print(list->notifications[i].title, 4, 80, stdout);
putchar('\n');
}
}
@@ -174,4 +174,3 @@ subcommand_status(int argc, char *argv[])
return EXIT_SUCCESS;
}
-
diff --git a/tests/Kyuafile b/tests/Kyuafile
index 77ad1658..7cc95bb8 100644
--- a/tests/Kyuafile
+++ b/tests/Kyuafile
@@ -30,10 +30,6 @@ atf_test_program{
name = 'url-encode'
}
- atf_test_program{
- name = 'pretty-print'
- }
-
atf_test_program{
name = 'jsongen'
}
diff --git a/tests/pretty-print.c b/tests/pretty-print.c
deleted file mode 100644
index c5379853..00000000
--- a/tests/pretty-print.c
@@ -1,106 +0,0 @@
- /*
- * Copyright 2023 Nico Sonack <nsonack@herrhotzenplotz.de>
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials provided
- * with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
- * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
- * OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
- #include <sn/sn.h>
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <unistd.h>
-
- #include <atf-c.h>
-
- static char *
- test_string(char const *const input)
- {
- FILE *f;
- long length;
- char *buf;
- static char const *const fname = "/tmp/gcli_pretty_print_test";
-
- f = fopen(fname, "w");
- pretty_print(input, 4, 80, f);
-
- length = ftell(f);
- fflush(f);
- fclose(f);
-
- f = fopen(fname, "r");
- buf = malloc(length + 1);
- fread(buf, 1, length, f);
- buf[length] = '\0';
-
- fclose(f);
- unlink(fname);
-
- return buf;
- }
-
- ATF_TC_WITHOUT_HEAD(simple_one_line);
- ATF_TC_BODY(simple_one_line, tc)
- {
- char *formatted = test_string("<empty>");
- ATF_CHECK_STREQ(formatted, " <empty>\n");
- }
-
- ATF_TC_WITHOUT_HEAD(long_line_doesnt_break);
- ATF_TC_BODY(long_line_doesnt_break, tc)
- {
- char const *const input =
- "0123456789012345678901234567890123456789012345678901234567890123456789"
- "0123456789012345678901234567890123456789012345678901234567890123456789";
- char *formatted = test_string(input);
- char const expected[] =
- " 0123456789012345678901234567890123456789012345678901234567890123456789012345"
- "6789012345678901234567890123456789012345678901234567890123456789\n";
-
- ATF_CHECK_STREQ(formatted, expected);
- }
-
- ATF_TC_WITHOUT_HEAD(line_overflow_break);
- ATF_TC_BODY(line_overflow_break, tc)
- {
- char const *const input =
- "0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 "
- "0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789";
- char *formatted = test_string(input);
- char const expected[] =
- " 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 \n"
- " 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 \n"
- " 0123456789 0123456789\n";
- ATF_CHECK_STREQ(formatted, expected);
- }
-
- ATF_TP_ADD_TCS(tp)
- {
- ATF_TP_ADD_TC(tp, simple_one_line);
- ATF_TP_ADD_TC(tp, long_line_doesnt_break);
- ATF_TP_ADD_TC(tp, line_overflow_break);
-
- return atf_no_error();
- }
diff --git a/thirdparty/sn/sn.c b/thirdparty/sn/sn.c
index 8eb9785f..66b6e4d6 100644
--- a/thirdparty/sn/sn.c
+++ b/thirdparty/sn/sn.c
@@ -158,49 +158,6 @@ sn_asprintf(const char *fmt, ...)
return result;
}
- static int
- word_length(const char *x)
- {
- int l = 0;
-
- while (*x && !isspace(*x++))
- l++;
- return l;
- }
-
- void
- pretty_print(const char *input, int indent, int maxlinelen, FILE *out)
- {
- const char *it = input;
-
- if (!it)
- return;
-
- while (*it) {
- int linelength = indent;
- fprintf(out, "%*.*s", indent, indent, "");
-
- do {
- int w = word_length(it) + 1;
-
- if (it[w - 1] == '\n') {
- fprintf(out, "%.*s", w - 1, it);
- it += w;
- break;
- } else if (it[w - 1] == '\0') {
- w -= 1;
- }
-
- fprintf(out, "%.*s", w, it);
- it += w;
- linelength += w;
-
- } while (*it && (linelength < maxlinelen));
-
- fputc('\n', out);
- }
- }
-
int
sn_mmap_file(const char *path, void **buffer)
{
diff --git a/thirdparty/sn/sn.h b/thirdparty/sn/sn.h
index 1b501c5c..7dc1631c 100644
--- a/thirdparty/sn/sn.h
+++ b/thirdparty/sn/sn.h
@@ -105,9 +105,6 @@ char *sn_asprintf(const char *fmt, ...) PRINTF_FORMAT(1, 2);
// modifies the underlying string
char *sn_strip_suffix(char *it, const char *suffix);
- /* pretty functions */
- void pretty_print(const char *input, int indent, int maxlinelen, FILE *out);
-
/* io file mapping */
int sn_mmap_file(const char *path, void **buffer);
int sn_read_file(char const *path, char **buffer);
--
2.45.2
[PATCH gcli v2 3/3] cmd: Add optional support for rendering Markdown with lowdown
Whenever lowdown is detected and enabled this will use lowdown to
render Markdown. Colour output can be disabled.
Signed-off-by: Nico Sonack <nsonack@herrhotzenplotz.de>
---
Makefile.in | 26 +++++++++++++++++ -------
configure | 24 ++++++++++++++++++++++
src/cmd/cmd.c | 55 +++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 98 insertions(+), 7 deletions(-)
diff --git a/Makefile.in b/Makefile.in
index 362aee32..fddfe030 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -70,19 +70,28 @@ LIBATFC_LIBS= @LIBATFC_LIBS@
LIBEDIT_FOUND= @LIBEDIT_FOUND@
LIBEDIT_CFLAGS_1= @LIBEDIT_CFLAGS@
LIBEDIT_LIBS_1= @LIBEDIT_LIBS@
- LIBEDIT_CFLAGS= ${LIBEDIT_CFLAGS_$(LIBEDIT_FOUND)}
- LIBEDIT_LIBS= ${LIBEDIT_LIBS_$(LIBEDIT_FOUND)}
+ LIBEDIT_CFLAGS= $(LIBEDIT_CFLAGS_$(LIBEDIT_FOUND))
+ LIBEDIT_LIBS= $(LIBEDIT_LIBS_$(LIBEDIT_FOUND))
LIBEDIT_CPPFLAGS_1= -DHAVE_LIBEDIT=1
- LIBEDIT_CPPFLAGS= ${LIBEDIT_CPPFLAGS_$(LIBEDIT_FOUND)}
+ LIBEDIT_CPPFLAGS= $(LIBEDIT_CPPFLAGS_$(LIBEDIT_FOUND))
############## READLINE #########################################
LIBREADLINE_FOUND= @LIBREADLINE_FOUND@
LIBREADLINE_CFLAGS_1= @LIBREADLINE_CFLAGS@
LIBREADLINE_LIBS_1= @LIBREADLINE_LIBS@
- LIBREADLINE_CFLAGS= ${LIBREADLINE_CFLAGS_$(LIBREADLINE_FOUND)}
- LIBREADLINE_LIBS= ${LIBREADLINE_LIBS_$(LIBREADLINE_FOUND)}
+ LIBREADLINE_CFLAGS= $(LIBREADLINE_CFLAGS_$(LIBREADLINE_FOUND))
+ LIBREADLINE_LIBS= $(LIBREADLINE_LIBS_$(LIBREADLINE_FOUND))
LIBREADLINE_CPPFLAGS_1= -DHAVE_LIBREADLINE=1
- LIBREADLINE_CPPFLAGS= ${LIBREADLINE_CPPFLAGS_$(LIBREADLINE_FOUND)}
+ LIBREADLINE_CPPFLAGS= $(LIBREADLINE_CPPFLAGS_$(LIBREADLINE_FOUND))
+
+ ############## LOWDOWN #########################################
+ LIBLOWDOWN_FOUND= @LIBLOWDOWN_FOUND@
+ LIBLOWDOWN_CFLAGS_1= @LIBLOWDOWN_CFLAGS@
+ LIBLOWDOWN_LIBS_1= @LIBLOWDOWN_LIBS@
+ LIBLOWDOWN_CFLAGS= $(LIBLOWDOWN_CFLAGS_$(LIBLOWDOWN_FOUND))
+ LIBLOWDOWN_LIBS= $(LIBLOWDOWN_LIBS_$(LIBLOWDOWN_FOUND))
+ LIBLOWDOWN_CPPFLAGS_1= -DHAVE_LIBLOWDOWN=1
+ LIBLOWDOWN_CPPFLAGS= $(LIBLOWDOWN_CPPFLAGS_$(LIBLOWDOWN_FOUND))
############## LIBCRYPTO ########################################
LIBCRYPTO_CFLAGS= @LIBCRYPTO_CFLAGS@
@@ -282,7 +291,8 @@ $(TEMPLATE_HEADERS) $(TEMPLATE_SRCS): pgen
gcli: libgcli.a $(GCLI_OBJS)
$(CCACHE) $(CC) $(CFLAGS) $(CPPFLAGS) $(LDFLAGS) -o gcli \
$(GCLI_OBJS) libgcli.a $(LIBCURL_LIBS) $(LIBEDIT_LIBS) \
- $(LIBREADLINE_LIBS) $(LIBCRYPTO_LIBS)
+ $(LIBREADLINE_LIBS) $(LIBCRYPTO_LIBS) \
+ $(LIBLOWDOWN_LIBS)
libgcli.a: $(LIBGCLI_OBJS)
$(AR) -rc libgcli.a $(LIBGCLI_OBJS)
@@ -295,6 +305,7 @@ $(LIBGCLI_OBJS): $(TEMPLATE_HEADERS) $(TEMPLATE_SRCS)
@mkdir -p $$(dirname $@)
$(CCACHE) $(CC) $(CFLAGS) $(CCDEPFLAGS) $(CPPFLAGS) \
$(LIBCURL_CFLAGS) $(LIBCRYPTO_CFLAGS) \
+ $(LIBLOWDOWN_CFLAGS) $(LIBLOWDOWN_CPPFLAGS) \
-DIN_LIBGCLI=1 -c -o $@ $<
.c.gcli.o:
@@ -303,6 +314,7 @@ $(LIBGCLI_OBJS): $(TEMPLATE_HEADERS) $(TEMPLATE_SRCS)
$(LIBEDIT_CPPFLAGS) $(LIBREADLINE_CPPFLAGS) \
$(LIBCURL_CFLAGS) $(LIBEDIT_CFLAGS) \
$(LIBREADLINE_CFLAGS) $(LIBCRYPTO_CFLAGS) \
+ $(LIBLOWDOWN_CFLAGS) $(LIBLOWDOWN_CPPFLAGS) \
-c -o $@ $<
.c.pgen.o:
diff --git a/configure b/configure
index 13b9be05..a894fbcd 100755
--- a/configure
+++ b/configure
@@ -148,6 +148,7 @@ PREFIX=/usr/local
OPTIMISE=
ENABLE_LIBEDIT=1
ENABLE_LIBREADLINE=1
+ ENABLE_LIBLOWDOWN=1
# Parse flags
while [ $# -gt 0 ]; do
@@ -176,6 +177,14 @@ while [ $# -gt 0 ]; do
ENABLE_LIBREADLINE=0
shift
;;
+ --enable-liblowdown)
+ ENABLE_LIBLOWDOWN=1
+ shift
+ ;;
+ --disable-liblowdown)
+ ENABLE_LIBLOWDOWN=0
+ shift
+ ;;
--debug)
OPTIMISE=debug
shift
@@ -262,6 +271,13 @@ else
LIBREADLINE_FOUND=0
fi
+ # Lowdown
+ if [ $ENABLE_LIBLOWDOWN -eq 1 ]; then
+ find_package lowdown LIBLOWDOWN optional
+ else
+ LIBLOWDOWN_FOUND=0
+ fi
+
###################################################################
# TESTS and other programs
###################################################################
@@ -299,6 +315,9 @@ sed \
-e "s|@LIBREADLINE_FOUND@|$LIBREADLINE_FOUND|g" \
-e "s|@LIBREADLINE_CFLAGS@|$LIBREADLINE_CFLAGS|g" \
-e "s|@LIBREADLINE_LIBS@|$LIBREADLINE_LIBS|g" \
+ -e "s|@LIBLOWDOWN_FOUND@|$LIBLOWDOWN_FOUND|g" \
+ -e "s|@LIBLOWDOWN_CFLAGS@|$LIBLOWDOWN_CFLAGS|g" \
+ -e "s|@LIBLOWDOWN_LIBS@|$LIBLOWDOWN_LIBS|g" \
-e "s|@CONFIGURE_CMD_ARGS@|$CONFIGURE_CMD_ARGS|g" \
-e "s|@CC@|$CC|g" \
-e "s|@CCOM@|$CCOM|g" \
@@ -356,5 +375,10 @@ echo " Using libreadline:"
echo " LIBREADLINE_CFLAGS: ${LIBREADLINE_CFLAGS}"
echo " LIBREADLINE_LIBS: ${LIBREADLINE_LIBS}"
fi
+ if [ $LIBLOWDOWN_FOUND -eq 1 ]; then
+ echo " Using lowdown:"
+ echo " LIBLOWDOWN_CFLAGS: ${LIBLOWDOWN_CFLAGS}"
+ echo " LIBLOWDOWN_LIBS: ${LIBLOWDOWN_LIBS}"
+ fi
echo ""
echo "Configuration done. You may now run make."
diff --git a/src/cmd/cmd.c b/src/cmd/cmd.c
index a1496e22..3ad75075 100644
--- a/src/cmd/cmd.c
+++ b/src/cmd/cmd.c
@@ -39,6 +39,13 @@
#include <curl/curl.h>
+ #ifdef HAVE_LIBLOWDOWN
+ #include <sys/queue.h>
+
+ #include <locale.h>
+ #include <lowdown.h>
+ #endif
+
void
copyright(void)
{
@@ -151,6 +158,53 @@ delete_repo(bool always_yes, const char *owner, const char *repo)
errx(1, "gcli: error: failed to delete repo");
}
+ #ifdef HAVE_LIBLOWDOWN
+ void
+ gcli_pretty_print(char const *input, int indent, int maxlinelen, FILE *stream)
+ {
+ size_t input_size;
+ struct lowdown_buf *out;
+ struct lowdown_doc *doc;
+ struct lowdown_node *n;
+ struct lowdown_opts opts = {0};
+ void *rndr;
+
+ input_size = strlen(input);
+
+ if (setlocale(LC_CTYPE, "en_US.UTF-8") == NULL)
+ err(1, NULL);
+
+ opts.feat |= LOWDOWN_FENCED|LOWDOWN_TASKLIST|LOWDOWN_TABLES;
+ if (!gcli_config_have_colours(g_clictx))
+ opts.oflags |= (LOWDOWN_TERM_NOANSI|LOWDOWN_TERM_NOCOLOUR);
+
+ opts.vmargin = 1;
+ opts.hmargin = indent - 4; /* somehow there's always 4 spaces being emitted by lowdown */
+ opts.cols = maxlinelen;
+
+ if ((doc = lowdown_doc_new(&opts)) == NULL)
+ err(1, NULL);
+
+ if ((n = lowdown_doc_parse(doc, NULL, input, input_size, NULL)) == NULL)
+ err(1, NULL);
+
+ if ((out = lowdown_buf_new(256)) == NULL)
+ err(1, NULL);
+
+ if ((rndr = lowdown_term_new(&opts)) == NULL)
+ err(1, NULL);
+
+ if (!lowdown_term_rndr(out, rndr, n))
+ err(1, NULL);
+
+ fwrite(out->data, 1, out->size, stream);
+
+ lowdown_term_free(rndr);
+ lowdown_buf_free(out);
+ lowdown_node_free(n);
+ lowdown_doc_free(doc);
+ }
+ #else
static int
word_length(const char *x)
{
@@ -193,3 +247,4 @@ gcli_pretty_print(const char *input, int indent, int maxlinelen, FILE *out)
fputc('\n', out);
}
}
+ #endif
--
2.45.2
Re: [PATCH gcli v2 1/3] Bump required C Language Standard to C11
Nico Sonack, Aug 16, 2024 at 19:17:
> We have made this decision after thinking and discussing. Reasons are:
>
> - C99 is now 25 years old and one can safely assume that any modern system
> supports it - C11 is now 13 years old and all platforms that we have
> tested so far have been supporting C11 for years now. This also applies
> to all the compilers we have been using to build gcli so far.
> - Compatibility with more optional libraries
> I plan to integrate the lowdown library for Markdown rendering. It requires
> C11. I have previously encountered such a case too.
> - More modern language features:
> We can now use anonymous unions and static assertions.
> - gcli is a tool for a modern development workflow:
> Thus we can assume a reasonably modern system - where C11 is supported.
>
> If you have a system where these changes cause trouble and heart
> ache or you wish to complain about this decision please do so on our
> mailing list or IRC.
>
> Signed-off-by: Nico Sonack <nsonack@herrhotzenplotz.de >
> ---
Applied and pushed the whole series, there was a missing include
However I have fixed.
Thanks!