#!/usr/bin/perl -W
use strict;
use File::Find ();

# For the convenience of &wanted calls, including -eval statements:
use vars qw/*name /;
*name = *File::Find::name;


package main;
    my %filesfullpath;

sub buildfullpaths {
    my @path;
    my $shortname;
    
    if ($name =~ m@./(\C*?)\.(hsf|hsh)$@i) { # Select .hsf and .hsh files. FIXME: are HSH files really needed here (cause a false full path for printf).
        $name = $1;
        @path = split /\//, $name;
        $shortname = $path[$#path];
        $filesfullpath{$shortname} = $name;
    }
}

sub putfullpaths {
    my @path;
    my $shortname;
    my $filecontents;
    my (@lines, @funcs);
    my $line;
    
    if ($name =~ m@./(\C*?)\.(hsf|hsh)$@i) { # Select .hsf and .hsh files
        @path = split /\//, $name;
        $shortname = $path[$#path];
        
        open(INFILE, '+<', $name) or die "Can't open $name: $!";
        read(INFILE, $filecontents, -s INFILE);
        close INFILE;

        # Split this line-based file into lines.
        @lines = split /\n/, $filecontents;
        for (my $i = 0; $i <= $#lines; $i++) {
            $lines[$i] =~ s@\r@@g;
            $lines[$i] =~ s@\n@@g;
            $line = $lines[$i];

            my $newline = '';
            
            # Handle interesting lines
            if (   (index($line, 'See Also=') == 0)
                || (index($line, 'In=') == 0)
                || (index($line, 'Out=') == 0)
               ) {
                my $linetype = substr($line, 0, index($line, '=') + 1);
                @funcs = split /, /, substr($line, index($line, '=') + 1);
                
                for my $func (@funcs) {
                    if (index($func, '/') != -1) {
                        # Skip complete paths
                        $newline = $newline . $func . ', ';
                    }
                    else {
                        if (defined($filesfullpath{$func})) {
                            $newline = $newline . $filesfullpath{$func} . ', ';
                        }
                        else {
                            if (index($func, ': ') != 0) {
                                # Special case, found in e.g. 'ST_flags_var: ST_flags'.
                                # It means that the link should point to 'ST_flags_var', but the text should read 'ST_flags'.
                                my $file = substr($func, 0, index($func, ': '));
                                my $linkname = substr($func, index($func,': ') + 2);
                                if (defined($filesfullpath{$file})) {
                                    $newline = $newline . $filesfullpath{$file} . ': ' . $linkname . ', ';
                                    next;
                                }
                            }
                            warn "$name: problem with string \"$func\"\n";
                        }
                    }
                }
                
                # Strip excess ', '.
                my $idx = rindex ($newline, ', ');
                if ($idx != length($newline) - 2) {
                    warn "Strange generated line \"$newline\"\n";
                }
                $newline = $linetype . substr($newline, 0, $idx);
                
                $lines[$i] = $newline;
            }
            elsif (index($line, '"$$LINK(') != -1) {
                # <I>fsPtr</I> is a pointer to a <A HREF="$$LINK(FILES)">FILES</A> structure previously opened with <A HREF="$$LINK(TIOS_FOpen)">FOpen</A>."
                @funcs = split /\"\$\$LINK\(/, $line;
                for (my $j = 1; $j <= $#funcs; $j++) {
                    my $idx = index($funcs[$j],')');
                    my $func = substr($funcs[$j], 0, $idx);
                    my $restofstring = substr($funcs[$j], $idx);
                    
                    if (index($func, '/') == -1) {
                        if (defined($filesfullpath{$func})) {
                            $funcs[$j] = $filesfullpath{$func} . $restofstring;
                        }
                        else {
                            warn "Found a link to undef function \"" . $func . "\"\n";
                        }
                    }
                    else {
                        # Skip complete paths
                    }
                }
                $lines[$i] = join '"$$LINK(', @funcs;
            }
        }
        push @lines, ''; # Push additional EOL at EOF.
        #~ print join ("\r\n", @lines);

        open(OUTFILE, '+>', "$name") or die "Can't open $name: $!";
        print OUTFILE join ("\r\n", @lines);
        close OUTFILE;
    }
}


    File::Find::find({wanted => \&buildfullpaths, no_chdir => 1}, '.');
    $filesfullpath{'printf'} = 'stdio.h/printf'; # Override printf (found in printf.h/printf.hsh).
    File::Find::find({wanted => \&putfullpaths, no_chdir => 1}, '.');
