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

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