Admin/isa-migrate
author haftmann
Thu, 16 Jun 2005 10:21:36 +0200
changeset 16404 5f263e81e366
parent 16382 4fc8d8c99e9e
child 16406 4f393b8f84b7
permissions -rw-r--r--
isa-migrate ++

#!/usr/bin/env perl
#
# $Id$
# Author: Florian Haftmann, TUM
#
# A generic framework script for simple theory file migrations
# (under developement)
#

use strict;
use File::Find;
use File::Basename;
use File::Copy;

# configuration
my @suffices = ('\.thy');
my $backupext = '.bak';

# migrator lookup hash
my %migrators = (
    id => sub {
        my ($file, @content) = @_;
    },
    thyheader => sub {
        my ($file, @content) = @_;
        #~ my $diag = 1;
        my $diag = 0;
        $_ = join("", @content);
        if (m!^theory!cgoms) {
            my $prelude = $';
            my $thyheader = "theory";
            $thyheader .= skip_wscomment();
            if (m!\G(\S+)!cgoms) {
                $thyheader .= $1;
                $thyheader .= skip_wscomment();
                $diag and print "--->\n(1)>>>$thyheader<<<\n<---\n";
                if (m!\G(?:imports|=)!cgoms) {
                    $thyheader .= "imports";
                    $thyheader .= skip_wscomment() || " ";
                    $diag and print "--->\n(2)>>>$thyheader<<<\n<---\n";
                    while (m/\G(?!uses|files|begin|:)/cgoms && m!\G\w+!cgoms) {
                        $diag and print "--->\n(3)>>>$&<<<\n<---\n";
                        $thyheader .= $&;
                        $thyheader .= skip_wscomment();
                        m/\G\+? ?/cgoms;
                        $thyheader .= skip_wscomment();
                    }
                    $diag and print "--->\n(4)>>>$thyheader<<<\n<---\n";
                }
                if (m!\G(?:files|uses)!cgoms) {
                    $thyheader .= "uses";
                    $thyheader .= skip_wscomment();
                    $diag and print "--->\n(5)>>>$thyheader<<<\n<---\n";
                    while (m/\G(?!begin|:)/cgoms && m!\G(\("[^"]+"\)|"[^"]+"|[^"\s]+)!cgoms) {
                        $diag and print "--->\n(6)>>>$&<<<\n<---\n";
                        $thyheader .= $&;
                        $thyheader .= skip_wscomment();
                    }
                    $diag and print "--->\n(7)>>>$thyheader<<<\n<---\n";
                }
                #~ m!\G.{19}!cgoms;
                #~ print "***$&\n";

                if (m!\G(?:begin|:)!cgoms) {
                    my $postlude = $';
                    if ($& == ":") {
                        $thyheader .= " ";
                    }
                    $thyheader .=  "begin";
                    # do replacement here
                    print "$file:\n$thyheader\n\n";
                }
            }
        }
    }
);

# utility functions
sub skip_wscomment {
    my $commentlevel = 0;
    my @skipped = ();
    while () {
        if (m!\G\{\*!cgoms) {
            push(@skipped, $&);
            $commentlevel++;
        } elsif ($commentlevel > 0) {
            if (m!\G\*\}!cgoms) {
                push(@skipped, $&);
                $commentlevel--;
            } elsif (m!\G(?:
                        [^{*]|\*[^{}]|\{[^*]
                       )*!cgomsx) {
                push(@skipped, $&);
            } else {
                die ("probably incorrectly nested comment");
            }
        } elsif (m!\G\s+!cgoms) {
            push(@skipped, $&);
        } else {
            return join('', @skipped);
        }
    }
}

# process dir tree
sub process_tree {
    my ($root, $migrator, $backupext) = @_;
    find(sub { process($_, $migrator, $backupext) }, $root);
}

# process single file
sub process {
    my ($file, $migrator, $backupext) = @_;
    my ($basename, $dirname, $ext) = fileparse($file, @suffices);
    #~ print "$file\n";
    if ($ext) {
        open ISTREAM, $file or die("error opening $file");
        my @content = <ISTREAM>;
        close ISTREAM;
        if ($backupext) {
            copy($file, "$file$backupext");
        }
        print "Migrating $file...\n";
        &$migrator($file, @content);
    }
}

# first argument: migrator name
my $migrator = $migrators{shift @ARGV};
$migrator or die ("invalid migrator name");
# other arguments: files or trees
foreach my $fileloc (@ARGV) {
    -e $fileloc or die ("no file $fileloc");
}
foreach my $fileloc (@ARGV) {
    if (-d $fileloc) {
        process_tree($fileloc, $migrator, $backupext);
    } else {
        process($fileloc, $migrator, $backupext);
    }
}

#!!! example file: