<commit_before>:
eval 'exec perl -wS $0 ${1+"$@"}'
    if 0;
#*************************************************************************
#
#   $RCSfile: deliver.pl,v $
#
#   $Revision: 1.72 $
#
#   last change: $Author: rt $ $Date: 2004-09-15 16:27:34 $
#
#   The Contents of this file are made available subject to the terms of
#   either of the following licenses
#
#          - GNU Lesser General Public License Version 2.1
#          - Sun Industry Standards Source License Version 1.1
#
#   Sun Microsystems Inc., October, 2000
#
#   GNU Lesser General Public License Version 2.1
#   =============================================
#   Copyright 2000 by Sun Microsystems, Inc.
#   901 San Antonio Road, Palo Alto, CA 94303, USA
#
#   This library is free software; you can redistribute it and/or
#   modify it under the terms of the GNU Lesser General Public
#   License version 2.1, as published by the Free Software Foundation.
#
#   This library 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
#   Lesser General Public License for more details.
#
#   You should have received a copy of the GNU Lesser General Public
#   License along with this library; if not, write to the Free Software
#   Foundation, Inc., 59 Temple Place, Suite 330, Boston,
#   MA  02111-1307  USA
#
#
#   Sun Industry Standards Source License Version 1.1
#   =================================================
#   The contents of this file are subject to the Sun Industry Standards
#   Source License Version 1.1 (the "License"); You may not use this file
#   except in compliance with the License. You may obtain a copy of the
#   License at http://www.openoffice.org/license.html.
#
#   Software provided under this License is provided on an "AS IS" basis,
#   WITHOUT WARRUNTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING,
#   WITHOUT LIMITATION, WARRUNTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
#   MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
#   See the License for the specific provisions governing your rights and
#   obligations concerning the Software.
#
#   The Initial Developer of the Original Code is: Sun Microsystems, Inc..
#
#   Copyright: 2000 by Sun Microsystems, Inc.
#
#   All Rights Reserved.
#
#   Contributor(s): _______________________________________
#
#
#
#*************************************************************************

#
# deliver.pl - copy from module output tree to solver
#

use Cwd;
use File::Basename;
use File::Copy;
use File::DosGlob 'glob';
use File::Path;
use File::Spec;

#### script id #####

( $script_name = $0 ) =~ s/^.*\b(\w+)\.pl$/$1/;

$id_str = ' $Revision: 1.72 $ ';
$id_str =~ /Revision:\s+(\S+)\s+\$/
  ? ($script_rev = $1) : ($script_rev = "-");

print "$script_name -- version: $script_rev\n";

#### globals ####

### valid actions ###
# if you add a action 'foo', than add 'foo' to this list and
# implement 'do_foo()' in the implemented actions area
@action_list        =   (           # valid actions
                        'copy',
                        'dos',
                        'hedabu',
                        'linklib',
                        'mkdir',
                        'symlink',
                        'touch'
                        );

# copy filter: files matching these patterns won't be copied by
# the copy action
@copy_filter_patterns = (
                        '\/_[\w\-]+\.dll$' # Win32 debug dll's
                        );

$is_debug           = 0;

$module             = 0;            # module name
$base_dir           = 0;            # path to module base directory
$dlst_file          = 0;            # path to d.lst
@ilst_file          = ();           # array of pathes to image lists
$ilst_ext           = 'ilst';      # extension of image lists
$umask              = 22;           # default file/directory creation mask
$dest               = 0;            # optional destination path
$common_build       = 0;            # do we have common trees?
$common_dest        = 0;            # common tree on solver

@action_data        = ();           # LoL with all action data
@macros             = ();           # d.lst macros
@hedabu_list        = ();           # files which have to be filtered through hedabu
@zip_list           = ();           # files which have to be zipped
@common_zip_list    = ();           # common files which have to be zipped

$files_copied       = 0;            # statistics
$files_unchanged    = 0;            # statistics

$opt_force          = 0;            # option force copy
$opt_minor          = 0;            # option deliver in minor
$opt_check          = 0;            # do actually execute any action
$opt_zip            = 0;            # create an additional zip file
$opt_link           = 0;            # hard link files into the solver to save disk space
$opt_deloutput      = 0;            # delete the output tree for the project once successfully delivered

$strip = 'strip' if ($ENV{COM} ne 'MSC');

$upd           = $ENV{'UPD'};
($gui       = lc($ENV{GUI}))        || die "can't determine GUI";

# zip is default for RE
$opt_zip = 1 if ( defined($ENV{UPDATER}) && $ENV{UPDATER} eq 'YES' && defined($ENV{DELIVER_TO_ZIP}) );

$has_symlinks       = 0;            # system supports symlinks

for (@action_list) {
    $action_hash{$_}++;
}

# trap normal signals (HUP, INT, PIPE, TERM)
# for clean up on unexpected termination
use sigtrap 'handler' => \&cleanup_and_die, 'normal-signals';

#### main ####

parse_options();
init_globals();
push_default_actions();
parse_dlst();
parse_imagelists();
walk_action_data();
walk_hedabu_list();
zip_files() if $opt_zip;
delete_output() if $opt_deloutput;
print_stats();

exit(0);

#### implemented actions #####

sub do_copy
{
    # We need to copy up to four times:
    # from the platform dependent output tree,
    # from the SO platform dependent tree,
    # from the common output tree,
    # and from the SO common output tree
    # in this order.
    my ($dependent, $common, $from, $to, $file_list);
    my $line = shift;
    my $touch = 0;

    $dependent = expand_macros($line);
    ($from, $to) = split(' ', $dependent);
    print "copy dependent: from: $from, to: $to\n" if $is_debug;
    glob_and_copy($from, $to, $touch);

    my $line_so = mod_so($line);
    if ( $line_so ) {
        my $dependent = expand_macros($line_so);
        ($from, $to) = split(' ', $dependent);
        print "copy dependent: from: $from, to: $to\n" if $is_debug;
        glob_and_copy($from, $to, $touch);
    }

    if ( $common_build ) {
        $line =~ s/%__SRC%/%COMMON_OUTDIR%/ig;
        if ( $line =~ /%COMMON_OUTDIR%/ ) {
            $line =~ s/%_DEST%/%COMMON_DEST%/ig;
            $common = expand_macros($line);
            ($from, $to) = split(' ', $common);
            print "copy common: from: $from, to: $to\n" if $is_debug;
            glob_and_copy($from, $to, $touch);

            my $line_so = mod_so($line);
            if ( $line_so ) {
                $common = expand_macros($line_so);
                ($from, $to) = split(' ', $common);
                print "copy common: from: $from, to: $to\n" if $is_debug;
                glob_and_copy($from, $to, $touch);
            }
        }
    }
}

sub do_dos
{
    my $line = shift;

    my $command = expand_macros($line);
    if ( $opt_check ) {
        print "DOS: $command\n";
    }
    else {
        # HACK: remove MACOSX stuff which is wrongly labled with dos
        # better: fix broken d.lst
        return if ( $command =~ /MACOSX/ );
        $command =~ s#/#\\#g if $^O eq 'MSWin32';
        system($command);
    }
}

sub do_hedabu
{
    # just collect all hedabu files, actual filtering is done later
    my $line = shift;
    my ($from, $to);
    my @globbed_files = ();

    $line = expand_macros($line);
    ($from, $to) = split(' ', $line);

    push( @hedabu_list, @{glob_line($from, $to)});
}

sub do_linklib
{
    my ($lib_base, $lib_major,$from_dir, $to_dir);
    my $lib = shift;
    my @globbed_files = ();
    my %globbed_hash = ();

    print "linklib: $lib\n" if $is_debug;
    print "has symlinks\n" if ( $has_symlinks && $is_debug );

    return unless $has_symlinks;

    $from_dir = expand_macros('../%__SRC%/lib');
    $to_dir = expand_macros('%_DEST%/lib%_EXT%');

    @globbed_files = glob("$from_dir/$lib");

    if ( $#globbed_files == -1 ) {
       $files_unchanged++;
       return;
    }

    foreach $lib (@globbed_files) {
        $lib = basename($lib);
        if ( $lib =~ /^(lib[\w-]+(\.so|\.dylib))\.(\d+)\.(\d+)(\.(\d+))?$/ ) {
           push(@{$globbed_hash{$1}}, $lib);
        }
        else {
            print_error("invalid library name: $lib");
        }
    }

    foreach $lib_base ( sort keys %globbed_hash ) {
        $lib = get_latest_patchlevel(@{$globbed_hash{$lib_base}});

        $lib =~ /^(lib[\w-]+(\.so|\.dylib))\.(\d+)\.(\d+)(\.(\d+))?$/;
        $lib_major = "$lib_base.$3";

        if ( $opt_check ) {
            if ( $opt_delete ) {
                print "REMOVE: $to_dir/$lib_major\n";
                print "REMOVE: $to_dir/$lib_base\n";
            }
            else {
                print "LINKLIB: $to_dir/$lib -> $to_dir/$lib_major\n";
                print "LINKLIB: $to_dir/$lib -> $to_dir/$lib_base\n";
            }
        }
        else {
            if ( $opt_delete ) {
                print "REMOVE: $to_dir/$lib_major\n";
                print "REMOVE: $to_dir/$lib_base\n";
                unlink "$to_dir/$lib_major";
                unlink "$to_dir/$lib_base";
                if ( $opt_zip ) {
                    push_on_ziplist("$to_dir/$lib_major");
                    push_on_ziplist("$to_dir/$lib_base");
                }
                return;
            }
            my $symlib;
            my @symlibs = ("$to_dir/$lib_major", "$to_dir/$lib_base");
            # remove old symlinks
            unlink(@symlibs);
            foreach $symlib (@symlibs) {
                print "LINKLIB: $lib -> $symlib\n";
                if ( !symlink("$lib", "$symlib") ) {
                    print_error("can't symlink $lib -> $symlib: $!",0);
                }
                else {
                    push_on_ziplist($symlib) if $opt_zip;
                }
            }
        }
    }
}

sub do_mkdir
{
    my $path = expand_macros(shift);
    if ( $opt_check ) {
        print "MKDIR: $path\n";
    }
    else {
        mkpath($path, 0, 0777-$umask);
    }
}

sub do_symlink
{
    my $line = shift;

    $line = expand_macros($line);
    ($from, $to) = split(' ',$line);
    if ( dirname($from) eq dirname($to) ) {
        $from = basename($from);
    }
    elsif ( dirname($from) eq '.' ) {
        # nothing to do
    }
    else {
        print_error("symlink: link must be in the same directory as file",0);
        return 0;
    }

    print "symlink: $from, to: $to\n" if $is_debug;

    return unless $has_symlinks;

    if ( $opt_check ) {
        if ( $opt_delete ) {
            print "REMOVE: $to\n";
        }
        else {
            print "SYMLINK $from -> $to\n";
        }
    }
    else {
        print "REMOVE: $to\n";
        unlink $to;
        if ( $opt_delete ) {
            push_on_ziplist($to) if $opt_zip;
            return;
        }

        print "SYMLIB: $from -> $to\n";
        if ( !symlink("$from", "$to") ) {
            print_error("can't symlink $from -> $to: $!",0);
        }
        else {
            push_on_ziplist($to) if $opt_zip;
        }
    }
}

sub do_touch
{
    my ($from, $to);
    my $line = shift;
    my $touch = 1;

    $line = expand_macros($line);
    ($from, $to) = split(' ', $line);
    print "touch: $from, to: $to\n" if $is_debug;
    glob_and_copy($from, $to, $touch);
}

#### subroutines #####

sub parse_options
{
    my $arg;
    while ( $arg = shift @ARGV ) {
        $arg =~ /^-force$/  and $opt_force  = 1 and next;
        $arg =~ /^-minor$/  and $opt_minor  = 1 and next;
        $arg =~ /^-check$/  and $opt_check  = 1 and next;
        $arg =~ /^-zip$/    and $opt_zip    = 1 and next;
        $arg =~ /^-delete$/ and $opt_delete = 1 and next;
        $arg =~ /^-link$/ and $ENV{GUI} ne 'WNT' and $opt_link = 1 and next;
        $arg =~ /^-deloutput$/ and $opt_deloutput = 1 and next;
        print_error("invalid option $arg") if ( $arg =~ /-/ );
        if ( $arg =~ /-/ || $#ARGV > -1 ) {
            usage();
            exit(1);
        }
        $dest = $arg;
    }
    # $dest and $opt_zip or $opt_delete are mutually exclusive
    if ( $dest and ($opt_zip || $opt_delete) ) {
        usage();
        exit(1);<commit_msg>INTEGRATION: CWS gh7 (1.71.74); FILE MERGED 2004/09/15 10:03:03 gh 1.71.74.1: also accept destination directories containing '-'<commit_after>:
eval 'exec perl -wS $0 ${1+"$@"}'
    if 0;
#*************************************************************************
#
#   $RCSfile: deliver.pl,v $
#
#   $Revision: 1.73 $
#
#   last change: $Author: rt $ $Date: 2004-09-20 12:27:28 $
#
#   The Contents of this file are made available subject to the terms of
#   either of the following licenses
#
#          - GNU Lesser General Public License Version 2.1
#          - Sun Industry Standards Source License Version 1.1
#
#   Sun Microsystems Inc., October, 2000
#
#   GNU Lesser General Public License Version 2.1
#   =============================================
#   Copyright 2000 by Sun Microsystems, Inc.
#   901 San Antonio Road, Palo Alto, CA 94303, USA
#
#   This library is free software; you can redistribute it and/or
#   modify it under the terms of the GNU Lesser General Public
#   License version 2.1, as published by the Free Software Foundation.
#
#   This library 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
#   Lesser General Public License for more details.
#
#   You should have received a copy of the GNU Lesser General Public
#   License along with this library; if not, write to the Free Software
#   Foundation, Inc., 59 Temple Place, Suite 330, Boston,
#   MA  02111-1307  USA
#
#
#   Sun Industry Standards Source License Version 1.1
#   =================================================
#   The contents of this file are subject to the Sun Industry Standards
#   Source License Version 1.1 (the "License"); You may not use this file
#   except in compliance with the License. You may obtain a copy of the
#   License at http://www.openoffice.org/license.html.
#
#   Software provided under this License is provided on an "AS IS" basis,
#   WITHOUT WARRUNTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING,
#   WITHOUT LIMITATION, WARRUNTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
#   MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
#   See the License for the specific provisions governing your rights and
#   obligations concerning the Software.
#
#   The Initial Developer of the Original Code is: Sun Microsystems, Inc..
#
#   Copyright: 2000 by Sun Microsystems, Inc.
#
#   All Rights Reserved.
#
#   Contributor(s): _______________________________________
#
#
#
#*************************************************************************

#
# deliver.pl - copy from module output tree to solver
#

use Cwd;
use File::Basename;
use File::Copy;
use File::DosGlob 'glob';
use File::Path;
use File::Spec;

#### script id #####

( $script_name = $0 ) =~ s/^.*\b(\w+)\.pl$/$1/;

$id_str = ' $Revision: 1.73 $ ';
$id_str =~ /Revision:\s+(\S+)\s+\$/
  ? ($script_rev = $1) : ($script_rev = "-");

print "$script_name -- version: $script_rev\n";

#### globals ####

### valid actions ###
# if you add a action 'foo', than add 'foo' to this list and
# implement 'do_foo()' in the implemented actions area
@action_list        =   (           # valid actions
                        'copy',
                        'dos',
                        'hedabu',
                        'linklib',
                        'mkdir',
                        'symlink',
                        'touch'
                        );

# copy filter: files matching these patterns won't be copied by
# the copy action
@copy_filter_patterns = (
                        '\/_[\w\-]+\.dll$' # Win32 debug dll's
                        );

$is_debug           = 0;

$module             = 0;            # module name
$base_dir           = 0;            # path to module base directory
$dlst_file          = 0;            # path to d.lst
@ilst_file          = ();           # array of pathes to image lists
$ilst_ext           = 'ilst';      # extension of image lists
$umask              = 22;           # default file/directory creation mask
$dest               = 0;            # optional destination path
$common_build       = 0;            # do we have common trees?
$common_dest        = 0;            # common tree on solver

@action_data        = ();           # LoL with all action data
@macros             = ();           # d.lst macros
@hedabu_list        = ();           # files which have to be filtered through hedabu
@zip_list           = ();           # files which have to be zipped
@common_zip_list    = ();           # common files which have to be zipped

$files_copied       = 0;            # statistics
$files_unchanged    = 0;            # statistics

$opt_force          = 0;            # option force copy
$opt_minor          = 0;            # option deliver in minor
$opt_check          = 0;            # do actually execute any action
$opt_zip            = 0;            # create an additional zip file
$opt_link           = 0;            # hard link files into the solver to save disk space
$opt_deloutput      = 0;            # delete the output tree for the project once successfully delivered

$strip = 'strip' if ($ENV{COM} ne 'MSC');

$upd           = $ENV{'UPD'};
($gui       = lc($ENV{GUI}))        || die "can't determine GUI";

# zip is default for RE
$opt_zip = 1 if ( defined($ENV{UPDATER}) && $ENV{UPDATER} eq 'YES' && defined($ENV{DELIVER_TO_ZIP}) );

$has_symlinks       = 0;            # system supports symlinks

for (@action_list) {
    $action_hash{$_}++;
}

# trap normal signals (HUP, INT, PIPE, TERM)
# for clean up on unexpected termination
use sigtrap 'handler' => \&cleanup_and_die, 'normal-signals';

#### main ####

parse_options();
init_globals();
push_default_actions();
parse_dlst();
parse_imagelists();
walk_action_data();
walk_hedabu_list();
zip_files() if $opt_zip;
delete_output() if $opt_deloutput;
print_stats();

exit(0);

#### implemented actions #####

sub do_copy
{
    # We need to copy up to four times:
    # from the platform dependent output tree,
    # from the SO platform dependent tree,
    # from the common output tree,
    # and from the SO common output tree
    # in this order.
    my ($dependent, $common, $from, $to, $file_list);
    my $line = shift;
    my $touch = 0;

    $dependent = expand_macros($line);
    ($from, $to) = split(' ', $dependent);
    print "copy dependent: from: $from, to: $to\n" if $is_debug;
    glob_and_copy($from, $to, $touch);

    my $line_so = mod_so($line);
    if ( $line_so ) {
        my $dependent = expand_macros($line_so);
        ($from, $to) = split(' ', $dependent);
        print "copy dependent: from: $from, to: $to\n" if $is_debug;
        glob_and_copy($from, $to, $touch);
    }

    if ( $common_build ) {
        $line =~ s/%__SRC%/%COMMON_OUTDIR%/ig;
        if ( $line =~ /%COMMON_OUTDIR%/ ) {
            $line =~ s/%_DEST%/%COMMON_DEST%/ig;
            $common = expand_macros($line);
            ($from, $to) = split(' ', $common);
            print "copy common: from: $from, to: $to\n" if $is_debug;
            glob_and_copy($from, $to, $touch);

            my $line_so = mod_so($line);
            if ( $line_so ) {
                $common = expand_macros($line_so);
                ($from, $to) = split(' ', $common);
                print "copy common: from: $from, to: $to\n" if $is_debug;
                glob_and_copy($from, $to, $touch);
            }
        }
    }
}

sub do_dos
{
    my $line = shift;

    my $command = expand_macros($line);
    if ( $opt_check ) {
        print "DOS: $command\n";
    }
    else {
        # HACK: remove MACOSX stuff which is wrongly labled with dos
        # better: fix broken d.lst
        return if ( $command =~ /MACOSX/ );
        $command =~ s#/#\\#g if $^O eq 'MSWin32';
        system($command);
    }
}

sub do_hedabu
{
    # just collect all hedabu files, actual filtering is done later
    my $line = shift;
    my ($from, $to);
    my @globbed_files = ();

    $line = expand_macros($line);
    ($from, $to) = split(' ', $line);

    push( @hedabu_list, @{glob_line($from, $to)});
}

sub do_linklib
{
    my ($lib_base, $lib_major,$from_dir, $to_dir);
    my $lib = shift;
    my @globbed_files = ();
    my %globbed_hash = ();

    print "linklib: $lib\n" if $is_debug;
    print "has symlinks\n" if ( $has_symlinks && $is_debug );

    return unless $has_symlinks;

    $from_dir = expand_macros('../%__SRC%/lib');
    $to_dir = expand_macros('%_DEST%/lib%_EXT%');

    @globbed_files = glob("$from_dir/$lib");

    if ( $#globbed_files == -1 ) {
       $files_unchanged++;
       return;
    }

    foreach $lib (@globbed_files) {
        $lib = basename($lib);
        if ( $lib =~ /^(lib[\w-]+(\.so|\.dylib))\.(\d+)\.(\d+)(\.(\d+))?$/ ) {
           push(@{$globbed_hash{$1}}, $lib);
        }
        else {
            print_error("invalid library name: $lib");
        }
    }

    foreach $lib_base ( sort keys %globbed_hash ) {
        $lib = get_latest_patchlevel(@{$globbed_hash{$lib_base}});

        $lib =~ /^(lib[\w-]+(\.so|\.dylib))\.(\d+)\.(\d+)(\.(\d+))?$/;
        $lib_major = "$lib_base.$3";

        if ( $opt_check ) {
            if ( $opt_delete ) {
                print "REMOVE: $to_dir/$lib_major\n";
                print "REMOVE: $to_dir/$lib_base\n";
            }
            else {
                print "LINKLIB: $to_dir/$lib -> $to_dir/$lib_major\n";
                print "LINKLIB: $to_dir/$lib -> $to_dir/$lib_base\n";
            }
        }
        else {
            if ( $opt_delete ) {
                print "REMOVE: $to_dir/$lib_major\n";
                print "REMOVE: $to_dir/$lib_base\n";
                unlink "$to_dir/$lib_major";
                unlink "$to_dir/$lib_base";
                if ( $opt_zip ) {
                    push_on_ziplist("$to_dir/$lib_major");
                    push_on_ziplist("$to_dir/$lib_base");
                }
                return;
            }
            my $symlib;
            my @symlibs = ("$to_dir/$lib_major", "$to_dir/$lib_base");
            # remove old symlinks
            unlink(@symlibs);
            foreach $symlib (@symlibs) {
                print "LINKLIB: $lib -> $symlib\n";
                if ( !symlink("$lib", "$symlib") ) {
                    print_error("can't symlink $lib -> $symlib: $!",0);
                }
                else {
                    push_on_ziplist($symlib) if $opt_zip;
                }
            }
        }
    }
}

sub do_mkdir
{
    my $path = expand_macros(shift);
    if ( $opt_check ) {
        print "MKDIR: $path\n";
    }
    else {
        mkpath($path, 0, 0777-$umask);
    }
}

sub do_symlink
{
    my $line = shift;

    $line = expand_macros($line);
    ($from, $to) = split(' ',$line);
    if ( dirname($from) eq dirname($to) ) {
        $from = basename($from);
    }
    elsif ( dirname($from) eq '.' ) {
        # nothing to do
    }
    else {
        print_error("symlink: link must be in the same directory as file",0);
        return 0;
    }

    print "symlink: $from, to: $to\n" if $is_debug;

    return unless $has_symlinks;

    if ( $opt_check ) {
        if ( $opt_delete ) {
            print "REMOVE: $to\n";
        }
        else {
            print "SYMLINK $from -> $to\n";
        }
    }
    else {
        print "REMOVE: $to\n";
        unlink $to;
        if ( $opt_delete ) {
            push_on_ziplist($to) if $opt_zip;
            return;
        }

        print "SYMLIB: $from -> $to\n";
        if ( !symlink("$from", "$to") ) {
            print_error("can't symlink $from -> $to: $!",0);
        }
        else {
            push_on_ziplist($to) if $opt_zip;
        }
    }
}

sub do_touch
{
    my ($from, $to);
    my $line = shift;
    my $touch = 1;

    $line = expand_macros($line);
    ($from, $to) = split(' ', $line);
    print "touch: $from, to: $to\n" if $is_debug;
    glob_and_copy($from, $to, $touch);
}

#### subroutines #####

sub parse_options
{
    my $arg;
    while ( $arg = shift @ARGV ) {
        $arg =~ /^-force$/  and $opt_force  = 1 and next;
        $arg =~ /^-minor$/  and $opt_minor  = 1 and next;
        $arg =~ /^-check$/  and $opt_check  = 1 and next;
        $arg =~ /^-zip$/    and $opt_zip    = 1 and next;
        $arg =~ /^-delete$/ and $opt_delete = 1 and next;
        $arg =~ /^-link$/ and $ENV{GUI} ne 'WNT' and $opt_link = 1 and next;
        $arg =~ /^-deloutput$/ and $opt_deloutput = 1 and next;
        print_error("invalid option $arg") if ( $arg =~ /^-/ );
        if ( $arg =~ /^-/ || $#ARGV > -1 ) {
            usage();
            exit(1);
        }
        $dest = $arg;
    }
    # $dest and $opt_zip or $opt_delete are mutually exclusive
    if ( $dest and ($opt_zip || $opt_delete) ) {
        usage();
        exit(1);
{'fraction_non_alphanumeric': 0.15899565200360374, 'fraction_numerical': 0.010419522895530574, 'mean_word_length': 2.0127448666509324, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 21, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 1, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 4, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1739927', 'n_tokens_mistral': 8528, 'n_tokens_neox': 8111, 'n_words': 2348}