mirror of
				git://git.code.sf.net/p/zsh/code
				synced 2025-11-04 07:21:06 +01:00 
			
		
		
		
	
		
			
				
	
	
		
			183 lines
		
	
	
	
		
			4.1 KiB
		
	
	
	
		
			Perl
		
	
	
		
			Executable file
		
	
	
	
	
			
		
		
	
	
			183 lines
		
	
	
	
		
			4.1 KiB
		
	
	
	
		
			Perl
		
	
	
		
			Executable file
		
	
	
	
	
#!/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-4.0.1				# or wherever
 | 
						|
#    mkdir Help
 | 
						|
#    cd Help
 | 
						|
#    man zshbuiltins | colcrt - | helpfiles
 | 
						|
#    run-help() {
 | 
						|
#      typeset zhelp=~/zsh-4.0.1/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*$)/) {
 | 
						|
	    # NAME is the start of the next section when in zshall.
 | 
						|
	    # (Historical note: we used to exit on the page header,
 | 
						|
	    # but text from the old section can continue to the
 | 
						|
	    # new page).
 | 
						|
	    last BUILTINS if /^\s*NAME\s*$/;
 | 
						|
	    last BUILTINS if /^STARTUP\/SHUTDOWN FILES/;
 | 
						|
	    last if /^zsh.*\s\d$/; # GNU nroff -man end-of-page marker
 | 
						|
	}
 | 
						|
        if (/^\s*Page/ || /^zsh.*\s\d$/) {
 | 
						|
	    do {
 | 
						|
		$_ = <>;
 | 
						|
	    } while (defined($_) && /^\s*$/);
 | 
						|
	    if (/^\s*ZSHBUILTINS/) {
 | 
						|
		do {
 | 
						|
		    $_ = <>;
 | 
						|
		} while (defined($_) && /^\s*$/);
 | 
						|
	    }
 | 
						|
	}
 | 
						|
	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__
 |