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