Subject: sysctl auto man page generation
To: None <current-users@netbsd.org>
From: Eric Haszlakiewicz <erh@jodi.nimenees.com>
List: current-users
Date: 07/29/2004 15:40:30
--/9DWx/yDrRhgMJTb
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline


	I wrote an awk script to re-arrange the output of "sysctl -M" into a
form suitable for insertion into sysctl.8.  I also have it including
the description of each node, but as another .It line after each .It
for the node.  It looks like crap.  My nroff/mandoc skills are mostly 
non-existant.  Can someone take a look and suggest a better way to format
it?

	I've attached the awk script.  An example updated man page is at:
http://www.nimenees.com/netbsd/sysctl.8.new

eric

--/9DWx/yDrRhgMJTb
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="sysctl.awk"

#
# Generate the list of sysctl nodes for use on the sysctl man page.
#
# sysctl -M | sort | awk -f sysctl.awk > sysctl.list
# Then paste sysctl.list into sysctl.8
# (look for "Changeable")
#

BEGIN {
	nodetype = "";
	nodename = "";
	changable = "";

	# Set special values for names, types and changability.
	special_name["vendor"] = "vendor.\\*[Lt]vendor\\*[Gt].*";

	special_type["vendor"] = "?";

	special_rw["kern.maxvnodes"] = "raise only";
	special_rw["kern.mbuf.nmbclusters"] = "raise only";
	special_rw["kern.securelevel"] = "raise only";
	special_rw["vendor"] = "vendor specific";

	cmd="uname -sr";
	cmd | getline osver;
	print ".\\\" This list was generated on", osver;
}

{
	# Save the actual node name for the lookup tables.
	realnodename=$1;

	# Turn the actual node name into the documented node name
	if (realnodename ~ /proc.curproc/)
	{
		# proc.curproc is special.
		nodename=realnodename;
		sub("proc.curproc", "proc.<pid>", nodename);
	}
	else if (special_name[realnodename])
		nodename=special_name[realnodename];
	else
		nodename=$1;

	# Decode the type of node
	if (special_type[realnodename])
		nodetype=special_type[realnodename];
	else if ($0 ~ /CTLTYPE_NODE/)
	{
		#nodetype = "node";
		# Skip non-leaf nodes.  They're not all that interesting.
		next;
	}
	else if ($0 ~ /CTLTYPE_INT/)
		nodetype = "integer";
	else if ($0 ~ /CTLTYPE_STRING/)
		nodetype = "string";
	else if ($0 ~ /CTLTYPE_QUAD/)
		nodetype = "quad";
	else if ($0 ~ /CTLTYPE_STRUCT/)
		nodetype = "struct";
	else
	{
		print "Unknown node type!:", $0;
		exit 1;
	}

	# Decode the writability of the node
	if (special_rw[realnodename])
		changeable = special_rw[realnodename];
	else if ($0 ~ /READONLY/)
		changeable = "no";
	else if ($0 ~ /READWRITE/)
	{
		if ($0 ~ /func=/)
			changeable = "yes, special";
		else
			changeable = "yes";
	}
	else
	{
		print "Unknown readwrite setting!:", $0;
		exit 1
	}

	# Print an item entry to put in the man page.
	printf(".It %s	%s	%s\n", nodename, nodetype, changeable);

	# Get the description from the kernel.
	cmd = "sysctl -nd " realnodename;
	cmd | getline description;
	close(cmd);
	if (description)
		printf(".It \\ \\ %s\n", description);
}


--/9DWx/yDrRhgMJTb--