1 #!/usr/bin/env perl 2 #*************************************************************************** 3 # _ _ ____ _ 4 # Project ___| | | | _ \| | 5 # / __| | | | |_) | | 6 # | (__| |_| | _ <| |___ 7 # \___|\___/|_| \_\_____| 8 # 9 # Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel (at] 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 26 use strict; 27 use warnings; 28 use Tie::File; 29 30 # Data from the command line. 31 32 my $curlver = $ARGV[0]; 33 my $curldate = $ARGV[1]; 34 35 # Directories and extensions. 36 37 my @dirlist = ("docs/", "docs/libcurl/", "docs/libcurl/opts/", "tests/"); 38 my @extlist = (".1", ".3"); 39 my @excludelist = ("mk-ca-bundle.1", "template.3"); 40 41 # Subroutines 42 43 sub printargs{ 44 # Print arguments and exit. 45 46 print "usage: updatemanpages.pl <version> <date>\n"; 47 exit; 48 } 49 50 sub 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 78 sub 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 117 sub 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 141 sub 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 195 sub 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 234 if(!$curlver) { 235 printargs(); 236 } 237 238 # check to see that the git command works, it requires git 2.6 something 239 my $gitcheck = `git log -1 --date="format:%B %d, %Y" $dirlist[0] 2>/dev/null`; 240 if(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 247 my $dir_handle; 248 249 foreach 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 322 Updates the man pages with the version number and optional date. If the date 323 isn't provided, the last modified date from git is used. 324 325 =head2 USAGE 326 327 updatemanpages.pl version [date] 328 329 =head3 version 330 331 Specifies version (required) 332 333 =head3 date 334 335 Specifies date (optional) 336 337 =head2 SETTINGS 338 339 =head3 @dirlist 340 341 Specifies the list of directories to look for files in. 342 343 =head3 @extlist 344 345 Specifies the list of files with extensions to process. 346 347 =head3 @excludelist 348 349 Specifies the list of files to not process. 350 351 =head2 NOTES 352 353 This script is used during maketgz. 354 355 =cut 356