#!/usr/bin/perl -CDS

#
# Automatic dependency maintainer for Tsukurimashou
# Copyright (C) 2011, 2012, 2013, 2016  Matthew Skala
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, version 3.
#
# As a special exception, if you create a document which uses this font, and
# embed this font or unaltered portions of this font into the document, this
# font does not by itself cause the resulting document to be covered by the
# GNU General Public License. This exception does not however invalidate any
# other reasons why the document might be covered by the GNU General Public
# License. If you modify this font, you may extend this exception to your
# version of the font, but you are not obligated to do so. If you do not
# wish to do so, delete this exception statement from your version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
#
# Matthew Skala
# http://ansuz.sooke.bc.ca/
# mskala@ansuz.sooke.bc.ca
#

if ($#ARGV<0) {
  if (-d './mp') {
    $dir='./mp';
  } else {
    die "Need a directory to scan";
  }
  @allfiles=<./mp/*.mp>;
} else {
  $dir=shift;
  if ($dir eq '-mkpl') {
    $dir=shift;
    $mkpl=1;
  }
  @allfiles=@ARGV;
}

$/=undef;

while (<$dir/*.mp>) {
  next if m!/(tsuku|bll|mande|kazoe|tsuita)-!;
  next if m!/(tsuku|bll|mande|kazoe|tsuita)\.!;
  next if m!intro\.!;
  next if m!fntbase\.!;
  m!/([^/]+)\.mp$!;
  $file=$1;
  open(MPFILE,$_);
  $content=<MPFILE>;
  close(MPFILE);
  while ($content=~/^(var)?def\s+([a-z0-9_.]+)\s*(\(|=)(.*?)enddef;/msg) {
    $macro=$2;
    $defn{$macro}=$4;
    if (($infile{$macro} ne '') && ($infile{$macro} ne $file)) {
      $multiple_file{$macro}=1;
    }
    $infile{$macro}=$file;
  }
}

foreach $macroa (keys %infile) {
  next if $multiple_file{$macroa};
  print "defines_macro('$infile{$macroa}','$macroa').\n" if $mkpl;
  foreach $macrob (keys %infile) {
    next if $multiple_file{$macrob};
    $macroc=$macrob;
    $macroc=~s/\./\\./g;
    if ($defn{$macroa}=~/\b$macroc\b/) {
      $macrodep{$macroa}.="$macrob\n";
    }
  }
}

while (@allfiles) {
  $file=shift @allfiles;
print "% Scanning $file...\n";
  open(MPFILE,$file);
  $content=<MPFILE>;
  close(MPFILE);
  if ($content=~/^(.*)\n% AUTODEPS\n((input (.*?)\.mp;\n)*)\n(.*)$/s) {
    $filestart=$1;
    $olddeps=$2;
    $fileend=$5;
    
    %seen=();
    @queue=();
    foreach $macro (keys %infile) {
      next if $multiple_file{$macro};
      next if $seen{$macro};
      $macroc=$macro;
      $macroc=~s/\./\\./g;
      next unless $content=~/\b$macroc\b/;
      $seen{$macro}=1;
      push @queue,$macro;
    }
    
    %incfile=();
    while (@queue) {
      $macro=pop @queue;
      $incfile{$infile{$macro}}=1;
      foreach $macrob (split("\n",$macrodep{$macro})) {
        next if $seen{$macrob};
        $seen{$macrob}=1;
        push @queue,$macrob;
      }
    }
    
    if ($mkpl) {
      $file=~m!(^|/)([^/]+)\.!;
      $fn=$2;
      foreach $macro (sort keys %seen) {
        print "uses_macro('$fn','$macro').\n";
      }
    } else {
      $newdeps='';
      foreach $ifile (sort keys %incfile) {
        next if $ifile eq 'obstack';
        $newdeps.="input $ifile.mp;\n";
      }
      if ($newdeps ne $olddeps) {
        print "%    editing!\n";
        open(MPFILE,">$file");
        print MPFILE "$filestart\n% AUTODEPS\n$newdeps\n$fileend";
        close(MPFILE);
      }
    }
  }
}
