anitazha / rpms / ndctl

Forked from rpms/ndctl a year ago
Clone

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

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