about summary refs log tree commit diff
path: root/Util
diff options
context:
space:
mode:
Diffstat (limited to 'Util')
-rw-r--r--Util/.distfiles4
-rwxr-xr-xUtil/helpfiles182
-rwxr-xr-xUtil/mkdisttree.sh76
-rw-r--r--Util/reporter444
-rw-r--r--Util/zsh-development-guide138
5 files changed, 844 insertions, 0 deletions
diff --git a/Util/.distfiles b/Util/.distfiles
new file mode 100644
index 000000000..1591692ce
--- /dev/null
+++ b/Util/.distfiles
@@ -0,0 +1,4 @@
+DISTFILES_SRC='
+    .distfiles
+    helpfiles mkdisttree.sh reporter zsh-development-guide
+'
diff --git a/Util/helpfiles b/Util/helpfiles
new file mode 100755
index 000000000..472132b29
--- /dev/null
+++ b/Util/helpfiles
@@ -0,0 +1,182 @@
+#!/usr/local/bin/perl -- -*-perl-*-
+
+# helpfiles:  make help files for Z-shell builtins from the manual entries.
+
+# Create help files for zsh commands in the current directory;
+# assumes no other files are present.
+# No overwriting check;  `.' becomes `dot', `:' becomes `colon'.
+
+# Any command claiming to be `same as <foo>' or `equivalent to <foo>'
+# has its help file appended to the end of <foo>'s and replaced by a
+# link to <foo>.  (Arguably the help file should be put at the start
+# instead.)
+
+# Takes one filename argument, or stdin: the zsh manual page as a plain
+# ascii file: `man zshbuiltins | colcrt -' (remember the -) should do
+# the trick.
+
+# If you don't have colcrt, try 'col -bx'.  The x is necessary so that
+# spaces don't turn into tabs, which messes up the calculations of
+# indentation on machines which randomly wrap lines round to the
+# previous line (so you see what we're up against).
+
+# Example usage:
+#    cd ~/zsh-3.0.0				# or wherever
+#    mkdir Help
+#    cd Help
+#    man zsh | colcrt - | helpfiles
+#    run-help() {
+#      typeset zhelp=~/zsh-3.0.0/Help		# or wherever
+#      [[ $1 = . ]] && 1=dot
+#      [[ $1 = : ]] && 1=colon
+#      if [[ $1 = compctl ]]; then
+#         man zshcompctl
+#      elif [[ -f $zhelp/$1 ]]; then
+#    	  ${=PAGER:-more} $zhelp/$1
+#      else
+#    	  man $1
+#      fi
+#    }
+# now <Esc>-h works for shell builtins.
+
+while (<>) {
+    last if /^\s*SHELL BUILTIN COMMANDS/;
+    /zshbuiltins/ && $zb++;
+    last if ($zb && /^\s*DESCRIPTIONS/);
+}
+
+$print = 0;
+
+sub namesub {
+    local($cmd) = shift;
+    if ($cmd =~ /^\w+$/) {
+	$cmd;
+    } elsif ($cmd eq '.') {
+	'dot';
+    } elsif ($cmd eq ':') {
+	'colon';
+    } else {
+	undef;
+    }
+}
+
+sub getsame {
+    local($_) = shift;
+    if (/same\s*as\s*(\S+)/i || /equivalent\s*to\s*(\S+)/i) {
+	local($name) = $1;
+	($name =~ /[.,]$/) && chop($name);
+	return $name;
+    } else {
+	return undef;
+    }
+}
+
+sub newcmd {
+    local($_) = shift;
+    local($cmd);
+    # new command
+    if (defined($cmd = &namesub($_))) {
+	# in case there's something nasty here like a link..
+	unlink $cmd;
+	open (OUT, ">$cmd");
+	select OUT;
+	$print = 1;
+    } else {
+	$print = 0;
+    }
+}
+
+sub doprint {
+    local($_) = shift;
+
+    s/^$indentstr//o;		# won't work if too many tabs
+    print;
+}
+
+while (<>) { last unless /^\s*$/; }
+
+/^(\s+)(\S+)/;
+$indentstr = $1;
+$indent = length($1);
+&newcmd($2);
+print if $print;
+
+BUILTINS: while (<>) {
+    next if /^\w/;
+
+    undef($undented);
+    if (/^\s*$/ || ($undented = (/^(\s*)/  && length($1) < $indent))) {
+	$undented && &doprint($_);
+	while (defined($_ = <>) && /(^\w)|(^\s*$)/) { 
+	    last BUILTINS if /^STARTUP\/SHUTDOWN FILES/;
+	}
+        if (/^\s*Page/) {
+	    do {
+		$_ = <>;
+	    } while (defined($_) && /^\s*$/);
+	    if (/^\s*ZSHBUILTINS/) {
+		do {
+		    $_ = <>;
+		} while (defined($_) && /^\s*$/);
+	    }
+	}
+	# In zshall, the zshcompctl manual page comes after the
+	# builtins.
+	if (/ZSHCOMPCTL\(1\).*ZSHCOMPCTL\(1\)/) {
+	    last BUILTINS;
+	}
+	if (/^(\s*)/ && length($1) < $indent) {
+	    # This may be just a bug on the SGI, or maybe something
+	    # more sinister (don\'t laugh, this is nroff).
+	    s/^\s*/ /;
+	    $defer = $_;
+	    do {
+		$_ = <>;
+	    } while (defined($_) && /^\s*$/);
+	    last unless defined($_);
+	}
+	if (/^(\s+)(\S+)/ && length($1) == $indent) {
+	    &newcmd($2);
+	}  else {
+	    print "\n";
+	}
+        if ($print) {
+	    if (defined($defer)) {
+		chop;
+		&doprint("$_$defer");
+		undef($defer);
+	    } else {
+		&doprint($_);
+	    }
+	}
+    } else {
+	&doprint($_) if $print;
+    }
+}
+
+select STDOUT;
+close OUT;
+
+foreach $file (<*>) {
+    open (IN, $file);
+    if ($sameas = (&getsame($_ = <IN>) || &getsame($_ = <IN>))) {
+	defined($sameas = &namesub($sameas)) || next;
+#	print "$file is the same as $sameas\n";
+	seek (IN, 0, 0);
+
+	# Copy this to base builtin.
+	open (OUT, ">>$sameas");
+	select OUT;
+	print "\n";
+	while (<IN>) { print; }
+	close IN;
+	select STDOUT;
+	close OUT;
+
+	# Make this a link to that.
+	unlink $file;
+	symlink ($sameas, $file);
+    }
+}
+
+__END__
diff --git a/Util/mkdisttree.sh b/Util/mkdisttree.sh
new file mode 100755
index 000000000..837ebbcc2
--- /dev/null
+++ b/Util/mkdisttree.sh
@@ -0,0 +1,76 @@
+#! /bin/sh
+
+if test $# -lt 4; then
+    echo >&2 "Usage: $0 <dist-tree-name> <top-source-dir> <top-build-dir> <type> <make-args>"
+    exit 2
+fi
+
+case "$1" in
+    /*) disttree=$1 ;;
+    *) disttree=`pwd`/$1 ;;
+esac
+
+case "$2" in
+    /*) sdir_top=$2 ;;
+    *) sdir_top=`pwd`/$2 ;;
+esac
+
+case "$3" in
+    /*) dir_top=$3 ;;
+    *) dir_top=`pwd`/$3 ;;
+esac
+
+type=$4
+shift 4
+
+rm -rf $disttree
+
+sed_separate='
+    :1
+    $!{
+	N
+	b1
+    }
+    s/\n/ /g
+    s/^/deplist=;globlist=! /
+    s/$/ !/
+    s/  */ /g
+    s/ \([^?*[!][^?*[!]*\) / !deplist="$deplist \1"! /g
+    s/! !/;/g
+    s/! \([^!]*\) !/;globlist="$globlist \1";/g
+    s/!/;/g
+    s/;;*/;/g
+'
+
+(
+    cd $sdir_top
+    find . \( -name '*.*' -prune -false \) -o \( -name .distfiles -print \)
+) | while read dfn; do
+    subdir=`echo $dfn | sed 's,/\.distfiles$,,'`
+    echo >&2 "Processing directory $subdir..."
+    eval "DISTFILES_$type="
+    . $sdir_top/$dfn
+    eval "distfiles=\$DISTFILES_$type"
+    if test -n "$distfiles"; then
+	cmds=`echo "$distfiles" | sed -e "$sed_separate"`
+	eval "$cmds"
+	if test -n "$deplist" && test -f $dir_top/$subdir/Makefile; then
+	    ( cd $dir_top/$subdir && "$@" $deplist ) || exit 1
+	fi
+	$sdir_top/mkinstalldirs $disttree/$subdir || exit 1
+	for f in $deplist `test -z "$globlist" || ( cd $dir_top/$subdir && eval "echo $globlist")`; do
+	    if test -f $dir_top/$subdir/$f; then
+		ln $dir_top/$subdir/$f $disttree/$subdir/$f || \
+		    cp -p $dir_top/$subdir/$f $disttree/$subdir/$f || exit 1
+	    elif test -f $sdir_top/$subdir/$f; then
+		ln $sdir_top/$subdir/$f $disttree/$subdir/$f || \
+		    cp -p $sdir_top/$subdir/$f $disttree/$subdir/$f || exit 1
+	    else
+		echo >&2 "$0: can't find file $subdir/$f"
+		exit 1
+	    fi
+	done
+    fi
+done
+
+exec chmod -R a+rX,u+w,go-w $disttree
diff --git a/Util/reporter b/Util/reporter
new file mode 100644
index 000000000..8f8f530ae
--- /dev/null
+++ b/Util/reporter
@@ -0,0 +1,444 @@
+#!/usr/local/bin/zsh
+#
+# NAME:
+#	reporter
+#
+# SYNOPSIS:
+#	reporter [all | aliases | bindings | completion | functions |
+#			limits | options | variables]
+#
+# DESCRIPTION:
+#	"reporter" prints your current environment variables, shell
+#	variables, limits, completion settings, and option settings to
+#	stdout in the form of a script.
+#
+#	If you run into a zsh bug, someone can source the output script to
+#	recreate most of the environment under which you were working.
+#
+#	IMPORTANT:	"source" this script, don't try to run it directly.
+#			Otherwise it won't report the settings for your
+#			current shell session.
+#
+# OPTIONS:
+#	All command-line options can be abbreviated.
+#
+#	"aliases"	prints only aliases.
+#	"bindings"	prints only "bindkey" commands.
+#	"completion"	prints only "compctl" commands.
+#	"functions"	prints "autoload" commands or actual functions.
+#	"limits"	prints "limit" commands for things like cputime, etc.
+#	"modules"	prints "zmodload" commands.
+#	"options"	prints "setopt" commands.
+#	"variables"	prints both shell and environment variables.
+#
+#	"all"		tries to find every useful setting under your shell.
+#			This is the default, and it's the same as typing all
+#			of the above options on the command line.
+#
+# CAVEATS:
+#	Assumes that you have the following programs in your search path:
+#		awk, cut, echo, grep, sed, sort
+#	Assumes that your C preprocessor lives in /lib/cpp or /usr/ccs/lib/cpp.
+#	Uses (and unsets) variables beginning with "reporter_".
+#
+# RESTRICTIONS:
+#	DON'T:	pretend you wrote it, sell it, or blame me if it breaks.
+#	DO:	as ye will an' ye harm none.
+#					--Wiccan saying, I think
+#
+# BUGS:
+#	I'm sure there are more than a few.  To be safe, run "zsh -f" before
+#	sourcing the output from this script.  If you have "screen", you may
+#	want to use that, too; I hammered my terminal settings beyond repair
+#	when using an early version, and "screen" saved me from having to
+#	login on another terminal.
+#
+# HISTORY:
+#	The name was ripped off from the Emacs "reporter.el" function.
+#	The idea came from a mail message to the ZSH mailing list:
+#
+# Begin Configuration Section
+#
+
+reporter_OSVersion="`uname -s`_`uname -r`"
+
+#
+# Solaris 2.x
+#
+case ${reporter_OSVersion} in
+	SunOS_5.*)
+		CPP=${CPP:-/usr/ccs/lib/cpp}
+		AWK=${AWK:-nawk}	# GNU AWK doesn't come standard :-(
+		;;
+esac
+
+#
+# Default Values 
+#
+
+CPP=${CPP:-/lib/cpp}
+AWK=${AWK:-awk}
+
+#
+# End Configuration Section
+#
+
+reporter_do_all=yes
+
+for each in $*
+do
+	case "$each"
+	in
+		ali*)	reporter_do_aliases=yes; reporter_do_all=no ;;
+		b*)	reporter_do_bindings=yes; reporter_do_all=no ;;
+		c*)	reporter_do_compctl=yes; reporter_do_all=no ;;
+		f*)	reporter_do_fun=yes; reporter_do_all=no ;;
+		l*)	reporter_do_lim=yes; reporter_do_all=no ;;
+		m*)	reporter_do_mod=yes; reporter_do_all=no ;;
+		o*)	reporter_do_setopt=yes; reporter_do_all=no ;;
+		v*)	reporter_do_vars=yes; reporter_do_all=no ;;
+		*)	;;
+	esac
+done
+
+#
+#	The "cshjunkiequotes" option can break some of the commands
+#	used in the remainder of this script, so we check for that first
+#	and disable it.  We'll re-enable it later.
+#
+
+reporter_junkiequotes="no"
+
+if setopt | grep "cshjunkiequotes" > /dev/null
+then
+	reporter_junkiequotes="yes"
+	unsetopt cshjunkiequotes
+fi
+
+#
+#	UNAME
+#
+#	This shows your system name.  It's extremely system-dependent, so
+#	we need a way to find out what system you're on.  The easiest
+#	way to do this is by using "uname", but not everyone has that,
+#	so first we go through the search path.
+#
+#	If we don't find it, then the only thing I can think of is to
+#	check what's defined in your C compiler, and code in some exceptions
+#	for the location of "uname" or an equivalent.  For example, Pyramid
+#	has "uname" only in the ATT universe.  This code assumes that
+#	the "-a" switch is valid for "uname".
+#
+#	This section of code sees what is defined by "cpp".  It was
+#	originally written by brandy@tramp.Colorado.EDU (Carl Brandauer).
+#	Additional error checking and sed hacking added by Ken Phelps.
+#
+
+reporter_cppdef=`strings -3 ${CPP} |
+	sed -n '
+	/^[a-zA-Z_][a-zA-Z0-9_]*$/{
+	s/.*/#ifdef &/p
+	s/.* \(.*\)/"\1";/p
+	s/.*/#endif/p
+	}
+	' | ${CPP} |sed '
+	/^[	 ]*$/d
+	/^#/d
+	s/.*"\(.*\)".*/\1/'`
+
+reporter_uname=""
+
+for each in `echo $PATH | sed -e 's/:/ /g'`
+do
+	if [ -x $each/uname ]
+	then
+		reporter_uname="$each/uname"
+		break
+	fi
+done
+
+case "$reporter_uname"
+in
+	"")	reporter_uname="echo not found on this system" ;;
+	*)	;;
+esac
+
+for each in $reporter_cppdef
+do
+	case "$each"
+	in
+		pyr)	reporter_uname="/bin/att uname" ;;
+		*)	;;
+	esac
+done
+
+str=`eval $reporter_uname -a`
+
+echo '# START zsh saveset'
+echo '# uname: ' $str
+echo
+
+unset reporter_cppdef
+unset reporter_uname
+
+#
+#	ALIASES
+#
+#	Use "alias -L" to get a listing of the aliases in the form we want.
+#
+
+if test "$reporter_do_all" = "yes" -o "$reporter_do_aliases" = "yes"
+then
+	echo '# Aliases.'
+	echo
+
+	alias -L
+fi
+
+#
+#	KEY BINDINGS
+#
+#	The -L option does most of the work.  The subshell is used to
+#	avoid modifying things that will be recorded later.
+#
+
+if test "$reporter_do_all" = "yes" -o "$reporter_do_bindings" = "yes"
+then
+	echo
+	echo "# Key bindings."
+	echo
+	bindkey -lL
+	(
+		alias bindkey=bindkey
+		bindkey () {
+			[[ "$1" == "-N" ]] || return
+			[[ "$2" == "--" ]] && shift
+			echo
+			builtin bindkey -L -M -- "$2"
+		}
+		eval "`builtin bindkey -lL`"
+	)
+fi
+
+#
+#	COMPLETION COMMANDS
+#	Warning:  this won't work for zsh-2.5.03.
+#
+
+if test "$reporter_do_all" = "yes" -o "$reporter_do_compctl" = "yes"
+then
+	echo
+	echo "# Completions."
+	echo
+
+	compctl -L
+fi
+
+#
+#	FUNCTIONS
+#
+
+if test "$reporter_do_all" = "yes" -o "$reporter_do_fun" = "yes"
+then
+	echo 
+	echo "# Undefined functions."
+	echo
+
+	functions | grep "undefined" | ${AWK} '{print "autoload " $2}'
+
+	echo 
+	echo "# Defined functions."
+	echo
+
+	functions | grep -v "undefined"
+fi
+
+#
+#	LIMITS
+#
+#	"cputime" has to be handled specially, because you can specify
+#	the time as just hours, or "minutes:seconds".
+#
+
+if test "$reporter_do_all" = "yes" -o "$reporter_do_lim" = "yes"
+then
+	echo
+	echo '# Limits.'
+	echo
+
+	(
+		set X `limit | grep "cputime" | grep -v "unlimited" |
+			sed -e 's/:/ /g'`
+
+		if test "$#" -gt 1
+		then
+			hr=$3
+			min=$4
+			sec=$5
+
+			if test "$hr" -gt 0
+			then
+				echo "limit cputime ${hr}h"
+			else
+				echo "limit cputime $min:$sec"
+			fi
+		fi
+	)
+
+	limit | grep -v "cputime" | grep -v "unlimited" |
+		sed -e 's/Mb/m/' -e 's/Kb/k/' |
+		${AWK} 'NF > 1 {print "limit " $0}'
+fi
+
+#
+#	MODULE LOADING COMMANDS
+#
+
+if test "$reporter_do_all" = "yes" -o "$reporter_do_mod" = "yes"
+then
+	echo
+	if ( zmodload ) >& /dev/null; then
+		echo "# Modules."
+		echo
+		zmodload -d -L
+		echo
+		zmodload -a -L
+		echo
+		zmodload -L
+	else
+		echo "# Modules: zmodload not available."
+	fi
+fi
+
+#
+#	NON-ARRAY VARIABLES
+#
+#	We run this in a subshell to preserve the TERMCAP and TERM settings
+#	in the current shell.  Also, reset the prompt to show you're now
+#	in a test shell.  I can't find an easy way to do IFS, so I ignore it.
+#
+#	Most of the sed nonsense is to make sure that variables are quoted
+#	when being set.  We also have to make sure that single-quotes and
+#	back-quotes are escaped.  This is why variable settings are
+#	surrounded by double quotes; some variables like SPROMPT have single
+#	quotes and back-quotes, and it's just too hard to escape those
+#	properly when setting them.
+#
+
+if test "$reporter_do_all" = "yes" -o "$reporter_do_vars" = "yes"
+then
+	echo
+	echo "# Non-array variables."
+	echo
+
+	(
+		echo "TERMCAP='$TERMCAP'"
+		echo "TERM='$TERM'"
+		unset TERMCAP
+
+		set | grep '=' | grep -v 'prompt=' |
+			grep -v 'reporter_do' |
+			grep -v '^[!#$*0?@_-]=' |
+			grep -v '=(' | sed -e "s/'/\\\'/g" |
+                        sed -e 's/`/\\`/g' |
+			sed -e 's/=/="/' -e 's/$/"/' |
+			grep -v '^IFS=' |
+			grep -v '^TERMCAP=' |
+			grep -v '^TERM='
+
+		echo "prompt='test%'"
+	)
+
+#
+#	ARRAY VARIABLES
+#
+#	The "grep -v" nonsense is to keep from setting shell variables
+#	that caused me some trouble from a script.
+#
+
+	echo
+	echo "# Array variables."
+	echo
+
+	echo "argv=()"
+	set | grep '=' | grep -v 'argv=' |
+		grep -v 'reporter_do' | grep -v '^[!#$*0?@_-]=' |
+		grep '=('
+
+#
+#	EXPORTED VARIABLES
+#
+#	Run this in a subshell to preserve the TERM and TERMCAP setting in
+#	the current shell.
+#
+
+	echo
+	echo "# Exported variables."
+	echo
+
+	(
+		echo "export TERMCAP"
+		echo "export TERM"
+		unset TERMCAP
+
+		export | grep -v '^[!#$*0?@_-]=' |
+			${AWK} -F='=' '{print "export " $1}' |
+			grep -v '^TERM=' | grep -v '^TERMCAP='
+	)
+fi
+
+#
+#	SETOPT
+#
+#	We exclude interactive because "setopt interactive" has no effect.
+#	The cshjunkiequotes option is dealt with separately; see the
+#	comments near the start of the script.
+#
+
+if test "$reporter_do_all" = "yes" -o "$reporter_do_setopt" = "yes"
+then
+	echo
+	echo '# Setopt.'
+	echo
+
+	(
+		setopt | grep -v 'interactive' | ${AWK} '{print "setopt " $0}'
+
+		case "$reporter_junkiequotes"
+		in
+			yes)	echo "setopt cshjunkiequotes" ;;
+			*)	;;
+		esac
+	) | sort
+fi
+
+echo
+echo '# END zsh saveset'
+
+#
+#	Don't put an exit here, or you'll get a nasty surprise when you
+#	source this thing.  Get rid of variables created when processing
+#	command line.
+#
+
+unset reporter_do_all
+unset reporter_do_aliases
+unset reporter_do_bindings
+unset reporter_do_compctl
+unset reporter_do_fun
+unset reporter_do_lim
+unset reporter_do_setopt
+unset reporter_do_vars
+
+#
+#	Turn cshjunkiequotes back on if necessary.
+#
+
+case "$reporter_junkiequotes"
+in
+	yes)	setopt cshjunkiequotes ;;
+	*)	;;
+esac
+
+unset reporter_junkiequotes
+
diff --git a/Util/zsh-development-guide b/Util/zsh-development-guide
new file mode 100644
index 000000000..d574d8af0
--- /dev/null
+++ b/Util/zsh-development-guide
@@ -0,0 +1,138 @@
+------------------------------
+GUIDELINES FOR ZSH DEVELOPMENT
+------------------------------
+
+Zsh is currently developed and maintained by the Zsh Development Group.
+This development takes place by mailing list.  Check the META-FAQ for the
+various zsh mailing lists and how to subscribe to them.  The development
+is very open and anyone is welcomed and encouraged to join and contribute.
+Because zsh is a very large package whose development can sometimes
+be very rapid, I kindly ask that people observe a few guidelines when
+contributing patches and feedback to the mailing list.  These guidelines
+are very simple and hopefully should make for a more orderly development
+of zsh.
+
+Patches
+-------
+
+* Send all patches to the mailing list rather than directly to me.
+
+* Send only context diffs "diff -c oldfile newfile".  They are much
+  easier to read and understand while also allowing the patch program
+  to patch more intelligently.  Please make sure the filenames in
+  the diff header are relative to the top-level directory of the zsh
+  distribution; for example, it should say "Src/init.c" rather than
+  "init.c" or "zsh/Src/init.c".
+
+* Please put only one bug fix or feature enhancement in a single patch and
+  only one patch per mail message.  This helps me to multiplex the many
+  (possibly conflicting) patches that I receive for zsh.  You shouldn't
+  needlessly split patches, but send them in the smallest LOGICAL unit.
+
+* If a patch depends on other patches, then please say so.  Also please
+  mention what version of zsh this patch is for.
+
+* Please test your patch and make sure it applies cleanly. It takes
+  considerably more time to manually merge a patch into the baseline code.
+
+* There is now a zsh patch archive.  To have your patches appear in the
+  archive, send them to the mailing list with a Subject: line starting
+  with "PATCH:".
+
+C coding style
+--------------
+
+* The primary language is ANSI C as defined by the 1989 standard, but the
+  code should always be compatible with late K&R era compilers ("The C
+  Programming Language" 1st edition, plus "void" and "enum").  There are
+  many hacks to avoid the need to actually restrict the code to K&R C --
+  check out the configure tests -- but always bear the compatibility
+  requirements in mind.  In particular, preprocessing directives must
+  have the "#" unindented, and string pasting is not available.
+
+* Conversely, there are preprocessor macros to provide safe access to some
+  language features not present in pure ANSI C, such as variable-length
+  arrays.  Always use the macros if you want to use these facilities.
+
+* Avoid writing code that generates warnings under gcc with the default
+  options set by the configure script.  For example, write
+  "if ((foo = bar))" rather than "if (foo = bar)".
+
+* Please try not using lines longer than 79 characters.
+
+* The indent/brace style is Kernighan and Ritchie with 4 characters
+  indentations (with leading tab characters replacing sequences of
+  8 spaces).  This means that the opening brace is the last character
+  in the line of the if/while/for/do statement and the closing brace
+  has its own line:
+
+      if (foo) {
+	  do that
+      }
+
+* Put only one simple statement on a line.  The body of an if/while/for/do
+  statement has its own line with 4 characters indentation even if there
+  are no braces.
+
+* Do not use space between the function name and the opening parenthesis.
+  Use space after if/for/while.  Use space after type casts.
+
+* Do not use (unsigned char) casts since some compilers do not handle
+  them properly.  Use the provided STOUC(X) macro instead.
+
+* If you use emacs 19.30 or newer you can put the following line to your
+  ~/.emacs file to make these formatting rules the default:
+
+    (add-hook 'c-mode-common-hook (function (lambda () (c-set-style "BSD"))))
+
+* Function declarations must look like this:
+
+  /**/
+  int
+  foo(char *s, char **p)
+  {
+      function body
+  }
+
+  There must be an empty line, a line with "/**/", a line with the
+  type of the function, and finally the name of the function with typed
+  arguments.  These lines must not be indented.  The script generating
+  function prototypes and the ansi2knr program depend on this format.
+  If the function is not used outside the file it is defined in, it
+  should be declared "static"; this keyword goes on the type line,
+  before the return type.
+
+* Global variable declarations must similarly be preceded by a
+  line containing only "/**/", for the prototype generation script.
+  The declaration itself should be all on one line (except for multi-line
+  initialisers).
+
+* Leave a blank line between the declarations and statements in a compound
+  statement, if both are present.  Use blank lines elsewhere to separate
+  groups of statements in the interests of clarity.  There should never
+  be two consecutive blank lines.
+
+Documentation
+-------------
+
+* Edit only the .yo files.  All other formats (man pages, TeXinfo, HTML,
+  etc.) are automatically generated from the yodl source.
+
+* Always use the correct markup.  em() is used for emphasis, and bf()
+  for citations.  tt() marks text that is literal input to or output
+  from the shell.  var() marks metasyntactic variables.
+
+* In addition to appropriate markup, always use quotes (`') where
+  appropriate.  Specifically, use quotes to mark text that is not a part
+  of the actual text of the documentation (i.e., that it is being quoted).
+  In principle, all combinations of quotes and markup are possible,
+  because the purposes of the two devices are completely orthogonal.
+  For example,
+
+      Type `tt(xyzzy)' to let zsh know you have played tt(advent).
+      Saying `plugh' aloud doesn't have much effect, however.
+
+  In this case, "zsh" is normal text (a name), "advent" is a command name
+  ocurring in the main text, "plugh" is a normal word that is being quoted
+  (it's the user that says `plugh', not the documentation), and "xyzzy"
+  is some text to be typed literally that is being quoted.