updatemanpages.pl 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357
  1. #!/usr/bin/env perl
  2. #***************************************************************************
  3. # _ _ ____ _
  4. # Project ___| | | | _ \| |
  5. # / __| | | | |_) | |
  6. # | (__| |_| | _ <| |___
  7. # \___|\___/|_| \_\_____|
  8. #
  9. # Copyright (C) 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.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. # SPDX-License-Identifier: curl
  23. #
  24. ###########################################################################
  25. # Update man pages.
  26. use strict;
  27. use warnings;
  28. use Tie::File;
  29. # Data from the command line.
  30. my $curlver = $ARGV[0];
  31. my $curldate = $ARGV[1];
  32. # Directories and extensions.
  33. my @dirlist = ("docs/", "docs/libcurl/", "docs/libcurl/opts/", "tests/");
  34. my @extlist = (".1", ".3");
  35. my @excludelist = ("mk-ca-bundle.1", "template.3");
  36. # Subroutines
  37. sub printargs{
  38. # Print arguments and exit.
  39. print "usage: updatemanpages.pl <version> <date>\n";
  40. exit;
  41. }
  42. sub getthline{
  43. # Process file looking for .TH section.
  44. my $filename = shift;
  45. my $file_handle;
  46. my $file_line;
  47. # Open the file.
  48. open($file_handle, $filename);
  49. # Look for the .TH section, process it into an array,
  50. # modify it and write to file.
  51. tie(my @file_data, 'Tie::File', $filename);
  52. foreach my $file_data_line(@file_data) {
  53. if($file_data_line =~ /^.TH/) {
  54. $file_line = $file_data_line;
  55. last;
  56. }
  57. }
  58. # Close the file.
  59. close($file_handle);
  60. return $file_line;
  61. }
  62. sub extractth{
  63. # Extract .TH section as an array.
  64. my $input = shift;
  65. # Split the line into an array.
  66. my @tharray;
  67. my $inputsize = length($input);
  68. my $inputcurrent = "";
  69. my $quotemode = 0;
  70. for(my $inputseek = 0; $inputseek < $inputsize; $inputseek++) {
  71. if(substr($input, $inputseek, 1) eq " " && $quotemode eq 0) {
  72. push(@tharray, $inputcurrent);
  73. $inputcurrent = "";
  74. next;
  75. }
  76. $inputcurrent = $inputcurrent . substr($input, $inputseek, 1);
  77. if(substr($input, $inputseek, 1) eq "\"") {
  78. if($quotemode eq 0) {
  79. $quotemode = 1;
  80. }
  81. else {
  82. $quotemode = 0;
  83. }
  84. }
  85. }
  86. if($inputcurrent ne "") {
  87. push(@tharray, $inputcurrent);
  88. }
  89. return @tharray;
  90. }
  91. sub getdate{
  92. # Get the date from the .TH section.
  93. my $filename = shift;
  94. my $thline;
  95. my @tharray;
  96. my $date = "";
  97. $thline = getthline($filename);
  98. # Return nothing if there is no .TH section found.
  99. if(!$thline || $thline eq "") {
  100. return "";
  101. }
  102. @tharray = extractth($thline);
  103. # Remove the quotes at the start and end.
  104. $date = substr($tharray[3], 1, -1);
  105. return $date;
  106. }
  107. sub processth{
  108. # Process .TH section.
  109. my $input = shift;
  110. my $date = shift;
  111. # Split the line into an array.
  112. my @tharray = extractth($input);
  113. # Alter the date.
  114. my $itemdate = "\"";
  115. $itemdate .= $date;
  116. $itemdate .= "\"";
  117. $tharray[3] = $itemdate;
  118. # Alter the item version.
  119. my $itemver = $tharray[4];
  120. my $itemname = "";
  121. for(my $itemnameseek = 1;
  122. $itemnameseek < length($itemver);
  123. $itemnameseek++) {
  124. if(substr($itemver, $itemnameseek, 1) eq " " ||
  125. substr($itemver, $itemnameseek, 1) eq "\"") {
  126. last;
  127. }
  128. $itemname .= substr($itemver, $itemnameseek, 1);
  129. }
  130. $itemver = "\"";
  131. $itemver .= $itemname;
  132. $itemver .= " ";
  133. $itemver .= $curlver;
  134. $itemver .= "\"";
  135. $tharray[4] = $itemver;
  136. my $thoutput = "";
  137. foreach my $thvalue (@tharray) {
  138. $thoutput .= $thvalue;
  139. $thoutput .= " ";
  140. }
  141. $thoutput =~ s/\s+$//;
  142. $thoutput .= "\n";
  143. # Return updated string.
  144. return $thoutput;
  145. }
  146. sub processfile{
  147. # Process file looking for .TH section.
  148. my $filename = shift;
  149. my $date = shift;
  150. my $file_handle;
  151. my $file_dist_handle;
  152. my $filename_dist;
  153. # Open a handle for the original file and a second file handle
  154. # for the dist file.
  155. $filename_dist = $filename . ".dist";
  156. open($file_handle, $filename);
  157. open($file_dist_handle, ">" . $filename_dist);
  158. # Look for the .TH section, process it into an array,
  159. # modify it and write to file.
  160. tie(my @file_data, 'Tie::File', $filename);
  161. foreach my $file_data_line (@file_data) {
  162. if($file_data_line =~ /^.TH/) {
  163. my $file_dist_line = processth($file_data_line, $date);
  164. print $file_dist_handle $file_dist_line . "\n";
  165. }
  166. else {
  167. print $file_dist_handle $file_data_line . "\n";
  168. }
  169. }
  170. # Close the file.
  171. close($file_handle);
  172. close($file_dist_handle);
  173. }
  174. # Check that $curlver is set, otherwise print arguments and exit.
  175. if(!$curlver) {
  176. printargs();
  177. }
  178. # check to see that the git command works, it requires git 2.6 something
  179. my $gitcheck = `git log -1 --date="format:%B %d, %Y" $dirlist[0] 2>/dev/null`;
  180. if(length($gitcheck) < 1) {
  181. print "git version too old or $dirlist[0] is a bad argument\n";
  182. exit;
  183. }
  184. # Look in each directory.
  185. my $dir_handle;
  186. foreach my $dirname (@dirlist) {
  187. foreach my $extname (@extlist) {
  188. # Go through the directory looking for files ending with
  189. # the current extension.
  190. opendir($dir_handle, $dirname);
  191. my @filelist = grep(/.$extname$/i, readdir($dir_handle));
  192. foreach my $file (@filelist) {
  193. # Skip if file is in exclude list.
  194. if(grep(/^$file$/, @excludelist)) {
  195. next;
  196. }
  197. # Load the file and get the date.
  198. my $filedate;
  199. # Check if dist version exists and load date from that
  200. # file if it does.
  201. if(-e ($dirname . $file . ".dist")) {
  202. $filedate = getdate(($dirname . $file . ".dist"));
  203. }
  204. else {
  205. $filedate = getdate(($dirname . $file));
  206. }
  207. # Skip if value is empty.
  208. if(!$filedate || $filedate eq "") {
  209. next;
  210. }
  211. # Check the man page in the git repository.
  212. my $repodata = `LC_TIME=C git log -1 --date="format:%B %d, %Y" \\
  213. --since="$filedate" $dirname$file | grep ^Date:`;
  214. # If there is output then update the man page
  215. # with the new date/version.
  216. # Process the file if there is output.
  217. if($repodata) {
  218. my $thisdate;
  219. if(!$curldate) {
  220. if($repodata =~ /^Date: +(.*)/) {
  221. $thisdate = $1;
  222. }
  223. else {
  224. print STDERR "Warning: " . ($dirname . $file) . ": found no " .
  225. "date\n";
  226. }
  227. }
  228. else {
  229. $thisdate = $curldate;
  230. }
  231. processfile(($dirname . $file), $thisdate);
  232. print $dirname . $file . " page updated to $thisdate\n";
  233. }
  234. }
  235. closedir($dir_handle);
  236. }
  237. }
  238. __END__
  239. =pod
  240. =head1 updatemanpages.pl
  241. Updates the man pages with the version number and optional date. If the date
  242. isn't provided, the last modified date from git is used.
  243. =head2 USAGE
  244. updatemanpages.pl version [date]
  245. =head3 version
  246. Specifies version (required)
  247. =head3 date
  248. Specifies date (optional)
  249. =head2 SETTINGS
  250. =head3 @dirlist
  251. Specifies the list of directories to look for files in.
  252. =head3 @extlist
  253. Specifies the list of files with extensions to process.
  254. =head3 @excludelist
  255. Specifies the list of files to not process.
  256. =head2 NOTES
  257. This script is used during maketgz.
  258. =cut