26763: fix problem on failed cd -s to relative path
[zsh.git] / Util / helpfiles
blobc1c16ff7464982bf680ad04bad883d0bda978fdb
1 #!/usr/local/bin/perl -- -*-perl-*-
3 # helpfiles: make help files for Z-shell builtins from the manual entries.
5 # Create help files for zsh commands in the current directory;
6 # assumes no other files are present.
7 # No overwriting check; `.' becomes `dot', `:' becomes `colon'.
9 # Any command claiming to be `same as <foo>' or `equivalent to <foo>'
10 # has its help file appended to the end of <foo>'s and replaced by a
11 # link to <foo>. (Arguably the help file should be put at the start
12 # instead.)
14 # Takes one filename argument, or stdin: the zsh manual page as a plain
15 # ascii file: `man zshbuiltins | colcrt -' (remember the -) should do
16 # the trick.
18 # If you don't have colcrt, try 'col -bx'. The x is necessary so that
19 # spaces don't turn into tabs, which messes up the calculations of
20 # indentation on machines which randomly wrap lines round to the
21 # previous line (so you see what we're up against).
23 # Example usage:
24 # cd ~/zsh-4.0.1 # or wherever
25 # mkdir Help
26 # cd Help
27 # man zshbuiltins | colcrt - | helpfiles
28 # run-help() {
29 # typeset zhelp=~/zsh-4.0.1/Help # or wherever
30 # [[ $1 = . ]] && 1=dot
31 # [[ $1 = : ]] && 1=colon
32 # if [[ $1 = compctl ]]; then
33 # man zshcompctl
34 # elif [[ -f $zhelp/$1 ]]; then
35 # ${=PAGER:-more} $zhelp/$1
36 # else
37 # man $1
38 # fi
39 # }
40 # now <Esc>-h works for shell builtins.
42 while (<>) {
43 last if /^\s*SHELL BUILTIN COMMANDS/;
44 /zshbuiltins/ && $zb++;
45 last if ($zb && /^\s*DESCRIPTIONS/);
48 $print = 0;
50 sub namesub {
51 local($cmd) = shift;
52 if ($cmd =~ /^\w+$/) {
53 $cmd;
54 } elsif ($cmd eq '.') {
55 'dot';
56 } elsif ($cmd eq ':') {
57 'colon';
58 } else {
59 undef;
63 sub getsame {
64 local($_) = shift;
65 if (/same\s*as\s*(\S+)/i || /equivalent\s*to\s*(\S+)/i) {
66 local($name) = $1;
67 ($name =~ /[.,]$/) && chop($name);
68 return $name;
69 } else {
70 return undef;
74 sub newcmd {
75 local($_) = shift;
76 local($cmd);
77 # new command
78 if (defined($cmd = &namesub($_))) {
79 # in case there's something nasty here like a link..
80 unlink $cmd;
81 open (OUT, ">$cmd");
82 select OUT;
83 $print = 1;
84 } else {
85 $print = 0;
89 sub doprint {
90 local($_) = shift;
92 s/^$indentstr//o; # won't work if too many tabs
93 print;
96 while (<>) { last unless /^\s*$/; }
98 /^(\s+)(\S+)/;
99 $indentstr = $1;
100 $indent = length($1);
101 &newcmd($2);
102 print if $print;
104 BUILTINS: while (<>) {
105 next if /^\w/;
107 undef($undented);
108 if (/^\s*$/ || ($undented = (/^(\s*)/ && length($1) < $indent))) {
109 $undented && &doprint($_);
110 while (defined($_ = <>) && /(^\w)|(^\s*$)/) {
111 # NAME is the start of the next section when in zshall.
112 # (Historical note: we used to exit on the page header,
113 # but text from the old section can continue to the
114 # new page).
115 last BUILTINS if /^\s*NAME\s*$/;
116 last BUILTINS if /^STARTUP\/SHUTDOWN FILES/;
117 last if /^zsh.*\s\d$/; # GNU nroff -man end-of-page marker
119 if (/^\s*Page/ || /^zsh.*\s\d$/) {
120 do {
121 $_ = <>;
122 } while (defined($_) && /^\s*$/);
123 if (/^\s*ZSHBUILTINS/) {
124 do {
125 $_ = <>;
126 } while (defined($_) && /^\s*$/);
129 if (/^(\s*)/ && length($1) < $indent) {
130 # This may be just a bug on the SGI, or maybe something
131 # more sinister (don\'t laugh, this is nroff).
132 s/^\s*/ /;
133 $defer = $_;
134 do {
135 $_ = <>;
136 } while (defined($_) && /^\s*$/);
137 last unless defined($_);
139 if (/^(\s+)(\S+)/ && length($1) == $indent) {
140 &newcmd($2);
141 } else {
142 print "\n";
144 if ($print) {
145 if (defined($defer)) {
146 chop;
147 &doprint("$_$defer");
148 undef($defer);
149 } else {
150 &doprint($_);
153 } else {
154 &doprint($_) if $print;
158 select STDOUT;
159 close OUT;
161 foreach $file (<*>) {
162 open (IN, $file);
163 if ($sameas = (&getsame($_ = <IN>) || &getsame($_ = <IN>))) {
164 defined($sameas = &namesub($sameas)) || next;
165 # print "$file is the same as $sameas\n";
166 seek (IN, 0, 0);
168 # Copy this to base builtin.
169 open (OUT, ">>$sameas");
170 select OUT;
171 print "\n";
172 while (<IN>) { print; }
173 close IN;
174 select STDOUT;
175 close OUT;
177 # Make this a link to that.
178 unlink $file;
179 symlink ($sameas, $file);
183 __END__