Blame SOURCES/0048-scripts-Add-a-man-page-template-generator.patch

26ccd9
From 706a418798633ccb550b114eca7cc11038ab2695 Mon Sep 17 00:00:00 2001
26ccd9
From: Vishal Verma <vishal.l.verma@intel.com>
26ccd9
Date: Tue, 14 Dec 2021 19:01:02 -0700
26ccd9
Subject: [PATCH 048/217] scripts: Add a man page template generator
26ccd9
26ccd9
Add a script to generate man page templates for the utils and libraries
26ccd9
under ndctl - including cxl, libcxl, ndctl, and daxctl.
26ccd9
26ccd9
The script can control certain include options depending on the options
26ccd9
supplied, and either dump the templates to stdout, or write the actual
26ccd9
files in their eventual directories, and open up an editor to further
26ccd9
edit them (unless --no-edit is used).
26ccd9
26ccd9
Link: https://lore.kernel.org/r/20211215020102.97880-1-vishal.l.verma@intel.com
26ccd9
Cc: Dan Williams <dan.j.williams@intel.com>
26ccd9
Signed-off-by: Vishal Verma <vishal.l.verma@intel.com>
26ccd9
---
26ccd9
 scripts/docsurgeon                     | 339 +++++++++++++++++++++++++
26ccd9
 scripts/docsurgeon_parser_generator.m4 |  23 ++
26ccd9
 2 files changed, 362 insertions(+)
26ccd9
 create mode 100755 scripts/docsurgeon
26ccd9
 create mode 100644 scripts/docsurgeon_parser_generator.m4
26ccd9
26ccd9
diff --git a/scripts/docsurgeon b/scripts/docsurgeon
26ccd9
new file mode 100755
26ccd9
index 0000000..ca0ad78
26ccd9
--- /dev/null
26ccd9
+++ b/scripts/docsurgeon
26ccd9
@@ -0,0 +1,339 @@
26ccd9
+#!/bin/bash -eE
26ccd9
+
26ccd9
+this_script="docsurgeon"
26ccd9
+script_dir="$(cd "$(dirname "$(readlink -e "${BASH_SOURCE[0]}")")" && pwd)"
26ccd9
+env_file="${script_dir}/.env"
26ccd9
+if [ -e "$env_file" ]; then
26ccd9
+	# shellcheck source=.env
26ccd9
+	. "$env_file"
26ccd9
+fi
26ccd9
+
26ccd9
+sources_file="${script_dir}/.sources"
26ccd9
+
26ccd9
+parser_generator="${script_dir}/${this_script}_parser_generator.m4"
26ccd9
+parser_lib="${script_dir}/${this_script}_parser.sh"
26ccd9
+if [ ! -e "$parser_lib" ] || [ "$parser_generator" -nt "$parser_lib" ]; then
26ccd9
+	if command -V argbash > /dev/null; then
26ccd9
+		argbash --strip user-content "$parser_generator" -o "$parser_lib"
26ccd9
+	else
26ccd9
+		echo "error: please install argbash" >&2
26ccd9
+		exit 1
26ccd9
+	fi
26ccd9
+fi
26ccd9
+
26ccd9
+if [[ $1 != "bin" ]]; then
26ccd9
+	# shellcheck source=docsurgeon_parser.sh
26ccd9
+	. "${script_dir}/${this_script}_parser.sh" || { echo "Couldn't find $parser_lib" >&2; exit 1; }
26ccd9
+fi
26ccd9
+
26ccd9
+# some script defaults - override using '.env'
26ccd9
+docbase="Documentation"
26ccd9
+copyright_cli="// SPDX-License-Identifier: GPL-2.0"
26ccd9
+copyright_footer_cli="include::../copyright.txt[]"
26ccd9
+copyright_lib="// SPDX-License-Identifier: LGPL-2.0"
26ccd9
+copyright_footer_lib="include::../../copyright.txt[]"
26ccd9
+
26ccd9
+# List of files we're creating, to be edited/renamed later
26ccd9
+# This starts out blank, and is filled in as we go by gen_*() functions
26ccd9
+declare -a outfiles
26ccd9
+
26ccd9
+cleanup()
26ccd9
+{
26ccd9
+	if [ ${#outfiles[@]} -gt 0 ]; then
26ccd9
+		rm -f "${outfiles[@]}"
26ccd9
+	fi
26ccd9
+	set +x
26ccd9
+}
26ccd9
+
26ccd9
+trap cleanup EXIT
26ccd9
+
26ccd9
+auto_detect_params()
26ccd9
+{
26ccd9
+	fs=""
26ccd9
+	module=""
26ccd9
+	section=""
26ccd9
+
26ccd9
+	# if module and section were explicitly specified, respect them
26ccd9
+	if [[ $_arg_module ]] && [[ $_arg_section ]]; then
26ccd9
+		return
26ccd9
+	fi
26ccd9
+
26ccd9
+	# check if names are self-consistent, and determine 'fs'
26ccd9
+	for name in ${_arg_name[@]}; do
26ccd9
+		if [[ ! $fs ]]; then
26ccd9
+			if [[ $name == *-* ]]; then
26ccd9
+				fs="-"
26ccd9
+			elif [[ $name == *_* ]]; then
26ccd9
+				fs="_"
26ccd9
+			else
26ccd9
+				# can't autodetect section
26ccd9
+				return
26ccd9
+			fi
26ccd9
+		fi
26ccd9
+		if [[ $fs == "-" ]] && [[ $name == *_* ]]; then
26ccd9
+			die "can't auto-detect params with mixed-style names"
26ccd9
+		fi
26ccd9
+		if [[ $fs == "_" ]] && [[ $name == *-* ]]; then
26ccd9
+			die "can't auto-detect params with mixed-style names"
26ccd9
+		fi
26ccd9
+	done
26ccd9
+
26ccd9
+	# try to detect module name
26ccd9
+	for name in ${_arg_name[@]}; do
26ccd9
+		str=${name%%$fs*}
26ccd9
+		if [[ $module ]]; then
26ccd9
+			if [[ $str != $module ]]; then
26ccd9
+				die "Can't autodetect module because of mixed names ($str and $module)"
26ccd9
+			fi
26ccd9
+		else
26ccd9
+			module="$str"
26ccd9
+		fi
26ccd9
+	done
26ccd9
+
26ccd9
+	# try to detect section number
26ccd9
+	case "$fs" in
26ccd9
+	-)
26ccd9
+		section=1
26ccd9
+		;;
26ccd9
+	_)
26ccd9
+		section=3
26ccd9
+		;;
26ccd9
+	*)
26ccd9
+		die "Unknown fs, can't autodetect section number"
26ccd9
+		;;
26ccd9
+	esac
26ccd9
+
26ccd9
+	if [[ $module ]]; then
26ccd9
+		_arg_module="$module"
26ccd9
+	fi
26ccd9
+	if [[ $section ]]; then
26ccd9
+		_arg_section="$section"
26ccd9
+	fi
26ccd9
+}
26ccd9
+
26ccd9
+process_options_logic()
26ccd9
+{
26ccd9
+	if [[ $_arg_debug == "on" ]]; then
26ccd9
+		set -x
26ccd9
+	fi
26ccd9
+
26ccd9
+	auto_detect_params
26ccd9
+}
26ccd9
+
26ccd9
+gen_underline()
26ccd9
+{
26ccd9
+	name="$1"
26ccd9
+	char="$2"
26ccd9
+	num="${#name}"
26ccd9
+
26ccd9
+	printf -v tmpstring "%-${num}s" " "
26ccd9
+	echo "${tmpstring// /$char}"
26ccd9
+}
26ccd9
+
26ccd9
+gen_header()
26ccd9
+{
26ccd9
+	printf "\n%s\n%s\n" "$1" "$(gen_underline "$1" "=")"
26ccd9
+}
26ccd9
+
26ccd9
+gen_section()
26ccd9
+{
26ccd9
+	printf "\n%s\n%s\n" "$1" "$(gen_underline "$1" "-")"
26ccd9
+}
26ccd9
+
26ccd9
+gen_section_name()
26ccd9
+{
26ccd9
+	name="$1"
26ccd9
+
26ccd9
+	gen_section "NAME"
26ccd9
+	cat <<- EOF
26ccd9
+		$name - 
26ccd9
+	EOF
26ccd9
+}
26ccd9
+
26ccd9
+gen_section_synopsis_1()
26ccd9
+{
26ccd9
+	name="$1"
26ccd9
+
26ccd9
+	gen_section "SYNOPSIS"
26ccd9
+	cat <<- EOF
26ccd9
+		[verse]
26ccd9
+		'$_arg_module ${name#*-} [<options>]'
26ccd9
+	EOF
26ccd9
+}
26ccd9
+
26ccd9
+gen_section_synopsis_3()
26ccd9
+{
26ccd9
+	name="$1"
26ccd9
+
26ccd9
+	gen_section "SYNOPSIS"
26ccd9
+	cat <<- EOF
26ccd9
+		[verse]
26ccd9
+		----
26ccd9
+		#include <$_arg_module/lib$_arg_module.h>
26ccd9
+
26ccd9
+		<type> $name();
26ccd9
+		----
26ccd9
+	EOF
26ccd9
+}
26ccd9
+
26ccd9
+gen_section_example_1()
26ccd9
+{
26ccd9
+	name="$1"
26ccd9
+
26ccd9
+	gen_section "EXAMPLE"
26ccd9
+	cat <<- EOF
26ccd9
+		----
26ccd9
+		# $_arg_module ${name#*-}
26ccd9
+		----
26ccd9
+	EOF
26ccd9
+}
26ccd9
+
26ccd9
+gen_section_example_3()
26ccd9
+{
26ccd9
+	name="$1"
26ccd9
+
26ccd9
+	gen_section "EXAMPLE"
26ccd9
+	cat <<- EOF
26ccd9
+		See example usage in test/lib$_arg_module.c
26ccd9
+	EOF
26ccd9
+}
26ccd9
+
26ccd9
+gen_section_options_1()
26ccd9
+{
26ccd9
+	gen_section "OPTIONS"
26ccd9
+cat << EOF
26ccd9
+-o::
26ccd9
+--option::
26ccd9
+	Description
26ccd9
+EOF
26ccd9
+
26ccd9
+	if [[ $_arg_human_option == "on" ]]; then
26ccd9
+		printf "\n%s\n" "include::human-option.txt[]"
26ccd9
+	fi
26ccd9
+	if [[ $_arg_verbose_option == "on" ]]; then
26ccd9
+		printf "\n%s\n" "include::verbose-option.txt[]"
26ccd9
+	fi
26ccd9
+}
26ccd9
+
26ccd9
+gen_section_seealso_1()
26ccd9
+{
26ccd9
+	gen_section "SEE ALSO"
26ccd9
+	cat <<- EOF
26ccd9
+	link$_arg_module:$_arg_module-list[$_arg_section],
26ccd9
+	EOF
26ccd9
+}
26ccd9
+
26ccd9
+gen_section_seealso_3()
26ccd9
+{
26ccd9
+	gen_section "SEE ALSO"
26ccd9
+	cat <<- EOF
26ccd9
+	linklib$_arg_module:${_arg_module}_other_API[$_arg_section],
26ccd9
+	EOF
26ccd9
+}
26ccd9
+
26ccd9
+gen_cli()
26ccd9
+{
26ccd9
+	name="$1"
26ccd9
+	path="$docbase/$_arg_module"
26ccd9
+	if [ ! -d "$path" ]; then
26ccd9
+		die "Not found: $path"
26ccd9
+	fi
26ccd9
+
26ccd9
+	tmp="$(mktemp -p "$path" "$name.txt.XXXX")"
26ccd9
+	outfiles+=("$tmp")
26ccd9
+
26ccd9
+	# Start template generation
26ccd9
+	printf "%s\n" "$copyright_cli" > "$tmp"
26ccd9
+	gen_header "$name" >> "$tmp"
26ccd9
+	gen_section_name "$name" >> "$tmp"
26ccd9
+	gen_section_synopsis_1 "$name" >> "$tmp"
26ccd9
+	gen_section "DESCRIPTION" >> "$tmp"
26ccd9
+	gen_section_example_1 "$name" >> "$tmp"
26ccd9
+	gen_section_options_1 >> "$tmp"
26ccd9
+	printf "\n%s\n" "$copyright_footer_cli" >> "$tmp"
26ccd9
+	gen_section_seealso_1 >> "$tmp"
26ccd9
+}
26ccd9
+
26ccd9
+gen_lib()
26ccd9
+{
26ccd9
+	name="$1"
26ccd9
+	path="$docbase/$_arg_module/lib"
26ccd9
+	if [ ! -d "$path" ]; then
26ccd9
+		die "Not found: $path"
26ccd9
+	fi
26ccd9
+
26ccd9
+	tmp="$(mktemp -p "$path" "$name.txt.XXXX")"
26ccd9
+	outfiles+=("$tmp")
26ccd9
+
26ccd9
+	# Start template generation
26ccd9
+	printf "%s\n" "$copyright_lib" > "$tmp"
26ccd9
+	gen_header "$name($_arg_section)" >> "$tmp"
26ccd9
+	gen_section_name "$name" >> "$tmp"
26ccd9
+	gen_section_synopsis_3 "$name" >> "$tmp"
26ccd9
+	gen_section "DESCRIPTION" >> "$tmp"
26ccd9
+	gen_section "RETURN VALUE" >> "$tmp"
26ccd9
+	gen_section_example_3 "$name" >> "$tmp"
26ccd9
+	printf "\n%s\n" "$copyright_footer_lib" >> "$tmp"
26ccd9
+	gen_section_seealso_3 >> "$tmp"
26ccd9
+}
26ccd9
+
26ccd9
+gen_man()
26ccd9
+{
26ccd9
+	name="$1"
26ccd9
+	case "$_arg_section" in
26ccd9
+	1)
26ccd9
+		gen_cli "$name"
26ccd9
+		;;
26ccd9
+	3)
26ccd9
+		gen_lib "$name"
26ccd9
+		;;
26ccd9
+	*)
26ccd9
+		die "Unknown section: $_arg_section"
26ccd9
+		;;
26ccd9
+	esac
26ccd9
+}
26ccd9
+
26ccd9
+gen_include()
26ccd9
+{
26ccd9
+	echo "in gen_include"
26ccd9
+}
26ccd9
+
26ccd9
+main()
26ccd9
+{
26ccd9
+	process_options_logic
26ccd9
+
26ccd9
+	cmd="$_arg_command"
26ccd9
+	case "$cmd" in
26ccd9
+	gen-man)
26ccd9
+		for name in ${_arg_name[@]}; do
26ccd9
+			gen_man "$name"
26ccd9
+		done
26ccd9
+		;;
26ccd9
+	gen-include)
26ccd9
+		for name in ${_arg_name[@]}; do
26ccd9
+			gen_include
26ccd9
+		done
26ccd9
+		;;
26ccd9
+	*)
26ccd9
+		die "Unknown command: $cmd"
26ccd9
+		;;
26ccd9
+	esac
26ccd9
+
26ccd9
+	if [[ $_arg_dump == "on" ]]; then
26ccd9
+		for file in ${outfiles[@]}; do
26ccd9
+			echo "${file##*/}"
26ccd9
+			cat "$file"
26ccd9
+			rm "$file"
26ccd9
+		done
26ccd9
+	elif [ ${#outfiles[@]} -gt 0 ]; then
26ccd9
+		if [[ $_arg_edit = "on" ]]; then
26ccd9
+			vim -p "${outfiles[@]}"
26ccd9
+		fi
26ccd9
+
26ccd9
+		for file in ${outfiles[@]}; do
26ccd9
+			mv "$file" "${file%.*}"
26ccd9
+		done
26ccd9
+	fi
26ccd9
+}
26ccd9
+
26ccd9
+main "$@"
26ccd9
diff --git a/scripts/docsurgeon_parser_generator.m4 b/scripts/docsurgeon_parser_generator.m4
26ccd9
new file mode 100644
26ccd9
index 0000000..9283c7c
26ccd9
--- /dev/null
26ccd9
+++ b/scripts/docsurgeon_parser_generator.m4
26ccd9
@@ -0,0 +1,23 @@
26ccd9
+#!/bin/bash
26ccd9
+
26ccd9
+# m4_ignore(
26ccd9
+echo "This is just a parsing library template, not the library - pass this file to 'argbash' to fix this." >&2
26ccd9
+exit 11  #)Created by argbash-init v2.9.0
26ccd9
+# Rearrange the order of options below according to what you would like to see in the help message.
26ccd9
+# ARG_OPTIONAL_REPEATED([name], [n], [Command or function name to generate a template for.\n Can be repeated for multiple names. ], [])
26ccd9
+# ARG_OPTIONAL_BOOLEAN([edit], [e], [Edit template files after creation], [on])
26ccd9
+# ARG_OPTIONAL_BOOLEAN([debug], [], [Debug script problems (enables set -x)], )
26ccd9
+# ARG_OPTIONAL_BOOLEAN([dump], [], [Write generated file to stdout instead of a file], )
26ccd9
+# ARG_OPTIONAL_SINGLE([module], [m], [Module (Docs subdir) in which to create the template], [])
26ccd9
+# ARG_OPTIONAL_SINGLE([section], [s], [man section for which to create the template], [])
26ccd9
+# ARG_OPTIONAL_BOOLEAN([human-option], [u], [Include the human option in 'OPTIONS'], )
26ccd9
+# ARG_OPTIONAL_BOOLEAN([verbose-option], [V], [Include the verbose option in 'OPTIONS'], )
26ccd9
+# ARG_POSITIONAL_DOUBLEDASH()
26ccd9
+# ARG_POSITIONAL_SINGLE([command], [Operation to perform:\n  gen-man\n  gen-include], [])
26ccd9
+# ARGBASH_SET_DELIM([ =])
26ccd9
+# ARG_OPTION_STACKING([getopt])
26ccd9
+# ARG_RESTRICT_VALUES([no-local-options])
26ccd9
+# ARG_DEFAULTS_POS
26ccd9
+# ARG_HELP([Tool to aid in creating and managing man page templates])
26ccd9
+# ARG_VERSION([echo "docsurgeon 0.1"])
26ccd9
+# ARGBASH_GO
26ccd9
-- 
26ccd9
2.27.0
26ccd9