# This module designed *only* for WinCE
# if you encounter a problem with this file, try using original Dynaloader.pm
# from perl distribution, it's larger but essentially the same.
package DynaLoader;
our $VERSION = 1.04;

$dl_debug ||= 0;

@dl_require_symbols = ();       # names of symbols we need

#@dl_librefs = (); # things we have loaded
#@dl_modules = (); # Modules we have loaded

boot_DynaLoader('DynaLoader') if defined(&boot_DynaLoader) && !defined(&dl_error);

print STDERR "DynaLoader not linked into this perl\n"
  unless defined(&boot_DynaLoader);

1; # End of main code

sub croak{require Carp;Carp::croak(@_)}
sub bootstrap_inherit {
    my $module = $_[0];
    local *isa = *{"$module\::ISA"};
    local @isa = (@isa, 'DynaLoader');
    bootstrap(@_);
}
sub bootstrap {
    # use local vars to enable $module.bs script to edit values
    local(@args) = @_;
    local($module) = $args[0];
    local(@dirs, $file);

    unless ($module) {
	require Carp;
	Carp::confess("Usage: DynaLoader::bootstrap(module)");
    }

    croak("Can't load module $module, dynamic loading not available in this perl.\n")
	unless defined(&dl_load_file);

    my @modparts = split(/::/,$module);
    my $modfname = $modparts[-1];
    my $modpname = join('/',@modparts);

    for (@INC) {
	my $dir = "$_/auto/$modpname";
	next unless -d $dir;
	my $try = "$dir/$modfname.dll";
	last if $file = ( (-f $try) && $try);
	
	$try = "$dir/${modfname}_1.dll";
	last if $file = ( (-f $try) && $try);
	push @dirs, $dir;
    }
    $file = dl_findfile(map("-L$_",@dirs,@INC), $modfname) unless $file;

    croak("Can't locate loadable object for module $module in \@INC (\@INC contains: @INC)")
	unless $file;

    (my $bootname = "boot_$module") =~ s/\W/_/g;
    @dl_require_symbols = ($bootname);

    # optional '.bootstrap' perl script
    my $bs = $file;
    $bs =~ s/(\.\w+)?(;\d*)?$/\.bs/;
    if (-s $bs) { # only read file if it's not empty
        eval { do $bs; };
        warn "$bs: $@\n" if $@;
    }

    my $libref = dl_load_file($file, 0) or
	croak("Can't load '$file' for module $module: ".dl_error());

    push(@dl_librefs,$libref);  # record loaded object

    my @unresolved = dl_undef_symbols();
    if (@unresolved) {
	require Carp;
	Carp::carp("Undefined symbols present after loading $file: @unresolved\n");
    }

    my $boot_symbol_ref = dl_find_symbol($libref, $bootname) or
         croak("Can't find '$bootname' symbol in $file\n");

    push(@dl_modules, $module);

  boot:
    my $xs = dl_install_xsub("${module}::bootstrap", $boot_symbol_ref, $file);
    &$xs(@args);
}

sub dl_findfile {
    my (@args) = @_;
    my (@dirs,  $dir);
    my (@found);

    arg: foreach(@args) {
        if (m:/: && -f $_) {
	    push(@found,$_);
	    last arg unless wantarray;
	    next;
	}

        if (s:^-L::) {push(@dirs, $_); next;}
        if (m:/: && -d $_) {push(@dirs, $_); next;}

        for $dir (@dirs) {
            next unless -d $dir;
            for my $name (/\.dll$/i?($_):("$_.dll",$_)) {
                print STDERR " checking in $dir for $name\n" if $dl_debug;
        	if (-f "$dir/$name") {
                    push(@found, "$dir/$name");
                    next arg;
                }
            }
        }
    }
    return $found[0] unless wantarray;
    @found;
}
