#!/usr/bin/env perl
#***************************************************************************
#                                  _   _ ____  _
#  Project                     ___| | | |  _ \| |
#                             / __| | | | |_) | |
#                            | (__| |_| |  _ <| |___
#                             \___|\___/|_| \_\_____|
#
# Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al.
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
# are also available at https://curl.se/docs/copyright.html.
#
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
# copies of the Software, and permit persons to whom the Software is
# furnished to do so, under the terms of the COPYING file.
#
# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
# KIND, either express or implied.
#
# SPDX-License-Identifier: curl
#
###########################################################################

use strict;
use warnings;

my @proto;
my %func;
my %inc;
my %test;
my %from;
my $error;

sub scanfile {
    my ($file) = @_;
    open(F, "<", $file) or die "$file failed";
    my $unit = 0;
    my $line = 0;
    my $unitref = 0;
    my $unittest = 0;
    while(<F>) {
        $line++;
        my $full = $_;
        if($_ =~ /\@unittest (\d+)/) {
            $unittest = $1;
            $unitref = $line; # store line number
        }
        if($_ =~ /^UNITTEST .*[* ]([a-z0-9_]+)\(/i) {
            my $n = $1;
            if($func{$n}) {
                # already prototyped, this is now the function itself
            }
            else {
                if($n =~ /^Curl_/) {
                    print STDERR "$file:$line:1: warn: $n is Curl_ prefixed?\n";
                    $error++;
                }
                if(($line - $unitref) > 10) {
                    print STDERR "$file:$line:1: warn: Missing \@unittest reference?\n";
                    $error++;
                }
                else {
                    $test{$full} = $unittest;
                    $from{$full} = "$file:$line";
                }

                $func{$n} = 1;
                push @proto, $_;
                $inc{$file} = 1;
                $unit = 1;
            }
        }
        if($unit) {
            if($unit != 1) {
                push @proto, $_;
            }
            if($_ =~ /\);/) {
                # end of proto
                $unit = 0;
            }
            else {
                # proto continues
                $unit++;
            }
        }
    }
    close(F);
}

foreach my $f (@ARGV) {
    scanfile($f);
}

if($error) {
    exit 1;
}

print <<HEAD
#ifndef UNITTESTPROTOS_H
#define UNITTESTPROTOS_H
/***************************************************************************
 *                                  _   _ ____  _
 *  Project                     ___| | | |  _ \\| |
 *                             / __| | | | |_) | |
 *                            | (__| |_| |  _ <| |___
 *                             \\___|\\___/|_| \\_\\_____|
 *
 * Copyright (C) Daniel Stenberg, <daniel\@haxx.se>, et al.
 *
 * This software is licensed as described in the file COPYING, which
 * you should have received as part of this distribution. The terms
 * are also available at https://curl.se/docs/copyright.html.
 *
 * You may opt to use, copy, modify, merge, publish, distribute and/or sell
 * copies of the Software, and permit persons to whom the Software is
 * furnished to do so, under the terms of the COPYING file.
 *
 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
 * KIND, either express or implied.
 *
 * SPDX-License-Identifier: curl
 *
 * Generated-by: extract-unit-protos
 *
 ***************************************************************************/
HEAD
    ;

for my $f (sort keys %inc) {
    # convert to suitable header file
    $f =~ s/\.c/.h/; # .h extension

    if(-f $f) {
        print "#include \"$f\"\n";
    }
}

for my $p (@proto) {
    if($test{$p}) {
        printf "\n/* for unit test %d from %s */\n",
            $test{$p}, $from{$p};
    }
    print $p;
}

print <<FOOT
#endif /* UNITTESTPROTOS_H */
FOOT
    ;
