diff options
author | Duncan Roe <duncan_roe@optusnet.com.au> | 2021-10-17 12:39:51 +1100 |
---|---|---|
committer | Pablo Neira Ayuso <pablo@netfilter.org> | 2021-10-27 10:14:54 +0200 |
commit | 74576db959cbb762780fdc3feadf6778a62c955b (patch) | |
tree | b4e4a66a4450a2b5fbe02759ed2dd977db961123 | |
parent | 826d412956d263ba0c05a1af52c5d78abfccae21 (diff) |
build: doc: `make` generates requested documentation
Generate man pages, HTML, neither or both according to ./configure.
Based on the work done for libnetfilter_queue.
[ This patch updates the default ./configure option to build the
manpages in case that doxygen is available. ]
Signed-off-by: Duncan Roe <duncan_roe@optusnet.com.au>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
-rw-r--r-- | .gitignore | 6 | ||||
-rw-r--r-- | Makefile.am | 2 | ||||
-rwxr-xr-x | autogen.sh | 8 | ||||
-rw-r--r-- | configure.ac | 46 | ||||
-rw-r--r-- | doxygen/Makefile.am | 39 | ||||
-rwxr-xr-x | doxygen/build_man.sh | 227 | ||||
-rw-r--r-- | doxygen/doxygen.cfg.in (renamed from doxygen.cfg.in) | 9 |
7 files changed, 329 insertions, 8 deletions
@@ -16,6 +16,8 @@ Makefile.in /configure /libtool -/doxygen/ -/doxygen.cfg +/doxygen/doxygen.cfg +/doxygen/doxyfile.stamp +/doxygen/man/ +/doxygen/html/ /*.pc diff --git a/Makefile.am b/Makefile.am index c7b86f7..46b14f9 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,4 +1,4 @@ -SUBDIRS = include src utils +SUBDIRS = include src utils doxygen ACLOCAL_AMFLAGS = -I m4 @@ -1,4 +1,12 @@ #!/bin/sh -e +BUILD_MAN=doxygen/build_man.sh + +# Allow to override build_man.sh url for local testing +# E.g. export NFQ_URL=file:///usr/src/libnetfilter_queue +curl ${NFQ_URL:-https://git.netfilter.org/libnetfilter_queue/plain}/$BUILD_MAN\ + -o$BUILD_MAN +chmod a+x $BUILD_MAN + autoreconf -fi rm -Rf autom4te.cache diff --git a/configure.ac b/configure.ac index 85e49ed..589eb59 100644 --- a/configure.ac +++ b/configure.ac @@ -12,6 +12,23 @@ m4_ifdef([AM_PROG_AR], [AM_PROG_AR]) dnl kernel style compile messages m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])]) +AC_ARG_ENABLE([html-doc], + AS_HELP_STRING([--enable-html-doc], [Enable html documentation]), + [], [enable_html_doc=no]) +AM_CONDITIONAL([BUILD_HTML], [test "$enable_html_doc" = yes]) +AS_IF([test "$enable_html_doc" = yes], + [AC_SUBST(GEN_HTML, YES)], + [AC_SUBST(GEN_HTML, NO)]) + +AC_ARG_ENABLE([man-pages], + AS_HELP_STRING([--disable-man-pages], + [Disable man page documentation]), + [], [enable_man_pages=yes]) +AM_CONDITIONAL([BUILD_MAN], [test "$enable_man_pages" = yes]) +AS_IF([test "$enable_man_pages" = yes], + [AC_SUBST(GEN_MAN, YES)], + [AC_SUBST(GEN_MAN, NO)]) + AC_PROG_CC AM_PROG_CC_C_O LT_INIT([disable_static]) @@ -37,6 +54,27 @@ PKG_CHECK_MODULES([LIBNETFILTER_CONNTRACK], [libnetfilter_conntrack >= 1.0.2], [HAVE_LNFCT=1], [HAVE_LNFCT=0]) AM_CONDITIONAL([BUILD_NFCT], [test "$HAVE_LNFCT" -eq 1]) +AS_IF([test "$enable_man_pages" = no -a "$enable_html_doc" = no], + [with_doxygen=no], [with_doxygen=yes]) + +AS_IF([test "x$with_doxygen" != xno], [ + AC_CHECK_PROGS([DOXYGEN], [doxygen], [""]) + AC_CHECK_PROGS([DOT], [dot], [""]) + AS_IF([test "x$DOT" != "x"], + [AC_SUBST(HAVE_DOT, YES)], + [AC_SUBST(HAVE_DOT, NO)]) +]) + +AM_CONDITIONAL([HAVE_DOXYGEN], [test -n "$DOXYGEN"]) +AS_IF([test "x$DOXYGEN" = x], [ + AS_IF([test "x$with_doxygen" != xno], [ + dnl Only run doxygen Makefile if doxygen installed + AC_MSG_WARN([Doxygen not found - not building documentation]) + enable_html_doc=no + enable_man_pages=no + ]) +]) + dnl Output the makefile AC_CONFIG_FILES([Makefile src/Makefile @@ -45,5 +83,11 @@ AC_CONFIG_FILES([Makefile utils/Makefile libnetfilter_log.pc libnetfilter_log_libipulog.pc - doxygen.cfg]) + doxygen/Makefile + doxygen/doxygen.cfg]) AC_OUTPUT + +echo " +libnetfilter_log configuration: +man pages: ${enable_man_pages} +html docs: ${enable_html_doc}" diff --git a/doxygen/Makefile.am b/doxygen/Makefile.am new file mode 100644 index 0000000..582db4e --- /dev/null +++ b/doxygen/Makefile.am @@ -0,0 +1,39 @@ +if HAVE_DOXYGEN + +doc_srcs = $(top_srcdir)/src/libnetfilter_log.c\ + $(top_srcdir)/src/nlmsg.c\ + $(top_srcdir)/src/libipulog_compat.c + +doxyfile.stamp: $(doc_srcs) Makefile + rm -rf html man + doxygen doxygen.cfg >/dev/null + +if BUILD_MAN + $(abs_top_srcdir)/doxygen/build_man.sh +endif + + touch doxyfile.stamp + +CLEANFILES = doxyfile.stamp + +all-local: doxyfile.stamp +clean-local: + rm -rf man html +install-data-local: +if BUILD_MAN + mkdir -p $(DESTDIR)$(mandir)/man3 + cp --no-dereference --preserve=links,mode,timestamps man/man3/*.3\ + $(DESTDIR)$(mandir)/man3/ +endif +if BUILD_HTML + mkdir -p $(DESTDIR)$(htmldir) + cp --no-dereference --preserve=links,mode,timestamps html/*\ + $(DESTDIR)$(htmldir) +endif + +# make distcheck needs uninstall-local +uninstall-local: + rm -rf $(DESTDIR)$(mandir) man html doxyfile.stamp $(DESTDIR)$(htmldir) +endif + +EXTRA_DIST = build_man.sh diff --git a/doxygen/build_man.sh b/doxygen/build_man.sh new file mode 100755 index 0000000..852c7b8 --- /dev/null +++ b/doxygen/build_man.sh @@ -0,0 +1,227 @@ +#!/bin/bash -p + +# Script to process man pages output by doxygen. +# We need to use bash for its associative array facility. +# (`bash -p` prevents import of functions from the environment). + +declare -A renamed_page + +main(){ + set -e + cd man/man3; rm -f _* + count_real_pages + rename_real_pages + make_symlinks + post_process +} + +count_real_pages(){ + page_count=0 + # + # Count "real" man pages (i.e. not generated by MAN_LINKS) + # MAN_LINKS pages are 1-liners starting .so + # Method: list files in descending order of size, + # looking for the first 1-liner + # + for i in $(ls -S) + do head -n1 $i | grep -E -q '^\.so' && break + page_count=$(($page_count + 1)) + done + first_link=$(($page_count + 1)) +} + +rename_real_pages(){ + for i in $(ls -S | head -n$page_count) + do for j in $(ls -S | tail -n+$first_link) + do grep -E -q $i$ $j && break + done + mv -f $i $j + renamed_page[$i]=$j + done +} + +make_symlinks(){ + for j in $(ls -S | tail -n+$first_link) + do ln -sf ${renamed_page[$(cat $j | cut -f2 -d/)]} $j + done +} + +post_process(){ + make_temp_files + # + # DIAGNOSTIC / DEVELOPMENT CODE + # set -x and restrict processing to keep_me: un-comment to activate + # Change keep_me as required + # + #keep_me=nfq_icmp_get_hdr.3;\ + #do_diagnostics;\ + # + # Work through the "real" man pages + for target in $(ls -S | head -n$page_count) + do mygrep "^\\.SH \"Function Documentation" $target + # Next file if this isn't a function page + [ $linnum -ne 0 ] || continue + + del_modules + del_bogus_synopsis + fix_name_line + move_synopsis + del_empty_det_desc + del_def_at_lines + fix_double_blanks + + # Fix rendering of verbatim "\n" (in code snippets) + sed -i 's/\\n/\\\\n/' $target + + done + + remove_temp_files +} + +fix_double_blanks(){ + linnum=1 + # + # Older versions of man display a blank line on encountering "\fB\fP"; + # newer versions of man do not. + # doxygen emits "\fB\fP" on seeing "\par" on a line by itself. + # "\par" gives us double-spacing in the web doc, which we want, but double- + # spacing looks odd in a man page so remove "\fB\fP". + # + while [ $linnum -ne 0 ] + do mygrep \\\\fB\\\\fP $target + [ $linnum -eq 0 ] || delete_lines $linnum $linnum + done +} + +del_def_at_lines(){ + linnum=1 + while [ $linnum -ne 0 ] + do mygrep "^Definition at line [[:digit:]]* of file" $target + [ $linnum -eq 0 ] || delete_lines $(($linnum - 1)) $linnum + done +} + +# Only invoked if you un-comment the 2 diagnostic / development lines above +do_diagnostics(){ + mv $keep_me xxx + rm *.3 + mv xxx $keep_me + page_count=1 + set -x +} + +del_empty_det_desc(){ + mygrep "^\\.SH \"Function Documentation" $target + i=$linnum + mygrep "^\\.SH \"Detailed Description" $target + [ $linnum -ne 0 ] || return 0 + [ $(($i - $linnum)) -eq 3 ] || return 0 + # A 1-line Detailed Description is also 3 lines long, + # but the 3rd line is not empty + i=$(($i -1)) + [ $(tail -n+$i $target | head -n1 | wc -c) -le 2 ] || return 0 + delete_lines $linnum $i +} + +move_synopsis(){ + mygrep "SH SYNOPSIS" $target + [ $linnum -ne 0 ] || return 0 + i=$linnum + # If this is a doxygen-created synopsis, leave it. + # (We haven't inserted our own one in the source yet) + mygrep "^\\.SS \"Functions" $target + [ $i -gt $linnum ] || return 0 + + mygrep "^\\.SH \"Function Documentation" $target + j=$(($linnum - 1)) + head -n$(($j - 1)) $target | tail -n$(($linnum - $i - 1)) >$fileC + delete_lines $i $j + mygrep "^\\.SS \"Functions" $target + head -n$(($linnum - 1)) $target >$fileA + tail -n+$(($linnum + 1)) $target >$fileB + cat $fileA $fileC $fileB >$target +} + +fix_name_line(){ + all_funcs="" + + # Search a shortened version of the page in case there are .RI lines later + mygrep "^\\.SH \"Function Documentation" $target + head -n$linnum $target >$fileC + + while : + do mygrep ^\\.RI $fileC + [ $linnum -ne 0 ] || break + # Discard this entry + tail -n+$(($linnum + 1)) $fileC >$fileB + cp $fileB $fileC + + func=$(cat $fileG | cut -f2 -d\\ | cut -c3-) + [ -z "$all_funcs" ] && all_funcs=$func ||\ + all_funcs="$all_funcs, $func" + done + # For now, assume name is at line 5 + head -n4 $target >$fileA + desc=$(head -n5 $target | tail -n1 | cut -f3- -d" ") + tail -n+6 $target >$fileB + cat $fileA >$target + echo "$all_funcs \\- $desc" >>$target + cat $fileB >>$target +} + +del_modules(){ + mygrep "^\.SS \"Modules" $target + [ $linnum -ne 0 ] || return 0 + i=$linnum + mygrep "^\\.SS \"Functions" $target + delete_lines $i $(($linnum - 1)) +} + +del_bogus_synopsis(){ + mygrep "SH SYNOPSIS" $target + # + # doxygen 1.8.20 inserts its own SYNOPSIS line but there is no mention + # in the documentation or git log what to do with it. + # So get rid of it + # + [ $linnum -ne 0 ] || return 0 + i=$linnum + # Look for the next one + tail -n+$(($i + 1)) $target >$fileC;\ + mygrep "SH SYNOPSIS" $fileC + [ $linnum -ne 0 ] || return 0 + + mygrep "^\\.SS \"Functions" $target + delete_lines $i $(($linnum - 1)) +} + +# Delete lines $1 through $2 from $target +delete_lines(){ + head -n$(($1 - 1)) $target >$fileA + tail -n+$(($2 +1)) $target >$fileB + cat $fileA $fileB >$target +} + +mygrep(){ + set +e + grep -En "$1" $2 2>/dev/null >$fileH + [ $? -ne 0 ] && linnum=0 ||\ + { head -n1 $fileH >$fileG; linnum=$(cat $fileG | cut -f1 -d:); } + set -e +} + +make_temp_files(){ + temps="A B C G H" + for i in $temps + do declare -g file$i=$(mktemp) + done +} + +remove_temp_files(){ + for i in $temps + do j=file$i + rm ${!j} + done +} + +main diff --git a/doxygen.cfg.in b/doxygen/doxygen.cfg.in index dc2fddb..b6c27dc 100644 --- a/doxygen.cfg.in +++ b/doxygen/doxygen.cfg.in @@ -1,12 +1,11 @@ # Difference with default Doxyfile 1.8.20 PROJECT_NAME = @PACKAGE@ PROJECT_NUMBER = @VERSION@ -OUTPUT_DIRECTORY = doxygen ABBREVIATE_BRIEF = FULL_PATH_NAMES = NO TAB_SIZE = 8 OPTIMIZE_OUTPUT_FOR_C = YES -INPUT = . +INPUT = @abs_top_srcdir@/src FILE_PATTERNS = *.c RECURSIVE = YES EXCLUDE_SYMBOLS = nflog_g_handle \ @@ -18,7 +17,9 @@ SOURCE_BROWSER = YES ALPHABETICAL_INDEX = NO GENERATE_LATEX = NO LATEX_CMD_NAME = latex -GENERATE_MAN = YES -HAVE_DOT = YES +GENERATE_MAN = @GEN_MAN@ +GENERATE_HTML = @GEN_HTML@ +MAN_LINKS = YES +HAVE_DOT = @HAVE_DOT@ DOT_TRANSPARENT = YES SEARCHENGINE = NO |