updatemanpages.pl 7.5 KB

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