sub process_branch { # this sub is infinitely recursive - it calls itself sometimes! local $branch = $_[0]; if (ref $branch eq 'SCALAR') { crapout("All branches must end in a piece of sub code, not a SCALAR\n$global->{breadcrumbs}"); } elsif (ref $branch eq 'ARRAY') { crapout("All branches must end in a piece of sub code, not an ARRAY\n$global->{breadcrumbs}"); } elsif (ref $branch eq 'HASH') { foreach my $nextbranch (keys %{$branch}) { # process special keywords if ($nextbranch eq 'directory') { # look for a single directory here my @dirs = list_of_dirs_here($global->{thisdirfull}); if (@dirs > 1) { # is there more than one directory here? crapout("Invalid tree structure defined.\nYou specified a single directory at $global->{thisdir}\nbut there is more than one directory here\+nPerhaps use foreachdir?"); } elsif (@dirs == 0) { crapout("Invalid tree structure defined.\nYou specified a single directory at $global->{thisdir}\nbut there are no directories here"); } else { $global->{breadcrumbs} .= " -> directory ($dirs[0])"; $global->{thisdirfull} .= "/$dirs[0]"; $global->{thisdir} = $dirs[0]; printlog("*=====Traversing: $global->{breadcrumbs}\n"); process_branch($branch->{$nextbranch}); } } else { # no keywords - process regular $global->{breadcrumbs} .= " -> $nextbranch"; $global->{thisdirfull} .= "/$nextbranch"; $global->{thisdir} = $nextbranch; if (!-e "$global->{thisdirfull}" || !-d "$global->{thisdirfull}") { crapout("The directory $global->{thisdirfull}\ndoesn't exist or is not a directory"); } printlog("**====Traversing: $global->{breadcrumbs}\n"); process_branch($branch->{$nextbranch}); } } } elsif (ref $branch eq 'GLOB') { crapout("All branches must end in a piece of sub code, not a GLOB\n$global->{breadcrumbs}"); } elsif (ref $branch eq 'REF') { crapout("All branches must end in a piece of sub code, not a REF\n$global->{breadcrumbs}"); } elsif (ref $branch eq 'CODE') { debug("Preparing to execute the code at\nbranch: $global->{breadcrumbs}\ncurrent directory: $global->{thisdirfull}") if $global->{debug}; $branch->(); } else { crapout("All tree branches must end in a piece of sub code, not values.\nThe $global->{breadcrumbs} branch ends with the value $branch"); } }