Gidday! I have ready some code to extract source code from EXAMPLES in man-pages. For that, I set up some convention: Enclose the code (including the enclosing .EX/.EE in a pair of comments with a very precise formatting: [[ ... .\" SRC BEGIN (program_name.c) .EX #include <stdio.h> int main(void) { printf("Hello, world!"); } .EE .\" SRC END ... ]] There can be multiple programs in a single page, with the only restriction that each of them has to have a different program_name (there can be collisions within different manual pages, but not within the same manual page) The Makefile will create a directory for each manal page, where the different programs will be created with the name specified in the comment (that's why it has to be different from others in the same page only). Please, check that you like what you see, and comment if not (or if yes too :). I tested it with membarrier.2, and it produced a correct .c file. The next step will be to add targets to lint and compile the produced files, to check their correctness. I hope this will make our lives much easier maintaining manual pages :-) Cheers, Alex diff --git a/Makefile b/Makefile index 03ebde18c..05a1b5950 100644 --- a/Makefile +++ b/Makefile @@ -30,19 +30,20 @@ MAKEFLAGS += --no-print-directory MAKEFLAGS += --warn-undefined-variables -srcdir := . +srcdir := . builddir := tmp -LINTDIR := $(builddir)/lint -HTMLDIR := $(builddir)/html +LINTDIR := $(builddir)/lint +HTMLDIR := $(builddir)/html +SRCDIR := $(builddir)/src DESTDIR := -prefix := /usr/local -SYSCONFDIR := $(srcdir)/etc -TMACDIR := $(SYSCONFDIR)/groff/tmac +prefix := /usr/local +SYSCONFDIR := $(srcdir)/etc +TMACDIR := $(SYSCONFDIR)/groff/tmac datarootdir := $(prefix)/share -docdir := $(datarootdir)/doc -MANDIR := $(srcdir) -mandir := $(datarootdir)/man +docdir := $(datarootdir)/doc +MANDIR := $(srcdir) +mandir := $(datarootdir)/man MAN0DIR := $(MANDIR)/man0 MAN1DIR := $(MANDIR)/man1 MAN2DIR := $(MANDIR)/man2 @@ -61,7 +62,7 @@ man5dir := $(mandir)/man5 man6dir := $(mandir)/man6 man7dir := $(mandir)/man7 man8dir := $(mandir)/man8 -manext := \.[0-9] +manext := \.[0-9] man0ext := .0 man1ext := .1 man2ext := .2 @@ -71,9 +72,9 @@ man5ext := .5 man6ext := .6 man7ext := .7 man8ext := .8 -htmldir := $(docdir) +htmldir := $(docdir) htmldir_ := $(htmldir)/man -htmlext := .html +htmlext := .html TMACFILES := $(sort $(shell find $(TMACDIR) -not -type d)) TMACNAMES := $(basename $(notdir $(TMACFILES))) @@ -99,9 +100,11 @@ MAN2HTMLFLAGS := $(DEFAULT_MAN2HTMLFLAGS) $(EXTRA_MAN2HTMLFLAGS) INSTALL := install INSTALL_DATA := $(INSTALL) -m 644 INSTALL_DIR := $(INSTALL) -m 755 -d +MKDIR := mkdir -p RM := rm RMDIR := rmdir --ignore-fail-on-non-empty GROFF := groff +MAN := man MANDOC := mandoc MAN2HTML := man2html @@ -161,12 +164,14 @@ _man5pages := $(filter %$(man5ext),$(_manpages)) _man6pages := $(filter %$(man6ext),$(_manpages)) _man7pages := $(filter %$(man7ext),$(_manpages)) _man8pages := $(filter %$(man8ext),$(_manpages)) -LINT_groff := $(patsubst $(MANDIR)/%,$(LINTDIR)/%.lint.groff.touch,$(LINTPAGES)) -LINT_mandoc:= $(patsubst $(MANDIR)/%,$(LINTDIR)/%.lint.mandoc.touch,$(LINTPAGES)) +LINT_groff :=$(patsubst $(MANDIR)/%,$(LINTDIR)/%.lint.groff.touch,$(LINTPAGES)) +LINT_mandoc:=$(patsubst $(MANDIR)/%,$(LINTDIR)/%.lint.mandoc.touch,$(LINTPAGES)) +SRCPAGEDIRS:=$(patsubst $(MANDIR)/%,$(SRCDIR)/%,$(LINTPAGES)) MANDIRS := $(sort $(shell find $(MANDIR)/man? -type d)) HTMLDIRS := $(patsubst $(MANDIR)/%,$(HTMLDIR)/%/.,$(MANDIRS)) LINTDIRS := $(patsubst $(MANDIR)/%,$(LINTDIR)/%/.,$(MANDIRS)) +SRCDIRS := $(patsubst $(MANDIR)/%,$(SRCDIR)/%/.,$(MANDIRS)) _htmldirs := $(patsubst $(HTMLDIR)/%,$(DESTDIR)$(htmldir_)/%,$(HTMLDIRS)) _mandirs := $(patsubst $(MANDIR)/%,$(DESTDIR)$(mandir)/%/.,$(MANDIRS)) _man0dir := $(filter %man0/.,$(_mandirs)) @@ -248,6 +253,37 @@ uninstall-man: $(_mandir_rmdir) $(uninstall_manX) @: +######################################################################## +# src + +$(SRCPAGEDIRS): $(SRCDIR)/%: $(MANDIR)/% | $$(@D)/. + $(info MKDIR $@ $<) + $(RM) -rf $@ + $(MKDIR) $@.tmp + <$< \ + sed -n 's/\.\\" SRC BEGIN (\(.*.c\))/\1/p' \ + | while read f; do \ + <$< \ + sed -n \ + -e '/^\.TH/,/^\.SH/{/^\.SH/!p}' \ + -e '/^\.SH EXAMPLES/p' \ + -e "/^\... SRC BEGIN ($$f)$$/,/^\... SRC END$$/p" \ + | $(MAN) -P cat -l - \ + | sed '/^[^ ]/d' \ + >$@.tmp/$$f; \ + done \ + || exit $$? + mv -T $@.tmp $@ + +.PHONY: build-src src +build-src src: $(SRCPAGEDIRS) | builddirs-src + @: + +.PHONY: builddirs-src +builddirs-src: $(SRCDIRS) + @: + + ######################################################################## # lint diff --git a/man2/membarrier.2 b/man2/membarrier.2 index b2e3e035e..a46283dd7 100644 --- a/man2/membarrier.2 +++ b/man2/membarrier.2 @@ -319,6 +319,7 @@ following code (x86) can be transformed using .BR membarrier (): .PP .in +4n +.\" SRC BEGIN (membarrier.c) .EX #include <stdlib.h> @@ -365,6 +366,7 @@ main(int argc, char *argv[]) exit(EXIT_SUCCESS); } .EE +.\" SRC END .in .PP The code above transformed to use -- Alejandro Colomar Linux man-pages comaintainer; https://www.kernel.org/doc/man-pages/ http://www.alejandro-colomar.es/