113498266Sopenharmony_ci#!/usr/bin/env perl
213498266Sopenharmony_ci#***************************************************************************
313498266Sopenharmony_ci#                                  _   _ ____  _
413498266Sopenharmony_ci#  Project                     ___| | | |  _ \| |
513498266Sopenharmony_ci#                             / __| | | | |_) | |
613498266Sopenharmony_ci#                            | (__| |_| |  _ <| |___
713498266Sopenharmony_ci#                             \___|\___/|_| \_\_____|
813498266Sopenharmony_ci#
913498266Sopenharmony_ci# Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al.
1013498266Sopenharmony_ci#
1113498266Sopenharmony_ci# This software is licensed as described in the file COPYING, which
1213498266Sopenharmony_ci# you should have received as part of this distribution. The terms
1313498266Sopenharmony_ci# are also available at https://curl.se/docs/copyright.html.
1413498266Sopenharmony_ci#
1513498266Sopenharmony_ci# You may opt to use, copy, modify, merge, publish, distribute and/or sell
1613498266Sopenharmony_ci# copies of the Software, and permit persons to whom the Software is
1713498266Sopenharmony_ci# furnished to do so, under the terms of the COPYING file.
1813498266Sopenharmony_ci#
1913498266Sopenharmony_ci# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
2013498266Sopenharmony_ci# KIND, either express or implied.
2113498266Sopenharmony_ci#
2213498266Sopenharmony_ci# SPDX-License-Identifier: curl
2313498266Sopenharmony_ci#
2413498266Sopenharmony_ci###########################################################################
2513498266Sopenharmony_ci
2613498266Sopenharmony_ci=begin comment
2713498266Sopenharmony_ci
2813498266Sopenharmony_ciThis script updates a curldown file to current/better curldown.
2913498266Sopenharmony_ci
3013498266Sopenharmony_ciExample: cd2cd [--in-place] <file.md> > <file.md>
3113498266Sopenharmony_ci
3213498266Sopenharmony_ci--in-place: if used, it replaces the original file with the cleaned up
3313498266Sopenharmony_ci            version. When this is used, cd2cd accepts multiple files to work
3413498266Sopenharmony_ci            on and it ignores errors on single files.
3513498266Sopenharmony_ci
3613498266Sopenharmony_ci=end comment
3713498266Sopenharmony_ci=cut
3813498266Sopenharmony_ci
3913498266Sopenharmony_cimy $cd2cd = "0.1"; # to keep check
4013498266Sopenharmony_cimy $dir;
4113498266Sopenharmony_cimy $extension;
4213498266Sopenharmony_cimy $inplace = 0;
4313498266Sopenharmony_ci
4413498266Sopenharmony_ciwhile(1) {
4513498266Sopenharmony_ci    if($ARGV[0] eq "--in-place") {
4613498266Sopenharmony_ci        shift @ARGV;
4713498266Sopenharmony_ci        $inplace = 1;
4813498266Sopenharmony_ci    }
4913498266Sopenharmony_ci    else {
5013498266Sopenharmony_ci        last;
5113498266Sopenharmony_ci    }
5213498266Sopenharmony_ci}
5313498266Sopenharmony_ci
5413498266Sopenharmony_ci
5513498266Sopenharmony_ciuse POSIX qw(strftime);
5613498266Sopenharmony_cimy @ts;
5713498266Sopenharmony_ciif (defined($ENV{SOURCE_DATE_EPOCH})) {
5813498266Sopenharmony_ci    @ts = localtime($ENV{SOURCE_DATE_EPOCH});
5913498266Sopenharmony_ci} else {
6013498266Sopenharmony_ci    @ts = localtime;
6113498266Sopenharmony_ci}
6213498266Sopenharmony_cimy $date = strftime "%B %d %Y", @ts;
6313498266Sopenharmony_ci
6413498266Sopenharmony_cisub outseealso {
6513498266Sopenharmony_ci    my (@sa) = @_;
6613498266Sopenharmony_ci    my $comma = 0;
6713498266Sopenharmony_ci    my @o;
6813498266Sopenharmony_ci    push @o, ".SH SEE ALSO\n";
6913498266Sopenharmony_ci    for my $s (sort @sa) {
7013498266Sopenharmony_ci        push @o, sprintf "%s.BR $s", $comma ? ",\n": "";
7113498266Sopenharmony_ci        $comma = 1;
7213498266Sopenharmony_ci    }
7313498266Sopenharmony_ci    push @o, "\n";
7413498266Sopenharmony_ci    return @o;
7513498266Sopenharmony_ci}
7613498266Sopenharmony_ci
7713498266Sopenharmony_cisub single {
7813498266Sopenharmony_ci    my @head;
7913498266Sopenharmony_ci    my @seealso;
8013498266Sopenharmony_ci    my ($f)=@_;
8113498266Sopenharmony_ci    my $title;
8213498266Sopenharmony_ci    my $section;
8313498266Sopenharmony_ci    my $source;
8413498266Sopenharmony_ci    my $start = 0;
8513498266Sopenharmony_ci    my $d;
8613498266Sopenharmony_ci    my $line = 0;
8713498266Sopenharmony_ci    open(F, "<:crlf", "$f") ||
8813498266Sopenharmony_ci        return 1;
8913498266Sopenharmony_ci    while(<F>) {
9013498266Sopenharmony_ci        $line++;
9113498266Sopenharmony_ci        $d = $_;
9213498266Sopenharmony_ci        if(!$start) {
9313498266Sopenharmony_ci            if(/^---/) {
9413498266Sopenharmony_ci                # header starts here
9513498266Sopenharmony_ci                $start = 1;
9613498266Sopenharmony_ci                push @head, $d;
9713498266Sopenharmony_ci            }
9813498266Sopenharmony_ci            next;
9913498266Sopenharmony_ci        }
10013498266Sopenharmony_ci        if(/^Title: *(.*)/i) {
10113498266Sopenharmony_ci            $title=$1;
10213498266Sopenharmony_ci        }
10313498266Sopenharmony_ci        elsif(/^Section: *(.*)/i) {
10413498266Sopenharmony_ci            $section=$1;
10513498266Sopenharmony_ci        }
10613498266Sopenharmony_ci        elsif(/^Source: *(.*)/i) {
10713498266Sopenharmony_ci            $source=$1;
10813498266Sopenharmony_ci        }
10913498266Sopenharmony_ci        elsif(/^See-also: +(.*)/i) {
11013498266Sopenharmony_ci            $salist = 0;
11113498266Sopenharmony_ci            push @seealso, $1;
11213498266Sopenharmony_ci        }
11313498266Sopenharmony_ci        elsif(/^See-also: */i) {
11413498266Sopenharmony_ci            if($seealso[0]) {
11513498266Sopenharmony_ci                print STDERR "$f:$line:1:ERROR: bad See-Also, needs list\n";
11613498266Sopenharmony_ci                return 2;
11713498266Sopenharmony_ci            }
11813498266Sopenharmony_ci            $salist = 1;
11913498266Sopenharmony_ci        }
12013498266Sopenharmony_ci        elsif(/^ +- (.*)/i) {
12113498266Sopenharmony_ci            # the only list we support is the see-also
12213498266Sopenharmony_ci            if($salist) {
12313498266Sopenharmony_ci                push @seealso, $1;
12413498266Sopenharmony_ci            }
12513498266Sopenharmony_ci        }
12613498266Sopenharmony_ci        # REUSE-IgnoreStart
12713498266Sopenharmony_ci        elsif(/^C: (.*)/i) {
12813498266Sopenharmony_ci            $copyright=$1;
12913498266Sopenharmony_ci        }
13013498266Sopenharmony_ci        elsif(/^SPDX-License-Identifier: (.*)/i) {
13113498266Sopenharmony_ci            $spdx=$1;
13213498266Sopenharmony_ci        }
13313498266Sopenharmony_ci        # REUSE-IgnoreEnd
13413498266Sopenharmony_ci        elsif(/^---/) {
13513498266Sopenharmony_ci            # end of the header section
13613498266Sopenharmony_ci            if(!$title) {
13713498266Sopenharmony_ci                print STDERR "ERROR: no 'Title:' in $f\n";
13813498266Sopenharmony_ci                return 1;
13913498266Sopenharmony_ci            }
14013498266Sopenharmony_ci            if(!$section) {
14113498266Sopenharmony_ci                print STDERR "ERROR: no 'Section:' in $f\n";
14213498266Sopenharmony_ci                return 2;
14313498266Sopenharmony_ci            }
14413498266Sopenharmony_ci            if(!$seealso[0]) {
14513498266Sopenharmony_ci                print STDERR "$f:$line:1:ERROR: no 'See-also:' present\n";
14613498266Sopenharmony_ci                return 2;
14713498266Sopenharmony_ci            }
14813498266Sopenharmony_ci            if(!$copyright) {
14913498266Sopenharmony_ci                print STDERR "$f:$line:1:ERROR: no 'C:' field present\n";
15013498266Sopenharmony_ci                return 2;
15113498266Sopenharmony_ci            }
15213498266Sopenharmony_ci            if(!$spdx) {
15313498266Sopenharmony_ci                print STDERR "$f:$line:1:ERROR: no 'SPDX-License-Identifier:' field present\n";
15413498266Sopenharmony_ci                return 2;
15513498266Sopenharmony_ci            }
15613498266Sopenharmony_ci            last;
15713498266Sopenharmony_ci        }
15813498266Sopenharmony_ci        else {
15913498266Sopenharmony_ci            chomp;
16013498266Sopenharmony_ci            print STDERR "WARN: unrecognized line in $f, ignoring:\n:'$_';"
16113498266Sopenharmony_ci        }
16213498266Sopenharmony_ci    }
16313498266Sopenharmony_ci
16413498266Sopenharmony_ci    if(!$start) {
16513498266Sopenharmony_ci        print STDERR "$f:$line:1:ERROR: no header present\n";
16613498266Sopenharmony_ci        return 2;
16713498266Sopenharmony_ci    }
16813498266Sopenharmony_ci
16913498266Sopenharmony_ci    my @desc;
17013498266Sopenharmony_ci
17113498266Sopenharmony_ci    push @desc, sprintf <<HEAD
17213498266Sopenharmony_ci---
17313498266Sopenharmony_cic: Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al.
17413498266Sopenharmony_ciSPDX-License-Identifier: curl
17513498266Sopenharmony_ciTitle: $title
17613498266Sopenharmony_ciSection: $section
17713498266Sopenharmony_ciSource: $source
17813498266Sopenharmony_ciHEAD
17913498266Sopenharmony_ci        ;
18013498266Sopenharmony_ci    push @desc, "See-also:\n";
18113498266Sopenharmony_ci    for my $s (sort @seealso) {
18213498266Sopenharmony_ci        push @desc, "  - $s\n" if($s);
18313498266Sopenharmony_ci    }
18413498266Sopenharmony_ci    push @desc, "---\n";
18513498266Sopenharmony_ci
18613498266Sopenharmony_ci    my $blankline = 0;
18713498266Sopenharmony_ci    while(<F>) {
18813498266Sopenharmony_ci        $d = $_;
18913498266Sopenharmony_ci        $line++;
19013498266Sopenharmony_ci        if($d =~ /^[ \t]*\n/) {
19113498266Sopenharmony_ci            $blankline++;
19213498266Sopenharmony_ci        }
19313498266Sopenharmony_ci        else {
19413498266Sopenharmony_ci            $blankline = 0;
19513498266Sopenharmony_ci        }
19613498266Sopenharmony_ci        # *italics* for curl symbol links get the asterisks removed
19713498266Sopenharmony_ci        $d =~ s/\*((lib|)curl[^ ]*\(3\))\*/$1/gi;
19813498266Sopenharmony_ci
19913498266Sopenharmony_ci        if(length($d) > 90) {
20013498266Sopenharmony_ci            print STDERR "$f:$line:1:WARN: excessive line length\n";
20113498266Sopenharmony_ci        }
20213498266Sopenharmony_ci
20313498266Sopenharmony_ci        push @desc, $d if($blankline < 2);
20413498266Sopenharmony_ci    }
20513498266Sopenharmony_ci    close(F);
20613498266Sopenharmony_ci
20713498266Sopenharmony_ci    if($inplace) {
20813498266Sopenharmony_ci        open(O, ">$f") || return 1;
20913498266Sopenharmony_ci        print O @desc;
21013498266Sopenharmony_ci        close(O);
21113498266Sopenharmony_ci    }
21213498266Sopenharmony_ci    else {
21313498266Sopenharmony_ci        print @desc;
21413498266Sopenharmony_ci    }
21513498266Sopenharmony_ci    return 0;
21613498266Sopenharmony_ci}
21713498266Sopenharmony_ci
21813498266Sopenharmony_ciif($inplace) {
21913498266Sopenharmony_ci    for my $a (@ARGV) {
22013498266Sopenharmony_ci        # this ignores errors
22113498266Sopenharmony_ci        single($a);
22213498266Sopenharmony_ci    }
22313498266Sopenharmony_ci}
22413498266Sopenharmony_cielse {
22513498266Sopenharmony_ci    exit single($ARGV[0]);
22613498266Sopenharmony_ci}
227