1#!/usr/bin/env perl 2#*************************************************************************** 3# _ _ ____ _ 4# Project ___| | | | _ \| | 5# / __| | | | |_) | | 6# | (__| |_| | _ <| |___ 7# \___|\___/|_| \_\_____| 8# 9# Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al. 10# 11# This software is licensed as described in the file COPYING, which 12# you should have received as part of this distribution. The terms 13# are also available at https://curl.haxx.se/docs/copyright.html. 14# 15# You may opt to use, copy, modify, merge, publish, distribute and/or sell 16# copies of the Software, and permit persons to whom the Software is 17# furnished to do so, under the terms of the COPYING file. 18# 19# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY 20# KIND, either express or implied. 21# 22########################################################################### 23 24# Update man pages. 25 26use strict; 27use warnings; 28use Tie::File; 29 30# Data from the command line. 31 32my $curlver = $ARGV[0]; 33my $curldate = $ARGV[1]; 34 35# Directories and extensions. 36 37my @dirlist = ("docs/", "docs/libcurl/", "docs/libcurl/opts/", "tests/"); 38my @extlist = (".1", ".3"); 39my @excludelist = ("mk-ca-bundle.1", "template.3"); 40 41# Subroutines 42 43sub printargs{ 44 # Print arguments and exit. 45 46 print "usage: updatemanpages.pl <version> <date>\n"; 47 exit; 48} 49 50sub getthline{ 51 # Process file looking for .TH section. 52 53 my $filename = shift; 54 my $file_handle; 55 my $file_line; 56 57 # Open the file. 58 59 open($file_handle, $filename); 60 61 # Look for the .TH section, process it into an array, 62 # modify it and write to file. 63 64 tie(my @file_data, 'Tie::File', $filename); 65 foreach my $file_data_line(@file_data) { 66 if($file_data_line =~ /^.TH/) { 67 $file_line = $file_data_line; 68 last; 69 } 70 } 71 72 # Close the file. 73 74 close($file_handle); 75 return $file_line; 76} 77 78sub extractth{ 79 # Extract .TH section as an array. 80 81 my $input = shift; 82 83 # Split the line into an array. 84 85 my @tharray; 86 my $inputsize = length($input); 87 my $inputcurrent = ""; 88 my $quotemode = 0; 89 90 for(my $inputseek = 0; $inputseek < $inputsize; $inputseek++) { 91 92 if(substr($input, $inputseek, 1) eq " " && $quotemode eq 0) { 93 push(@tharray, $inputcurrent); 94 $inputcurrent = ""; 95 next; 96 } 97 98 $inputcurrent = $inputcurrent . substr($input, $inputseek, 1); 99 100 if(substr($input, $inputseek, 1) eq "\"") { 101 if($quotemode eq 0) { 102 $quotemode = 1; 103 } 104 else { 105 $quotemode = 0; 106 } 107 } 108 } 109 110 if($inputcurrent ne "") { 111 push(@tharray, $inputcurrent); 112 } 113 114 return @tharray; 115} 116 117sub getdate{ 118 # Get the date from the .TH section. 119 120 my $filename = shift; 121 my $thline; 122 my @tharray; 123 my $date = ""; 124 125 $thline = getthline($filename); 126 127 # Return nothing if there is no .TH section found. 128 129 if(!$thline || $thline eq "") { 130 return ""; 131 } 132 133 @tharray = extractth($thline); 134 135 # Remove the quotes at the start and end. 136 137 $date = substr($tharray[3], 1, -1); 138 return $date; 139} 140 141sub processth{ 142 # Process .TH section. 143 144 my $input = shift; 145 my $date = shift; 146 147 # Split the line into an array. 148 149 my @tharray = extractth($input); 150 151 # Alter the date. 152 153 my $itemdate = "\""; 154 $itemdate .= $date; 155 $itemdate .= "\""; 156 $tharray[3] = $itemdate; 157 158 # Alter the item version. 159 160 my $itemver = $tharray[4]; 161 my $itemname = ""; 162 163 for(my $itemnameseek = 1; 164 $itemnameseek < length($itemver); 165 $itemnameseek++) { 166 if(substr($itemver, $itemnameseek, 1) eq " " || 167 substr($itemver, $itemnameseek, 1) eq "\"") { 168 last; 169 } 170 $itemname .= substr($itemver, $itemnameseek, 1); 171 } 172 173 $itemver = "\""; 174 $itemver .= $itemname; 175 $itemver .= " "; 176 $itemver .= $curlver; 177 $itemver .= "\""; 178 179 $tharray[4] = $itemver; 180 181 my $thoutput = ""; 182 183 foreach my $thvalue (@tharray) { 184 $thoutput .= $thvalue; 185 $thoutput .= " "; 186 } 187 $thoutput =~ s/\s+$//; 188 $thoutput .= "\n"; 189 190 # Return updated string. 191 192 return $thoutput; 193} 194 195sub processfile{ 196 # Process file looking for .TH section. 197 198 my $filename = shift; 199 my $date = shift; 200 my $file_handle; 201 my $file_dist_handle; 202 my $filename_dist; 203 204 # Open a handle for the original file and a second file handle 205 # for the dist file. 206 207 $filename_dist = $filename . ".dist"; 208 209 open($file_handle, $filename); 210 open($file_dist_handle, ">" . $filename_dist); 211 212 # Look for the .TH section, process it into an array, 213 # modify it and write to file. 214 215 tie(my @file_data, 'Tie::File', $filename); 216 foreach my $file_data_line (@file_data) { 217 if($file_data_line =~ /^.TH/) { 218 my $file_dist_line = processth($file_data_line, $date); 219 print $file_dist_handle $file_dist_line . "\n"; 220 } 221 else { 222 print $file_dist_handle $file_data_line . "\n"; 223 } 224 } 225 226 # Close the file. 227 228 close($file_handle); 229 close($file_dist_handle); 230} 231 232# Check that $curlver is set, otherwise print arguments and exit. 233 234if(!$curlver) { 235 printargs(); 236} 237 238# check to see that the git command works, it requires git 2.6 something 239my $gitcheck = `git log -1 --date="format:%B %d, %Y" $dirlist[0] 2>/dev/null`; 240if(length($gitcheck) < 1) { 241 print "git version too old or $dirlist[0] is a bad argument\n"; 242 exit; 243} 244 245# Look in each directory. 246 247my $dir_handle; 248 249foreach my $dirname (@dirlist) { 250 foreach my $extname (@extlist) { 251 # Go through the directory looking for files ending with 252 # the current extension. 253 254 opendir($dir_handle, $dirname); 255 my @filelist = grep(/.$extname$/i, readdir($dir_handle)); 256 257 foreach my $file (@filelist) { 258 # Skip if file is in exclude list. 259 260 if(grep(/^$file$/, @excludelist)) { 261 next; 262 } 263 264 # Load the file and get the date. 265 266 my $filedate; 267 268 # Check if dist version exists and load date from that 269 # file if it does. 270 271 if(-e ($dirname . $file . ".dist")) { 272 $filedate = getdate(($dirname . $file . ".dist")); 273 } 274 else { 275 $filedate = getdate(($dirname . $file)); 276 } 277 278 # Skip if value is empty. 279 280 if(!$filedate || $filedate eq "") { 281 next; 282 } 283 284 # Check the man page in the git repository. 285 286 my $repodata = `LC_TIME=C git log -1 --date="format:%B %d, %Y" \\ 287 --since="$filedate" $dirname$file | grep ^Date:`; 288 289 # If there is output then update the man page 290 # with the new date/version. 291 292 # Process the file if there is output. 293 294 if($repodata) { 295 my $thisdate; 296 if(!$curldate) { 297 if($repodata =~ /^Date: +(.*)/) { 298 $thisdate = $1; 299 } 300 else { 301 print STDERR "Warning: " . ($dirname . $file) . ": found no " . 302 "date\n"; 303 } 304 } 305 else { 306 $thisdate = $curldate; 307 } 308 processfile(($dirname . $file), $thisdate); 309 print $dirname . $file . " page updated to $thisdate\n"; 310 } 311 } 312 closedir($dir_handle); 313 } 314} 315 316__END__ 317 318=pod 319 320=head1 updatemanpages.pl 321 322Updates the man pages with the version number and optional date. If the date 323isn't provided, the last modified date from git is used. 324 325=head2 USAGE 326 327updatemanpages.pl version [date] 328 329=head3 version 330 331Specifies version (required) 332 333=head3 date 334 335Specifies date (optional) 336 337=head2 SETTINGS 338 339=head3 @dirlist 340 341Specifies the list of directories to look for files in. 342 343=head3 @extlist 344 345Specifies the list of files with extensions to process. 346 347=head3 @excludelist 348 349Specifies the list of files to not process. 350 351=head2 NOTES 352 353This script is used during maketgz. 354 355=cut 356